mirror of
https://github.com/leafo/moonscript.git
synced 2024-11-22 02:44:23 +00:00
function calls, compiler
This commit is contained in:
parent
3bc7a28d13
commit
65cdd26784
@ -4,43 +4,83 @@ module("moonscript", package.seeall)
|
|||||||
require"util"
|
require"util"
|
||||||
require"lpeg"
|
require"lpeg"
|
||||||
|
|
||||||
|
require"moonscript.compile"
|
||||||
|
|
||||||
local R, S, V, P = lpeg.R, lpeg.S, lpeg.V, lpeg.P
|
local R, S, V, P = lpeg.R, lpeg.S, lpeg.V, lpeg.P
|
||||||
local C, Ct = lpeg.C, lpeg.Ct
|
local C, Ct = lpeg.C, lpeg.Ct
|
||||||
|
|
||||||
local Space = S" \n\t"^0
|
local Space = S" \t"^0
|
||||||
local Indent = S"\t"^0
|
local Indent = S"\t"^0
|
||||||
local Break = S"\n"^1
|
local Break = S"\n" + -1
|
||||||
|
local ArgDelim = "," * Space
|
||||||
|
|
||||||
local Name = C(R("az", "AZ", "__") * R("az", "AZ", "__")^0) * Space
|
local Name = C(R("az", "AZ", "__") * R("az", "AZ", "__")^0) * Space
|
||||||
local Num = C(R("09")^1) * Space
|
local Num = C(R("09")^1) / tonumber * Space
|
||||||
|
|
||||||
local FactorOp = lpeg.C(S"+-") * Space
|
local FactorOp = lpeg.C(S"+-") * Space
|
||||||
local TermOp = lpeg.C(S"*/%") * Space
|
local TermOp = lpeg.C(S"*/%") * Space
|
||||||
|
|
||||||
function define(items)
|
function wrap(fn)
|
||||||
for _, name in ipairs(items) do
|
local env = getfenv(fi)
|
||||||
_G[name] = lpeg.V(name)
|
|
||||||
|
return setfenv(fn, setmetatable({}, {
|
||||||
|
__index = function(self, name)
|
||||||
|
local value = env[name]
|
||||||
|
if value ~= nil then return value end
|
||||||
|
|
||||||
|
if name:match"^[A-Z][A-Za-z0-9]*$" then
|
||||||
|
local v = V(name)
|
||||||
|
rawset(self, name, v)
|
||||||
|
return v
|
||||||
|
end
|
||||||
|
error("unknown variable referenced: "..name)
|
||||||
|
end
|
||||||
|
}))
|
||||||
|
end
|
||||||
|
|
||||||
|
function mark(name)
|
||||||
|
return function(...)
|
||||||
|
return name, ...
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
define { "Block", "Line", "Value", "Exp", "Factor", "Term" }
|
function flatten(tbl)
|
||||||
|
if #tbl == 1 then
|
||||||
|
return tbl[1]
|
||||||
|
end
|
||||||
|
return tbl
|
||||||
|
end
|
||||||
|
|
||||||
local grammar = lpeg.P{
|
|
||||||
|
local build_grammar = wrap(function()
|
||||||
|
local g = lpeg.P{
|
||||||
Block,
|
Block,
|
||||||
Block = Ct(Line^0),
|
Block = Ct(Line^0),
|
||||||
Line = Ct(C"print" * Space * Exp * Space),
|
Line = Ct(Funcall) * Break,
|
||||||
Exp = Ct(Value * (FactorOp * Value)^0),
|
Funcall = Name * ArgList / mark"fncall",
|
||||||
Value = Num + Name
|
ArgList = Ct(Exp * (ArgDelim * Exp)^0),
|
||||||
|
Exp = Ct(Value * (FactorOp * Value)^0) / flatten,
|
||||||
|
Value = Funcall + Num + Name
|
||||||
}
|
}
|
||||||
grammar = Space * grammar * Space * -1
|
return Space * g * Space * -1
|
||||||
|
end)
|
||||||
|
|
||||||
|
local grammar = build_grammar()
|
||||||
|
|
||||||
local program = [[
|
local program = [[
|
||||||
print 2323
|
hello world nuts
|
||||||
print hi + world + 2342
|
eat 232, 343
|
||||||
print 23424
|
|
||||||
]]
|
]]
|
||||||
|
-- print hi + world + 2342
|
||||||
|
-- print 23424
|
||||||
|
-- ]]
|
||||||
|
|
||||||
print(util.dump(grammar:match(program)))
|
|
||||||
|
local tree = grammar:match(program)
|
||||||
|
if not tree then error("failed to compile") end
|
||||||
|
|
||||||
|
print(util.dump(tree))
|
||||||
|
print(compile.tree(tree))
|
||||||
|
|
||||||
local program2 = [[
|
local program2 = [[
|
||||||
if something
|
if something
|
||||||
@ -73,7 +113,6 @@ class Hello
|
|||||||
}}
|
}}
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
|
||||||
function names()
|
function names()
|
||||||
tests = {
|
tests = {
|
||||||
"hello",
|
"hello",
|
||||||
|
45
moonscript/compile.lua
Normal file
45
moonscript/compile.lua
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
|
||||||
|
module("moonscript.compile", package.seeall)
|
||||||
|
require "util"
|
||||||
|
|
||||||
|
-- setmetatable(_M, {
|
||||||
|
-- __call = setfenv(function(self, ...)
|
||||||
|
-- compile(...)
|
||||||
|
-- end, _G)
|
||||||
|
-- })
|
||||||
|
|
||||||
|
local compilers = {
|
||||||
|
fncall = function(self, node)
|
||||||
|
local _, name, args = unpack(node)
|
||||||
|
return name .. self:args(args)
|
||||||
|
end,
|
||||||
|
args = function(self, node)
|
||||||
|
local values = {}
|
||||||
|
for _, v in ipairs(node) do
|
||||||
|
table.insert(values, self:value(v))
|
||||||
|
end
|
||||||
|
return "(" .. table.concat(values, ", ") .. ")"
|
||||||
|
end,
|
||||||
|
value = function(self, node)
|
||||||
|
if type(node) == "table" then
|
||||||
|
local op = unpack(node)
|
||||||
|
return self[op](self, node)
|
||||||
|
end
|
||||||
|
|
||||||
|
return node
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
_M.tree = function(tree)
|
||||||
|
local buff = {}
|
||||||
|
for _, line in ipairs(tree) do
|
||||||
|
local op = line[1]
|
||||||
|
local fn = compilers[op]
|
||||||
|
if not fn then error("Unknown op: "..op) end
|
||||||
|
table.insert(buff, compilers[op](compilers, line))
|
||||||
|
end
|
||||||
|
|
||||||
|
return table.concat(buff, "\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user