mirror of
https://github.com/Reuh/anselme.git
synced 2025-10-27 16:49:31 +00:00
stdlib cleanup
This commit is contained in:
parent
dac5b74fa6
commit
a212dd7fd1
17 changed files with 212 additions and 190 deletions
39
anselme/stdlib/attached block.lua
Normal file
39
anselme/stdlib/attached block.lua
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
local ast = require("anselme.ast")
|
||||||
|
local Function, ParameterTuple, Identifier = ast.Function, ast.ParameterTuple, ast.Identifier
|
||||||
|
|
||||||
|
local calling_environment_manager = require("anselme.state.calling_environment_manager")
|
||||||
|
|
||||||
|
local block_identifier = Identifier:new("_")
|
||||||
|
|
||||||
|
return {
|
||||||
|
{
|
||||||
|
"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, 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", "(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)
|
||||||
|
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
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
@ -1,21 +1,10 @@
|
||||||
local ast = require("anselme.ast")
|
local ast = require("anselme.ast")
|
||||||
local Pair, ArgumentTuple, Nil, String, Typed, Boolean = ast.Pair, ast.ArgumentTuple, ast.Nil, ast.String, ast.Typed, ast.Boolean
|
local Nil, String = ast.Nil, ast.String
|
||||||
|
|
||||||
return {
|
return {
|
||||||
{ "_;_", "(left, right)", function(state, left, right) return right end },
|
{ "_;_", "(left, right)", function(state, left, right) return right end },
|
||||||
{ "_;", "(left)", function(state, left) return Nil:new() end },
|
{ "_;", "(left)", function(state, left) return Nil:new() end },
|
||||||
{ "_:_", "(name, value)", function(state, a, b) return Pair:new(a,b) end },
|
|
||||||
{
|
|
||||||
"_::_", "(value, check)",
|
|
||||||
function(state, value, check)
|
|
||||||
local r = check:call(state, ArgumentTuple:new(value))
|
|
||||||
if r:truthy() then
|
|
||||||
return value
|
|
||||||
else
|
|
||||||
error(("type check failure: %s does not satisfy %s"):format(value:format(state), check:format(state)), 0)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"print", "(a)",
|
"print", "(a)",
|
||||||
function(state, a)
|
function(state, a)
|
||||||
|
|
@ -29,35 +18,6 @@ return {
|
||||||
return String:new(a:hash())
|
return String:new(a:hash())
|
||||||
end
|
end
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"type", "(value)",
|
|
||||||
function(state, v)
|
|
||||||
if v.type == "typed" then
|
|
||||||
return v.type_expression
|
|
||||||
else
|
|
||||||
return String:new(v.type)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"value", "(value)",
|
|
||||||
function(state, v)
|
|
||||||
if v.type == "typed" then
|
|
||||||
return v.expression
|
|
||||||
else
|
|
||||||
return v
|
|
||||||
end
|
|
||||||
end
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type", "(value, type)",
|
|
||||||
function(state, v, t)
|
|
||||||
return Typed:new(v, t)
|
|
||||||
end
|
|
||||||
},
|
|
||||||
{ "true", Boolean:new(true) },
|
|
||||||
{ "false", Boolean:new(false) },
|
|
||||||
|
|
||||||
{
|
{
|
||||||
"error", "(message=\"error\")",
|
"error", "(message=\"error\")",
|
||||||
function(state, message)
|
function(state, message)
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,9 @@ local ast = require("anselme.ast")
|
||||||
local Boolean, ArgumentTuple = ast.Boolean, ast.ArgumentTuple
|
local Boolean, ArgumentTuple = ast.Boolean, ast.ArgumentTuple
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
{ "true", Boolean:new(true) },
|
||||||
|
{ "false", Boolean:new(false) },
|
||||||
|
|
||||||
{
|
{
|
||||||
"_==_", "(a, b)",
|
"_==_", "(a, b)",
|
||||||
function(state, a, b)
|
function(state, a, b)
|
||||||
|
|
|
||||||
|
|
@ -1,122 +0,0 @@
|
||||||
local ast = require("anselme.ast")
|
|
||||||
local Nil, Boolean, Definition, Call, Function, ParameterTuple, FunctionParameter, Identifier, Overload, Assignment, Return = ast.Nil, ast.Boolean, ast.Definition, ast.Call, ast.Function, ast.ParameterTuple, ast.FunctionParameter, ast.Identifier, ast.Overload, ast.Assignment, ast.Return
|
|
||||||
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)",
|
|
||||||
function(state, c, s)
|
|
||||||
return Boolean:new(c.scope:defined_in_current(state, s:to_identifier()))
|
|
||||||
end
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"has upvalue", "(c::function, s::string)",
|
|
||||||
function(state, c, s)
|
|
||||||
return Boolean:new(c.scope:defined(state, s:to_identifier()))
|
|
||||||
end
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"_._", "(c::function, s::string)",
|
|
||||||
function(state, c, s)
|
|
||||||
local identifier = s:to_identifier()
|
|
||||||
assert0(c.scope:defined(state, identifier), ("no variable %q defined in closure"):format(s.string))
|
|
||||||
return c.scope:get(state, identifier)
|
|
||||||
end
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"_._", "(c::function, s::string) = v",
|
|
||||||
function(state, c, s, v)
|
|
||||||
local identifier = s:to_identifier()
|
|
||||||
assert0(c.scope:defined(state, identifier), ("no variable %q defined in closure"):format(s.string))
|
|
||||||
c.scope:set(state, identifier, v)
|
|
||||||
return Nil:new()
|
|
||||||
end
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"_._", "(c::function, s::symbol) = v",
|
|
||||||
function(state, c, s, v)
|
|
||||||
state.scope:push(c.scope)
|
|
||||||
local r = Definition:new(s, v):eval(state)
|
|
||||||
state.scope:pop()
|
|
||||||
return r
|
|
||||||
end
|
|
||||||
},
|
|
||||||
{
|
|
||||||
">_", "(q::is(\"quote\"))",
|
|
||||||
function(state, q)
|
|
||||||
local exp = q.expression
|
|
||||||
local get = Function:with_return_boundary(ParameterTuple:new(), exp):eval(state)
|
|
||||||
|
|
||||||
local set_exp
|
|
||||||
if Call:is(exp) then
|
|
||||||
set_exp = Call:new(exp.func, exp.arguments:with_assignment(Identifier:new("value")))
|
|
||||||
elseif Identifier:is(exp) then
|
|
||||||
set_exp = Assignment:new(exp, Identifier:new("value"))
|
|
||||||
end
|
|
||||||
|
|
||||||
if set_exp then
|
|
||||||
local set_param = ParameterTuple:new()
|
|
||||||
set_param:insert_assignment(FunctionParameter:new(Identifier:new("value")))
|
|
||||||
local set = Function:with_return_boundary(set_param, set_exp):eval(state)
|
|
||||||
return Overload:new(get, set)
|
|
||||||
else
|
|
||||||
return get
|
|
||||||
end
|
|
||||||
end
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"return", "(value=())",
|
|
||||||
function(state, val)
|
|
||||||
if Return:is(val) then val = val.expression end
|
|
||||||
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, 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, 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", "(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)
|
|
||||||
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
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
@ -66,6 +66,7 @@ return {
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"while", "(condition, expression=attached block(keep return=true))",
|
"while", "(condition, expression=attached block(keep return=true))",
|
||||||
function(state, condition, expression)
|
function(state, condition, expression)
|
||||||
|
|
@ -94,4 +95,18 @@ return {
|
||||||
return r
|
return r
|
||||||
end
|
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
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
53
anselme/stdlib/function.lua
Normal file
53
anselme/stdlib/function.lua
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
local ast = require("anselme.ast")
|
||||||
|
local Nil, Boolean, Definition, Return = ast.Nil, ast.Boolean, ast.Definition, ast.Return
|
||||||
|
local assert0 = require("anselme.common").assert0
|
||||||
|
|
||||||
|
return {
|
||||||
|
{
|
||||||
|
"defined", "(c::function, s::string)",
|
||||||
|
function(state, c, s)
|
||||||
|
return Boolean:new(c.scope:defined_in_current(state, s:to_identifier()))
|
||||||
|
end
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"has upvalue", "(c::function, s::string)",
|
||||||
|
function(state, c, s)
|
||||||
|
return Boolean:new(c.scope:defined(state, s:to_identifier()))
|
||||||
|
end
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"_._", "(c::function, s::string)",
|
||||||
|
function(state, c, s)
|
||||||
|
local identifier = s:to_identifier()
|
||||||
|
assert0(c.scope:defined(state, identifier), ("no variable %q defined in closure"):format(s.string))
|
||||||
|
return c.scope:get(state, identifier)
|
||||||
|
end
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_._", "(c::function, s::string) = v",
|
||||||
|
function(state, c, s, v)
|
||||||
|
local identifier = s:to_identifier()
|
||||||
|
assert0(c.scope:defined(state, identifier), ("no variable %q defined in closure"):format(s.string))
|
||||||
|
c.scope:set(state, identifier, v)
|
||||||
|
return Nil:new()
|
||||||
|
end
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_._", "(c::function, s::symbol) = v",
|
||||||
|
function(state, c, s, v)
|
||||||
|
state.scope:push(c.scope)
|
||||||
|
local r = Definition:new(s, v):eval(state)
|
||||||
|
state.scope:pop()
|
||||||
|
return r
|
||||||
|
end
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"return", "(value=())",
|
||||||
|
function(state, val)
|
||||||
|
if Return:is(val) then val = val.expression end
|
||||||
|
return Return:new(val)
|
||||||
|
end
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
@ -7,7 +7,12 @@ local function define_lua(state, list)
|
||||||
end
|
end
|
||||||
local function load(state, l)
|
local function load(state, l)
|
||||||
for _, m in ipairs(l) do
|
for _, m in ipairs(l) do
|
||||||
define_lua(state, require("anselme.stdlib."..m))
|
local mod = require("anselme.stdlib."..m)
|
||||||
|
if type(mod) == "string" then
|
||||||
|
parser(mod, m..".ans"):eval(state)
|
||||||
|
else
|
||||||
|
define_lua(state, mod)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -17,21 +22,18 @@ return function(main_state)
|
||||||
"tag",
|
"tag",
|
||||||
"conditionals",
|
"conditionals",
|
||||||
"base",
|
"base",
|
||||||
"type_check"
|
"types",
|
||||||
})
|
"boot",
|
||||||
|
|
||||||
parser(require("anselme.stdlib.boot_script"), "boot.ans"):eval(main_state)
|
|
||||||
|
|
||||||
load(main_state, {
|
|
||||||
"number",
|
"number",
|
||||||
"string",
|
"string",
|
||||||
"text",
|
"text",
|
||||||
"pair",
|
"pair",
|
||||||
"structures",
|
"structures",
|
||||||
"closure",
|
"wrap",
|
||||||
"checkpoint",
|
"attached block",
|
||||||
|
"function",
|
||||||
|
"resume",
|
||||||
"persist",
|
"persist",
|
||||||
|
"script"
|
||||||
})
|
})
|
||||||
|
|
||||||
parser(require("anselme.stdlib.script_script"), "script.ans"):eval(main_state)
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ local ast = require("anselme.ast")
|
||||||
local Boolean, Number = ast.Boolean, ast.Number
|
local Boolean, Number = ast.Boolean, ast.Number
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
{ "pi", Number:new(math.pi) },
|
||||||
|
|
||||||
{
|
{
|
||||||
"_<_", "(a::number, b::number)",
|
"_<_", "(a::number, b::number)",
|
||||||
function(state, a, b)
|
function(state, a, b)
|
||||||
|
|
@ -64,6 +66,4 @@ return {
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
},
|
},
|
||||||
|
|
||||||
{ "pi", Number:new(math.pi) }
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,9 @@
|
||||||
|
local ast = require("anselme.ast")
|
||||||
|
local Pair = ast.Pair
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
{ "_:_", "(name, value)", function(state, a, b) return Pair:new(a,b) end },
|
||||||
|
|
||||||
{
|
{
|
||||||
"name", "(pair::pair)",
|
"name", "(pair::pair)",
|
||||||
function(state, pair)
|
function(state, pair)
|
||||||
|
|
|
||||||
|
|
@ -6,13 +6,13 @@ local calling_environment_manager = require("anselme.state.calling_environment_m
|
||||||
|
|
||||||
return {
|
return {
|
||||||
{
|
{
|
||||||
"resume", "(function::function, anchor::anchor)",
|
"from", "(function::function, anchor::anchor)",
|
||||||
function(state, func, anchor)
|
function(state, func, anchor)
|
||||||
return func:resume(state, anchor)
|
return func:resume(state, anchor)
|
||||||
end
|
end
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"resume", "(function::function, anchor::nil)",
|
"from", "(function::function, anchor::nil)",
|
||||||
function(state, func)
|
function(state, func)
|
||||||
return func:call(state, ArgumentTuple:new())
|
return func:call(state, ArgumentTuple:new())
|
||||||
end
|
end
|
||||||
|
|
@ -4,30 +4,30 @@ return [[
|
||||||
fn.:&reached => "{name}.reached"!persist(*{})
|
fn.:&reached => "{name}.reached"!persist(*{})
|
||||||
fn.:&run => "{name}.run"!persist(0)
|
fn.:&run => "{name}.run"!persist(0)
|
||||||
|
|
||||||
:resumed from = ()
|
:resume target = ()
|
||||||
|
|
||||||
fn.:check = $(anchor::anchor)
|
fn.:check = $(anchor::anchor)
|
||||||
fn.reached(anchor) = (fn.reached(anchor) | 0) + 1
|
fn.reached(anchor) = (fn.reached(anchor) | 0) + 1
|
||||||
fn.:checkpoint = $(anchor::anchor, on resume=attached block(default=()))
|
fn.:checkpoint = $(anchor::anchor, on resume=attached block(default=()))
|
||||||
if(on resume)
|
if(on resume)
|
||||||
fn.current checkpoint = anchor
|
fn.current checkpoint = anchor
|
||||||
if(resumed from == anchor | resuming(4))
|
if(resume target == anchor | resuming(4))
|
||||||
on resume!
|
on resume!
|
||||||
else!
|
else!
|
||||||
fn.reached(anchor) = (fn.reached(anchor) | 0) + 1
|
fn.reached(anchor) = (fn.reached(anchor) | 0) + 1
|
||||||
merge branch!
|
merge branch!
|
||||||
else!
|
else!
|
||||||
fn.current checkpoint = anchor
|
fn.current checkpoint = anchor
|
||||||
if(resumed from != anchor)
|
if(resume target != anchor)
|
||||||
fn.reached(anchor) = (fn.reached(anchor) | 0) + 1
|
fn.reached(anchor) = (fn.reached(anchor) | 0) + 1
|
||||||
merge branch!
|
merge branch!
|
||||||
|
|
||||||
:f = $
|
:f = $
|
||||||
if(fn.current checkpoint)
|
if(fn.current checkpoint)
|
||||||
resumed from = fn.current checkpoint
|
resume target = fn.current checkpoint
|
||||||
fn!resume(fn.current checkpoint)
|
fn!from(fn.current checkpoint)
|
||||||
else!
|
else!
|
||||||
resumed from = ()
|
resume target = ()
|
||||||
fn!
|
fn!
|
||||||
fn.run += 1
|
fn.run += 1
|
||||||
|
|
||||||
|
|
@ -52,7 +52,7 @@ return [[
|
||||||
s.current checkpoint = ()
|
s.current checkpoint = ()
|
||||||
return(s!)
|
return(s!)
|
||||||
|
|
||||||
/*Additionnal helpers*/
|
/* Additionnal helpers */
|
||||||
:@$ cycle(l::tuple)
|
:@$ cycle(l::tuple)
|
||||||
:i = 2
|
:i = 2
|
||||||
while($i <= l!len)
|
while($i <= l!len)
|
||||||
|
|
@ -1,7 +1,46 @@
|
||||||
local ast = require("anselme.ast")
|
local ast = require("anselme.ast")
|
||||||
local Boolean = ast.Boolean
|
local ArgumentTuple, Boolean, String, Typed = ast.ArgumentTuple, ast.Boolean, ast.String, ast.Typed
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
{
|
||||||
|
"_::_", "(value, check)",
|
||||||
|
function(state, value, check)
|
||||||
|
local r = check:call(state, ArgumentTuple:new(value))
|
||||||
|
if r:truthy() then
|
||||||
|
return value
|
||||||
|
else
|
||||||
|
error(("type check failure: %s does not satisfy %s"):format(value:format(state), check:format(state)), 0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"type", "(value)",
|
||||||
|
function(state, v)
|
||||||
|
if v.type == "typed" then
|
||||||
|
return v.type_expression
|
||||||
|
else
|
||||||
|
return String:new(v.type)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type", "(value, type)",
|
||||||
|
function(state, v, t)
|
||||||
|
return Typed:new(v, t)
|
||||||
|
end
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value", "(value)",
|
||||||
|
function(state, v)
|
||||||
|
if v.type == "typed" then
|
||||||
|
return v.expression
|
||||||
|
else
|
||||||
|
return v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
},
|
||||||
|
|
||||||
{ "nil", "(x)", function(state, x) return Boolean:new(x.type == "nil") end },
|
{ "nil", "(x)", function(state, x) return Boolean:new(x.type == "nil") end },
|
||||||
{ "number", "(x)", function(state, x) return Boolean:new(x.type == "number") end },
|
{ "number", "(x)", function(state, x) return Boolean:new(x.type == "number") end },
|
||||||
{ "string", "(x)", function(state, x) return Boolean:new(x.type == "string") end },
|
{ "string", "(x)", function(state, x) return Boolean:new(x.type == "string") end },
|
||||||
28
anselme/stdlib/wrap.lua
Normal file
28
anselme/stdlib/wrap.lua
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
local ast = require("anselme.ast")
|
||||||
|
local Call, Function, ParameterTuple, FunctionParameter, Identifier, Overload, Assignment = ast.Call, ast.Function, ast.ParameterTuple, ast.FunctionParameter, ast.Identifier, ast.Overload, ast.Assignment
|
||||||
|
|
||||||
|
return {
|
||||||
|
{
|
||||||
|
">_", "(q::is(\"quote\"))",
|
||||||
|
function(state, q)
|
||||||
|
local exp = q.expression
|
||||||
|
local get = Function:with_return_boundary(ParameterTuple:new(), exp):eval(state)
|
||||||
|
|
||||||
|
local set_exp
|
||||||
|
if Call:is(exp) then
|
||||||
|
set_exp = Call:new(exp.func, exp.arguments:with_assignment(Identifier:new("value")))
|
||||||
|
elseif Identifier:is(exp) then
|
||||||
|
set_exp = Assignment:new(exp, Identifier:new("value"))
|
||||||
|
end
|
||||||
|
|
||||||
|
if set_exp then
|
||||||
|
local set_param = ParameterTuple:new()
|
||||||
|
set_param:insert_assignment(FunctionParameter:new(Identifier:new("value")))
|
||||||
|
local set = Function:with_return_boundary(set_param, set_exp):eval(state)
|
||||||
|
return Overload:new(get, set)
|
||||||
|
else
|
||||||
|
return get
|
||||||
|
end
|
||||||
|
end
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
↳ from [4mtest/tests/merge nested mutable error bis.ans:3:1[0m in block: [2minsert(a, b)…[0m[0m
|
↳ from [4mtest/tests/merge nested mutable error bis.ans:3:1[0m in block: [2minsert(a, b)…[0m[0m
|
||||||
↳ from [4mtest/tests/merge nested mutable error bis.ans:3:18[0m in call: [2m_[0m[0m
|
↳ from [4mtest/tests/merge nested mutable error bis.ans:3:18[0m in call: [2m_[0m[0m
|
||||||
↳ from [4mscript.ans:30:6[0m in call: [2mfn![0m[0m
|
↳ from [4mscript.ans:30:6[0m in call: [2mfn![0m[0m
|
||||||
↳ from [4mscript.ans:28:3[0m in block: [2mresumed from = ()…[0m[0m
|
↳ from [4mscript.ans:28:3[0m in block: [2mresume target = ()…[0m[0m
|
||||||
↳ from [4mscript.ans:28:7[0m in call: [2melse![0m[0m
|
↳ from [4mscript.ans:28:7[0m in call: [2melse![0m[0m
|
||||||
↳ from [4mscript.ans:24:2[0m in block: [2mif(fn . "current checkpoint")…[0m[0m
|
↳ from [4mscript.ans:24:2[0m in block: [2mif(fn . "current checkpoint")…[0m[0m
|
||||||
↳ from [4mscript.ans:24:9[0m in call: [2m_[0m[0m
|
↳ from [4mscript.ans:24:9[0m in call: [2m_[0m[0m
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
↳ from [4mtest/tests/merge nested mutable error.ans:3:1[0m in block: [2minsert(a, b)…[0m[0m
|
↳ from [4mtest/tests/merge nested mutable error.ans:3:1[0m in block: [2minsert(a, b)…[0m[0m
|
||||||
↳ from [4mtest/tests/merge nested mutable error.ans:3:18[0m in call: [2m_[0m[0m
|
↳ from [4mtest/tests/merge nested mutable error.ans:3:18[0m in call: [2m_[0m[0m
|
||||||
↳ from [4mscript.ans:30:6[0m in call: [2mfn![0m[0m
|
↳ from [4mscript.ans:30:6[0m in call: [2mfn![0m[0m
|
||||||
↳ from [4mscript.ans:28:3[0m in block: [2mresumed from = ()…[0m[0m
|
↳ from [4mscript.ans:28:3[0m in block: [2mresume target = ()…[0m[0m
|
||||||
↳ from [4mscript.ans:28:7[0m in call: [2melse![0m[0m
|
↳ from [4mscript.ans:28:7[0m in call: [2melse![0m[0m
|
||||||
↳ from [4mscript.ans:24:2[0m in block: [2mif(fn . "current checkpoint")…[0m[0m
|
↳ from [4mscript.ans:24:2[0m in block: [2mif(fn . "current checkpoint")…[0m[0m
|
||||||
↳ from [4mscript.ans:24:9[0m in call: [2m_[0m[0m
|
↳ from [4mscript.ans:24:9[0m in call: [2m_[0m[0m
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
:f = $(anchor=())
|
:f = $(anchor=())
|
||||||
:x = 8
|
:x = 8
|
||||||
($_)!resume(anchor)
|
($_)!from(anchor)
|
||||||
|a
|
|a
|
||||||
| A |>
|
| A |>
|
||||||
| b
|
| b
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue