assignable if, exp list as statement, ; as value separator

This commit is contained in:
leaf corcoran 2011-05-29 22:38:47 -07:00
parent 2e8c33ad23
commit 233738aad2
7 changed files with 77 additions and 17 deletions

View File

@ -44,7 +44,10 @@ local moonlib = {
} }
-- these are always expressions, never statements, must be sent into temp variable -- these are always expressions, never statements, must be sent into temp variable
local must_return = data.Set{ 'parens', 'exp', 'value', 'string', 'table', 'fndef' } local must_return = data.Set{ 'parens', 'exp', 'value', 'string', 'table', 'fndef', 'explist' }
-- these can't return a value, and must be munged
local block_statements = data.Set{ 'if' }
-- make sure there are no block levels statements in expression -- make sure there are no block levels statements in expression
local function validate_expression(block) local function validate_expression(block)
@ -324,7 +327,7 @@ local compiler_index = {
local len = #node local len = #node
for i=1,len do for i=1,len do
local ln = node[i] local ln = node[i]
local value = self:stm(ln, return_value and i == len) local value = self:stm(ln, i == len and return_value)
if type(value) == "table" then if type(value) == "table" then
for _, v in ipairs(value) do for _, v in ipairs(value) do
table.insert(lines, v) table.insert(lines, v)
@ -384,7 +387,6 @@ local compiler_index = {
assign = function(self, node) assign = function(self, node)
local _, names, values = unpack(node) local _, names, values = unpack(node)
local assigns, current = {}, nil
-- declare undeclared names -- declare undeclared names
local undeclared_names = {} local undeclared_names = {}
@ -395,19 +397,26 @@ local compiler_index = {
end end
end end
local compact = not block_statements[ntype(values)] and #undeclared_names == #names
local lines = {} local lines = {}
local num_undeclared = #undeclared_names local num_undeclared = #undeclared_names
if num_undeclared > 0 and num_undeclared ~= #names then if num_undeclared > 0 and not compact then
table.insert(lines, "local "..table.concat(undeclared_names, ", ")) table.insert(lines, "local "..table.concat(undeclared_names, ", "))
end end
local ln = self:name_list(names).. " = "..table.concat(self:values(values), ", ") if block_statements[ntype(values)] then
table.insert(lines, self:stm(values, self:name_list(names)))
else
local ln = self:name_list(names).." = "..table.concat(self:values(values), ", ")
if num_undeclared == #names then if compact then
ln = "local "..ln ln = "local "..ln
end end
table.insert(lines, ln) table.insert(lines, ln)
end
return self:pretty(lines) return self:pretty(lines)
end, end,
@ -432,6 +441,14 @@ local compiler_index = {
return delim..inner..(delim_end or delim) return delim..inner..(delim_end or delim)
end, end,
explist = function(self, node)
local values = {}
for i=2,#node do
table.insert(values, self:value(node[i]))
end
return table.concat(values, ", ")
end,
value = function(self, node, return_value, ...) value = function(self, node, return_value, ...)
if return_value == nil then return_value = true end if return_value == nil then return_value = true end
@ -452,7 +469,12 @@ local compiler_index = {
if must_return[ntype(node)] then if must_return[ntype(node)] then
if return_value then if return_value then
return "return "..value local return_to = "return"
if type(return_value) == "string" then
return_to = return_value.." ="
end
return return_to.." "..value
else else
return self:value({"assign", {"_"}, {value}}, false) return self:value({"assign", {"_"}, {value}}, false)
end end

View File

@ -218,7 +218,7 @@ local build_grammar = wrap(function()
Block = Ct(Line * (Break^1 * Line)^0), Block = Ct(Line * (Break^1 * Line)^0),
Line = Cmt(Indent, check_indent) * Statement + _Space * Comment, Line = Cmt(Indent, check_indent) * Statement + _Space * Comment,
Statement = (Import + If + While + Exp * Space) * ( Statement = (Import + If + While + Ct(ExpList) / flatten_or_mark"explist" * Space) * (
-- statement decorators -- statement decorators
key"if" * Exp * (key"else" * Exp)^-1 * Space / mark"if" + key"if" * Exp * (key"else" * Exp)^-1 * Space / mark"if" +
CompInner / mark"comprehension" CompInner / mark"comprehension"
@ -249,7 +249,7 @@ local build_grammar = wrap(function()
CompFor = key"for" * Ct(NameList) * key"in" * Exp / mark"for", CompFor = key"for" * Ct(NameList) * key"in" * Exp / mark"for",
CompClause = CompFor + key"when" * Exp / mark"when", CompClause = CompFor + key"when" * Exp / mark"when",
Assign = Ct(AssignableList) * sym"=" * Ct(TableBlock + ExpList) / mark"assign", Assign = Ct(AssignableList) * sym"=" * (Ct(TableBlock + ExpListLow) + If) / mark"assign",
-- we can ignore precedence for now -- we can ignore precedence for now
OtherOps = op"or" + op"and" + op"<=" + op">=" + op"~=" + op"!=" + op"==" + op".." + op"<" + op">", OtherOps = op"or" + op"and" + op"<=" + op">=" + op"~=" + op"!=" + op"==" + op".." + op"<" + op">",
@ -324,7 +324,8 @@ local build_grammar = wrap(function()
(Body + Ct"") / mark"fndef", (Body + Ct"") / mark"fndef",
NameList = Name * (sym"," * Name)^0, NameList = Name * (sym"," * Name)^0,
ExpList = Exp * (sym"," * Exp)^0 ExpList = Exp * (sym"," * Exp)^0,
ExpListLow = Exp * ((sym"," + sym";") * Exp)^0,
} }
return { return {

View File

@ -50,13 +50,16 @@ local function run_file(name, benchmark)
if benchmark then parse_time = gettime() - start_parse end if benchmark then parse_time = gettime() - start_parse end
if not tree then if not tree then
error("Compile error in "..name.."\n"..err) error("Parse error in "..name.."\n"..err)
end end
local start_compile local start_compile
if benchmark then start_compile = gettime() end if benchmark then start_compile = gettime() end
local code = compile.tree(tree) local success, code = pcall(compile.tree, tree)
if not success then
error("Compile error in"..name..":\n"..code)
end
if benchmark then if benchmark then
local compile_time = gettime() - start_compile local compile_time = gettime() - start_compile

View File

@ -14,3 +14,17 @@
joop = 2345 joop = 2345
a, b = if hello
"hello"
else
"nothing", "yeah"
a, b = if hello
if yeah then "one", "two" else "mmhh"
else
print "the other"
"nothing", "yeah"

View File

@ -26,7 +26,7 @@ a, bunch, go, here = another, world
func arg1, arg2, another, arg3 func arg1, arg2, another, arg3
here, we = () ->, yeah here, we = () ->, yeah
the, different = () -> approach, yeah the, different = () -> approach; yeah
dad() dad()
dad(lord) dad(lord)
@ -132,4 +132,7 @@ y = #"hello"
x = #{#{},#{1},#{1,2}} x = #{#{},#{1},#{1,2}}
hello, world

View File

@ -11,3 +11,19 @@ local _ = function()
end end
end end
local joop = 2345 local joop = 2345
local a, b
if hello then
a, b = "hello"
else
a, b = "nothing", "yeah"
end
if hello then
if yeah then
a, b = "one", "two"
else
a, b = "mmhh"
end
else
print("the other")
a, b = "nothing", "yeah"
end

View File

@ -87,3 +87,4 @@ x = not true
local y = not (5 + 5) local y = not (5 + 5)
y = #"hello" y = #"hello"
x = #{ #{ }, #{ 1 }, #{ 1, 2 } } x = #{ #{ }, #{ 1 }, #{ 1, 2 } }
_ = hello, world