switch statement

This commit is contained in:
leaf corcoran 2011-11-17 21:48:50 -08:00
parent 636c24258f
commit 7334678579
5 changed files with 105 additions and 4 deletions

View File

@ -272,7 +272,7 @@ local build_grammar = wrap_env(function()
CheckIndent = Cmt(Indent, check_indent), -- validates line is in correct indent
Line = (CheckIndent * Statement + Space * #Stop),
Statement = (Import + While + With + For + ForEach + Return
Statement = (Import + While + With + For + ForEach + Switch + Return
+ ClassDecl + Export + BreakLoop + Ct(ExpList) / flatten_or_mark"explist" * Space) * ((
-- statement decorators
key"if" * Exp * (key"else" * Exp)^-1 * Space / mark"if" +
@ -298,6 +298,12 @@ local build_grammar = wrap_env(function()
With = key"with" * Exp * key"do"^-1 * Body / mark"with",
Switch = key"switch" * Exp * key"do"^-1 * Space^-1 * Break * SwitchBlock / mark"switch",
SwitchBlock = EmptyLine^0 * Advance * Ct(SwitchCase * (Break^1 * SwitchCase)^0 * (Break^1 * SwitchElse)^-1) * PopIndent,
SwitchCase = key"when" * Exp * key"then"^-1 * Body / mark"case",
SwitchElse = key"else" * Body / mark"else",
If = key"if" * Exp * 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",
@ -317,7 +323,7 @@ local build_grammar = wrap_env(function()
CompFor = key"for" * Ct(NameList) * key"in" * (sym"*" * Exp / mark"unpack" + Exp) / mark"for",
CompClause = CompFor + key"when" * Exp / mark"when",
Assign = Ct(AssignableList) * sym"=" * (Ct(With + If) + Ct(TableBlock + ExpListLow)) / mark"assign",
Assign = Ct(AssignableList) * sym"=" * (Ct(With + If + Switch) + Ct(TableBlock + ExpListLow)) / mark"assign",
Update = Assignable * ((sym"..=" + sym"+=" + sym"-=" + sym"*=" + sym"/=" + sym"%=")/trim) * Exp / mark"update",
-- we can ignore precedence for now

View File

@ -492,6 +492,54 @@ Statement = Transformer({
})
end
end,
switch = function(self, node, ret)
local _, exp, conds = unpack(node)
print("compiling switch", ret)
local exp_name = NameProxy("exp")
local convert_cond
convert_cond = function(cond)
local t, case_exp, body = unpack(cond)
local out = { }
insert(out, t == "case" and "elseif" or "else")
if t ~= "else" then
if t ~= "else" then
insert(out, {
"exp",
case_exp,
"==",
exp_name
})
end
else
body = case_exp
end
if ret then
body = apply_to_last(body, ret)
end
insert(out, body)
return out
end
local first = true
local if_stm = {
"if"
}
local _list_0 = conds
for _index_0 = 1, #_list_0 do
local cond = _list_0[_index_0]
local if_cond = convert_cond(cond)
if first then
first = false
insert(if_stm, if_cond[2])
insert(if_stm, if_cond[3])
else
insert(if_stm, if_cond)
end
end
return build.group({
build.assign_one(exp_name, exp),
if_stm
})
end,
class = function(self, node)
local _, name, parent_val, tbl = unpack(node)
local constructor = nil
@ -856,6 +904,11 @@ Value = Transformer({
node
})
end,
switch = function(self, node)
return build.block_exp({
node
})
end,
chain = function(self, node)
local stub = node[#node]
if type(stub) == "table" and stub[1] == "colon_stub" then

View File

@ -267,6 +267,45 @@ Statement = Transformer {
}
}
switch: (node, ret) =>
_, exp, conds = unpack node
print "compiling switch", ret
exp_name = NameProxy "exp"
-- convert switch conds into if statment conds
convert_cond = (cond) ->
t, case_exp, body = unpack cond
out = {}
insert out, t == "case" and "elseif" or "else"
if t != "else"
insert out, {"exp", case_exp, "==", exp_name} if t != "else"
else
body = case_exp
if ret
body = apply_to_last body, ret
insert out, body
out
first = true
if_stm = {"if"}
for cond in *conds
if_cond = convert_cond cond
if first
first = false
insert if_stm, if_cond[2]
insert if_stm, if_cond[3]
else
insert if_stm, if_cond
build.group {
build.assign_one exp_name, exp
if_stm
}
class: (node) =>
_, name, parent_val, tbl = unpack node
@ -473,6 +512,8 @@ Value = Transformer {
if: (node) => build.block_exp { node }
with: (node) => build.block_exp { node }
switch: (node) =>
build.block_exp { node }
-- pull out colon chain
chain: (node) =>

View File

@ -10,7 +10,8 @@ manual_return = data.Set({
})
cascading = data.Set({
"if",
"with"
"with",
"switch"
})
ntype = function(node)
if type(node) ~= "table" then

View File

@ -11,7 +11,7 @@ import insert from table
manual_return = data.Set{"foreach", "for", "while", "return"}
-- assigns and returns are bubbled into their bodies
cascading = data.Set{ "if", "with" }
cascading = data.Set{ "if", "with", "switch" }
-- type of node as string
ntype = (node) ->