diff --git a/moonscript/compile/statement.lua b/moonscript/compile/statement.lua index 870c3ce..e773203 100644 --- a/moonscript/compile/statement.lua +++ b/moonscript/compile/statement.lua @@ -231,66 +231,12 @@ line_compile = { _with_0:append(" do") loop = _with_0 end - local continue_name = nil - local out do local _with_0 = self:block(loop) - _with_0:listen("continue", function() - if not (continue_name) then - continue_name = NameProxy("continue") - _with_0:put_name(continue_name) - end - return continue_name - end) _with_0:declare(names) _with_0:stms(block) - out = _with_0 + return _with_0 end - if continue_name then - out:put_name(continue_name, nil) - out:splice(function(lines) - return { - { - "assign", - { - continue_name - }, - { - "false" - } - }, - { - "repeat", - "true", - { - lines, - { - "assign", - { - continue_name - }, - { - "true" - } - } - } - }, - { - "if", - { - "not", - continue_name - }, - { - { - "break" - } - } - } - } - end) - end - return out end, export = function(self, node) local _, names = unpack(node) diff --git a/moonscript/compile/statement.moon b/moonscript/compile/statement.moon index 6b7f79a..00f9f38 100644 --- a/moonscript/compile/statement.moon +++ b/moonscript/compile/statement.moon @@ -122,33 +122,10 @@ line_compile = \append_list [@value exp for exp in *exps], "," \append " do" - continue_name = nil - out = with @block loop - \listen "continue", -> - unless continue_name - continue_name = NameProxy"continue" - \put_name continue_name - continue_name - + with @block loop \declare names \stms block - -- todo: figure out how to put this in the transformer - if continue_name - out\put_name continue_name, nil - out\splice (lines) -> { - {"assign", {continue_name}, {"false"}} - {"repeat", "true", { - lines - {"assign", {continue_name}, {"true"}} - }} - {"if", {"not", continue_name}, { - {"break"} - }} - } - - out - export: (node) => _, names = unpack node if type(names) == "string" diff --git a/moonscript/transform.lua b/moonscript/transform.lua index b89802f..c9618dd 100644 --- a/moonscript/transform.lua +++ b/moonscript/transform.lua @@ -275,6 +275,69 @@ expand_elseif_assign = function(ifstm) return ifstm end local constructor_name = "new" +local with_continue_listener +with_continue_listener = function(body) + local continue_name = nil + return { + Run(function(self) + return self:listen("continue", function() + if not (continue_name) then + continue_name = NameProxy("continue") + self:put_name(continue_name) + end + return continue_name + end) + end), + build.group(body), + Run(function(self) + if not (continue_name) then + return + end + self:put_name(continue_name, nil) + return self:splice(function(lines) + return { + { + "assign", + { + continue_name + }, + { + "false" + } + }, + { + "repeat", + "true", + { + lines, + { + "assign", + { + continue_name + }, + { + "true" + } + } + } + }, + { + "if", + { + "not", + continue_name + }, + { + { + "break" + } + } + } + } + end) + end) + } +end local Transformer Transformer = (function() local _parent_0 = nil @@ -753,6 +816,15 @@ Statement = Transformer({ }) }) end + node.body = with_continue_listener(node.body) + end, + ["while"] = function(self, node) + smart_node(node) + node.body = with_continue_listener(node.body) + end, + ["for"] = function(self, node) + smart_node(node) + node.body = with_continue_listener(node.body) end, switch = function(self, node, ret) local _, exp, conds = unpack(node) diff --git a/moonscript/transform.moon b/moonscript/transform.moon index ef8fd0b..7a839d4 100644 --- a/moonscript/transform.moon +++ b/moonscript/transform.moon @@ -116,6 +116,34 @@ expand_elseif_assign = (ifstm) -> constructor_name = "new" +with_continue_listener = (body) -> + continue_name = nil + { + Run => + @listen "continue", -> + unless continue_name + continue_name = NameProxy"continue" + @put_name continue_name + continue_name + + build.group body + + Run => + return unless continue_name + @put_name continue_name, nil + @splice (lines) -> { + {"assign", {continue_name}, {"false"}} + {"repeat", "true", { + lines + {"assign", {continue_name}, {"true"}} + }} + {"if", {"not", continue_name}, { + {"break"} + }} + } + } + + class Transformer new: (@transformers) => @seen_nodes = setmetatable {}, __mode: "k" @@ -346,7 +374,7 @@ Statement = Transformer { else {1, {"length", list_name}} - build.group { + return build.group { build.assign_one list_name, list slice_var build["for"] { @@ -359,6 +387,16 @@ Statement = Transformer { } } + node.body = with_continue_listener node.body + + while: (node) => + smart_node node + node.body = with_continue_listener node.body + + for: (node) => + smart_node node + node.body = with_continue_listener node.body + switch: (node, ret) => _, exp, conds = unpack node exp_name = NameProxy "exp" diff --git a/moonscript/types.lua b/moonscript/types.lua index 36d88bd..fc5ec01 100644 --- a/moonscript/types.lua +++ b/moonscript/types.lua @@ -74,7 +74,7 @@ local node_types = { }, { "body", - { } + t } }, ["for"] = { @@ -90,6 +90,16 @@ local node_types = { t } }, + ["while"] = { + { + "cond", + t + }, + { + "body", + t + } + }, assign = { { "names", diff --git a/moonscript/types.moon b/moonscript/types.moon index 3f6eb45..d072adb 100644 --- a/moonscript/types.moon +++ b/moonscript/types.moon @@ -51,13 +51,17 @@ node_types = { foreach: { {"names", t} {"iter"} - {"body", {}} + {"body", t} } for: { {"name"} {"bounds", t} {"body", t} } + while: { + {"cond", t} + {"body", t} + } assign: { {"names", t} {"values", t}