From 1d6bf564af34d0c03d7f9c444aa1a8bcb6e25030 Mon Sep 17 00:00:00 2001 From: leaf corcoran Date: Mon, 1 Oct 2012 09:19:19 -0700 Subject: [PATCH] allow assignment in if condition --- moonscript/parse.lua | 11 ++++++++++- moonscript/transform.lua | 22 ++++++++++++++++++++-- moonscript/transform.moon | 19 +++++++++++++++++-- tests/inputs/cond.moon | 15 +++++++++++++++ tests/outputs/cond.lua | 27 ++++++++++++++++++++++++++- todo | 5 +++++ 6 files changed, 93 insertions(+), 6 deletions(-) diff --git a/moonscript/parse.lua b/moonscript/parse.lua index 63576c8..c1e06f8 100644 --- a/moonscript/parse.lua +++ b/moonscript/parse.lua @@ -191,6 +191,15 @@ local function format_assign(lhs_exps, assign) error "unknown assign expression" end +-- the if statement only takes a single lhs, so we wrap in table to git to +-- "assign" tuple format +local function format_assign_for_if(lhs, assign) + if assign then + return format_assign({lhs}, assign) + end + return lhs +end + local function sym(chars) return Space * chars end @@ -389,7 +398,7 @@ local build_grammar = wrap_env(function() SwitchCase = key"when" * Exp * key"then"^-1 * Body / mark"case", SwitchElse = key"else" * Body / mark"else", - If = key"if" * Exp * key"then"^-1 * Body * + If = key"if" * (Exp * Assign^-1 / format_assign_for_if) * key"then"^-1 * Body * ((Break * CheckIndent)^-1 * EmptyLine^0 * key"elseif" * Exp * key"then"^-1 * Body / mark"elseif")^0 * ((Break * CheckIndent)^-1 * EmptyLine^0 * key"else" * Body / mark"else")^-1 / mark"if", diff --git a/moonscript/transform.lua b/moonscript/transform.lua index 955881b..d01e8cd 100644 --- a/moonscript/transform.lua +++ b/moonscript/transform.lua @@ -519,9 +519,27 @@ Statement = Transformer({ end return construct_comprehension(action(exp), clauses) end, - ["if"] = function(self, node, ret) + ["do"] = function(self, node, ret) + if ret then + node[2] = apply_to_last(node[2], ret) + end + return node + end, + ["if"] = function(self, node, ret) + smart_node(node) + if ntype(node.cond) == "assign" then + local _, assign, body = unpack(node) + local name = assign[2][1] + return build["do"]({ + assign, + { + "if", + name, + unpack(node, 3) + } + }) + end if ret then - smart_node(node) node['then'] = apply_to_last(node['then'], ret) for i = 4, #node do local case = node[i] diff --git a/moonscript/transform.moon b/moonscript/transform.moon index 522b647..d512e14 100644 --- a/moonscript/transform.moon +++ b/moonscript/transform.moon @@ -226,16 +226,31 @@ Statement = Transformer { action = action or (exp) -> {exp} construct_comprehension action(exp), clauses - -- handle cascading return decorator + do: (node, ret) => + node[2] = apply_to_last node[2], ret if ret + node + if: (node, ret) => + smart_node node + + -- extract assigns in cond + if ntype(node.cond) == "assign" + _, assign, body = unpack node + name = assign[2][1] + return build["do"] { + assign + {"if", name, unpack node, 3} + } + + -- handle cascading return decorator if ret - smart_node node -- mutate all the bodies node['then'] = apply_to_last node['then'], ret for i = 4, #node case = node[i] body_idx = #node[i] case[body_idx] = apply_to_last case[body_idx], ret + node with: (node, ret) => diff --git a/tests/inputs/cond.moon b/tests/inputs/cond.moon index 9b74c0c..17b894e 100644 --- a/tests/inputs/cond.moon +++ b/tests/inputs/cond.moon @@ -50,4 +50,19 @@ if lets go elseif "just us" print "will smith" else show 5555555 +-- + +if something = 10 + print something +else + print "else" + +hello = if something = 10 + print something +else + print "else" + + +hello = 5 + if something = 10 + print something diff --git a/tests/outputs/cond.lua b/tests/outputs/cond.lua index ff2f8bc..47ea285 100644 --- a/tests/outputs/cond.lua +++ b/tests/outputs/cond.lua @@ -84,4 +84,29 @@ elseif "just us" then print("will smith") else show(5555555) -end \ No newline at end of file +end +do + local something = 10 + if something then + print(something) + else + print("else") + end +end +local hello +do + local something = 10 + if something then + hello = print(something) + else + hello = print("else") + end +end +hello = 5 + (function() + do + local something = 10 + if something then + return print(something) + end + end +end)() \ No newline at end of file diff --git a/todo b/todo index adecb28..eaf32cc 100644 --- a/todo +++ b/todo @@ -50,3 +50,8 @@ not working right: * let array items in table be defined without {} when indented + +* allow dot access with names that are keywords: hello.then + +* convert tree transformer to be depth first instead of breadth first (lazy) +