1
0
Fork 0
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:
Étienne Fildadut 2024-01-02 00:34:30 +01:00
parent 7635261a3f
commit e71096cab7
14 changed files with 65 additions and 99 deletions

View file

@ -31,7 +31,6 @@ local common = {
regular_operators = {
prefixes = {
{ ">", 3.1 }, -- just above _=_
{ "~", 3.5 }, -- just below _~_ so else-if (~ condition ~ expression) parses as (~ (condition ~ expression))
{ "!", 11 },
{ "-", 11 },
{ "*", 11 },
@ -44,7 +43,6 @@ local common = {
infixes = {
{ ";", 1 },
{ "#", 2 }, { "->", 2 },
{ "~", 4 }, { "~?", 4 },
{ "|>", 5 }, { "&", 5 }, { "|", 5 },
{ "==", 7 }, { "!=", 7 }, { ">=", 7 }, { "<=", 7 }, { "<", 7 }, { ">", 7 },
{ "+", 8 }, { "-", 8 },
@ -58,8 +56,7 @@ local common = {
-- list of all operators and their priority
operator_priority = {
[";_"] = 1,
["$_"] = 1,
["@_"] = 1,
["$_"] = 2,
["_,_"] = 2,
["_=_"] = 3,
["_!_"] = 12,

View file

@ -18,15 +18,9 @@ local primaries = {
r("struct"),
-- prefixes
-- 1
r("prefix.semicolon"),
r("prefix.function"),
r("prefix.return"),
-- 3.1
r("prefix.wrap"),
-- 3.5
r("prefix.else"),
-- 11
r("prefix.negation"),
r("prefix.not"),
r("prefix.mutable"),

View file

@ -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["~_"]
}

View file

@ -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
}

View file

@ -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["_~_"]
}

View file

@ -9,7 +9,7 @@ local Call, Identifier, ArgumentTuple = ast.Call, ast.Identifier, ast.ArgumentTu
return infix {
operator = "*",
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)
return self.priority > current_priority and identifier:match(str)

View file

@ -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["_~?_"]
}

View file

@ -6,58 +6,39 @@ end
local secondaries = {
-- binary infix operators
-- 1
r("infix.semicolon"),
-- 2
r("infix.tuple"),
r("infix.tag"),
r("infix.translate"),
-- 4
r("infix.while"),
r("infix.if"),
-- 6
r("infix.choice"),
r("infix.and"),
r("infix.or"),
-- 7
r("infix.equal"),
r("infix.different"),
r("infix.greater_equal"),
r("infix.lower_equal"),
r("infix.greater"),
r("infix.lower"),
-- 8
r("infix.addition"),
r("infix.substraction"),
-- 9
r("infix.multiplication"),
r("infix.integer_division"),
r("infix.division"),
r("infix.modulo"),
-- 9.5
r("infix.implicit_multiplication"),
-- 10
r("infix.exponent"),
-- 11
r("infix.type_check"),
-- 12
r("infix.call"),
-- 14
r("infix.index_identifier"),
r("infix.index"),
-- 3
r("infix.assignment"), -- deported after equal
r("infix.assignment_call"),
r("infix.definition"),
-- 5
r("infix.pair"), -- deported after type_check
-- unary suffix operators
-- 1
r("suffix.semicolon"),
-- 12
r("suffix.exclamation_call"),
-- 13
r("suffix.call"),
}

View file

@ -22,7 +22,11 @@ return secondary {
local exp, rem = parenthesis:parse(source, str, limit_pattern)
if Nil:is(exp) then
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
exp = Tuple:new(exp)
end

View file

@ -12,7 +12,7 @@ local parser = require("anselme.parser")
local binser = require("anselme.lib.binser")
local assert0 = require("anselme.common").assert0
local anselme
local Identifier
local Identifier, Return
local State
State = class {
@ -158,6 +158,7 @@ State = class {
self._coroutine = coroutine.create(function()
local r = assert0(self:eval_local(code, source))
event_manager:final_flush(self)
if Return:is(r) then r = r.expression end
return "return", r
end)
end,
@ -194,6 +195,7 @@ State = class {
local r = assert0(self:eval_local(code, source))
event_manager:final_flush(self)
self.scope:reset() -- scope stack is probably messed up after the switch
if Return:is(r) then r = r.expression end
return "return", r
end)
else
@ -239,6 +241,6 @@ State = class {
package.loaded[...] = State
anselme = require("anselme")
local ast = require("anselme.ast")
Identifier = ast.Identifier
Identifier, Return = ast.Identifier, ast.Return
return State

View file

@ -45,5 +45,5 @@ return {
state:merge()
return Nil:new()
end
}
},
}

View file

@ -65,7 +65,14 @@ return {
return get
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)",
function(state, level)

View file

@ -1,8 +1,6 @@
local ast = require("anselme.ast")
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_symbol = if_identifier:to_symbol()
@ -20,9 +18,9 @@ end
return {
{
"_~_", "(condition, expression)", function(state, condition, expression)
"if", "(condition, expression=attached block keep return!)", function(state, condition, expression)
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)
return expression:call(state, ArgumentTuple:new())
else
@ -32,10 +30,35 @@ return {
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)
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)
return expression:call(state, ArgumentTuple:new())
else
@ -43,9 +66,8 @@ return {
end
end
},
{
"_~?_", "(condition, expression)",
"while", "(condition, expression=attached block keep return!)",
function(state, condition, expression)
ensure_if_variable(state)
local cond = condition:call(state, ArgumentTuple:new())

View file

@ -1,5 +1,5 @@
return [[
:@script = $(name, fn)
:@script = $(name, fn=attached block!)
fn.:&current checkpoint => "{name}.checkpoint"!persist(false)
fn.:&reached => "{name}.reached"!persist(*{})
fn.:&run => "{name}.run"!persist(0)
@ -10,22 +10,22 @@ return [[
fn.reached(anchor) = (fn.reached(anchor) | 0) + 1
fn.:checkpoint = $(anchor::anchor)
fn.current checkpoint = anchor
resumed from != 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
resumed from == anchor | resuming(1) ~
if(resumed from == anchor | resuming(2))
on resume!
~
else!
fn.reached(anchor) = (fn.reached(anchor) | 0) + 1
merge branch!
:f = $
fn.current checkpoint ~
if(fn.current checkpoint)
resumed from = fn.current checkpoint
fn!resume(fn.current checkpoint)
~
else!
resumed from = ()
fn!
fn.run += 1
@ -38,7 +38,7 @@ return [[
s!value!
:@$_._(s::is script, k::string)
@(s!value).fn.(k)
(s!value).fn.(k)
:@$_._(s::is script, k::string) = val
(s!value).fn.(k) = val
:@$_._(s::is script, k::symbol) = val
@ -46,25 +46,25 @@ return [[
:@$from(s::is script, a::anchor)
s.current checkpoint = a
@s!
return(s!)
:@$from(s::is script)
s.current checkpoint = ()
@s!
return(s!)
/*Additionnal helpers*/
:@$ cycle(l::tuple)
:i = 2
i <= l!len ~?
l(i).run < l(1).run ~
@l(i)!
while($i <= l!len)
if(l(i).run < l(1).run)
return(l(i)!)
i += 1
l(1)!
:@$ next(l::tuple)
:i = 1
i <= l!len ~?
l(i).run == 0 ~
@l(i)!
while($i <= l!len)
if(l(i).run == 0)
return(l(i)!)
i += 1
l(i-1)!