mirror of
https://github.com/Reuh/anselme.git
synced 2025-10-27 16:49:31 +00:00
Fix scoping with mutable variables
This commit is contained in:
parent
16d0bb8d7a
commit
bb45cc8fdd
16 changed files with 1243 additions and 38 deletions
|
|
@ -487,11 +487,12 @@ local vm_mt = {
|
|||
return cache[k]
|
||||
end,
|
||||
-- variables that keep current state and should be cleared at each checkpoint
|
||||
copy_cache = {}, -- table of [original table] = copied table
|
||||
modified_tables = {}, -- list of modified tables (copies) that should be merged with global state on next checkpoint
|
||||
cache = {}, -- cache of previously read values (copies), to get repeatable reads & handle mutable types without changing global state
|
||||
modified_tables = {}, -- list of modified tables (copies) that should be merged with global state on next checkpoint
|
||||
copy_cache = {}, -- table of [original table] = copied table. Automatically filled by copy().
|
||||
-- keep track of scoped variables in scoped functions [fn line] = {{scoped variables}, next scope, ...}
|
||||
-- (scoped variables aren't merged on checkpoint, shouldn't be cleared at checkpoints)
|
||||
-- (only stores scoped variables that have been reassigned at some point (i.e. every accessed one since they start as undefined))
|
||||
scoped = {}
|
||||
}),
|
||||
interpreter = {
|
||||
|
|
|
|||
26
common.lua
26
common.lua
|
|
@ -1,3 +1,5 @@
|
|||
local common
|
||||
|
||||
--- replace values recursively in table t according to to_replace ([old table] = new table)
|
||||
-- already_replaced is a temporary table to avoid infinite loop & duplicate processing, no need to give it
|
||||
local function replace_in_table(t, to_replace, already_replaced)
|
||||
|
|
@ -12,7 +14,6 @@ local function replace_in_table(t, to_replace, already_replaced)
|
|||
end
|
||||
end
|
||||
|
||||
local common
|
||||
common = {
|
||||
--- recursively copy a table, handle cyclic references, no metatable, don't copy keys
|
||||
-- cache is table with copied tables [original table] = copied value, will use temporary table is omitted
|
||||
|
|
@ -59,6 +60,29 @@ common = {
|
|||
end
|
||||
-- replace in t
|
||||
replace_in_table(t, to_replace)
|
||||
end,
|
||||
--- given a table t issued from some copy, the copy cache, and a list of tables from the copied version,
|
||||
-- put the original tables that are not in the list in t in place of their copied values
|
||||
fix_not_modified_references = function(t, cache, copied_to_replace)
|
||||
-- reverse copy cache
|
||||
local ehcac = {}
|
||||
for k, v in pairs(cache) do ehcac[v] = k end
|
||||
-- build table of [original table] = replacement copied table
|
||||
local to_replace = {}
|
||||
for _, v in ipairs(copied_to_replace) do
|
||||
local original = ehcac[v]
|
||||
if original then -- table doesn't have an original value if it's a new table...
|
||||
to_replace[original] = v
|
||||
end
|
||||
end
|
||||
-- fix references to not-modified tables in t
|
||||
local not_modified = {}
|
||||
for original, modified in pairs(cache) do
|
||||
if not to_replace[original] then
|
||||
not_modified[modified] = original
|
||||
end
|
||||
end
|
||||
replace_in_table(t, not_modified)
|
||||
end
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
local atypes, ltypes
|
||||
local eval, run_block
|
||||
local replace_with_copied_values
|
||||
local replace_with_copied_values, fix_not_modified_references
|
||||
local common
|
||||
local identifier_pattern
|
||||
|
||||
|
|
@ -44,6 +44,11 @@ end
|
|||
common = {
|
||||
--- merge interpreter state with global state
|
||||
merge_state = function(state)
|
||||
local mt = getmetatable(state.variables)
|
||||
-- store current scoped variables before merging them
|
||||
for fn in pairs(mt.scoped) do
|
||||
common.scope:store_last_scope(state, fn)
|
||||
end
|
||||
-- merge alias state
|
||||
local global = state.interpreter.global_state
|
||||
for alias, fqm in pairs(state.aliases) do
|
||||
|
|
@ -51,15 +56,38 @@ common = {
|
|||
state.aliases[alias] = nil
|
||||
end
|
||||
-- merge modified mutable varables
|
||||
local mt = getmetatable(state.variables)
|
||||
replace_with_copied_values(global.variables, mt.copy_cache, mt.modified_tables)
|
||||
local copy_cache, modified_tables = mt.copy_cache, mt.modified_tables
|
||||
replace_with_copied_values(global.variables, copy_cache, modified_tables)
|
||||
mt.copy_cache = {}
|
||||
mt.modified = {}
|
||||
mt.modified_tables = {}
|
||||
mt.cache = {}
|
||||
-- merge modified re-assigned variables
|
||||
for var, value in pairs(state.variables) do
|
||||
global.variables[var] = value
|
||||
state.variables[var] = nil
|
||||
if var:match("^"..identifier_pattern.."$") then -- skip scoped variables
|
||||
global.variables[var] = value
|
||||
state.variables[var] = nil
|
||||
end
|
||||
end
|
||||
-- scoping: since merging means we will re-copy every variable from global state again, we need to simulate this
|
||||
-- behavious for scoped variables (to have consistent references for mutables values in particular), including
|
||||
-- scopes that aren't currently active
|
||||
fix_not_modified_references(mt.scoped, copy_cache, modified_tables) -- replace not modified values in scope with original before re-copying to keep consistent references
|
||||
for _, scopes in pairs(mt.scoped) do
|
||||
for _, scope in ipairs(scopes) do
|
||||
for var, value in pairs(scope) do
|
||||
-- pretend the value for this scope is the global value so the cache system perform the new copy from it
|
||||
local old_var = global.variables[var]
|
||||
global.variables[var] = value
|
||||
state.variables[var] = nil
|
||||
scope[var] = state.variables[var]
|
||||
mt.cache[var] = nil
|
||||
global.variables[var] = old_var
|
||||
end
|
||||
end
|
||||
end
|
||||
-- restore last scopes
|
||||
for fn in pairs(mt.scoped) do
|
||||
common.scope:set_last_scope(state, fn)
|
||||
end
|
||||
end,
|
||||
--- returns a variable's value, evaluating a pending expression if neccessary
|
||||
|
|
@ -85,46 +113,66 @@ common = {
|
|||
end,
|
||||
--- handle scoped function
|
||||
scope = {
|
||||
push = function(self, state, fn)
|
||||
init_scope = function(self, state, fn)
|
||||
local scoped = getmetatable(state.variables).scoped
|
||||
if not fn.scoped then error("trying to push a scope for a non-scoped function") end
|
||||
-- add scope
|
||||
if not scoped[fn] then
|
||||
scoped[fn] = {}
|
||||
end
|
||||
local last_scope = scoped[fn][#scoped[fn]]
|
||||
local fn_scope = {}
|
||||
table.insert(scoped[fn], fn_scope)
|
||||
-- add scoped variables to scope
|
||||
if not fn.scoped then error("trying to initialize the scope stack for a non-scoped function") end
|
||||
if not scoped[fn] then scoped[fn] = {} end
|
||||
-- check scoped variables
|
||||
for _, name in ipairs(fn.scoped) do
|
||||
-- preserve current values in last scope
|
||||
if last_scope then
|
||||
last_scope[name] = state.variables[name]
|
||||
-- put fresh variable from global state in scope
|
||||
local val = state.interpreter.global_state.variables[name]
|
||||
if val.type ~= "undefined argument" and val.type ~= "pending definition" then -- only possibilities for scoped variable, and they're immutable
|
||||
error("invalid scoped variable")
|
||||
end
|
||||
-- set last value to nil to force to copy again from global variables in new scope
|
||||
state.variables[name] = nil
|
||||
local value = state.variables[name]
|
||||
fn_scope[name] = value
|
||||
end
|
||||
end,
|
||||
--- push a new scope for this function
|
||||
push = function(self, state, fn)
|
||||
local scoped = getmetatable(state.variables).scoped
|
||||
self:init_scope(state, fn)
|
||||
-- preserve current values in last scope
|
||||
self:store_last_scope(state, fn)
|
||||
-- add scope
|
||||
local fn_scope = {}
|
||||
table.insert(scoped[fn], fn_scope)
|
||||
self:set_last_scope(state, fn)
|
||||
end,
|
||||
--- pop the last scope for this function
|
||||
pop = function(self, state, fn)
|
||||
local scoped = getmetatable(state.variables).scoped
|
||||
if not scoped[fn] then error("trying to pop a scope without any pushed scope") end
|
||||
-- remove current scope
|
||||
table.remove(scoped[fn])
|
||||
-- set scopped variables to previous scope
|
||||
local last_scope = scoped[fn][#scoped[fn]]
|
||||
-- restore last scope
|
||||
self:set_last_scope(state, fn)
|
||||
-- if the stack is empty,
|
||||
-- we could remove mt.scoped[fn] I guess, but I don't think there's going to be a million different functions in a single game so should be ok
|
||||
-- (anselme's performance is already bad enough, let's not create tables at each function call...)
|
||||
end,
|
||||
--- store the current values of the scoped variables in the last scope of this function
|
||||
store_last_scope = function(self, state, fn)
|
||||
local scopes = getmetatable(state.variables).scoped[fn]
|
||||
local last_scope = scopes[#scopes]
|
||||
if last_scope then
|
||||
for _, name in ipairs(fn.scoped) do
|
||||
state.variables[name] = last_scope[name]
|
||||
for _, name in pairs(fn.scoped) do
|
||||
local val = rawget(state.variables, name)
|
||||
if val then
|
||||
last_scope[name] = val
|
||||
end
|
||||
end
|
||||
else -- no previous scope
|
||||
for _, name in ipairs(fn.scoped) do
|
||||
state.variables[name] = nil
|
||||
end
|
||||
end,
|
||||
--- set scopped variables to previous scope
|
||||
set_last_scope = function(self, state, fn)
|
||||
local scopes = getmetatable(state.variables).scoped[fn]
|
||||
for _, name in ipairs(fn.scoped) do
|
||||
state.variables[name] = nil
|
||||
end
|
||||
local last_scope = scopes[#scopes]
|
||||
if last_scope then
|
||||
for name, val in pairs(last_scope) do
|
||||
state.variables[name] = val
|
||||
end
|
||||
-- no need to remove this I think, there's not going to be a million different functions in a single game so we can keep the tables
|
||||
-- (anselme's performance is already bad enough, let's not create tables at each function call...)
|
||||
-- scoped[fn] = nil
|
||||
end
|
||||
end
|
||||
},
|
||||
|
|
@ -468,7 +516,8 @@ local types = require((...):gsub("interpreter%.common$", "stdlib.types"))
|
|||
atypes, ltypes = types.anselme, types.lua
|
||||
eval = require((...):gsub("common$", "expression"))
|
||||
run_block = require((...):gsub("common$", "interpreter")).run_block
|
||||
replace_with_copied_values = require((...):gsub("interpreter%.common$", "common")).replace_with_copied_values
|
||||
local acommon = require((...):gsub("interpreter%.common$", "common"))
|
||||
replace_with_copied_values, fix_not_modified_references = acommon.replace_with_copied_values, acommon.fix_not_modified_references
|
||||
identifier_pattern = require((...):gsub("interpreter%.common$", "parser.common")).identifier_pattern
|
||||
|
||||
return common
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ lua_functions = {
|
|||
local rval = r.value
|
||||
local name = n.value
|
||||
for _, ffqm in ipairs(rval) do
|
||||
local var, vfqm = find(state.aliases, state.variables, ffqm..".", name)
|
||||
local var, vfqm = find(state.aliases, state.interpreter.global_state.variables, ffqm..".", name)
|
||||
if var then
|
||||
return get_variable(state, vfqm)
|
||||
end
|
||||
|
|
|
|||
49
test/tests/scope checkpoint mutable bis error.ans
Normal file
49
test/tests/scope checkpoint mutable bis error.ans
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
:post run = "check"
|
||||
|
||||
:x = [99]
|
||||
|
||||
:l = [1,x]
|
||||
|
||||
:n = 0
|
||||
|
||||
$ f(t)
|
||||
~ t!insert(len(l)+1)
|
||||
|
||||
f1: {l} {t}
|
||||
|
||||
CHECK
|
||||
§ c
|
||||
|
||||
~ n < 1
|
||||
REC
|
||||
|
||||
~ n += 1
|
||||
~ f(t)
|
||||
|
||||
END REC
|
||||
|
||||
f2: {l}
|
||||
|
||||
CHECK 2
|
||||
§ d
|
||||
|
||||
~ t!insert(len(t)+1)
|
||||
|
||||
~ t(2)!insert(len(l)+1)
|
||||
|
||||
~ error("t")
|
||||
|
||||
f3: {l} {t}
|
||||
|
||||
~ f(l)
|
||||
|
||||
FINAL
|
||||
|
||||
l: {l}
|
||||
|
||||
x: {x}
|
||||
|
||||
$ check
|
||||
AFTER ERROR
|
||||
|
||||
l: {l}
|
||||
120
test/tests/scope checkpoint mutable bis error.lua
Normal file
120
test/tests/scope checkpoint mutable bis error.lua
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
local _={}
|
||||
_[54]={}
|
||||
_[53]={}
|
||||
_[52]={}
|
||||
_[51]={}
|
||||
_[50]={}
|
||||
_[49]={}
|
||||
_[48]={}
|
||||
_[47]={}
|
||||
_[46]={}
|
||||
_[45]={}
|
||||
_[44]={}
|
||||
_[43]={}
|
||||
_[42]={}
|
||||
_[41]={}
|
||||
_[40]={}
|
||||
_[39]={}
|
||||
_[38]={}
|
||||
_[37]={text="[1, [99], 3, 4]",tags=_[54]}
|
||||
_[36]={text="l: ",tags=_[53]}
|
||||
_[35]={text="AFTER ERROR",tags=_[52]}
|
||||
_[34]={text="CHECK 2",tags=_[51]}
|
||||
_[33]={text="[1, [99], 3, 4]",tags=_[50]}
|
||||
_[32]={text="f2: ",tags=_[49]}
|
||||
_[31]={text="CHECK",tags=_[48]}
|
||||
_[30]={text="[1, [99], 3, 4]",tags=_[47]}
|
||||
_[29]={text=" ",tags=_[46]}
|
||||
_[28]={text="[1, [99], 3, 4]",tags=_[45]}
|
||||
_[27]={text="f1: ",tags=_[44]}
|
||||
_[26]={text="REC",tags=_[43]}
|
||||
_[25]={text="CHECK",tags=_[42]}
|
||||
_[24]={text="[1, [99], 3]",tags=_[41]}
|
||||
_[23]={text=" ",tags=_[40]}
|
||||
_[22]={text="[1, [99], 3]",tags=_[39]}
|
||||
_[21]={text="f1: ",tags=_[38]}
|
||||
_[20]={_[36],_[37]}
|
||||
_[19]={_[35]}
|
||||
_[18]={_[34]}
|
||||
_[17]={_[32],_[33]}
|
||||
_[16]={_[31]}
|
||||
_[15]={_[27],_[28],_[29],_[30]}
|
||||
_[14]={_[26]}
|
||||
_[13]={_[25]}
|
||||
_[12]={_[21],_[22],_[23],_[24]}
|
||||
_[11]={"return"}
|
||||
_[10]={"text",_[20]}
|
||||
_[9]={"text",_[19]}
|
||||
_[8]={"error","t; in Lua function \"error\"; at test/tests/scope checkpoint mutable bis error.ans:34; at test/tests/scope checkpoint mutable bis error.ans:21; at test/tests/scope checkpoint mutable bis error.ans:38"}
|
||||
_[7]={"text",_[18]}
|
||||
_[6]={"text",_[17]}
|
||||
_[5]={"text",_[16]}
|
||||
_[4]={"text",_[15]}
|
||||
_[3]={"text",_[14]}
|
||||
_[2]={"text",_[13]}
|
||||
_[1]={"text",_[12]}
|
||||
return {_[1],_[2],_[3],_[4],_[5],_[6],_[7],_[8],_[9],_[10],_[11]}
|
||||
--[[
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "f1: "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, [99], 3]"
|
||||
}, {
|
||||
tags = {},
|
||||
text = " "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, [99], 3]"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "CHECK"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "REC"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "f1: "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, [99], 3, 4]"
|
||||
}, {
|
||||
tags = {},
|
||||
text = " "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, [99], 3, 4]"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "CHECK"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "f2: "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, [99], 3, 4]"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "CHECK 2"
|
||||
} } }
|
||||
{ "error", 't; in Lua function "error"; at test/tests/scope checkpoint mutable bis error.ans:34; at test/tests/scope checkpoint mutable bis error.ans:21; at test/tests/scope checkpoint mutable bis error.ans:38' }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "AFTER ERROR"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "l: "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, [99], 3, 4]"
|
||||
} } }
|
||||
{ "return" }
|
||||
]]--
|
||||
40
test/tests/scope checkpoint mutable bis.ans
Normal file
40
test/tests/scope checkpoint mutable bis.ans
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
:x = [99]
|
||||
|
||||
:l = [1,x]
|
||||
|
||||
:n = 0
|
||||
|
||||
$ f(t)
|
||||
~ t!insert(len(l)+1)
|
||||
|
||||
f1: {l} {t}
|
||||
|
||||
CHECK
|
||||
§ c
|
||||
|
||||
~ n < 1
|
||||
REC
|
||||
|
||||
~ n += 1
|
||||
~ f(t)
|
||||
|
||||
END REC
|
||||
|
||||
f2: {l}
|
||||
|
||||
CHECK 2
|
||||
§ d
|
||||
|
||||
~ t!insert(len(t)+1)
|
||||
|
||||
~ t(2)!insert(len(l)+1)
|
||||
|
||||
f3: {l} {t}
|
||||
|
||||
~ f(l)
|
||||
|
||||
FINAL
|
||||
|
||||
l: {l}
|
||||
|
||||
x: {x}
|
||||
206
test/tests/scope checkpoint mutable bis.lua
Normal file
206
test/tests/scope checkpoint mutable bis.lua
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
local _={}
|
||||
_[93]={}
|
||||
_[92]={}
|
||||
_[91]={}
|
||||
_[90]={}
|
||||
_[89]={}
|
||||
_[88]={}
|
||||
_[87]={}
|
||||
_[86]={}
|
||||
_[85]={}
|
||||
_[84]={}
|
||||
_[83]={}
|
||||
_[82]={}
|
||||
_[81]={}
|
||||
_[80]={}
|
||||
_[79]={}
|
||||
_[78]={}
|
||||
_[77]={}
|
||||
_[76]={}
|
||||
_[75]={}
|
||||
_[74]={}
|
||||
_[73]={}
|
||||
_[72]={}
|
||||
_[71]={}
|
||||
_[70]={}
|
||||
_[69]={}
|
||||
_[68]={}
|
||||
_[67]={}
|
||||
_[66]={}
|
||||
_[65]={}
|
||||
_[64]={}
|
||||
_[63]={}
|
||||
_[62]={tags=_[93],text="[99, 6, 7]"}
|
||||
_[61]={tags=_[92],text="x: "}
|
||||
_[60]={tags=_[91],text="[1, [99, 6, 7], 3, 4, 5, 6]"}
|
||||
_[59]={tags=_[90],text="l: "}
|
||||
_[58]={tags=_[89],text="FINAL"}
|
||||
_[57]={tags=_[88],text="[1, [99, 6, 7], 3, 4, 5, 6]"}
|
||||
_[56]={tags=_[87],text=" "}
|
||||
_[55]={tags=_[86],text="[1, [99, 6, 7], 3, 4, 5, 6]"}
|
||||
_[54]={tags=_[85],text="f3: "}
|
||||
_[53]={tags=_[84],text="CHECK 2"}
|
||||
_[52]={tags=_[83],text="[1, [99, 6], 3, 4, 5]"}
|
||||
_[51]={tags=_[82],text="f2: "}
|
||||
_[50]={tags=_[81],text="END REC"}
|
||||
_[49]={tags=_[80],text="[1, [99, 6], 3, 4, 5]"}
|
||||
_[48]={tags=_[79],text=" "}
|
||||
_[47]={tags=_[78],text="[1, [99, 6], 3, 4, 5]"}
|
||||
_[46]={tags=_[77],text="f3: "}
|
||||
_[45]={tags=_[76],text="CHECK 2"}
|
||||
_[44]={tags=_[75],text="[1, [99], 3, 4]"}
|
||||
_[43]={tags=_[74],text="f2: "}
|
||||
_[42]={tags=_[73],text="CHECK"}
|
||||
_[41]={tags=_[72],text="[1, [99], 3, 4]"}
|
||||
_[40]={tags=_[71],text=" "}
|
||||
_[39]={tags=_[70],text="[1, [99], 3, 4]"}
|
||||
_[38]={tags=_[69],text="f1: "}
|
||||
_[37]={tags=_[68],text="REC"}
|
||||
_[36]={tags=_[67],text="CHECK"}
|
||||
_[35]={tags=_[66],text="[1, [99], 3]"}
|
||||
_[34]={tags=_[65],text=" "}
|
||||
_[33]={tags=_[64],text="[1, [99], 3]"}
|
||||
_[32]={tags=_[63],text="f1: "}
|
||||
_[31]={_[61],_[62]}
|
||||
_[30]={_[59],_[60]}
|
||||
_[29]={_[58]}
|
||||
_[28]={_[54],_[55],_[56],_[57]}
|
||||
_[27]={_[53]}
|
||||
_[26]={_[51],_[52]}
|
||||
_[25]={_[50]}
|
||||
_[24]={_[46],_[47],_[48],_[49]}
|
||||
_[23]={_[45]}
|
||||
_[22]={_[43],_[44]}
|
||||
_[21]={_[42]}
|
||||
_[20]={_[38],_[39],_[40],_[41]}
|
||||
_[19]={_[37]}
|
||||
_[18]={_[36]}
|
||||
_[17]={_[32],_[33],_[34],_[35]}
|
||||
_[16]={"return"}
|
||||
_[15]={"text",_[31]}
|
||||
_[14]={"text",_[30]}
|
||||
_[13]={"text",_[29]}
|
||||
_[12]={"text",_[28]}
|
||||
_[11]={"text",_[27]}
|
||||
_[10]={"text",_[26]}
|
||||
_[9]={"text",_[25]}
|
||||
_[8]={"text",_[24]}
|
||||
_[7]={"text",_[23]}
|
||||
_[6]={"text",_[22]}
|
||||
_[5]={"text",_[21]}
|
||||
_[4]={"text",_[20]}
|
||||
_[3]={"text",_[19]}
|
||||
_[2]={"text",_[18]}
|
||||
_[1]={"text",_[17]}
|
||||
return {_[1],_[2],_[3],_[4],_[5],_[6],_[7],_[8],_[9],_[10],_[11],_[12],_[13],_[14],_[15],_[16]}
|
||||
--[[
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "f1: "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, [99], 3]"
|
||||
}, {
|
||||
tags = {},
|
||||
text = " "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, [99], 3]"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "CHECK"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "REC"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "f1: "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, [99], 3, 4]"
|
||||
}, {
|
||||
tags = {},
|
||||
text = " "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, [99], 3, 4]"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "CHECK"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "f2: "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, [99], 3, 4]"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "CHECK 2"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "f3: "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, [99, 6], 3, 4, 5]"
|
||||
}, {
|
||||
tags = {},
|
||||
text = " "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, [99, 6], 3, 4, 5]"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "END REC"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "f2: "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, [99, 6], 3, 4, 5]"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "CHECK 2"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "f3: "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, [99, 6, 7], 3, 4, 5, 6]"
|
||||
}, {
|
||||
tags = {},
|
||||
text = " "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, [99, 6, 7], 3, 4, 5, 6]"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "FINAL"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "l: "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, [99, 6, 7], 3, 4, 5, 6]"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "x: "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[99, 6, 7]"
|
||||
} } }
|
||||
{ "return" }
|
||||
]]--
|
||||
38
test/tests/scope checkpoint mutable error.ans
Normal file
38
test/tests/scope checkpoint mutable error.ans
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
:post run = "check"
|
||||
|
||||
:l = [1]
|
||||
|
||||
:n = 0
|
||||
|
||||
$ f(t)
|
||||
~ t!insert(len(l)+1)
|
||||
|
||||
f1: {l} {t}
|
||||
|
||||
CHECK
|
||||
§ c
|
||||
|
||||
~ n < 1
|
||||
REC
|
||||
|
||||
~ n += 1
|
||||
~ f(t)
|
||||
|
||||
END REC
|
||||
|
||||
~ t!insert(len(t)+1)
|
||||
|
||||
~ error("t")
|
||||
|
||||
f2: {l}
|
||||
|
||||
~ f(l)
|
||||
|
||||
FINAL
|
||||
|
||||
l: {l}
|
||||
|
||||
$ check
|
||||
AFTER ERROR
|
||||
|
||||
l: {l}
|
||||
99
test/tests/scope checkpoint mutable error.lua
Normal file
99
test/tests/scope checkpoint mutable error.lua
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
local _={}
|
||||
_[44]={}
|
||||
_[43]={}
|
||||
_[42]={}
|
||||
_[41]={}
|
||||
_[40]={}
|
||||
_[39]={}
|
||||
_[38]={}
|
||||
_[37]={}
|
||||
_[36]={}
|
||||
_[35]={}
|
||||
_[34]={}
|
||||
_[33]={}
|
||||
_[32]={}
|
||||
_[31]={}
|
||||
_[30]={tags=_[44],text="[1, 2, 3]"}
|
||||
_[29]={tags=_[43],text="l: "}
|
||||
_[28]={tags=_[42],text="AFTER ERROR"}
|
||||
_[27]={tags=_[41],text="CHECK"}
|
||||
_[26]={tags=_[40],text="[1, 2, 3]"}
|
||||
_[25]={tags=_[39],text=" "}
|
||||
_[24]={tags=_[38],text="[1, 2, 3]"}
|
||||
_[23]={tags=_[37],text="f1: "}
|
||||
_[22]={tags=_[36],text="REC"}
|
||||
_[21]={tags=_[35],text="CHECK"}
|
||||
_[20]={tags=_[34],text="[1, 2]"}
|
||||
_[19]={tags=_[33],text=" "}
|
||||
_[18]={tags=_[32],text="[1, 2]"}
|
||||
_[17]={tags=_[31],text="f1: "}
|
||||
_[16]={_[29],_[30]}
|
||||
_[15]={_[28]}
|
||||
_[14]={_[27]}
|
||||
_[13]={_[23],_[24],_[25],_[26]}
|
||||
_[12]={_[22]}
|
||||
_[11]={_[21]}
|
||||
_[10]={_[17],_[18],_[19],_[20]}
|
||||
_[9]={"return"}
|
||||
_[8]={"text",_[16]}
|
||||
_[7]={"text",_[15]}
|
||||
_[6]={"error","t; in Lua function \"error\"; at test/tests/scope checkpoint mutable error.ans:25; at test/tests/scope checkpoint mutable error.ans:19; at test/tests/scope checkpoint mutable error.ans:29"}
|
||||
_[5]={"text",_[14]}
|
||||
_[4]={"text",_[13]}
|
||||
_[3]={"text",_[12]}
|
||||
_[2]={"text",_[11]}
|
||||
_[1]={"text",_[10]}
|
||||
return {_[1],_[2],_[3],_[4],_[5],_[6],_[7],_[8],_[9]}
|
||||
--[[
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "f1: "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, 2]"
|
||||
}, {
|
||||
tags = {},
|
||||
text = " "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, 2]"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "CHECK"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "REC"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "f1: "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, 2, 3]"
|
||||
}, {
|
||||
tags = {},
|
||||
text = " "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, 2, 3]"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "CHECK"
|
||||
} } }
|
||||
{ "error", 't; in Lua function "error"; at test/tests/scope checkpoint mutable error.ans:25; at test/tests/scope checkpoint mutable error.ans:19; at test/tests/scope checkpoint mutable error.ans:29' }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "AFTER ERROR"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "l: "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, 2, 3]"
|
||||
} } }
|
||||
{ "return" }
|
||||
]]--
|
||||
51
test/tests/scope checkpoint mutable ter error.ans
Normal file
51
test/tests/scope checkpoint mutable ter error.ans
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
:post run = "check"
|
||||
|
||||
:x = [99]
|
||||
|
||||
:l = [1,x]
|
||||
|
||||
:n = 0
|
||||
|
||||
$ f(t)
|
||||
~ t!insert(len(l)+1)
|
||||
|
||||
f1: {l} {t}
|
||||
|
||||
CHECK
|
||||
§ c
|
||||
|
||||
~ n < 1
|
||||
REC
|
||||
|
||||
~ n += 1
|
||||
~ f(t)
|
||||
|
||||
END REC
|
||||
|
||||
~ x!insert(12)
|
||||
|
||||
f2: {l}
|
||||
|
||||
CHECK 2
|
||||
§ d
|
||||
|
||||
~ t!insert(len(t)+1)
|
||||
|
||||
~ t(2)!insert(len(l)+1)
|
||||
|
||||
~ error("t")
|
||||
|
||||
f3: {l} {t}
|
||||
|
||||
~ f(l)
|
||||
|
||||
FINAL
|
||||
|
||||
l: {l}
|
||||
|
||||
x: {x}
|
||||
|
||||
$ check
|
||||
AFTER ERROR
|
||||
|
||||
l: {l}
|
||||
120
test/tests/scope checkpoint mutable ter error.lua
Normal file
120
test/tests/scope checkpoint mutable ter error.lua
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
local _={}
|
||||
_[54]={}
|
||||
_[53]={}
|
||||
_[52]={}
|
||||
_[51]={}
|
||||
_[50]={}
|
||||
_[49]={}
|
||||
_[48]={}
|
||||
_[47]={}
|
||||
_[46]={}
|
||||
_[45]={}
|
||||
_[44]={}
|
||||
_[43]={}
|
||||
_[42]={}
|
||||
_[41]={}
|
||||
_[40]={}
|
||||
_[39]={}
|
||||
_[38]={}
|
||||
_[37]={text="[1, [99, 12], 3, 4]",tags=_[54]}
|
||||
_[36]={text="l: ",tags=_[53]}
|
||||
_[35]={text="AFTER ERROR",tags=_[52]}
|
||||
_[34]={text="CHECK 2",tags=_[51]}
|
||||
_[33]={text="[1, [99, 12], 3, 4]",tags=_[50]}
|
||||
_[32]={text="f2: ",tags=_[49]}
|
||||
_[31]={text="CHECK",tags=_[48]}
|
||||
_[30]={text="[1, [99], 3, 4]",tags=_[47]}
|
||||
_[29]={text=" ",tags=_[46]}
|
||||
_[28]={text="[1, [99], 3, 4]",tags=_[45]}
|
||||
_[27]={text="f1: ",tags=_[44]}
|
||||
_[26]={text="REC",tags=_[43]}
|
||||
_[25]={text="CHECK",tags=_[42]}
|
||||
_[24]={text="[1, [99], 3]",tags=_[41]}
|
||||
_[23]={text=" ",tags=_[40]}
|
||||
_[22]={text="[1, [99], 3]",tags=_[39]}
|
||||
_[21]={text="f1: ",tags=_[38]}
|
||||
_[20]={_[36],_[37]}
|
||||
_[19]={_[35]}
|
||||
_[18]={_[34]}
|
||||
_[17]={_[32],_[33]}
|
||||
_[16]={_[31]}
|
||||
_[15]={_[27],_[28],_[29],_[30]}
|
||||
_[14]={_[26]}
|
||||
_[13]={_[25]}
|
||||
_[12]={_[21],_[22],_[23],_[24]}
|
||||
_[11]={"return"}
|
||||
_[10]={"text",_[20]}
|
||||
_[9]={"text",_[19]}
|
||||
_[8]={"error","t; in Lua function \"error\"; at test/tests/scope checkpoint mutable ter error.ans:36; at test/tests/scope checkpoint mutable ter error.ans:21; at test/tests/scope checkpoint mutable ter error.ans:40"}
|
||||
_[7]={"text",_[18]}
|
||||
_[6]={"text",_[17]}
|
||||
_[5]={"text",_[16]}
|
||||
_[4]={"text",_[15]}
|
||||
_[3]={"text",_[14]}
|
||||
_[2]={"text",_[13]}
|
||||
_[1]={"text",_[12]}
|
||||
return {_[1],_[2],_[3],_[4],_[5],_[6],_[7],_[8],_[9],_[10],_[11]}
|
||||
--[[
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "f1: "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, [99], 3]"
|
||||
}, {
|
||||
tags = {},
|
||||
text = " "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, [99], 3]"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "CHECK"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "REC"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "f1: "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, [99], 3, 4]"
|
||||
}, {
|
||||
tags = {},
|
||||
text = " "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, [99], 3, 4]"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "CHECK"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "f2: "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, [99, 12], 3, 4]"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "CHECK 2"
|
||||
} } }
|
||||
{ "error", 't; in Lua function "error"; at test/tests/scope checkpoint mutable ter error.ans:36; at test/tests/scope checkpoint mutable ter error.ans:21; at test/tests/scope checkpoint mutable ter error.ans:40' }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "AFTER ERROR"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "l: "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, [99, 12], 3, 4]"
|
||||
} } }
|
||||
{ "return" }
|
||||
]]--
|
||||
42
test/tests/scope checkpoint mutable ter.ans
Normal file
42
test/tests/scope checkpoint mutable ter.ans
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
:x = [99]
|
||||
|
||||
:l = [1,x]
|
||||
|
||||
:n = 0
|
||||
|
||||
$ f(t)
|
||||
~ t!insert(len(l)+1)
|
||||
|
||||
f1: {l} {t}
|
||||
|
||||
CHECK
|
||||
§ c
|
||||
|
||||
~ n < 1
|
||||
REC
|
||||
|
||||
~ n += 1
|
||||
~ f(t)
|
||||
|
||||
END REC
|
||||
|
||||
~ x!insert(12)
|
||||
|
||||
f2: {l}
|
||||
|
||||
CHECK 2
|
||||
§ d
|
||||
|
||||
~ t!insert(len(t)+1)
|
||||
|
||||
~ t(2)!insert(len(l)+1)
|
||||
|
||||
f3: {l} {t}
|
||||
|
||||
~ f(l)
|
||||
|
||||
FINAL
|
||||
|
||||
l: {l}
|
||||
|
||||
x: {x}
|
||||
206
test/tests/scope checkpoint mutable ter.lua
Normal file
206
test/tests/scope checkpoint mutable ter.lua
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
local _={}
|
||||
_[93]={}
|
||||
_[92]={}
|
||||
_[91]={}
|
||||
_[90]={}
|
||||
_[89]={}
|
||||
_[88]={}
|
||||
_[87]={}
|
||||
_[86]={}
|
||||
_[85]={}
|
||||
_[84]={}
|
||||
_[83]={}
|
||||
_[82]={}
|
||||
_[81]={}
|
||||
_[80]={}
|
||||
_[79]={}
|
||||
_[78]={}
|
||||
_[77]={}
|
||||
_[76]={}
|
||||
_[75]={}
|
||||
_[74]={}
|
||||
_[73]={}
|
||||
_[72]={}
|
||||
_[71]={}
|
||||
_[70]={}
|
||||
_[69]={}
|
||||
_[68]={}
|
||||
_[67]={}
|
||||
_[66]={}
|
||||
_[65]={}
|
||||
_[64]={}
|
||||
_[63]={}
|
||||
_[62]={tags=_[93],text="[99, 12, 6, 12, 7]"}
|
||||
_[61]={tags=_[92],text="x: "}
|
||||
_[60]={tags=_[91],text="[1, [99, 12, 6, 12, 7], 3, 4, 5, 6]"}
|
||||
_[59]={tags=_[90],text="l: "}
|
||||
_[58]={tags=_[89],text="FINAL"}
|
||||
_[57]={tags=_[88],text="[1, [99, 12, 6, 12, 7], 3, 4, 5, 6]"}
|
||||
_[56]={tags=_[87],text=" "}
|
||||
_[55]={tags=_[86],text="[1, [99, 12, 6, 12, 7], 3, 4, 5, 6]"}
|
||||
_[54]={tags=_[85],text="f3: "}
|
||||
_[53]={tags=_[84],text="CHECK 2"}
|
||||
_[52]={tags=_[83],text="[1, [99, 12, 6, 12], 3, 4, 5]"}
|
||||
_[51]={tags=_[82],text="f2: "}
|
||||
_[50]={tags=_[81],text="END REC"}
|
||||
_[49]={tags=_[80],text="[1, [99, 12, 6], 3, 4, 5]"}
|
||||
_[48]={tags=_[79],text=" "}
|
||||
_[47]={tags=_[78],text="[1, [99, 12, 6], 3, 4, 5]"}
|
||||
_[46]={tags=_[77],text="f3: "}
|
||||
_[45]={tags=_[76],text="CHECK 2"}
|
||||
_[44]={tags=_[75],text="[1, [99, 12], 3, 4]"}
|
||||
_[43]={tags=_[74],text="f2: "}
|
||||
_[42]={tags=_[73],text="CHECK"}
|
||||
_[41]={tags=_[72],text="[1, [99], 3, 4]"}
|
||||
_[40]={tags=_[71],text=" "}
|
||||
_[39]={tags=_[70],text="[1, [99], 3, 4]"}
|
||||
_[38]={tags=_[69],text="f1: "}
|
||||
_[37]={tags=_[68],text="REC"}
|
||||
_[36]={tags=_[67],text="CHECK"}
|
||||
_[35]={tags=_[66],text="[1, [99], 3]"}
|
||||
_[34]={tags=_[65],text=" "}
|
||||
_[33]={tags=_[64],text="[1, [99], 3]"}
|
||||
_[32]={tags=_[63],text="f1: "}
|
||||
_[31]={_[61],_[62]}
|
||||
_[30]={_[59],_[60]}
|
||||
_[29]={_[58]}
|
||||
_[28]={_[54],_[55],_[56],_[57]}
|
||||
_[27]={_[53]}
|
||||
_[26]={_[51],_[52]}
|
||||
_[25]={_[50]}
|
||||
_[24]={_[46],_[47],_[48],_[49]}
|
||||
_[23]={_[45]}
|
||||
_[22]={_[43],_[44]}
|
||||
_[21]={_[42]}
|
||||
_[20]={_[38],_[39],_[40],_[41]}
|
||||
_[19]={_[37]}
|
||||
_[18]={_[36]}
|
||||
_[17]={_[32],_[33],_[34],_[35]}
|
||||
_[16]={"return"}
|
||||
_[15]={"text",_[31]}
|
||||
_[14]={"text",_[30]}
|
||||
_[13]={"text",_[29]}
|
||||
_[12]={"text",_[28]}
|
||||
_[11]={"text",_[27]}
|
||||
_[10]={"text",_[26]}
|
||||
_[9]={"text",_[25]}
|
||||
_[8]={"text",_[24]}
|
||||
_[7]={"text",_[23]}
|
||||
_[6]={"text",_[22]}
|
||||
_[5]={"text",_[21]}
|
||||
_[4]={"text",_[20]}
|
||||
_[3]={"text",_[19]}
|
||||
_[2]={"text",_[18]}
|
||||
_[1]={"text",_[17]}
|
||||
return {_[1],_[2],_[3],_[4],_[5],_[6],_[7],_[8],_[9],_[10],_[11],_[12],_[13],_[14],_[15],_[16]}
|
||||
--[[
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "f1: "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, [99], 3]"
|
||||
}, {
|
||||
tags = {},
|
||||
text = " "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, [99], 3]"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "CHECK"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "REC"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "f1: "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, [99], 3, 4]"
|
||||
}, {
|
||||
tags = {},
|
||||
text = " "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, [99], 3, 4]"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "CHECK"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "f2: "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, [99, 12], 3, 4]"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "CHECK 2"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "f3: "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, [99, 12, 6], 3, 4, 5]"
|
||||
}, {
|
||||
tags = {},
|
||||
text = " "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, [99, 12, 6], 3, 4, 5]"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "END REC"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "f2: "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, [99, 12, 6, 12], 3, 4, 5]"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "CHECK 2"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "f3: "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, [99, 12, 6, 12, 7], 3, 4, 5, 6]"
|
||||
}, {
|
||||
tags = {},
|
||||
text = " "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, [99, 12, 6, 12, 7], 3, 4, 5, 6]"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "FINAL"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "l: "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, [99, 12, 6, 12, 7], 3, 4, 5, 6]"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "x: "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[99, 12, 6, 12, 7]"
|
||||
} } }
|
||||
{ "return" }
|
||||
]]--
|
||||
29
test/tests/scope checkpoint mutable.ans
Normal file
29
test/tests/scope checkpoint mutable.ans
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
:l = [1]
|
||||
|
||||
:n = 0
|
||||
|
||||
$ f(t)
|
||||
~ t!insert(len(l)+1)
|
||||
|
||||
f1: {l} {t}
|
||||
|
||||
CHECK
|
||||
§ c
|
||||
|
||||
~ n < 1
|
||||
REC
|
||||
|
||||
~ n += 1
|
||||
~ f(t)
|
||||
|
||||
END REC
|
||||
|
||||
~ t!insert(len(t)+1)
|
||||
|
||||
f2: {l}
|
||||
|
||||
~ f(l)
|
||||
|
||||
FINAL
|
||||
|
||||
l: {l}
|
||||
131
test/tests/scope checkpoint mutable.lua
Normal file
131
test/tests/scope checkpoint mutable.lua
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
local _={}
|
||||
_[59]={}
|
||||
_[58]={}
|
||||
_[57]={}
|
||||
_[56]={}
|
||||
_[55]={}
|
||||
_[54]={}
|
||||
_[53]={}
|
||||
_[52]={}
|
||||
_[51]={}
|
||||
_[50]={}
|
||||
_[49]={}
|
||||
_[48]={}
|
||||
_[47]={}
|
||||
_[46]={}
|
||||
_[45]={}
|
||||
_[44]={}
|
||||
_[43]={}
|
||||
_[42]={}
|
||||
_[41]={}
|
||||
_[40]={text="[1, 2, 3, 4, 5]",tags=_[59]}
|
||||
_[39]={text="l: ",tags=_[58]}
|
||||
_[38]={text="FINAL",tags=_[57]}
|
||||
_[37]={text="[1, 2, 3, 4, 5]",tags=_[56]}
|
||||
_[36]={text="f2: ",tags=_[55]}
|
||||
_[35]={text="END REC",tags=_[54]}
|
||||
_[34]={text="[1, 2, 3, 4]",tags=_[53]}
|
||||
_[33]={text="f2: ",tags=_[52]}
|
||||
_[32]={text="CHECK",tags=_[51]}
|
||||
_[31]={text="[1, 2, 3]",tags=_[50]}
|
||||
_[30]={text=" ",tags=_[49]}
|
||||
_[29]={text="[1, 2, 3]",tags=_[48]}
|
||||
_[28]={text="f1: ",tags=_[47]}
|
||||
_[27]={text="REC",tags=_[46]}
|
||||
_[26]={text="CHECK",tags=_[45]}
|
||||
_[25]={text="[1, 2]",tags=_[44]}
|
||||
_[24]={text=" ",tags=_[43]}
|
||||
_[23]={text="[1, 2]",tags=_[42]}
|
||||
_[22]={text="f1: ",tags=_[41]}
|
||||
_[21]={_[39],_[40]}
|
||||
_[20]={_[38]}
|
||||
_[19]={_[36],_[37]}
|
||||
_[18]={_[35]}
|
||||
_[17]={_[33],_[34]}
|
||||
_[16]={_[32]}
|
||||
_[15]={_[28],_[29],_[30],_[31]}
|
||||
_[14]={_[27]}
|
||||
_[13]={_[26]}
|
||||
_[12]={_[22],_[23],_[24],_[25]}
|
||||
_[11]={"return"}
|
||||
_[10]={"text",_[21]}
|
||||
_[9]={"text",_[20]}
|
||||
_[8]={"text",_[19]}
|
||||
_[7]={"text",_[18]}
|
||||
_[6]={"text",_[17]}
|
||||
_[5]={"text",_[16]}
|
||||
_[4]={"text",_[15]}
|
||||
_[3]={"text",_[14]}
|
||||
_[2]={"text",_[13]}
|
||||
_[1]={"text",_[12]}
|
||||
return {_[1],_[2],_[3],_[4],_[5],_[6],_[7],_[8],_[9],_[10],_[11]}
|
||||
--[[
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "f1: "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, 2]"
|
||||
}, {
|
||||
tags = {},
|
||||
text = " "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, 2]"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "CHECK"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "REC"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "f1: "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, 2, 3]"
|
||||
}, {
|
||||
tags = {},
|
||||
text = " "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, 2, 3]"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "CHECK"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "f2: "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, 2, 3, 4]"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "END REC"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "f2: "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, 2, 3, 4, 5]"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "FINAL"
|
||||
} } }
|
||||
{ "text", { {
|
||||
tags = {},
|
||||
text = "l: "
|
||||
}, {
|
||||
tags = {},
|
||||
text = "[1, 2, 3, 4, 5]"
|
||||
} } }
|
||||
{ "return" }
|
||||
]]--
|
||||
Loading…
Add table
Add a link
Reference in a new issue