From e71096cab76e956698c038873bff52ce0c569c3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Reuh=20Fildadut?= Date: Tue, 2 Jan 2024 00:34:30 +0100 Subject: [PATCH] Remove ~, ~?, and @ operators and replace with function calls --- anselme/common/init.lua | 5 +-- anselme/parser/expression/primary/init.lua | 6 --- .../parser/expression/primary/prefix/else.lua | 8 ---- .../expression/primary/prefix/return.lua | 15 -------- .../parser/expression/secondary/infix/if.lua | 9 ----- .../infix/implicit_multiplication.lua | 2 +- .../expression/secondary/infix/while.lua | 9 ----- anselme/parser/expression/secondary/init.lua | 19 ---------- .../expression/secondary/suffix/call.lua | 6 ++- anselme/state/State.lua | 6 ++- anselme/stdlib/checkpoint.lua | 2 +- anselme/stdlib/closure.lua | 9 ++++- anselme/stdlib/conditionals.lua | 38 +++++++++++++++---- anselme/stdlib/script_script.lua | 30 +++++++-------- 14 files changed, 65 insertions(+), 99 deletions(-) delete mode 100644 anselme/parser/expression/primary/prefix/else.lua delete mode 100644 anselme/parser/expression/primary/prefix/return.lua delete mode 100644 anselme/parser/expression/secondary/infix/if.lua delete mode 100644 anselme/parser/expression/secondary/infix/while.lua diff --git a/anselme/common/init.lua b/anselme/common/init.lua index bdad1ce..acf07a8 100644 --- a/anselme/common/init.lua +++ b/anselme/common/init.lua @@ -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, diff --git a/anselme/parser/expression/primary/init.lua b/anselme/parser/expression/primary/init.lua index 82ce6d8..e7c717d 100644 --- a/anselme/parser/expression/primary/init.lua +++ b/anselme/parser/expression/primary/init.lua @@ -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"), diff --git a/anselme/parser/expression/primary/prefix/else.lua b/anselme/parser/expression/primary/prefix/else.lua deleted file mode 100644 index 6da0d46..0000000 --- a/anselme/parser/expression/primary/prefix/else.lua +++ /dev/null @@ -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["~_"] -} diff --git a/anselme/parser/expression/primary/prefix/return.lua b/anselme/parser/expression/primary/prefix/return.lua deleted file mode 100644 index c3b8764..0000000 --- a/anselme/parser/expression/primary/prefix/return.lua +++ /dev/null @@ -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 -} diff --git a/anselme/parser/expression/secondary/infix/if.lua b/anselme/parser/expression/secondary/infix/if.lua deleted file mode 100644 index fc7c7ab..0000000 --- a/anselme/parser/expression/secondary/infix/if.lua +++ /dev/null @@ -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["_~_"] -} diff --git a/anselme/parser/expression/secondary/infix/implicit_multiplication.lua b/anselme/parser/expression/secondary/infix/implicit_multiplication.lua index ad5a9c7..4757e06 100644 --- a/anselme/parser/expression/secondary/infix/implicit_multiplication.lua +++ b/anselme/parser/expression/secondary/infix/implicit_multiplication.lua @@ -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) diff --git a/anselme/parser/expression/secondary/infix/while.lua b/anselme/parser/expression/secondary/infix/while.lua deleted file mode 100644 index 464dbb2..0000000 --- a/anselme/parser/expression/secondary/infix/while.lua +++ /dev/null @@ -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["_~?_"] -} diff --git a/anselme/parser/expression/secondary/init.lua b/anselme/parser/expression/secondary/init.lua index 08b50a3..cc4d412 100644 --- a/anselme/parser/expression/secondary/init.lua +++ b/anselme/parser/expression/secondary/init.lua @@ -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"), } diff --git a/anselme/parser/expression/secondary/suffix/call.lua b/anselme/parser/expression/secondary/suffix/call.lua index 7f634c7..100015c 100644 --- a/anselme/parser/expression/secondary/suffix/call.lua +++ b/anselme/parser/expression/secondary/suffix/call.lua @@ -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 diff --git a/anselme/state/State.lua b/anselme/state/State.lua index 9fa3f98..6d3a169 100644 --- a/anselme/state/State.lua +++ b/anselme/state/State.lua @@ -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 diff --git a/anselme/stdlib/checkpoint.lua b/anselme/stdlib/checkpoint.lua index 2abad0f..19e2912 100644 --- a/anselme/stdlib/checkpoint.lua +++ b/anselme/stdlib/checkpoint.lua @@ -45,5 +45,5 @@ return { state:merge() return Nil:new() end - } + }, } diff --git a/anselme/stdlib/closure.lua b/anselme/stdlib/closure.lua index 702e26c..f27747f 100644 --- a/anselme/stdlib/closure.lua +++ b/anselme/stdlib/closure.lua @@ -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) diff --git a/anselme/stdlib/conditionals.lua b/anselme/stdlib/conditionals.lua index 459fc6f..07b8308 100644 --- a/anselme/stdlib/conditionals.lua +++ b/anselme/stdlib/conditionals.lua @@ -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()) diff --git a/anselme/stdlib/script_script.lua b/anselme/stdlib/script_script.lua index e4167b8..4078a07 100644 --- a/anselme/stdlib/script_script.lua +++ b/anselme/stdlib/script_script.lua @@ -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)!