Skip to content

Commit 7334678

Browse files
committed
switch statement
1 parent 636c242 commit 7334678

File tree

5 files changed

+105
-4
lines changed

5 files changed

+105
-4
lines changed

moonscript/parse.lua

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ local build_grammar = wrap_env(function()
272272
CheckIndent = Cmt(Indent, check_indent), -- validates line is in correct indent
273273
Line = (CheckIndent * Statement + Space * #Stop),
274274

275-
Statement = (Import + While + With + For + ForEach + Return
275+
Statement = (Import + While + With + For + ForEach + Switch + Return
276276
+ ClassDecl + Export + BreakLoop + Ct(ExpList) / flatten_or_mark"explist" * Space) * ((
277277
-- statement decorators
278278
key"if" * Exp * (key"else" * Exp)^-1 * Space / mark"if" +
@@ -298,6 +298,12 @@ local build_grammar = wrap_env(function()
298298

299299
With = key"with" * Exp * key"do"^-1 * Body / mark"with",
300300

301+
Switch = key"switch" * Exp * key"do"^-1 * Space^-1 * Break * SwitchBlock / mark"switch",
302+
303+
SwitchBlock = EmptyLine^0 * Advance * Ct(SwitchCase * (Break^1 * SwitchCase)^0 * (Break^1 * SwitchElse)^-1) * PopIndent,
304+
SwitchCase = key"when" * Exp * key"then"^-1 * Body / mark"case",
305+
SwitchElse = key"else" * Body / mark"else",
306+
301307
If = key"if" * Exp * key"then"^-1 * Body *
302308
((Break * CheckIndent)^-1 * EmptyLine^0 * key"elseif" * Exp * key"then"^-1 * Body / mark"elseif")^0 *
303309
((Break * CheckIndent)^-1 * EmptyLine^0 * key"else" * Body / mark"else")^-1 / mark"if",
@@ -317,7 +323,7 @@ local build_grammar = wrap_env(function()
317323
CompFor = key"for" * Ct(NameList) * key"in" * (sym"*" * Exp / mark"unpack" + Exp) / mark"for",
318324
CompClause = CompFor + key"when" * Exp / mark"when",
319325

320-
Assign = Ct(AssignableList) * sym"=" * (Ct(With + If) + Ct(TableBlock + ExpListLow)) / mark"assign",
326+
Assign = Ct(AssignableList) * sym"=" * (Ct(With + If + Switch) + Ct(TableBlock + ExpListLow)) / mark"assign",
321327
Update = Assignable * ((sym"..=" + sym"+=" + sym"-=" + sym"*=" + sym"/=" + sym"%=")/trim) * Exp / mark"update",
322328

323329
-- we can ignore precedence for now

moonscript/transform.lua

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,54 @@ Statement = Transformer({
492492
})
493493
end
494494
end,
495+
switch = function(self, node, ret)
496+
local _, exp, conds = unpack(node)
497+
print("compiling switch", ret)
498+
local exp_name = NameProxy("exp")
499+
local convert_cond
500+
convert_cond = function(cond)
501+
local t, case_exp, body = unpack(cond)
502+
local out = { }
503+
insert(out, t == "case" and "elseif" or "else")
504+
if t ~= "else" then
505+
if t ~= "else" then
506+
insert(out, {
507+
"exp",
508+
case_exp,
509+
"==",
510+
exp_name
511+
})
512+
end
513+
else
514+
body = case_exp
515+
end
516+
if ret then
517+
body = apply_to_last(body, ret)
518+
end
519+
insert(out, body)
520+
return out
521+
end
522+
local first = true
523+
local if_stm = {
524+
"if"
525+
}
526+
local _list_0 = conds
527+
for _index_0 = 1, #_list_0 do
528+
local cond = _list_0[_index_0]
529+
local if_cond = convert_cond(cond)
530+
if first then
531+
first = false
532+
insert(if_stm, if_cond[2])
533+
insert(if_stm, if_cond[3])
534+
else
535+
insert(if_stm, if_cond)
536+
end
537+
end
538+
return build.group({
539+
build.assign_one(exp_name, exp),
540+
if_stm
541+
})
542+
end,
495543
class = function(self, node)
496544
local _, name, parent_val, tbl = unpack(node)
497545
local constructor = nil
@@ -856,6 +904,11 @@ Value = Transformer({
856904
node
857905
})
858906
end,
907+
switch = function(self, node)
908+
return build.block_exp({
909+
node
910+
})
911+
end,
859912
chain = function(self, node)
860913
local stub = node[#node]
861914
if type(stub) == "table" and stub[1] == "colon_stub" then

moonscript/transform.moon

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,45 @@ Statement = Transformer {
267267
}
268268
}
269269

270+
switch: (node, ret) =>
271+
_, exp, conds = unpack node
272+
print "compiling switch", ret
273+
274+
exp_name = NameProxy "exp"
275+
276+
-- convert switch conds into if statment conds
277+
convert_cond = (cond) ->
278+
t, case_exp, body = unpack cond
279+
out = {}
280+
insert out, t == "case" and "elseif" or "else"
281+
if t != "else"
282+
insert out, {"exp", case_exp, "==", exp_name} if t != "else"
283+
else
284+
body = case_exp
285+
286+
if ret
287+
body = apply_to_last body, ret
288+
289+
insert out, body
290+
291+
out
292+
293+
first = true
294+
if_stm = {"if"}
295+
for cond in *conds
296+
if_cond = convert_cond cond
297+
if first
298+
first = false
299+
insert if_stm, if_cond[2]
300+
insert if_stm, if_cond[3]
301+
else
302+
insert if_stm, if_cond
303+
304+
build.group {
305+
build.assign_one exp_name, exp
306+
if_stm
307+
}
308+
270309
class: (node) =>
271310
_, name, parent_val, tbl = unpack node
272311

@@ -473,6 +512,8 @@ Value = Transformer {
473512

474513
if: (node) => build.block_exp { node }
475514
with: (node) => build.block_exp { node }
515+
switch: (node) =>
516+
build.block_exp { node }
476517

477518
-- pull out colon chain
478519
chain: (node) =>

moonscript/types.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ manual_return = data.Set({
1010
})
1111
cascading = data.Set({
1212
"if",
13-
"with"
13+
"with",
14+
"switch"
1415
})
1516
ntype = function(node)
1617
if type(node) ~= "table" then

moonscript/types.moon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import insert from table
1111
manual_return = data.Set{"foreach", "for", "while", "return"}
1212

1313
-- assigns and returns are bubbled into their bodies
14-
cascading = data.Set{ "if", "with" }
14+
cascading = data.Set{ "if", "with", "switch" }
1515

1616
-- type of node as string
1717
ntype = (node) ->

0 commit comments

Comments
 (0)