module ('spmatch', package.seeall)\r
-{extension 'log'}\r
\r
+match_function_builder = |tag| function (x) \r
+ local func_name, _, cases = unpack(x)\r
+ local arity = #cases[1][1][1]\r
+ if arity==0 then \r
+ error "There must be at least 1 case in match function" \r
+ end\r
+ local args = { }\r
+ for i=1, arity do args[i] = mlp.gensym("arg."..i) end\r
+ local body = match_builder{args, cases}\r
+ return { tag=tag, {func_name}, { `Function{ args, {body} } } }\r
+end\r
+\r
-- Get rid of the former parser, it will be blended in a multiseq:\r
mlp.stat:del 'match'\r
\r
-- "match function f $2 end"\r
----------------------------------------------------------------\r
{ 'function', mlp.expr, gg.optkeyword '|',\r
- match_cases_list_parser,\r
- 'end',\r
- builder = function(x) \r
- local func_name, _, cases = unpack(x)\r
- local arity = #cases[1][1][1]\r
- if arity==0 then \r
- error "There must be at least 1 case in match function" \r
- end\r
- local args = { }\r
- for i=1, arity do args[i] = mlp.gensym("arg."..i) end\r
- local body = match_builder{args, cases}\r
- return `Set{ {func_name}, { `Function{ args, {body} } } }\r
- end },\r
+ match_cases_list_parser, 'end', \r
+ builder = match_function_builder 'Set' },\r
\r
----------------------------------------------------------------\r
-- Reintroduce the original match statement:\r
----------------------------------------------------------------\r
default = gg.sequence{\r
mlp.expr_list, 'with', gg.optkeyword '|',\r
- match_cases_list_parser,\r
- 'end',\r
+ match_cases_list_parser, 'end',\r
builder = |x| match_builder{ x[1], x[3] } } } }\r
\r
+----------------------------------------------------------------------\r
+-- Shortcut: "local match function f $cases end" translates to:\r
+-- "local function f($args) match $args with $cases end end"\r
+----------------------------------------------------------------------\r
+mlp.stat:get'local'[2]:add{\r
+ 'match', 'function', mlp.expr, gg.optkeyword '|',\r
+ match_cases_list_parser, 'end',\r
+ builder = match_function_builder 'Localrec' }\r
+\r
mlp.expr:add{ 'match', builder = |x| x[1], gg.multisequence{\r
\r
----------------------------------------------------------------\r
-{ extension 'xmatch' }\r
\r
-print(match 1 with 1 -> 'ok' | 2 -> 'KO' end)\r
+WIDTH=60\r
+function p(msg) io.write(msg..' ':rep(WIDTH-#msg)) end\r
\r
-function f(x)\r
- match x with\r
- | y if y<10 -> print 'small'\r
- | _ -> print 'big'\r
- end\r
-end\r
+----------------------------------------------------------------------\r
+p"match as an expression"\r
+print(match 1 with 1 -> 'ok' | 2 -> 'KO' end)\r
\r
+----------------------------------------------------------------------\r
+p "global match function"\r
match function g\r
-| x if x<10 -> print 'small'\r
-| _ -> print 'big'\r
+| x if x<10 -> return 'o'\r
+| _ -> return 'k'\r
end\r
+print(g(1)..g(11))\r
\r
+----------------------------------------------------------------------\r
+p "global match function, multi-args"\r
match function cmp\r
-| x, y if x<y -> print 'increasing'\r
-| _, _ -> print 'decreasing'\r
-end\r
+| x, y if x<y -> return 'increasing'\r
+| _, _ -> return 'decreasing'\r
+ end\r
\r
-f(1) f(11) g(1) g(11)\r
+if cmp(1,2)=='increasing' and cmp(2,1)=='decreasing' then\r
+ print "ok" else print "KO"\r
+end\r
\r
-cmp(1,2) cmp(2,1)\r
+----------------------------------------------------------------------\r
+p "local match function"\r
+do\r
+ local match function x\r
+ | 1 -> print 'ok'\r
+ end\r
+ x(1)\r
+end\r
+assert(not x)\r
\r
+----------------------------------------------------------------------\r
+p "global bind assignment"\r
bind {a, b} = {'o', 'k'}\r
-\r
print(a..b)\r
\r
+----------------------------------------------------------------------\r
+p "local bind assignment"\r
c, d = 'k', 'o'\r
-\r
do\r
local bind {c, {d}} = {'o', {'k'}}\r
print(c..d)\r
end\r
\r
+----------------------------------------------------------------------\r
+p "local bind assignment scope"\r
print(d..c)\r