diff --git a/anselme/ast/Environment.lua b/anselme/ast/Environment.lua index 891a671..7465331 100644 --- a/anselme/ast/Environment.lua +++ b/anselme/ast/Environment.lua @@ -68,6 +68,7 @@ local Environment = ast.abstract.Runtime { variables = nil, -- Table of { {identifier} = variable metadata, ... } partial = nil, -- { [name string] = true, ... } + undefine = nil, -- { [name string] = true, ... } export = nil, -- bool init = function(self, state, parent, partial_names, is_export) @@ -75,6 +76,7 @@ local Environment = ast.abstract.Runtime { self.parent = parent self.partial = partial_names self.export = is_export + self.undefine = {} end, traverse = function(self, fn, ...) @@ -97,7 +99,11 @@ local Environment = ast.abstract.Runtime { or (self.export ~= symbol.exported) then return self.parent:define(state, symbol, exp) end - self.variables:set(state, symbol:to_identifier(), VariableMetadata:new(state, symbol, exp)) + if symbol.undefine then + self.undefine[name] = true + else + self.variables:set(state, symbol:to_identifier(), VariableMetadata:new(state, symbol, exp)) + end end, -- define or redefine new overloadable variable in current environment, inheriting existing overload variants from (parent) scopes define_overloadable = function(self, state, symbol, exp) @@ -132,7 +138,7 @@ local Environment = ast.abstract.Runtime { defined = function(self, state, identifier) if self.variables:has(state, identifier) then return true - elseif self.parent then + elseif self.parent and not self.undefine[identifier.name] then return self.parent:defined(state, identifier) end return false @@ -143,9 +149,10 @@ local Environment = ast.abstract.Runtime { local name = symbol.string if self.variables:has(state, symbol:to_identifier()) then return true - elseif (self.partial and not self.partial[name]) - or (self.export ~= symbol.exported) then - return self.parent:defined_in_current(state, symbol) + elseif self.parent and not self.undefine[name] then + if (self.partial and not self.partial[name]) or (self.export ~= symbol.exported) then + return self.parent:defined_in_current(state, symbol) + end end return false end, @@ -159,7 +166,7 @@ local Environment = ast.abstract.Runtime { if self:defined(state, identifier) then if self.variables:has(state, identifier) then return self.variables:get(state, identifier) - elseif self.parent then + elseif self.parent and not self.undefine[identifier.name] then return self.parent:_get_variable(state, identifier) end else diff --git a/anselme/ast/PartialScope.lua b/anselme/ast/PartialScope.lua index 73f9ab1..d1517a9 100644 --- a/anselme/ast/PartialScope.lua +++ b/anselme/ast/PartialScope.lua @@ -1,7 +1,7 @@ -- create a partial layer to define temporary variables local ast = require("anselme.ast") -local Identifier, Quote +local Identifier, Quote, Nil local attached_block_identifier, attached_block_symbol local unpack = table.unpack or unpack @@ -11,7 +11,7 @@ PartialScope = ast.abstract.Node { type = "partial scope", expression = nil, - definitions = nil, -- {[sym]=value,...} where values are already evaluated! + definitions = nil, -- {[sym]=value,...} _identifiers = nil, -- {identifier,...} - just a cache so we don't rebuild it on every eval init = function(self, expression) @@ -49,7 +49,7 @@ PartialScope = ast.abstract.Node { _eval = function(self, state) state.scope:push_partial(unpack(self._identifiers)) - for sym, val in pairs(self.definitions) do state.scope:define(sym, val) end + for sym, val in pairs(self.definitions) do state.scope:define(sym:eval(state), val:eval(state)) end local exp = self.expression:eval(state) state.scope:pop() @@ -71,14 +71,16 @@ PartialScope = ast.abstract.Node { end, -- class method: return a PartialScope that define the block identifier _ to a Quote of `block` attach_block = function(self, expression, block) - local partial = ast.PartialScope:new(expression) - partial:define(attached_block_symbol, Quote:new(block)) + local partial = PartialScope:new(expression) + local unpartial = PartialScope:new(block) + unpartial:define(attached_block_symbol:with{undefine=true}, Nil:new()) + partial:define(attached_block_symbol, Quote:new(unpartial)) return partial end } package.loaded[...] = PartialScope -Identifier, Quote = ast.Identifier, ast.Quote +Identifier, Quote, Nil = ast.Identifier, ast.Quote, ast.Nil attached_block_identifier = Identifier:new("_") attached_block_symbol = attached_block_identifier:to_symbol() diff --git a/anselme/ast/Symbol.lua b/anselme/ast/Symbol.lua index 189f626..c7e7ab7 100644 --- a/anselme/ast/Symbol.lua +++ b/anselme/ast/Symbol.lua @@ -15,6 +15,7 @@ Symbol = ast.abstract.Node { exported = nil, -- bool confined_to_branch = nil, -- bool + undefine = nil, -- bool init = function(self, str, modifiers) modifiers = modifiers or {} @@ -24,6 +25,7 @@ Symbol = ast.abstract.Node { self.alias = modifiers.alias self.confined_to_branch = modifiers.confined_to_branch self.exported = modifiers.exported + self.undefine = modifiers.undefine end, _eval = function(self, state) @@ -34,7 +36,7 @@ Symbol = ast.abstract.Node { with = function(self, modifiers) modifiers = modifiers or {} - for _, k in ipairs{"constant", "type_check", "alias", "exported", "confined_to_branch"} do + for _, k in ipairs{"constant", "type_check", "alias", "exported", "confined_to_branch", "undefine"} do if modifiers[k] == nil then modifiers[k] = self[k] end diff --git a/anselme/stdlib/closure.lua b/anselme/stdlib/closure.lua index ca1bac0..5e5e010 100644 --- a/anselme/stdlib/closure.lua +++ b/anselme/stdlib/closure.lua @@ -4,6 +4,8 @@ local assert0 = require("anselme.common").assert0 local calling_environment_manager = require("anselme.state.calling_environment_manager") +local block_identifier = Identifier:new("_") + return { { "defined", "(c::function, s::string)", @@ -88,21 +90,33 @@ return { end }, { - "attached block", "(level::number=1)", - function(state, level) + "attached block", "(level::number=1, keep return=false)", + function(state, level, keep_return) -- level 2: env of the function that called the function that called attached block local env = calling_environment_manager:get_level(state, level:to_lua(state)+1) - local r = env:get(state, Identifier:new("_")) - return Function:with_return_boundary(ParameterTuple:new(), r.expression):eval(state) + local r = env:get(state, block_identifier) + if keep_return:truthy() then + return Function:new(ParameterTuple:new(), r.expression):eval(state) + else + return Function:with_return_boundary(ParameterTuple:new(), r.expression):eval(state) + end end }, { - "attached block keep return", "(level::number=1)", - function(state, level) + "attached block", "(level::number=1, keep return=false, default)", + function(state, level, keep_return, default) -- level 2: env of the function that called the function that called attached block local env = calling_environment_manager:get_level(state, level:to_lua(state)+1) - local r = env:get(state, Identifier:new("_")) - return Function:new(ParameterTuple:new(), r.expression):eval(state) + if env:defined(state, block_identifier) then + local r = env:get(state, block_identifier) + if keep_return:truthy() then + return Function:new(ParameterTuple:new(), r.expression):eval(state) + else + return Function:with_return_boundary(ParameterTuple:new(), r.expression):eval(state) + end + else + return default + end end }, } diff --git a/anselme/stdlib/conditionals.lua b/anselme/stdlib/conditionals.lua index 1021146..b39056a 100644 --- a/anselme/stdlib/conditionals.lua +++ b/anselme/stdlib/conditionals.lua @@ -18,7 +18,7 @@ end return { { - "if", "(condition, expression=attached block keep return!)", function(state, condition, expression) + "if", "(condition, expression=attached block(keep return=true))", function(state, condition, expression) ensure_if_variable(state) if condition:truthy() or expression:contains_current_resume_target(state) then set_if_variable(state, true) @@ -42,7 +42,7 @@ return { end }, { - "else if", "(condition, expression=attached block keep return!)", + "else if", "(condition, expression=attached block(keep return=true))", function(state, condition, expression) ensure_if_variable(state) if (not last_if_success(state) and condition:truthy()) or expression:contains_current_resume_target(state) then @@ -55,7 +55,7 @@ return { end }, { - "else", "(expression=attached block keep return!)", + "else", "(expression=attached block(keep return=true))", function(state, expression) ensure_if_variable(state) if not last_if_success(state) or expression:contains_current_resume_target(state) then @@ -67,7 +67,7 @@ return { end }, { - "while", "(condition, expression=attached block keep return!)", + "while", "(condition, expression=attached block(keep return=true))", function(state, condition, expression) ensure_if_variable(state) local cond = condition:call(state, ArgumentTuple:new()) diff --git a/anselme/stdlib/script_script.lua b/anselme/stdlib/script_script.lua index 4078a07..8fe0b68 100644 --- a/anselme/stdlib/script_script.lua +++ b/anselme/stdlib/script_script.lua @@ -8,18 +8,19 @@ return [[ fn.:check = $(anchor::anchor) fn.reached(anchor) = (fn.reached(anchor) | 0) + 1 - fn.:checkpoint = $(anchor::anchor) - fn.current checkpoint = anchor - if(resumed from != anchor) - fn.reached(anchor) = (fn.reached(anchor) | 0) + 1 - merge branch! - fn.:checkpoint = $(anchor::anchor, on resume::function) - fn.current checkpoint = anchor - if(resumed from == anchor | resuming(2)) - on resume! + fn.:checkpoint = $(anchor::anchor, on resume=attached block(default=())) + if(on resume) + fn.current checkpoint = anchor + if(resumed from == anchor | resuming(4)) + on resume! + else! + fn.reached(anchor) = (fn.reached(anchor) | 0) + 1 + merge branch! else! - fn.reached(anchor) = (fn.reached(anchor) | 0) + 1 - merge branch! + fn.current checkpoint = anchor + if(resumed from != anchor) + fn.reached(anchor) = (fn.reached(anchor) | 0) + 1 + merge branch! :f = $ if(fn.current checkpoint) diff --git a/ideas.md b/ideas.md index 2ea2909..74f6d87 100644 --- a/ideas.md +++ b/ideas.md @@ -34,9 +34,8 @@ Standard library. * Text manipulation would make sense, but that would require a full UTF-8/Unicode support library like https://github.com/starwing/luautf8. * Something to load other files. Maybe not load it by default to let the calling game sandbox Anselme. Probably create an export scope per file to perform some nice module loading. * Implement the useful functions from Anselme v1. -* Checkpoint management. -* Overloadable :format for custom types. * Text manipulation: concatenation, retag/add tags +* And in general, clean up everything. --- diff --git a/test/results/checkpoint merging mutable value.ans b/test/results/checkpoint merging mutable value.ans index 735d602..2ab75df 100644 --- a/test/results/checkpoint merging mutable value.ans +++ b/test/results/checkpoint merging mutable value.ans @@ -9,8 +9,6 @@ | {}"1,2,3,4,5: " {}"*[1, 2, 3, 4, 5]" {}"" | --- error --- cancel merge - ↳ from test/tests/checkpoint merging mutable value.ans:24:6 in call: error("cancel merge") - ↳ from ? in block: :l = *[1, 2]… --# post run check #-- --- text --- | {}"1,2,3,4: " {}"*[1, 2, 3, 4]" {}"" | diff --git a/test/results/checkpoint merging variable.ans b/test/results/checkpoint merging variable.ans index 5522ad8..e222db9 100644 --- a/test/results/checkpoint merging variable.ans +++ b/test/results/checkpoint merging variable.ans @@ -9,8 +9,6 @@ | {}"4: " {}"4" {}"" | --- error --- cancel merge - ↳ from test/tests/checkpoint merging variable.ans:24:6 in call: error("cancel merge") - ↳ from ? in block: :l = 1… --# post run check #-- --- text --- | {}"3: " {}"3" {}"" | diff --git a/test/results/closure define nested.ans b/test/results/closure define nested.ans index c108ce5..4cbb41e 100644 --- a/test/results/closure define nested.ans +++ b/test/results/closure define nested.ans @@ -3,9 +3,5 @@ | {}"" {}"42" {}"" | --- error --- no variable "y" defined in closure - ↳ from test/tests/closure define nested.ans:12:4 in call: f . "y" - ↳ from test/tests/closure define nested.ans:12:1 in text interpolation: | {f . "y"} | - ↳ from test/tests/closure define nested.ans:12:1 in translatable: | {f . "y"} | - ↳ from ? in block: :f = ($() _)… --# saved #-- {} \ No newline at end of file diff --git a/test/results/constant variable.ans b/test/results/constant variable.ans index 53dc1fc..560257c 100644 --- a/test/results/constant variable.ans +++ b/test/results/constant variable.ans @@ -1,7 +1,5 @@ --# run #-- --- error --- trying to change the value of constant a - ↳ from test/tests/constant variable.ans:5:3 in assignment: a = 52 - ↳ from ? in block: ::a = 3… --# saved #-- {} \ No newline at end of file diff --git a/test/results/constrained variable assignement.ans b/test/results/constrained variable assignement.ans index 8944dc7..293289e 100644 --- a/test/results/constrained variable assignement.ans +++ b/test/results/constrained variable assignement.ans @@ -5,7 +5,5 @@ | {}"" {}"type(\"kg\", 12)" {}"" | --- error --- type check failure for weigh; 32 does not satisfy $(x) type(x) == t - ↳ from test/tests/constrained variable assignement.ans:9:7 in assignment: weigh = 32 - ↳ from ? in block: :weigh::is("kg") = type(5, "kg")… --# saved #-- {} \ No newline at end of file diff --git a/test/results/define override function.ans b/test/results/define override function.ans index b548d21..c14fab4 100644 --- a/test/results/define override function.ans +++ b/test/results/define override function.ans @@ -1,7 +1,5 @@ --# run #-- --- error --- a is already defined in the current scope - ↳ from test/tests/define override function.ans:4:4 in definition: :a = 2 - ↳ from ? in block: :a = ($() _)… --# saved #-- {} \ No newline at end of file diff --git a/test/results/define override variable.ans b/test/results/define override variable.ans index 7d6d95a..93efbc7 100644 --- a/test/results/define override variable.ans +++ b/test/results/define override variable.ans @@ -1,8 +1,5 @@ --# run #-- --- error --- can't add an overload variant to non-overloadable variable a defined in the same scope - ↳ from test/tests/define override variable.ans:3:1 in definition: :a = ($() _) - ↳ from test/tests/define override variable.ans:3:1 in partial scope: :a = ($() _)… - ↳ from ? in block: :a = 2… --# saved #-- {} \ No newline at end of file diff --git a/test/results/define override.ans b/test/results/define override.ans index 770be88..c14fab4 100644 --- a/test/results/define override.ans +++ b/test/results/define override.ans @@ -1,7 +1,5 @@ --# run #-- --- error --- a is already defined in the current scope - ↳ from test/tests/define override.ans:3:4 in definition: :a = 2 - ↳ from ? in block: :a = 5… --# saved #-- {} \ No newline at end of file diff --git a/test/results/exported variable nested.ans b/test/results/exported variable nested.ans index 111e816..4b7972c 100644 --- a/test/results/exported variable nested.ans +++ b/test/results/exported variable nested.ans @@ -6,9 +6,5 @@ | {}"" {}"42" {}"" | --- error --- identifier "z" is undefined in branch cf017f8a-7c86-4871-109af-6658231331e6 - ↳ from test/tests/exported variable nested.ans:12:3 in identifier: z - ↳ from test/tests/exported variable nested.ans:12:1 in text interpolation: | {z} | - ↳ from test/tests/exported variable nested.ans:12:1 in translatable: | {z} | - ↳ from ? in block: :f = ($() _)… --# saved #-- {} \ No newline at end of file diff --git a/test/results/function args arity check fail.ans b/test/results/function args arity check fail.ans index dea819f..599327d 100644 --- a/test/results/function args arity check fail.ans +++ b/test/results/function args arity check fail.ans @@ -1,7 +1,5 @@ --# run #-- --- error --- can't call function $(a, b) _: expected 2 arguments, received 1 - ↳ from test/tests/function args arity check fail.ans:4:2 in call: f("ok") - ↳ from ? in block: :f = ($(a, b) _)… --# saved #-- {} \ No newline at end of file diff --git a/test/results/function conflict.ans b/test/results/function conflict.ans index 3b84880..1cf0b97 100644 --- a/test/results/function conflict.ans +++ b/test/results/function conflict.ans @@ -1,7 +1,5 @@ --# run #-- --- error --- a function with parameters (a, b) is already defined in the overload - ↳ from test/tests/function conflict.ans:5:1 in definition: :f = ($(a, b) 0) - ↳ from ? in block: :f = ($(a, b) 0)… --# saved #-- {} \ No newline at end of file diff --git a/test/results/function custom type dispatch error.ans b/test/results/function custom type dispatch error.ans index 0f10730..a2a89f9 100644 --- a/test/results/function custom type dispatch error.ans +++ b/test/results/function custom type dispatch error.ans @@ -7,7 +7,5 @@ can't call overload overload<($(name::($(x) type(x) == t)) _), ($(name::($(x) type(x) == t)) _)>: no function match (type("nope", 5)), possible functions were: • (name::($(x) type(x) == t)): type check failure for parameter name in function (name::($(x) type(x) == t)) • (name::($(x) type(x) == t)): type check failure for parameter name in function (name::($(x) type(x) == t)) - ↳ from test/tests/function custom type dispatch error.ans:14:2 in call: a(type(5, "nope")) - ↳ from ? in block: :french name = "french name"… --# saved #-- {} \ No newline at end of file diff --git a/test/results/function scope wrong.ans b/test/results/function scope wrong.ans index 2e1173b..f425648 100644 --- a/test/results/function scope wrong.ans +++ b/test/results/function scope wrong.ans @@ -1,9 +1,5 @@ --# run #-- --- error --- identifier "b" is undefined in branch cf017f8a-7c86-4871-109af-6658231331e6 - ↳ from test/tests/function scope wrong.ans:4:7 in identifier: b - ↳ from test/tests/function scope wrong.ans:4:1 in text interpolation: | a: {b} | - ↳ from test/tests/function scope wrong.ans:4:1 in translatable: | a: {b} | - ↳ from ? in block: :a = ($() _)… --# saved #-- {} \ No newline at end of file diff --git a/test/results/function separate variable from variants.ans b/test/results/function separate variable from variants.ans index b1b54df..8a0b487 100644 --- a/test/results/function separate variable from variants.ans +++ b/test/results/function separate variable from variants.ans @@ -7,9 +7,5 @@ • (c::($(x) ), s::($(x) )) = v: expected 3 arguments, received 2 • (c::($(x) ), s::($(x) )) = v: expected 3 arguments, received 2 • (c::($(x) ), s::($(x) )): type check failure for parameter c in function (c::($(x) ), s::($(x) )) - ↳ from test/tests/function separate variable from variants.ans:10:4 in call: f . "a" - ↳ from test/tests/function separate variable from variants.ans:10:1 in text interpolation: | {f . "a"} = 2 | - ↳ from test/tests/function separate variable from variants.ans:10:1 in translatable: | {f . "a"} = 2 | - ↳ from ? in block: :f = ($() _)… --# saved #-- {} \ No newline at end of file diff --git a/test/results/function type dispatch ambigous.ans b/test/results/function type dispatch ambigous.ans index 8d6a596..506fb21 100644 --- a/test/results/function type dispatch ambigous.ans +++ b/test/results/function type dispatch ambigous.ans @@ -3,7 +3,5 @@ can't call overload overload<($(a::($(x) )) _), ($(x::($(x) )) _)>: more than one function match (5), matching functions were at least (specificity 1.3): • (x::($(x) )) • (a::($(x) )) - ↳ from test/tests/function type dispatch ambigous.ans:7:3 in call: fn(5) - ↳ from ? in block: :fn = ($(x::number) _)… --# saved #-- {} \ No newline at end of file diff --git a/test/results/list assignement.ans b/test/results/list assignement.ans index 327cc09..b1f2aca 100644 --- a/test/results/list assignement.ans +++ b/test/results/list assignement.ans @@ -11,7 +11,5 @@ | {}"" {}"*[3, 12, 99]" {}"" | --- error --- list index out of bounds - ↳ from test/tests/list assignement.ans:21:6 in call: x(5) = 0 - ↳ from ? in block: :x = *[1, 2]… --# saved #-- {} \ No newline at end of file diff --git a/test/results/list index.ans b/test/results/list index.ans index 42d485e..5e113e0 100644 --- a/test/results/list index.ans +++ b/test/results/list index.ans @@ -9,9 +9,5 @@ | {}"" {}"3" {}" == " {}"3" {}"" | --- error --- tuple index out of bounds - ↳ from test/tests/list index.ans:11:4 in call: x(-4) - ↳ from test/tests/list index.ans:11:1 in text interpolation: | {x(-4)} | - ↳ from test/tests/list index.ans:11:1 in translatable: | {x(-4)} | - ↳ from ? in block: :x = [1, 2, 3]… --# saved #-- {} \ No newline at end of file diff --git a/test/results/merge nested mutable error bis.ans b/test/results/merge nested mutable error bis.ans index 13f9096..aa1b66b 100644 --- a/test/results/merge nested mutable error bis.ans +++ b/test/results/merge nested mutable error bis.ans @@ -1,23 +1,6 @@ --# run #-- --- error --- -abort - ↳ from test/tests/merge nested mutable error bis.ans:14:7 in call: error("abort") - ↳ from test/tests/merge nested mutable error bis.ans:3:1 in block: insert(a, b)… - ↳ from test/tests/merge nested mutable error bis.ans:3:18 in call: _ - ↳ from test/tests/merge nested mutable error bis.ans:3:17 in return boundary: _ - ↳ from script.ans:29:6 in call: fn! - ↳ from script.ans:27:3 in block: resumed from = ()… - ↳ from script.ans:27:7 in call: else! - ↳ from script.ans:27:3 in partial scope: else!… - ↳ from script.ans:23:2 in block: if(fn . "current checkpoint")… - ↳ from script.ans:23:9 in call: _ - ↳ from script.ans:23:7 in return boundary: _ - ↳ from script.ans:37:9 in call: value(s)! - ↳ from script.ans:36:1 in block: value(s)! - ↳ from script.ans:36:20 in call: _ - ↳ from script.ans:36:1 in return boundary: _ - ↳ from test/tests/merge nested mutable error bis.ans:19:2 in call: f! - ↳ from ? in block: :a = *[1]… +abort --# post run check #-- --- text --- | {}"[1,[2,3]]: " {}"*[1, *[2, 3]]" {}"" | diff --git a/test/results/merge nested mutable error.ans b/test/results/merge nested mutable error.ans index 1b3be88..aa1b66b 100644 --- a/test/results/merge nested mutable error.ans +++ b/test/results/merge nested mutable error.ans @@ -1,23 +1,6 @@ --# run #-- --- error --- -abort - ↳ from test/tests/merge nested mutable error.ans:14:7 in call: error("abort") - ↳ from test/tests/merge nested mutable error.ans:3:1 in block: insert(a, b)… - ↳ from test/tests/merge nested mutable error.ans:3:18 in call: _ - ↳ from test/tests/merge nested mutable error.ans:3:17 in return boundary: _ - ↳ from script.ans:29:6 in call: fn! - ↳ from script.ans:27:3 in block: resumed from = ()… - ↳ from script.ans:27:7 in call: else! - ↳ from script.ans:27:3 in partial scope: else!… - ↳ from script.ans:23:2 in block: if(fn . "current checkpoint")… - ↳ from script.ans:23:9 in call: _ - ↳ from script.ans:23:7 in return boundary: _ - ↳ from script.ans:37:9 in call: value(s)! - ↳ from script.ans:36:1 in block: value(s)! - ↳ from script.ans:36:20 in call: _ - ↳ from script.ans:36:1 in return boundary: _ - ↳ from test/tests/merge nested mutable error.ans:19:2 in call: f! - ↳ from ? in block: :a = *[1]… +abort --# post run check #-- --- text --- | {}"[1,[2,3]]: " {}"*[1, *[2, 3]]" {}"" | diff --git a/test/results/scope checkpoint mutable bis error.ans b/test/results/scope checkpoint mutable bis error.ans index 867c4b9..cdc95da 100644 --- a/test/results/scope checkpoint mutable bis error.ans +++ b/test/results/scope checkpoint mutable bis error.ans @@ -14,20 +14,7 @@ --- text --- | {}"CHECK 2" | --- error --- -t - ↳ from test/tests/scope checkpoint mutable bis error.ans:32:7 in call: error("t") - ↳ from test/tests/scope checkpoint mutable bis error.ans:7:1 in block: insert(t, len(l) + 1)… - ↳ from test/tests/scope checkpoint mutable bis error.ans:7:8 in call: _ - ↳ from test/tests/scope checkpoint mutable bis error.ans:7:1 in return boundary: _ - ↳ from test/tests/scope checkpoint mutable bis error.ans:19:4 in call: f(t) - ↳ from test/tests/scope checkpoint mutable bis error.ans:15:2 in block: | REC |… - ↳ from test/tests/scope checkpoint mutable bis error.ans:15:4 in call: if(n < 1) - ↳ from test/tests/scope checkpoint mutable bis error.ans:15:2 in partial scope: if(n < 1)… - ↳ from test/tests/scope checkpoint mutable bis error.ans:7:1 in block: insert(t, len(l) + 1)… - ↳ from test/tests/scope checkpoint mutable bis error.ans:7:8 in call: _ - ↳ from test/tests/scope checkpoint mutable bis error.ans:7:1 in return boundary: _ - ↳ from test/tests/scope checkpoint mutable bis error.ans:41:2 in call: f(l) - ↳ from ? in block: :x = *[99]… +t --# post run check #-- --- text --- | {}"AFTER ERROR" | diff --git a/test/results/scope checkpoint mutable error.ans b/test/results/scope checkpoint mutable error.ans index 3b6de4d..36816ef 100644 --- a/test/results/scope checkpoint mutable error.ans +++ b/test/results/scope checkpoint mutable error.ans @@ -10,20 +10,7 @@ --- text --- | {}"CHECK" | --- error --- -t - ↳ from test/tests/scope checkpoint mutable error.ans:23:7 in call: error("t") - ↳ from test/tests/scope checkpoint mutable error.ans:5:1 in block: insert(t, len(l) + 1)… - ↳ from test/tests/scope checkpoint mutable error.ans:5:8 in call: _ - ↳ from test/tests/scope checkpoint mutable error.ans:5:1 in return boundary: _ - ↳ from test/tests/scope checkpoint mutable error.ans:17:4 in call: f(t) - ↳ from test/tests/scope checkpoint mutable error.ans:13:2 in block: | REC |… - ↳ from test/tests/scope checkpoint mutable error.ans:13:4 in call: if(n < 1) - ↳ from test/tests/scope checkpoint mutable error.ans:13:2 in partial scope: if(n < 1)… - ↳ from test/tests/scope checkpoint mutable error.ans:5:1 in block: insert(t, len(l) + 1)… - ↳ from test/tests/scope checkpoint mutable error.ans:5:8 in call: _ - ↳ from test/tests/scope checkpoint mutable error.ans:5:1 in return boundary: _ - ↳ from test/tests/scope checkpoint mutable error.ans:32:2 in call: f(l) - ↳ from ? in block: :l = *[1]… +t --# post run check #-- --- text --- | {}"AFTER ERROR" | diff --git a/test/results/scope checkpoint mutable ter error.ans b/test/results/scope checkpoint mutable ter error.ans index 90ce1d0..12723bc 100644 --- a/test/results/scope checkpoint mutable ter error.ans +++ b/test/results/scope checkpoint mutable ter error.ans @@ -14,20 +14,7 @@ --- text --- | {}"CHECK 2" | --- error --- -t - ↳ from test/tests/scope checkpoint mutable ter error.ans:34:7 in call: error("t") - ↳ from test/tests/scope checkpoint mutable ter error.ans:7:1 in block: insert(t, len(l) + 1)… - ↳ from test/tests/scope checkpoint mutable ter error.ans:7:8 in call: _ - ↳ from test/tests/scope checkpoint mutable ter error.ans:7:1 in return boundary: _ - ↳ from test/tests/scope checkpoint mutable ter error.ans:19:4 in call: f(t) - ↳ from test/tests/scope checkpoint mutable ter error.ans:15:2 in block: | REC |… - ↳ from test/tests/scope checkpoint mutable ter error.ans:15:4 in call: if(n < 1) - ↳ from test/tests/scope checkpoint mutable ter error.ans:15:2 in partial scope: if(n < 1)… - ↳ from test/tests/scope checkpoint mutable ter error.ans:7:1 in block: insert(t, len(l) + 1)… - ↳ from test/tests/scope checkpoint mutable ter error.ans:7:8 in call: _ - ↳ from test/tests/scope checkpoint mutable ter error.ans:7:1 in return boundary: _ - ↳ from test/tests/scope checkpoint mutable ter error.ans:43:2 in call: f(l) - ↳ from ? in block: :x = *[99]… +t --# post run check #-- --- text --- | {}"AFTER ERROR" | diff --git a/test/results/symbol alias constant.ans b/test/results/symbol alias constant.ans index f311b8f..d8394d9 100644 --- a/test/results/symbol alias constant.ans +++ b/test/results/symbol alias constant.ans @@ -6,7 +6,5 @@ | {}"d=" {}"2" {}" (2)" | --- error --- trying to change the value of constant d - ↳ from test/tests/symbol alias constant.ans:12:3 in assignment: d = 5 - ↳ from ? in block: :l = *[1, 2, 3]… --# saved #-- {} \ No newline at end of file diff --git a/test/run.lua b/test/run.lua index 3645bb3..f33c313 100644 --- a/test/run.lua +++ b/test/run.lua @@ -47,6 +47,8 @@ local function run_loop(run_state, out) elseif e == "return" then table.insert(out, data:format(run_state)) run_state:merge() + elseif e == "error" then + table.insert(out, (tostring(data):gsub("\n%s*↳[^\n]*", ""))) -- traceback change every day and a half due to AST changes. TODO: only keep ast layers relevant for the user else table.insert(out, tostring(data)) end