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