mirror of
https://github.com/Reuh/anselme.git
synced 2025-10-27 08:39:30 +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 = {
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -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"),
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
-- 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"),
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,11 @@ return secondary {
|
|||
local exp, rem = parenthesis:parse(source, str, limit_pattern)
|
||||
|
||||
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
|
||||
exp = Tuple:new(exp)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -45,5 +45,5 @@ return {
|
|||
state:merge()
|
||||
return Nil:new()
|
||||
end
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
return [[
|
||||
:@script = $(name, fn)
|
||||
:@script = $(name, fn=attached block!)
|
||||
fn.:¤t 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)!
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue