Skip to content

Commit 1e6b9c8

Browse files
committed
allow assignment in elseif
1 parent 1d6bf56 commit 1e6b9c8

File tree

5 files changed

+115
-9
lines changed

5 files changed

+115
-9
lines changed

moonscript/parse.lua

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -398,8 +398,10 @@ local build_grammar = wrap_env(function()
398398
SwitchCase = key"when" * Exp * key"then"^-1 * Body / mark"case",
399399
SwitchElse = key"else" * Body / mark"else",
400400

401-
If = key"if" * (Exp * Assign^-1 / format_assign_for_if) * key"then"^-1 * Body *
402-
((Break * CheckIndent)^-1 * EmptyLine^0 * key"elseif" * Exp * key"then"^-1 * Body / mark"elseif")^0 *
401+
IfCond = Exp * Assign^-1 / format_assign_for_if,
402+
403+
If = key"if" * IfCond * key"then"^-1 * Body *
404+
((Break * CheckIndent)^-1 * EmptyLine^0 * key"elseif" * IfCond * key"then"^-1 * Body / mark"elseif")^0 *
403405
((Break * CheckIndent)^-1 * EmptyLine^0 * key"else" * Body / mark"else")^-1 / mark"if",
404406

405407
While = key"while" * Exp * key"do"^-1 * Body / mark"while",

moonscript/transform.lua

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,30 @@ hoist_declarations = function(body, rules)
250250
assigns
251251
})
252252
end
253+
local expand_elseif_assign
254+
expand_elseif_assign = function(ifstm)
255+
for i = 4, #ifstm do
256+
local case = ifstm[i]
257+
if ntype(case) == "elseif" and ntype(case[2]) == "assign" then
258+
local split = {
259+
unpack(ifstm, 1, i - 1)
260+
}
261+
insert(split, {
262+
"else",
263+
{
264+
{
265+
"if",
266+
case[2],
267+
case[3],
268+
unpack(ifstm, i + 1)
269+
}
270+
}
271+
})
272+
return split
273+
end
274+
end
275+
return ifstm
276+
end
253277
local constructor_name = "new"
254278
local Transformer
255279
Transformer = (function()
@@ -526,8 +550,7 @@ Statement = Transformer({
526550
return node
527551
end,
528552
["if"] = function(self, node, ret)
529-
smart_node(node)
530-
if ntype(node.cond) == "assign" then
553+
if ntype(node[2]) == "assign" then
531554
local _, assign, body = unpack(node)
532555
local name = assign[2][1]
533556
return build["do"]({
@@ -539,7 +562,9 @@ Statement = Transformer({
539562
}
540563
})
541564
end
565+
node = expand_elseif_assign(node)
542566
if ret then
567+
smart_node(node)
543568
node['then'] = apply_to_last(node['then'], ret)
544569
for i = 4, #node do
545570
local case = node[i]

moonscript/transform.moon

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,20 @@ hoist_declarations = (body, rules) ->
100100

101101
table.insert body, 1, {"declare", assigns}
102102

103+
expand_elseif_assign = (ifstm) ->
104+
for i = 4, #ifstm
105+
case = ifstm[i]
106+
if ntype(case) == "elseif" and ntype(case[2]) == "assign"
107+
split = { unpack ifstm, 1, i - 1 }
108+
insert split, {
109+
"else", {
110+
{"if", case[2], case[3], unpack ifstm, i + 1}
111+
}
112+
}
113+
return split
114+
115+
ifstm
116+
103117
constructor_name = "new"
104118

105119
class Transformer
@@ -231,19 +245,21 @@ Statement = Transformer {
231245
node
232246

233247
if: (node, ret) =>
234-
smart_node node
235248

236-
-- extract assigns in cond
237-
if ntype(node.cond) == "assign"
249+
-- expand assign in cond
250+
if ntype(node[2]) == "assign"
238251
_, assign, body = unpack node
239252
name = assign[2][1]
240253
return build["do"] {
241254
assign
242255
{"if", name, unpack node, 3}
243256
}
244257

245-
-- handle cascading return decorator
258+
node = expand_elseif_assign node
259+
260+
-- apply cascading return decorator
246261
if ret
262+
smart_node node
247263
-- mutate all the bodies
248264
node['then'] = apply_to_last node['then'], ret
249265
for i = 4, #node

tests/inputs/cond.moon

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,26 @@ else
6666
hello = 5 + if something = 10
6767
print something
6868

69+
---
70+
71+
z = false
72+
73+
if false
74+
one
75+
elseif x = true
76+
two
77+
elseif z = true
78+
three
79+
else
80+
four
81+
82+
83+
out = if false
84+
one
85+
elseif x = true
86+
two
87+
elseif z = true
88+
three
89+
else
90+
four
91+

tests/outputs/cond.lua

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,4 +109,44 @@ hello = 5 + (function()
109109
return print(something)
110110
end
111111
end
112-
end)()
112+
end)()
113+
local z = false
114+
if false then
115+
local _ = one
116+
else
117+
do
118+
local x = true
119+
if x then
120+
local _ = two
121+
else
122+
do
123+
z = true
124+
if z then
125+
local _ = three
126+
else
127+
local _ = four
128+
end
129+
end
130+
end
131+
end
132+
end
133+
local out
134+
if false then
135+
out = one
136+
else
137+
do
138+
local x = true
139+
if x then
140+
out = two
141+
else
142+
do
143+
z = true
144+
if z then
145+
out = three
146+
else
147+
out = four
148+
end
149+
end
150+
end
151+
end
152+
end

0 commit comments

Comments
 (0)