mirror of
https://github.com/Reuh/anselme.git
synced 2025-10-27 16:49:31 +00:00
Remove ~, ~?, and @ operators and replace with function calls
This commit is contained in:
parent
7635261a3f
commit
e71096cab7
14 changed files with 65 additions and 99 deletions
|
|
@ -31,7 +31,6 @@ local common = {
|
||||||
regular_operators = {
|
regular_operators = {
|
||||||
prefixes = {
|
prefixes = {
|
||||||
{ ">", 3.1 }, -- just above _=_
|
{ ">", 3.1 }, -- just above _=_
|
||||||
{ "~", 3.5 }, -- just below _~_ so else-if (~ condition ~ expression) parses as (~ (condition ~ expression))
|
|
||||||
{ "!", 11 },
|
{ "!", 11 },
|
||||||
{ "-", 11 },
|
{ "-", 11 },
|
||||||
{ "*", 11 },
|
{ "*", 11 },
|
||||||
|
|
@ -44,7 +43,6 @@ local common = {
|
||||||
infixes = {
|
infixes = {
|
||||||
{ ";", 1 },
|
{ ";", 1 },
|
||||||
{ "#", 2 }, { "->", 2 },
|
{ "#", 2 }, { "->", 2 },
|
||||||
{ "~", 4 }, { "~?", 4 },
|
|
||||||
{ "|>", 5 }, { "&", 5 }, { "|", 5 },
|
{ "|>", 5 }, { "&", 5 }, { "|", 5 },
|
||||||
{ "==", 7 }, { "!=", 7 }, { ">=", 7 }, { "<=", 7 }, { "<", 7 }, { ">", 7 },
|
{ "==", 7 }, { "!=", 7 }, { ">=", 7 }, { "<=", 7 }, { "<", 7 }, { ">", 7 },
|
||||||
{ "+", 8 }, { "-", 8 },
|
{ "+", 8 }, { "-", 8 },
|
||||||
|
|
@ -58,8 +56,7 @@ local common = {
|
||||||
-- list of all operators and their priority
|
-- list of all operators and their priority
|
||||||
operator_priority = {
|
operator_priority = {
|
||||||
[";_"] = 1,
|
[";_"] = 1,
|
||||||
["$_"] = 1,
|
["$_"] = 2,
|
||||||
["@_"] = 1,
|
|
||||||
["_,_"] = 2,
|
["_,_"] = 2,
|
||||||
["_=_"] = 3,
|
["_=_"] = 3,
|
||||||
["_!_"] = 12,
|
["_!_"] = 12,
|
||||||
|
|
|
||||||
|
|
@ -18,15 +18,9 @@ local primaries = {
|
||||||
r("struct"),
|
r("struct"),
|
||||||
|
|
||||||
-- prefixes
|
-- prefixes
|
||||||
-- 1
|
|
||||||
r("prefix.semicolon"),
|
r("prefix.semicolon"),
|
||||||
r("prefix.function"),
|
r("prefix.function"),
|
||||||
r("prefix.return"),
|
|
||||||
-- 3.1
|
|
||||||
r("prefix.wrap"),
|
r("prefix.wrap"),
|
||||||
-- 3.5
|
|
||||||
r("prefix.else"),
|
|
||||||
-- 11
|
|
||||||
r("prefix.negation"),
|
r("prefix.negation"),
|
||||||
r("prefix.not"),
|
r("prefix.not"),
|
||||||
r("prefix.mutable"),
|
r("prefix.mutable"),
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
local prefix_quote_right = require("anselme.parser.expression.primary.prefix.prefix_quote_right")
|
|
||||||
local operator_priority = require("anselme.common").operator_priority
|
|
||||||
|
|
||||||
return prefix_quote_right {
|
|
||||||
operator = "~",
|
|
||||||
identifier = "~_",
|
|
||||||
priority = operator_priority["~_"]
|
|
||||||
}
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
local prefix_maybe_nil_right = require("anselme.parser.expression.primary.prefix.prefix_maybe_nil_right")
|
|
||||||
|
|
||||||
local ast = require("anselme.ast")
|
|
||||||
local Return = ast.Return
|
|
||||||
|
|
||||||
local operator_priority = require("anselme.common").operator_priority
|
|
||||||
|
|
||||||
return prefix_maybe_nil_right {
|
|
||||||
operator = "@",
|
|
||||||
priority = operator_priority["@_"],
|
|
||||||
|
|
||||||
build_ast = function(self, right)
|
|
||||||
return Return:new(right)
|
|
||||||
end
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
local infix_quote_right = require("anselme.parser.expression.secondary.infix.infix_quote_right")
|
|
||||||
|
|
||||||
local operator_priority = require("anselme.common").operator_priority
|
|
||||||
|
|
||||||
return infix_quote_right {
|
|
||||||
operator = "~",
|
|
||||||
identifier = "_~_",
|
|
||||||
priority = operator_priority["_~_"]
|
|
||||||
}
|
|
||||||
|
|
@ -9,7 +9,7 @@ local Call, Identifier, ArgumentTuple = ast.Call, ast.Identifier, ast.ArgumentTu
|
||||||
return infix {
|
return infix {
|
||||||
operator = "*",
|
operator = "*",
|
||||||
identifier = "_*_",
|
identifier = "_*_",
|
||||||
priority = operator_priority["_*_"]+.5, -- just above / so 1/2x gives 1/(2x)
|
priority = operator_priority["_*_"]+.1, -- just above / so 1/2x gives 1/(2x)
|
||||||
|
|
||||||
match = function(self, str, current_priority, primary)
|
match = function(self, str, current_priority, primary)
|
||||||
return self.priority > current_priority and identifier:match(str)
|
return self.priority > current_priority and identifier:match(str)
|
||||||
|
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
local infix_quote_both = require("anselme.parser.expression.secondary.infix.infix_quote_both")
|
|
||||||
|
|
||||||
local operator_priority = require("anselme.common").operator_priority
|
|
||||||
|
|
||||||
return infix_quote_both {
|
|
||||||
operator = "~?",
|
|
||||||
identifier = "_~?_",
|
|
||||||
priority = operator_priority["_~?_"]
|
|
||||||
}
|
|
||||||
|
|
@ -6,58 +6,39 @@ end
|
||||||
|
|
||||||
local secondaries = {
|
local secondaries = {
|
||||||
-- binary infix operators
|
-- binary infix operators
|
||||||
-- 1
|
|
||||||
r("infix.semicolon"),
|
r("infix.semicolon"),
|
||||||
-- 2
|
|
||||||
r("infix.tuple"),
|
r("infix.tuple"),
|
||||||
r("infix.tag"),
|
r("infix.tag"),
|
||||||
r("infix.translate"),
|
r("infix.translate"),
|
||||||
-- 4
|
|
||||||
r("infix.while"),
|
|
||||||
r("infix.if"),
|
|
||||||
-- 6
|
|
||||||
r("infix.choice"),
|
r("infix.choice"),
|
||||||
r("infix.and"),
|
r("infix.and"),
|
||||||
r("infix.or"),
|
r("infix.or"),
|
||||||
-- 7
|
|
||||||
r("infix.equal"),
|
r("infix.equal"),
|
||||||
r("infix.different"),
|
r("infix.different"),
|
||||||
r("infix.greater_equal"),
|
r("infix.greater_equal"),
|
||||||
r("infix.lower_equal"),
|
r("infix.lower_equal"),
|
||||||
r("infix.greater"),
|
r("infix.greater"),
|
||||||
r("infix.lower"),
|
r("infix.lower"),
|
||||||
-- 8
|
|
||||||
r("infix.addition"),
|
r("infix.addition"),
|
||||||
r("infix.substraction"),
|
r("infix.substraction"),
|
||||||
-- 9
|
|
||||||
r("infix.multiplication"),
|
r("infix.multiplication"),
|
||||||
r("infix.integer_division"),
|
r("infix.integer_division"),
|
||||||
r("infix.division"),
|
r("infix.division"),
|
||||||
r("infix.modulo"),
|
r("infix.modulo"),
|
||||||
-- 9.5
|
|
||||||
r("infix.implicit_multiplication"),
|
r("infix.implicit_multiplication"),
|
||||||
-- 10
|
|
||||||
r("infix.exponent"),
|
r("infix.exponent"),
|
||||||
-- 11
|
|
||||||
r("infix.type_check"),
|
r("infix.type_check"),
|
||||||
-- 12
|
|
||||||
r("infix.call"),
|
r("infix.call"),
|
||||||
-- 14
|
|
||||||
r("infix.index_identifier"),
|
r("infix.index_identifier"),
|
||||||
r("infix.index"),
|
r("infix.index"),
|
||||||
-- 3
|
|
||||||
r("infix.assignment"), -- deported after equal
|
r("infix.assignment"), -- deported after equal
|
||||||
r("infix.assignment_call"),
|
r("infix.assignment_call"),
|
||||||
r("infix.definition"),
|
r("infix.definition"),
|
||||||
-- 5
|
|
||||||
r("infix.pair"), -- deported after type_check
|
r("infix.pair"), -- deported after type_check
|
||||||
|
|
||||||
-- unary suffix operators
|
-- unary suffix operators
|
||||||
-- 1
|
|
||||||
r("suffix.semicolon"),
|
r("suffix.semicolon"),
|
||||||
-- 12
|
|
||||||
r("suffix.exclamation_call"),
|
r("suffix.exclamation_call"),
|
||||||
-- 13
|
|
||||||
r("suffix.call"),
|
r("suffix.call"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,11 @@ return secondary {
|
||||||
local exp, rem = parenthesis:parse(source, str, limit_pattern)
|
local exp, rem = parenthesis:parse(source, str, limit_pattern)
|
||||||
|
|
||||||
if Nil:is(exp) then
|
if Nil:is(exp) then
|
||||||
exp = Tuple:new()
|
if str:match("^%(%s*%(%s*%)%s*%)") then -- special case: single nil argument
|
||||||
|
exp = Tuple:new(Nil:new())
|
||||||
|
else -- no arguments
|
||||||
|
exp = Tuple:new()
|
||||||
|
end
|
||||||
elseif not Tuple:is(exp) or exp.explicit then -- single argument
|
elseif not Tuple:is(exp) or exp.explicit then -- single argument
|
||||||
exp = Tuple:new(exp)
|
exp = Tuple:new(exp)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ local parser = require("anselme.parser")
|
||||||
local binser = require("anselme.lib.binser")
|
local binser = require("anselme.lib.binser")
|
||||||
local assert0 = require("anselme.common").assert0
|
local assert0 = require("anselme.common").assert0
|
||||||
local anselme
|
local anselme
|
||||||
local Identifier
|
local Identifier, Return
|
||||||
|
|
||||||
local State
|
local State
|
||||||
State = class {
|
State = class {
|
||||||
|
|
@ -158,6 +158,7 @@ State = class {
|
||||||
self._coroutine = coroutine.create(function()
|
self._coroutine = coroutine.create(function()
|
||||||
local r = assert0(self:eval_local(code, source))
|
local r = assert0(self:eval_local(code, source))
|
||||||
event_manager:final_flush(self)
|
event_manager:final_flush(self)
|
||||||
|
if Return:is(r) then r = r.expression end
|
||||||
return "return", r
|
return "return", r
|
||||||
end)
|
end)
|
||||||
end,
|
end,
|
||||||
|
|
@ -194,6 +195,7 @@ State = class {
|
||||||
local r = assert0(self:eval_local(code, source))
|
local r = assert0(self:eval_local(code, source))
|
||||||
event_manager:final_flush(self)
|
event_manager:final_flush(self)
|
||||||
self.scope:reset() -- scope stack is probably messed up after the switch
|
self.scope:reset() -- scope stack is probably messed up after the switch
|
||||||
|
if Return:is(r) then r = r.expression end
|
||||||
return "return", r
|
return "return", r
|
||||||
end)
|
end)
|
||||||
else
|
else
|
||||||
|
|
@ -239,6 +241,6 @@ State = class {
|
||||||
package.loaded[...] = State
|
package.loaded[...] = State
|
||||||
anselme = require("anselme")
|
anselme = require("anselme")
|
||||||
local ast = require("anselme.ast")
|
local ast = require("anselme.ast")
|
||||||
Identifier = ast.Identifier
|
Identifier, Return = ast.Identifier, ast.Return
|
||||||
|
|
||||||
return State
|
return State
|
||||||
|
|
|
||||||
|
|
@ -45,5 +45,5 @@ return {
|
||||||
state:merge()
|
state:merge()
|
||||||
return Nil:new()
|
return Nil:new()
|
||||||
end
|
end
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,14 @@ return {
|
||||||
return get
|
return get
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
"return", "(value=())",
|
||||||
|
function(state, val)
|
||||||
|
if Return:is(val) then val = val.expression end
|
||||||
|
return Return:new(val)
|
||||||
|
end
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"attached block", "(level::number=1)",
|
"attached block", "(level::number=1)",
|
||||||
function(state, level)
|
function(state, level)
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
local ast = require("anselme.ast")
|
local ast = require("anselme.ast")
|
||||||
local ArgumentTuple, Nil, Boolean, Identifier, Return = ast.ArgumentTuple, ast.Nil, ast.Boolean, ast.Identifier, ast.Return
|
local ArgumentTuple, Nil, Boolean, Identifier, Return = ast.ArgumentTuple, ast.Nil, ast.Boolean, ast.Identifier, ast.Return
|
||||||
|
|
||||||
local resume_manager = require("anselme.state.resume_manager")
|
|
||||||
|
|
||||||
local if_identifier = Identifier:new("_if_status")
|
local if_identifier = Identifier:new("_if_status")
|
||||||
local if_symbol = if_identifier:to_symbol()
|
local if_symbol = if_identifier:to_symbol()
|
||||||
|
|
||||||
|
|
@ -20,9 +18,9 @@ end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
{
|
{
|
||||||
"_~_", "(condition, expression)", function(state, condition, expression)
|
"if", "(condition, expression=attached block keep return!)", function(state, condition, expression)
|
||||||
ensure_if_variable(state)
|
ensure_if_variable(state)
|
||||||
if condition:truthy() or resume_manager:resuming(state) then--expression:contains_current_resume_target(state) then TODO fix
|
if condition:truthy() or expression:contains_current_resume_target(state) then
|
||||||
set_if_variable(state, true)
|
set_if_variable(state, true)
|
||||||
return expression:call(state, ArgumentTuple:new())
|
return expression:call(state, ArgumentTuple:new())
|
||||||
else
|
else
|
||||||
|
|
@ -32,10 +30,35 @@ return {
|
||||||
end
|
end
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"~_", "(expression)",
|
"if", "(condition, true, false)", function(state, condition, if_true, if_false)
|
||||||
|
ensure_if_variable(state)
|
||||||
|
if condition:truthy() or if_true:contains_current_resume_target(state) then
|
||||||
|
set_if_variable(state, true)
|
||||||
|
return if_true:call(state, ArgumentTuple:new())
|
||||||
|
else
|
||||||
|
set_if_variable(state, false)
|
||||||
|
return if_false:call(state, ArgumentTuple:new())
|
||||||
|
end
|
||||||
|
end
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"else if", "(condition, expression=attached block keep return!)",
|
||||||
|
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
|
||||||
|
set_if_variable(state, true)
|
||||||
|
return expression:call(state, ArgumentTuple:new())
|
||||||
|
else
|
||||||
|
set_if_variable(state, false)
|
||||||
|
return Nil:new()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"else", "(expression=attached block keep return!)",
|
||||||
function(state, expression)
|
function(state, expression)
|
||||||
ensure_if_variable(state)
|
ensure_if_variable(state)
|
||||||
if not last_if_success(state) or resume_manager:resuming(state) then--expression:contains_current_resume_target(state) then TODO fix
|
if not last_if_success(state) or expression:contains_current_resume_target(state) then
|
||||||
set_if_variable(state, true)
|
set_if_variable(state, true)
|
||||||
return expression:call(state, ArgumentTuple:new())
|
return expression:call(state, ArgumentTuple:new())
|
||||||
else
|
else
|
||||||
|
|
@ -43,9 +66,8 @@ return {
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"_~?_", "(condition, expression)",
|
"while", "(condition, expression=attached block keep return!)",
|
||||||
function(state, condition, expression)
|
function(state, condition, expression)
|
||||||
ensure_if_variable(state)
|
ensure_if_variable(state)
|
||||||
local cond = condition:call(state, ArgumentTuple:new())
|
local cond = condition:call(state, ArgumentTuple:new())
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
return [[
|
return [[
|
||||||
:@script = $(name, fn)
|
:@script = $(name, fn=attached block!)
|
||||||
fn.:¤t checkpoint => "{name}.checkpoint"!persist(false)
|
fn.:¤t checkpoint => "{name}.checkpoint"!persist(false)
|
||||||
fn.:&reached => "{name}.reached"!persist(*{})
|
fn.:&reached => "{name}.reached"!persist(*{})
|
||||||
fn.:&run => "{name}.run"!persist(0)
|
fn.:&run => "{name}.run"!persist(0)
|
||||||
|
|
@ -10,22 +10,22 @@ return [[
|
||||||
fn.reached(anchor) = (fn.reached(anchor) | 0) + 1
|
fn.reached(anchor) = (fn.reached(anchor) | 0) + 1
|
||||||
fn.:checkpoint = $(anchor::anchor)
|
fn.:checkpoint = $(anchor::anchor)
|
||||||
fn.current checkpoint = anchor
|
fn.current checkpoint = anchor
|
||||||
resumed from != anchor ~
|
if(resumed from != anchor)
|
||||||
fn.reached(anchor) = (fn.reached(anchor) | 0) + 1
|
fn.reached(anchor) = (fn.reached(anchor) | 0) + 1
|
||||||
merge branch!
|
merge branch!
|
||||||
fn.:checkpoint = $(anchor::anchor, on resume::function)
|
fn.:checkpoint = $(anchor::anchor, on resume::function)
|
||||||
fn.current checkpoint = anchor
|
fn.current checkpoint = anchor
|
||||||
resumed from == anchor | resuming(1) ~
|
if(resumed from == anchor | resuming(2))
|
||||||
on resume!
|
on resume!
|
||||||
~
|
else!
|
||||||
fn.reached(anchor) = (fn.reached(anchor) | 0) + 1
|
fn.reached(anchor) = (fn.reached(anchor) | 0) + 1
|
||||||
merge branch!
|
merge branch!
|
||||||
|
|
||||||
:f = $
|
:f = $
|
||||||
fn.current checkpoint ~
|
if(fn.current checkpoint)
|
||||||
resumed from = fn.current checkpoint
|
resumed from = fn.current checkpoint
|
||||||
fn!resume(fn.current checkpoint)
|
fn!resume(fn.current checkpoint)
|
||||||
~
|
else!
|
||||||
resumed from = ()
|
resumed from = ()
|
||||||
fn!
|
fn!
|
||||||
fn.run += 1
|
fn.run += 1
|
||||||
|
|
@ -38,7 +38,7 @@ return [[
|
||||||
s!value!
|
s!value!
|
||||||
|
|
||||||
:@$_._(s::is script, k::string)
|
:@$_._(s::is script, k::string)
|
||||||
@(s!value).fn.(k)
|
(s!value).fn.(k)
|
||||||
:@$_._(s::is script, k::string) = val
|
:@$_._(s::is script, k::string) = val
|
||||||
(s!value).fn.(k) = val
|
(s!value).fn.(k) = val
|
||||||
:@$_._(s::is script, k::symbol) = val
|
:@$_._(s::is script, k::symbol) = val
|
||||||
|
|
@ -46,25 +46,25 @@ return [[
|
||||||
|
|
||||||
:@$from(s::is script, a::anchor)
|
:@$from(s::is script, a::anchor)
|
||||||
s.current checkpoint = a
|
s.current checkpoint = a
|
||||||
@s!
|
return(s!)
|
||||||
:@$from(s::is script)
|
:@$from(s::is script)
|
||||||
s.current checkpoint = ()
|
s.current checkpoint = ()
|
||||||
@s!
|
return(s!)
|
||||||
|
|
||||||
/*Additionnal helpers*/
|
/*Additionnal helpers*/
|
||||||
:@$ cycle(l::tuple)
|
:@$ cycle(l::tuple)
|
||||||
:i = 2
|
:i = 2
|
||||||
i <= l!len ~?
|
while($i <= l!len)
|
||||||
l(i).run < l(1).run ~
|
if(l(i).run < l(1).run)
|
||||||
@l(i)!
|
return(l(i)!)
|
||||||
i += 1
|
i += 1
|
||||||
l(1)!
|
l(1)!
|
||||||
|
|
||||||
:@$ next(l::tuple)
|
:@$ next(l::tuple)
|
||||||
:i = 1
|
:i = 1
|
||||||
i <= l!len ~?
|
while($i <= l!len)
|
||||||
l(i).run == 0 ~
|
if(l(i).run == 0)
|
||||||
@l(i)!
|
return(l(i)!)
|
||||||
i += 1
|
i += 1
|
||||||
l(i-1)!
|
l(i-1)!
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue