| ------------------------------------------------------------------------------- |
| -- Copyright (c) 2006-2013 Fabien Fleutot and others. |
| -- |
| -- All rights reserved. |
| -- |
| -- This program and the accompanying materials are made available |
| -- under the terms of the Eclipse Public License v1.0 which |
| -- accompanies this distribution, and is available at |
| -- http://www.eclipse.org/legal/epl-v10.html |
| -- |
| -- This program and the accompanying materials are also made available |
| -- under the terms of the MIT public license which accompanies this |
| -- distribution, and is available at http://www.lua.org/license.html |
| -- |
| -- Contributors: |
| -- Fabien Fleutot - API and implementation |
| -- |
| ------------------------------------------------------------------------------- |
| |
| -------------------------------------------------------------------------------- |
| -- |
| -- Non-Lua syntax extensions |
| -- |
| -------------------------------------------------------------------------------- |
| |
| module ("mlp", package.seeall) |
| |
| -------------------------------------------------------------------------------- |
| -- Alebraic Datatypes |
| -------------------------------------------------------------------------------- |
| local function adt (lx) |
| local tagval = id (lx) [1] |
| local tagkey = {tag="Pair", {tag="String", "tag"}, {tag="String", tagval} } |
| if lx:peek().tag == "String" or lx:peek().tag == "Number" then |
| return { tag="Table", tagkey, lx:next() } |
| elseif lx:is_keyword (lx:peek(), "{") then |
| local x = table (lx) |
| _G.table.insert (x, 1, tagkey) |
| return x |
| else return { tag="Table", tagkey } end |
| end |
| |
| expr:add{ "`", adt, builder = fget(1) } |
| |
| -------------------------------------------------------------------------------- |
| -- Anonymous lambda |
| -------------------------------------------------------------------------------- |
| local lambda_expr = gg.sequence{ |
| "|", func_params_content, "|", expr, |
| builder= function (x) |
| local li = x[2].lineinfo |
| return { tag="Function", x[1], |
| { {tag="Return", x[2], lineinfo=li }, lineinfo=li } } |
| end } |
| |
| -- In an earlier version, lambda_expr took an expr_list rather than an expr |
| -- after the 2nd bar. However, it happened to be much more of a burden than an |
| -- help, So finally I disabled it. If you want to return several results, |
| -- use the long syntax. |
| -------------------------------------------------------------------------------- |
| -- local lambda_expr = gg.sequence{ |
| -- "|", func_params_content, "|", expr_list, |
| -- builder= function (x) |
| -- return {tag="Function", x[1], { {tag="Return", unpack(x[2]) } } } end } |
| |
| expr:add (lambda_expr) |
| |
| -------------------------------------------------------------------------------- |
| -- Allows to write "a `f` b" instead of "f(a, b)". Taken from Haskell. |
| -- This is not part of Lua 5.1 syntax, so it's added to the expression |
| -- afterwards, so that it's easier to disable. |
| -------------------------------------------------------------------------------- |
| local function expr_in_backquotes (lx) return expr(lx, 35) end |
| |
| expr.infix:add{ name = "infix function", |
| "`", expr_in_backquotes, "`", prec = 35, assoc="left", |
| builder = function(a, op, b) return {tag="Call", op[1], a, b} end } |
| |
| |
| -------------------------------------------------------------------------------- |
| -- table.override assignment |
| -------------------------------------------------------------------------------- |
| |
| mlp.lexer:add "<-" |
| stat.assignments["<-"] = function (a, b) |
| assert( #a==1 and #b==1, "No multi-args for '<-'") |
| return { tag="Call", { tag="Index", { tag="Id", "table" }, |
| { tag="String", "override" } }, |
| a[1], b[1]} |
| end |
| |
| -------------------------------------------------------------------------------- |
| -- C-style op+assignments |
| -------------------------------------------------------------------------------- |
| local function op_assign(kw, op) |
| local function rhs(a, b) |
| return { tag="Op", op, a, b } |
| end |
| local function f(a,b) |
| return { tag="Set", a, _G.table.imap(rhs, a, b) } |
| end |
| mlp.lexer:add (kw) |
| mlp.stat.assignments[kw] = f |
| end |
| |
| _G.table.iforeach (op_assign, |
| {"+=", "-=", "*=", "/="}, |
| {"add", "sub", "mul", "div"}) |