implicit return has returned, cascading assignment

This commit is contained in:
leaf corcoran 2011-06-11 09:45:25 -07:00
parent 02fac90e4c
commit 8fb80ee799
2 changed files with 70 additions and 14 deletions

View File

@ -3,9 +3,10 @@ module "moonscript.compile", package.seeall
util = require "moonscript.util" util = require "moonscript.util"
data = require "moonscript.data" data = require "moonscript.data"
dump = require "moonscript.dump"
import map, bind, itwos, every, reversed from util import map, bind, itwos, every, reversed from util
import Stack, ntype from data import Stack, Set, ntype from data
import concat, insert from table import concat, insert from table
indent_char = " " indent_char = " "
@ -23,6 +24,8 @@ moonlib =
bind: (tbl, name) -> bind: (tbl, name) ->
concat {"moon.bind(", tbl, ".", name, ", ", tbl, ")"} concat {"moon.bind(", tbl, ".", name, ", ", tbl, ")"}
cascading = Set{ "if" }
line_compile = line_compile =
assign: (node) => assign: (node) =>
_, names, values = unpack node _, names, values = unpack node
@ -32,14 +35,27 @@ line_compile =
@put_name name for name in *undeclared @put_name name for name in *undeclared
declare = "local "..(concat undeclared, ", ") declare = "local "..(concat undeclared, ", ")
values = concat [@value v for v in *values], ", "
if @is_stm values
@add_line declare if #undeclared > 0
if cascading[ntype(values)]
decorate = (value) ->
{"assign", names, {value}}
@stm values, decorate
else
@add_line concat([@value n for n in *names], ", ").." = "..@value values
else
values = concat [@value v for v in *values], ", "
if #undeclared == #names if #undeclared == #names
@add_line declare..' = '..values @add_line declare..' = '..values
else else
@add_line declare if #undeclared > 0 @add_line declare if #undeclared > 0
@add_line concat([@value n for n in *names], ", ").." = "..values @add_line concat([@value n for n in *names], ", ").." = "..values
["return"]: (node) =>
@add_line "return", @value node[2]
["import"]: (node) => ["import"]: (node) =>
_, names, source = unpack node _, names, source = unpack node
@ -81,7 +97,7 @@ line_compile =
@add_line "end" @add_line "end"
["if"]: (node) => ["if"]: (node, ret) =>
cond, block = node[2], node[3] cond, block = node[2], node[3]
add_clause = (clause) -> add_clause = (clause) ->
@ -94,13 +110,13 @@ line_compile =
clause[3] clause[3]
b = @block() b = @block()
b:stms block b:stms block, ret
@add_line b:render() @add_line b:render()
@add_line "if", (@value cond), "then" @add_line "if", (@value cond), "then"
b = @block() b = @block()
b:stms block b:stms block, ret
@add_line b:render() @add_line b:render()
add_clause cond for i, cond in ipairs node when i > 3 add_clause cond for i, cond in ipairs node when i > 3
@ -167,7 +183,6 @@ line_compile =
render_clause action, clause for i, clause in reversed clauses render_clause action, clause for i, clause in reversed clauses
-- do this in a do end? probably a good idea
@add_lines action._lines -- do this better? @add_lines action._lines -- do this better?
value_compile = value_compile =
@ -190,6 +205,11 @@ value_compile =
_, delim, inner, delim_end = unpack node _, delim, inner, delim_end = unpack node
delim..inner..(delim_end or delim) delim..inner..(delim_end or delim)
["if"]: (node) =>
func = @block()
func:stm node, (exp) -> {"return", exp}
@format "(function()", func:render(), "end)()"
comprehension: (node) => comprehension: (node) =>
exp = node[2] exp = node[2]
func = @block() func = @block()
@ -239,7 +259,7 @@ value_compile =
b = @block() b = @block()
b:put_name name for name in *args b:put_name name for name in *args
b:stms block b:ret_stms block
decl = "function("..(concat args, ", ")..")" decl = "function("..(concat args, ", ")..")"
if #b._lines == 0 if #b._lines == 0
@ -354,12 +374,19 @@ B =
block: (node) => block: (node) =>
Block(self) Block(self)
is_stm: (node) =>
line_compile[ntype node] != nil
is_value: (node) =>
t = ntype node
value_compile[t] != nil or t == "value"
-- line wise compile functions -- line wise compile functions
name: (node) => @value node name: (node) => @value node
value: (node, ...) => value: (node, ...) =>
return tostring node if type(node) != "table" return tostring node if type(node) != "table"
fn = value_compile[node[1]] fn = value_compile[node[1]]
error "Failed to compile value: "..node[1] if not fn error "Failed to compile value: "..dump.value node if not fn
fn self, node, ... fn self, node, ...
values: (values, delim) => values: (values, delim) =>
@ -374,7 +401,32 @@ B =
out = fn self, node, ... out = fn self, node, ...
@add_line out if out @add_line out if out
stms: (stms) => ret_stms: (stms, ret) =>
if not ret
ret = (exp) -> {"return", exp}
-- wow I really need a for loop
i = 1
while i < #stms
@stm stms[i]
i = i + 1
if stms[i]
if cascading[ntype(stms[i])]
@stm stms[i], ret
else
line = ret stms[i]
if @is_stm line
@stm line
else
@stm strms[i]
nil
stms: (stms, ret) =>
if ret
@ret_stms stms, ret
else
@stm stm for stm in *stms @stm stm for stm in *stms
nil nil

View File

@ -14,6 +14,10 @@ local function flat_value(op, depth)
return "{"..table.concat(items, ", ").."}" return "{"..table.concat(items, ", ").."}"
end end
function value(op)
return flat_value(op)
end
function tree(block, depth) function tree(block, depth)
depth = depth or 0 depth = depth or 0
for _, op in ipairs(block) do for _, op in ipairs(block) do