mirror of
https://github.com/leafo/moonscript.git
synced 2025-01-09 00:04:22 +00:00
continue support in foreach loop
This commit is contained in:
parent
9d6467977a
commit
0d5abf6cc4
@ -134,6 +134,17 @@ Block = (function()
|
|||||||
get = function(self, name)
|
get = function(self, name)
|
||||||
return self._state[name]
|
return self._state[name]
|
||||||
end,
|
end,
|
||||||
|
listen = function(self, name, fn)
|
||||||
|
self._listeners[name] = fn
|
||||||
|
end,
|
||||||
|
send = function(self, name, ...)
|
||||||
|
do
|
||||||
|
local fn = self._listeners[name]
|
||||||
|
if fn then
|
||||||
|
return fn(self, ...)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
declare = function(self, names)
|
declare = function(self, names)
|
||||||
local undeclared = (function()
|
local undeclared = (function()
|
||||||
local _accum_0 = { }
|
local _accum_0 = { }
|
||||||
@ -173,11 +184,15 @@ Block = (function()
|
|||||||
whitelist_names = function(self, names)
|
whitelist_names = function(self, names)
|
||||||
self._name_whitelist = Set(names)
|
self._name_whitelist = Set(names)
|
||||||
end,
|
end,
|
||||||
put_name = function(self, name)
|
put_name = function(self, name, ...)
|
||||||
|
value = ...
|
||||||
|
if select("#", ...) == 0 then
|
||||||
|
value = true
|
||||||
|
end
|
||||||
if util.moon.type(name) == NameProxy then
|
if util.moon.type(name) == NameProxy then
|
||||||
name = name:get_name(self)
|
name = name:get_name(self)
|
||||||
end
|
end
|
||||||
self._names[name] = true
|
self._names[name] = value
|
||||||
end,
|
end,
|
||||||
has_name = function(self, name, skip_exports)
|
has_name = function(self, name, skip_exports)
|
||||||
if not skip_exports then
|
if not skip_exports then
|
||||||
@ -415,6 +430,14 @@ Block = (function()
|
|||||||
self:stm(stm)
|
self:stm(stm)
|
||||||
end
|
end
|
||||||
return nil
|
return nil
|
||||||
|
end,
|
||||||
|
splice = function(self, fn)
|
||||||
|
local lines = {
|
||||||
|
"lines",
|
||||||
|
self._lines
|
||||||
|
}
|
||||||
|
self._lines = { }
|
||||||
|
return self:stms(fn(lines))
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
_base_0.__index = _base_0
|
_base_0.__index = _base_0
|
||||||
@ -429,6 +452,7 @@ Block = (function()
|
|||||||
self._posmap = { }
|
self._posmap = { }
|
||||||
self._names = { }
|
self._names = { }
|
||||||
self._state = { }
|
self._state = { }
|
||||||
|
self._listeners = { }
|
||||||
do
|
do
|
||||||
local _with_0 = transform
|
local _with_0 = transform
|
||||||
self.transform = {
|
self.transform = {
|
||||||
@ -439,9 +463,12 @@ Block = (function()
|
|||||||
if self.parent then
|
if self.parent then
|
||||||
self.root = self.parent.root
|
self.root = self.parent.root
|
||||||
self.indent = self.parent.indent + 1
|
self.indent = self.parent.indent + 1
|
||||||
return setmetatable(self._state, {
|
setmetatable(self._state, {
|
||||||
__index = self.parent._state
|
__index = self.parent._state
|
||||||
})
|
})
|
||||||
|
return setmetatable(self._listeners, {
|
||||||
|
__index = self.parent._listeners
|
||||||
|
})
|
||||||
else
|
else
|
||||||
self.indent = 0
|
self.indent = 0
|
||||||
end
|
end
|
||||||
|
@ -70,6 +70,7 @@ class Block
|
|||||||
@_posmap = {}
|
@_posmap = {}
|
||||||
@_names = {}
|
@_names = {}
|
||||||
@_state = {}
|
@_state = {}
|
||||||
|
@_listeners = {}
|
||||||
|
|
||||||
with transform
|
with transform
|
||||||
@transform = {
|
@transform = {
|
||||||
@ -81,6 +82,7 @@ class Block
|
|||||||
@root = @parent.root
|
@root = @parent.root
|
||||||
@indent = @parent.indent + 1
|
@indent = @parent.indent + 1
|
||||||
setmetatable @_state, { __index: @parent._state }
|
setmetatable @_state, { __index: @parent._state }
|
||||||
|
setmetatable @_listeners, { __index: @parent._listeners }
|
||||||
else
|
else
|
||||||
@indent = 0
|
@indent = 0
|
||||||
|
|
||||||
@ -98,6 +100,13 @@ class Block
|
|||||||
get: (name) =>
|
get: (name) =>
|
||||||
@_state[name]
|
@_state[name]
|
||||||
|
|
||||||
|
listen: (name, fn) =>
|
||||||
|
@_listeners[name] = fn
|
||||||
|
|
||||||
|
send: (name, ...) =>
|
||||||
|
if fn = @_listeners[name]
|
||||||
|
fn self, ...
|
||||||
|
|
||||||
declare: (names) =>
|
declare: (names) =>
|
||||||
undeclared = for name in *names
|
undeclared = for name in *names
|
||||||
is_local = false
|
is_local = false
|
||||||
@ -116,9 +125,12 @@ class Block
|
|||||||
whitelist_names: (names) =>
|
whitelist_names: (names) =>
|
||||||
@_name_whitelist = Set names
|
@_name_whitelist = Set names
|
||||||
|
|
||||||
put_name: (name) =>
|
put_name: (name, ...) =>
|
||||||
|
value = ...
|
||||||
|
value = true if select("#", ...) == 0
|
||||||
|
|
||||||
name = name\get_name self if util.moon.type(name) == NameProxy
|
name = name\get_name self if util.moon.type(name) == NameProxy
|
||||||
@_names[name] = true
|
@_names[name] = value
|
||||||
|
|
||||||
has_name: (name, skip_exports) =>
|
has_name: (name, skip_exports) =>
|
||||||
if not skip_exports
|
if not skip_exports
|
||||||
@ -282,6 +294,11 @@ class Block
|
|||||||
@stm stm for stm in *stms
|
@stm stm for stm in *stms
|
||||||
nil
|
nil
|
||||||
|
|
||||||
|
splice: (fn) =>
|
||||||
|
lines = {"lines", @_lines}
|
||||||
|
@_lines = {}
|
||||||
|
@stms fn lines
|
||||||
|
|
||||||
class RootBlock extends Block
|
class RootBlock extends Block
|
||||||
new: (...) =>
|
new: (...) =>
|
||||||
@root = self
|
@root = self
|
||||||
|
@ -2,6 +2,8 @@ module("moonscript.compile", package.seeall)
|
|||||||
local util = require("moonscript.util")
|
local util = require("moonscript.util")
|
||||||
require("moonscript.compile.format")
|
require("moonscript.compile.format")
|
||||||
local dump = require("moonscript.dump")
|
local dump = require("moonscript.dump")
|
||||||
|
local transform = require("moonscript.transform")
|
||||||
|
local NameProxy = transform.NameProxy
|
||||||
local reversed = util.reversed
|
local reversed = util.reversed
|
||||||
local ntype
|
local ntype
|
||||||
do
|
do
|
||||||
@ -11,8 +13,14 @@ end
|
|||||||
local concat, insert = table.concat, table.insert
|
local concat, insert = table.concat, table.insert
|
||||||
line_compile = {
|
line_compile = {
|
||||||
raw = function(self, node)
|
raw = function(self, node)
|
||||||
local _, text = unpack(node)
|
return self:add(node[2])
|
||||||
return self:add(text)
|
end,
|
||||||
|
lines = function(self, node)
|
||||||
|
local _list_0 = node[2]
|
||||||
|
for _index_0 = 1, #_list_0 do
|
||||||
|
local line = _list_0[_index_0]
|
||||||
|
self:add(line)
|
||||||
|
end
|
||||||
end,
|
end,
|
||||||
declare = function(self, node)
|
declare = function(self, node)
|
||||||
local names = node[2]
|
local names = node[2]
|
||||||
@ -142,6 +150,14 @@ line_compile = {
|
|||||||
end
|
end
|
||||||
return root
|
return root
|
||||||
end,
|
end,
|
||||||
|
["repeat"] = function(self, node)
|
||||||
|
local cond, block = unpack(node, 2)
|
||||||
|
do
|
||||||
|
local _with_0 = self:block("repeat", self:line("until ", self:value(cond)))
|
||||||
|
_with_0:stms(block)
|
||||||
|
return _with_0
|
||||||
|
end
|
||||||
|
end,
|
||||||
["while"] = function(self, node)
|
["while"] = function(self, node)
|
||||||
local _, cond, block = unpack(node)
|
local _, cond, block = unpack(node)
|
||||||
local out
|
local out
|
||||||
@ -215,12 +231,66 @@ line_compile = {
|
|||||||
_with_0:append(" do")
|
_with_0:append(" do")
|
||||||
loop = _with_0
|
loop = _with_0
|
||||||
end
|
end
|
||||||
|
local continue_name = nil
|
||||||
|
local out
|
||||||
do
|
do
|
||||||
local _with_0 = self:block(loop)
|
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:declare(names)
|
||||||
_with_0:stms(block)
|
_with_0:stms(block)
|
||||||
return _with_0
|
out = _with_0
|
||||||
end
|
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,
|
end,
|
||||||
export = function(self, node)
|
export = function(self, node)
|
||||||
local _, names = unpack(node)
|
local _, names = unpack(node)
|
||||||
|
@ -4,7 +4,9 @@ util = require "moonscript.util"
|
|||||||
|
|
||||||
require "moonscript.compile.format"
|
require "moonscript.compile.format"
|
||||||
dump = require "moonscript.dump"
|
dump = require "moonscript.dump"
|
||||||
|
transform = require "moonscript.transform"
|
||||||
|
|
||||||
|
import NameProxy from transform
|
||||||
import reversed from util
|
import reversed from util
|
||||||
import ntype from require "moonscript.types"
|
import ntype from require "moonscript.types"
|
||||||
import concat, insert from table
|
import concat, insert from table
|
||||||
@ -12,9 +14,11 @@ import concat, insert from table
|
|||||||
export line_compile
|
export line_compile
|
||||||
|
|
||||||
line_compile =
|
line_compile =
|
||||||
raw: (node) =>
|
raw: (node) => @add node[2]
|
||||||
_, text = unpack node
|
|
||||||
@add text
|
lines: (node) =>
|
||||||
|
for line in *node[2]
|
||||||
|
@add line
|
||||||
|
|
||||||
declare: (node) =>
|
declare: (node) =>
|
||||||
names = node[2]
|
names = node[2]
|
||||||
@ -82,6 +86,11 @@ line_compile =
|
|||||||
add_clause cond for cond in *node[4,]
|
add_clause cond for cond in *node[4,]
|
||||||
root
|
root
|
||||||
|
|
||||||
|
repeat: (node) =>
|
||||||
|
cond, block = unpack node, 2
|
||||||
|
with @block "repeat", @line "until ", @value cond
|
||||||
|
\stms block
|
||||||
|
|
||||||
while: (node) =>
|
while: (node) =>
|
||||||
_, cond, block = unpack node
|
_, cond, block = unpack node
|
||||||
|
|
||||||
@ -113,10 +122,33 @@ line_compile =
|
|||||||
\append_list [@value exp for exp in *exps], ","
|
\append_list [@value exp for exp in *exps], ","
|
||||||
\append " do"
|
\append " do"
|
||||||
|
|
||||||
with @block loop
|
continue_name = nil
|
||||||
|
out = with @block loop
|
||||||
|
\listen "continue", ->
|
||||||
|
unless continue_name
|
||||||
|
continue_name = NameProxy"continue"
|
||||||
|
\put_name continue_name
|
||||||
|
continue_name
|
||||||
|
|
||||||
\declare names
|
\declare names
|
||||||
\stms block
|
\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) =>
|
export: (node) =>
|
||||||
_, names = unpack node
|
_, names = unpack node
|
||||||
if type(names) == "string"
|
if type(names) == "string"
|
||||||
|
@ -368,7 +368,7 @@ local build_grammar = wrap_env(function()
|
|||||||
|
|
||||||
NameList = Name * (sym"," * Name)^0,
|
NameList = Name * (sym"," * Name)^0,
|
||||||
|
|
||||||
BreakLoop = Ct(key"break"/trim),
|
BreakLoop = Ct(key"break"/trim) + Ct(key"continue"/trim),
|
||||||
|
|
||||||
Return = key"return" * (ExpListLow/mark"explist" + C"") / mark"return",
|
Return = key"return" * (ExpListLow/mark"explist" + C"") / mark"return",
|
||||||
|
|
||||||
|
@ -414,6 +414,18 @@ Statement = Transformer({
|
|||||||
end
|
end
|
||||||
return transformed or node
|
return transformed or node
|
||||||
end,
|
end,
|
||||||
|
continue = function(self, node)
|
||||||
|
local continue_name = self:send("continue")
|
||||||
|
if not (continue_name) then
|
||||||
|
error("continue must be inside of a loop")
|
||||||
|
end
|
||||||
|
return build.group({
|
||||||
|
build.assign_one(continue_name, "true"),
|
||||||
|
{
|
||||||
|
"break"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end,
|
||||||
export = function(self, node)
|
export = function(self, node)
|
||||||
if #node > 2 then
|
if #node > 2 then
|
||||||
if node[2] == "class" then
|
if node[2] == "class" then
|
||||||
|
@ -181,6 +181,13 @@ Statement = Transformer {
|
|||||||
|
|
||||||
transformed or node
|
transformed or node
|
||||||
|
|
||||||
|
continue: (node) =>
|
||||||
|
continue_name = @send"continue"
|
||||||
|
error "continue must be inside of a loop" unless continue_name
|
||||||
|
build.group {
|
||||||
|
build.assign_one continue_name, "true"
|
||||||
|
{"break"}
|
||||||
|
}
|
||||||
|
|
||||||
export: (node) =>
|
export: (node) =>
|
||||||
-- assign values if they are included
|
-- assign values if they are included
|
||||||
|
Loading…
Reference in New Issue
Block a user