continue on all loops

This commit is contained in:
leaf corcoran 2012-10-27 22:23:06 -07:00
parent 0d5abf6cc4
commit 52655cf199
6 changed files with 129 additions and 82 deletions

View File

@ -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)

View File

@ -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"

View File

@ -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)

View File

@ -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"

View File

@ -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",

View File

@ -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}