diff --git a/anselme/ast/Return.lua b/anselme/ast/Return.lua index 4880aa0..a255115 100644 --- a/anselme/ast/Return.lua +++ b/anselme/ast/Return.lua @@ -1,32 +1,29 @@ local ast = require("anselme.ast") -local operator_priority = require("anselme.common").operator_priority - local Return -Return = ast.abstract.Node { +Return = ast.abstract.Runtime { type = "return", expression = nil, + subtype = nil, -- string; "break" or "continue" - init = function(self, expression) + init = function(self, expression, subtype) self.expression = expression + self.subtype = subtype end, _format = function(self, ...) - return ("@%s"):format(self.expression:format_right(...)) - end, - _format_priority = function(self) - return operator_priority["@_"] + if self.subtype then + return ("return(%s, %s)"):format(self.expression:format(...), self.subtype) + else + return ("return(%s)"):format(self.expression:format(...)) + end end, traverse = function(self, fn, ...) fn(self.expression, ...) end, - _eval = function(self, state) - return Return:new(self.expression:eval(state)) - end, - to_lua = function(self, state) return self.expression:to_lua(state) end diff --git a/anselme/stdlib/closure.lua b/anselme/stdlib/closure.lua index f27747f..ca1bac0 100644 --- a/anselme/stdlib/closure.lua +++ b/anselme/stdlib/closure.lua @@ -73,6 +73,20 @@ return { return Return:new(val) end }, + { + "break", "(value=())", + function(state, val) + if Return:is(val) then val = val.expression end + return Return:new(val, "break") + end + }, + { + "continue", "(value=())", + function(state, val) + if Return:is(val) then val = val.expression end + return Return:new(val, "continue") + end + }, { "attached block", "(level::number=1)", function(state, level) diff --git a/anselme/stdlib/conditionals.lua b/anselme/stdlib/conditionals.lua index 07b8308..1021146 100644 --- a/anselme/stdlib/conditionals.lua +++ b/anselme/stdlib/conditionals.lua @@ -80,7 +80,15 @@ return { end while cond:truthy() do r = expression:call(state, ArgumentTuple:new()) - if Return:is(r) then break end + if Return:is(r) then + if r.subtype == "continue" then + r = r.expression -- consume return & pass + elseif r.subtype == "break" then + return r.expression -- consume return & break + else + return r + end + end cond = condition:call(state, ArgumentTuple:new()) end return r