]> git.lizzy.rs Git - metalua.git/blob - src/compiler/mlp_ext.lua
minor stuff
[metalua.git] / src / compiler / mlp_ext.lua
1 --------------------------------------------------------------------------------
2 --
3 -- Non-Lua syntax extensions
4 --
5 --------------------------------------------------------------------------------
6
7 module ("mlp", package.seeall)
8
9 --------------------------------------------------------------------------------
10 -- Alebraic Datatypes
11 --------------------------------------------------------------------------------
12 local function adt (lx)
13    local tagval = id (lx) [1]
14    local tagkey = {tag="Pair", {tag="String", "tag"}, {tag="String", tagval} }
15    if lx:peek().tag == "String" or lx:peek().tag == "Number" then
16       return { tag="Table", tagkey, lx:next() }
17    elseif lx:is_keyword (lx:peek(), "{") then
18       local x = table (lx)
19       _G.table.insert (x, 1, tagkey)
20       return x
21    else return { tag="Table", tagkey } end
22 end
23
24 expr:add{ "`", adt, builder = fget(1) }
25
26 --------------------------------------------------------------------------------
27 -- Anonymous lambda
28 --------------------------------------------------------------------------------
29 local lambda_expr = gg.sequence{ 
30    "|", func_params_content, "|", expr,
31    builder= function (x) 
32       return {tag="Function", x[1], { {tag="Return", x[2] } } } end }
33
34 -- In an earlier version, lambda_expr took an expr_list rather than an expr
35 -- after the 2nd bar. However, it happened to be much more of a burden than an
36 -- help, So finally I disabled it. If you want to return several results, 
37 -- use the long syntax.
38 --------------------------------------------------------------------------------
39 -- local lambda_expr = gg.sequence{ 
40 --    "|", func_params_content, "|", expr_list,
41 --    builder= function (x) 
42 --       return {tag="Function", x[1], { {tag="Return", unpack(x[2]) } } } end }
43
44 expr:add (lambda_expr)
45
46 --------------------------------------------------------------------------------
47 -- Allows to write "a `f` b" instead of "f(a, b)". Taken from Haskell.
48 -- This is not part of Lua 5.1 syntax, so it's added to the expression
49 -- afterwards, so that it's easier to disable.
50 --------------------------------------------------------------------------------
51 local function expr_in_backquotes (lx) return expr(lx, 35) end
52
53 expr.infix:add{ name = "infix function", 
54    "`", expr_in_backquotes, "`", prec = 35, assoc="left", 
55    builder = function(a, op, b) return {tag="Call", op[1], a, b} end }
56
57
58 --------------------------------------------------------------------------------
59 -- table.override assignment
60 --------------------------------------------------------------------------------
61
62 mlp.lexer:add "<-"
63 stat.assignments["<-"] = function (a, b)
64    assert( #a==1 and #b==1, "No multi-args for '<-'")                         
65    return { tag="Call", { tag="Index", { tag="Id", "table" },
66                                        { tag="String", "override" } },
67                         a[1], b[1]} 
68 end
69
70 --------------------------------------------------------------------------------
71 -- C-style op+assignments
72 --------------------------------------------------------------------------------
73 local function op_assign(kw, op) 
74    local function rhs(a, b)
75       return { tag="Op", op, a, b } 
76    end
77    local function f(a,b) 
78       return { tag="Set", a, _G.table.imap(rhs, a, b) }
79    end
80    mlp.lexer:add (kw)
81    mlp.stat.assignments[kw] = f
82 end
83
84 _G.table.iforeach (op_assign, 
85                 {"+=", "-=", "*=", "/="},
86                 {"add", "sub", "mul", "div"})