diff --git a/examples/README.md b/examples/README.md index 3c966e7..8bad858 100644 --- a/examples/README.md +++ b/examples/README.md @@ -60,9 +60,10 @@ ## 推荐的例子 -有一些大型且之后编写的例子, 熟练后可以作为参考 +有一些大型且之后编写的例子, 熟练后可以作为参考, 或截取其中部分作为工具库 -- [`21point.mdtlbl`](./21point.mdtlbl)
-- [`bezier_curve.mdtlbl`](./bezier_curve.mdtlbl)
-- [`gravity_simulation.mdtlbl`](./gravity_simulation.mdtlbl)
-- [`sine_superposition.mdtlbl`](./sine_superposition.mdtlbl)
+- [`21point.mdtlbl`](./21point.mdtlbl) +- [`bezier_curve.mdtlbl`](./bezier_curve.mdtlbl) +- [`gravity_simulation.mdtlbl`](./gravity_simulation.mdtlbl) +- [`sine_superposition.mdtlbl`](./sine_superposition.mdtlbl) +- [`function.mdtlbl`](./function.mdtlbl) diff --git a/examples/function.mdtlbl b/examples/function.mdtlbl new file mode 100644 index 0000000..5da91ec --- /dev/null +++ b/examples/function.mdtlbl @@ -0,0 +1,118 @@ +#** +* 虽然直接展开代码可以无性能损耗, 但是如果行数过多, +* 我们就需要考虑原生逻辑中常用的封装方法: 函数 了 +* 函数虽然相对来说限制很多, 只能传普通值, 速度慢等 +* 但是节省代码行数很有效 +* +* 如果要使用可以直接将这部分复制粘贴到你的代码中, 非常方便 +*# + +Builtin.BindSep! '.'; +Builtin.MissesMatch! 1; + +const Function = (const match @ => @ F { + match @ => @ { } + + take B = $; + + skip { + const B.Body = F; + const B.Expander = ( + :start + ...Body! @; + @counter = ...ret_counter; + + const ...Goto = ([B:..| :start]( + B.ret_counter = @counter + 1; + goto :start; + )); + ); + const B.RawCall = (match @ { + { + ...Goto!; + setres ...result; + } + }); + inline@ Arg { + take Handle = Builtin.BindHandle2[`B` Arg]; + const B.Expander = ([Handle &E:B->Expander]( + setres E[Handle @]; + )); + const B.RawCall = ([Handle &C:B->RawCall](match @ { + @ Fst { + Handle = Fst; + setres C[@]; + } + })); + } + B.Expander!; + + take*B.ArgC = Builtin.ArgsLen[]; + const B.RawCall = ([ArgC:B.ArgC &C:B->RawCall]( + match Builtin.ArgsLen[] { + [ArgC] { + setres C[@]; + } + N { + Builtin.ExpandStack!; + Builtin.Err! *Builtin.Concat[ + "Unexpected argc " + *Builtin.Concat[ + *Builtin.Stringify[N] + *Builtin.Concat[ + ", expected: " + *Builtin.Stringify[ArgC] + ] + ] + ]; + inline@ Arg { + Builtin.Err! Arg; + } + Builtin.Exit! 3; + } + } + )); + + const B.Call = (match @ => @ { + setres ...RawCall[@]; + }); + } +}); + +const Add = Function[a b ( + ...result = _0 + _1; +)]->Call; + +const Foo = Function[( + ...result = 3; +)]->Call; + +print Add[1 2]", "Add[3 4]"\n"; +print "foo: "Foo[]; +printflush message1; + +#* >>> +jump 6 always 0 0 +op add __5.result __5.a __5.b +set @counter __5.ret_counter +jump 6 always 0 0 +set __32.result 3 +set @counter __32.ret_counter +set __5.b 2 +set __5.a 1 +op add __5.ret_counter @counter 1 +jump 1 always 0 0 +print __5.result +print ", " +set __5.b 4 +set __5.a 3 +op add __5.ret_counter @counter 1 +jump 1 always 0 0 +print __5.result +print "\n" +print "foo: " +op add __32.ret_counter @counter 1 +jump 4 always 0 0 +print __32.result +printflush message1 +*#