From 88157b04b952997c01bf37444e78d546ee886127 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Reuh=20Fildadut?= Date: Tue, 14 Dec 2021 02:37:09 +0100 Subject: [PATCH] Merge behavior of : and = into single = operator for pairs; add assignment with _._ operator in function references --- LANGUAGE.md | 12 +++++----- notes.txt | 2 +- parser/common.lua | 2 +- parser/expression.lua | 9 ++++---- stdlib/functions.lua | 22 ++++++++++++++++--- stdlib/types.lua | 2 +- test/tests/choice preserve tags.ans | 2 +- test/tests/equality operator.ans | 8 +++---- .../tests/function reference dot operator.ans | 10 +++++++++ .../tests/function reference dot operator.lua | 22 +++++++++++++++++++ test/tests/list assignement.lua | 12 +++++----- test/tests/pair operator.ans | 3 +++ test/tests/pair operator.lua | 14 ++++++++++++ .../resume from paragraph restore tags.ans | 8 +++---- test/tests/subtext.ans | 4 ++-- test/tests/tag decorator nested.ans | 4 ++-- test/tests/tag decorator.ans | 2 +- test/tests/tag operator.ans | 2 +- test/tests/tag.ans | 2 +- 19 files changed, 104 insertions(+), 38 deletions(-) create mode 100644 test/tests/function reference dot operator.ans create mode 100644 test/tests/function reference dot operator.lua create mode 100644 test/tests/pair operator.ans create mode 100644 test/tests/pair operator.lua diff --git a/LANGUAGE.md b/LANGUAGE.md index 4d98052..88b1f73 100644 --- a/LANGUAGE.md +++ b/LANGUAGE.md @@ -274,7 +274,7 @@ Checkpoints always have the following variable defined in its namespace by defau * `#`: tag line. Can be followed by an [expression](#expressions); otherwise nil expression is assumed. The results of the [expression](#expressions) will be added to the tags send along with any `choice` or `text` event sent from its children. Can be nested. ``` -# "color": "red" +# color="red" Text tagged with a red color # "blink" @@ -570,7 +570,7 @@ Default types are: * `string`: a string. Can be defined between double quotes `"string"`. Support [text interpolation](#text-interpolation). Support [escape codes](#escape-codes). -* `pair`: a couple of values. Types can be mixed. Can be defined using colon `"key":5`. Pairs named by a string that is also a valid identifier can be created using the `key=5` shorthand syntax. +* `pair`: a couple of values. Types can be mixed. Can be defined using equal sign `"key"=5`. Pairs named by a string that is also a valid identifier can be created using the `key=5` shorthand syntax; `key` will not be interpreted as the variable `key` but the string `"key"` (if `key` is a variable and you want to force the use of its value as a key instead of the string `"key"`, you can wrap it in parentheses). * `type`: a couple of values. Types can be mixed. Can be defined using colon `expr::type`. The second value is used in type checks, this is intended to be use to give a custom type to a value. @@ -590,7 +590,7 @@ How conversions are handled from Anselme to Lua: * `string` -> `string` -* `list` -> `table`. Pair elements in the list will be assigned as a key-value pair in the Lua list and its index skipped in the sequential part, e.g. `[1,2,"key":"value",3]` -> `{1,2,3,key="value"}`. +* `list` -> `table`. Pair elements in the list will be assigned as a key-value pair in the Lua list and its index skipped in the sequential part, e.g. `[1,2,"key"="value",3]` -> `{1,2,3,key="value"}`. * `pair` -> `table`, with a single key-value pair. @@ -602,7 +602,7 @@ How conservions are handled from Lua to Anselme: * `string` -> `string` -* `table` -> `list`. First add the sequential part of the table in the list, then add pairs for the remaining elements, e.g. `{1,2,key="value",3}` -> `[1,2,3,"key":"value"]` +* `table` -> `list`. First add the sequential part of the table in the list, then add pairs for the remaining elements, e.g. `{1,2,key="value",3}` -> `[1,2,3,"key"="value"]` * `boolean` -> `number`, 0 for false, 1 for true. @@ -820,7 +820,7 @@ _|_ _&_ _~?_ _~_ _#_ _!=_ _==_ _>=_ _<=_ _<_ _>_ _+_ _-_ _*_ _//_ _/_ _%_ -_::_ _:_ +_::_ _=_ -_ !_ _^_ _._ _!_ @@ -905,7 +905,7 @@ This only works on strings: `a;`: evaluate a, discard its result, returns nil. -`a : b`: evaluate a and b, returns a new pair with a as key and b as value. +`a = b`: evaluate a and b, returns a new pair with a as key and b as value. If a is an identifier, will interpret it as a string (and not a variable; you can wrap a in parentheses if you want to use the value associated with variable a instead). `a :: b`: evaluate a and b, returns a new typed value with a as value and b as type. diff --git a/notes.txt b/notes.txt index f7672c9..df7c6b6 100644 --- a/notes.txt +++ b/notes.txt @@ -43,7 +43,7 @@ Reserved symbols that are still not used as a line type: `^+-= meh, this means we can capture choice events, and choice events contain their code block, and we don't want to store code blocks in the save file (as code can be updated/translated/whatever) diff --git a/parser/common.lua b/parser/common.lua index 00c9c2a..0ec595b 100644 --- a/parser/common.lua +++ b/parser/common.lua @@ -42,7 +42,7 @@ common = { "_!=_", "_==_", "_>=_", "_<=_", "_<_", "_>_", "_+_", "_-_", "_*_", "_//_", "_/_", "_%_", - "_::_", "_:_", + "_::_", "_=_", "_^_", "_._", "_!_", -- suffix unop diff --git a/parser/expression.lua b/parser/expression.lua index 6f90291..415bba6 100644 --- a/parser/expression.lua +++ b/parser/expression.lua @@ -9,12 +9,13 @@ local binops_prio = { [5] = { "!=", "==", ">=", "<=", "<", ">" }, [6] = { "+", "-" }, [7] = { "*", "//", "/", "%" }, - [8] = { "::", ":" }, + [8] = { "::", "=" }, [9] = {}, -- unary operators [10] = { "^" }, [11] = { ".", "!" }, [12] = {} } +local pair_priority = 8 -- unop priority local prefix_unops_prio = { [1] = {}, @@ -129,9 +130,9 @@ local function expression(s, state, namespace, current_priority, operating_on) local name, r = s:match("^("..identifier_pattern..")(.-)$") name = format_identifier(name) -- string:value pair shorthand using = - if r:match("^=[^=]") then + if r:match("^=[^=]") and pair_priority > current_priority then local val - val, r = expression(r:match("^=(.*)$"), state, namespace, 9) + val, r = expression(r:match("^=(.*)$"), state, namespace, pair_priority) if not val then return val, r end local args = { type = "list", @@ -142,7 +143,7 @@ local function expression(s, state, namespace, current_priority, operating_on) right = val } -- find compatible variant - local variant, err = find_function(state, namespace, "_:_", args, true) + local variant, err = find_function(state, namespace, "_=_", args, true) if not variant then return variant, err end return expression(r, state, namespace, current_priority, variant) end diff --git a/stdlib/functions.lua b/stdlib/functions.lua index 7468073..a4d68c2 100644 --- a/stdlib/functions.lua +++ b/stdlib/functions.lua @@ -1,4 +1,4 @@ -local truthy, anselme, compare, is_of_type, identifier_pattern, format_identifier, find, get_variable, mark_as_modified +local truthy, anselme, compare, is_of_type, identifier_pattern, format_identifier, find, get_variable, mark_as_modified, set_variable local lua_functions lua_functions = { @@ -54,7 +54,7 @@ lua_functions = { end }, -- pair - ["_:_(a, b)"] = { + ["_=_(a, b)"] = { mode = "raw", value = function(a, b) return { @@ -89,6 +89,22 @@ lua_functions = { return nil, ("can't find variable %q in function reference (searched in namespaces: %s)"):format(name, table.concat(rval, ", ")) end }, + ["_._(r::function reference, name::string) := v"] = { + mode = "raw", + value = function(r, n, v) + local state = anselme.running.state + local rval = r.value + local name = n.value + for _, ffqm in ipairs(rval) do + local var, vfqm = find(state.aliases, state.interpreter.global_state.variables, ffqm..".", name) + if var then + set_variable(state, vfqm, v) + return v + end + end + return nil, ("can't find variable %q in function reference (searched in namespaces: %s)"):format(name, table.concat(rval, ", ")) + end + }, -- index ["()(l::list, i::number)"] = { mode = "untyped raw", @@ -326,7 +342,7 @@ local functions = { package.loaded[...] = functions local icommon = require((...):gsub("stdlib%.functions$", "interpreter.common")) -truthy, compare, is_of_type, get_variable, mark_as_modified = icommon.truthy, icommon.compare, icommon.is_of_type, icommon.get_variable, icommon.mark_as_modified +truthy, compare, is_of_type, get_variable, mark_as_modified, set_variable = icommon.truthy, icommon.compare, icommon.is_of_type, icommon.get_variable, icommon.mark_as_modified, icommon.set_variable local pcommon = require((...):gsub("stdlib%.functions$", "parser.common")) identifier_pattern, format_identifier, find = pcommon.identifier_pattern, pcommon.format_identifier, pcommon.find anselme = require((...):gsub("stdlib%.functions$", "anselme")) diff --git a/stdlib/types.lua b/stdlib/types.lua index a05b484..03249c6 100644 --- a/stdlib/types.lua +++ b/stdlib/types.lua @@ -126,7 +126,7 @@ types.anselme = { if not k then return k, ke end local v, ve = format(val[2]) if not v then return v, ve end - return ("%s:%s"):format(k, v) + return ("%s=%s"):format(k, v) end, to_lua = function(val) local k, ke = to_lua(val[1]) diff --git a/test/tests/choice preserve tags.ans b/test/tests/choice preserve tags.ans index 2db0ed6..1df204f 100644 --- a/test/tests/choice preserve tags.ans +++ b/test/tests/choice preserve tags.ans @@ -7,7 +7,7 @@ $ f > c ~ choose(1) -# "k":"v" +# "k"="v" ~ f > d ~ choose(1) diff --git a/test/tests/equality operator.ans b/test/tests/equality operator.ans index c48d644..4cc418f 100644 --- a/test/tests/equality operator.ans +++ b/test/tests/equality operator.ans @@ -1,10 +1,10 @@ -:a = [1:2] +:a = [1=2] -0 = {a == [5:2]} +0 = {a == [5=2]} -0 = {a == [1:3]} +0 = {a == [1=3]} -1 = {a == [1:2]} +1 = {a == [1=2]} :b = [1,2,3] diff --git a/test/tests/function reference dot operator.ans b/test/tests/function reference dot operator.ans new file mode 100644 index 0000000..4a7ec38 --- /dev/null +++ b/test/tests/function reference dot operator.ans @@ -0,0 +1,10 @@ +$ f + :a = 12 + +:x = &f + +{x.a} + +~ x.a := 52 + +{x.a} diff --git a/test/tests/function reference dot operator.lua b/test/tests/function reference dot operator.lua new file mode 100644 index 0000000..b442a53 --- /dev/null +++ b/test/tests/function reference dot operator.lua @@ -0,0 +1,22 @@ +local _={} +_[9]={} +_[8]={} +_[7]={tags=_[9],text="52"} +_[6]={tags=_[8],text="12"} +_[5]={_[7]} +_[4]={_[6]} +_[3]={"return"} +_[2]={"text",_[5]} +_[1]={"text",_[4]} +return {_[1],_[2],_[3]} +--[[ +{ "text", { { + tags = {}, + text = "12" + } } } +{ "text", { { + tags = {}, + text = "52" + } } } +{ "return" } +]]-- \ No newline at end of file diff --git a/test/tests/list assignement.lua b/test/tests/list assignement.lua index f4ef410..986eba4 100644 --- a/test/tests/list assignement.lua +++ b/test/tests/list assignement.lua @@ -8,11 +8,11 @@ _[32]={} _[31]={} _[30]={} _[29]={} -_[28]={tags=_[37],text="[3, 2, foo:c, bar:b]"} +_[28]={tags=_[37],text="[3, 2, foo=c, bar=b]"} _[27]={tags=_[36],text="c"} -_[26]={tags=_[35],text="[3, 2, foo:a, bar:b]"} +_[26]={tags=_[35],text="[3, 2, foo=a, bar=b]"} _[25]={tags=_[34],text="b"} -_[24]={tags=_[33],text="[3, 2, foo:a]"} +_[24]={tags=_[33],text="[3, 2, foo=a]"} _[23]={tags=_[32],text="a"} _[22]={tags=_[31],text="[3, 2]"} _[21]={tags=_[30],text="3"} @@ -56,7 +56,7 @@ return {_[1],_[2],_[3],_[4],_[5],_[6],_[7],_[8],_[9],_[10]} } } } { "text", { { tags = {}, - text = "[3, 2, foo:a]" + text = "[3, 2, foo=a]" } } } { "text", { { tags = {}, @@ -64,7 +64,7 @@ return {_[1],_[2],_[3],_[4],_[5],_[6],_[7],_[8],_[9],_[10]} } } } { "text", { { tags = {}, - text = "[3, 2, foo:a, bar:b]" + text = "[3, 2, foo=a, bar=b]" } } } { "text", { { tags = {}, @@ -72,7 +72,7 @@ return {_[1],_[2],_[3],_[4],_[5],_[6],_[7],_[8],_[9],_[10]} } } } { "text", { { tags = {}, - text = "[3, 2, foo:c, bar:b]" + text = "[3, 2, foo=c, bar=b]" } } } { "return" } ]]-- \ No newline at end of file diff --git a/test/tests/pair operator.ans b/test/tests/pair operator.ans new file mode 100644 index 0000000..e428ac5 --- /dev/null +++ b/test/tests/pair operator.ans @@ -0,0 +1,3 @@ +:name = "test" + +{[name=1, 3="p", (name)="foo", "ho"="ah", name=name]} diff --git a/test/tests/pair operator.lua b/test/tests/pair operator.lua new file mode 100644 index 0000000..43b90fd --- /dev/null +++ b/test/tests/pair operator.lua @@ -0,0 +1,14 @@ +local _={} +_[5]={} +_[4]={tags=_[5],text="[name=1, 3=p, test=foo, ho=ah, name=test]"} +_[3]={_[4]} +_[2]={"return"} +_[1]={"text",_[3]} +return {_[1],_[2]} +--[[ +{ "text", { { + tags = {}, + text = "[name=1, 3=p, test=foo, ho=ah, name=test]" + } } } +{ "return" } +]]-- \ No newline at end of file diff --git a/test/tests/resume from paragraph restore tags.ans b/test/tests/resume from paragraph restore tags.ans index ecece48..9124c78 100644 --- a/test/tests/resume from paragraph restore tags.ans +++ b/test/tests/resume from paragraph restore tags.ans @@ -1,10 +1,10 @@ $ f - # "a":"a" + # "a"="a" a - ~ 1 # "x":"x" - # "b":"b" + ~ 1 # "x"="x" + # "b"="b" ยง p - b # "c":"c" + b # "c"="c" c diff --git a/test/tests/subtext.ans b/test/tests/subtext.ans index 57e5a11..a8a7353 100644 --- a/test/tests/subtext.ans +++ b/test/tests/subtext.ans @@ -1,5 +1,5 @@ $ button - A # 2:2 + A # 2=2 Press A # 5 @@ -9,4 +9,4 @@ Press [A#5] to jump. Press [{button}#1] to jump. -Press [-[button#3:3]-#1] to jump. +Press [-[button#3=3]-#1] to jump. diff --git a/test/tests/tag decorator nested.ans b/test/tests/tag decorator nested.ans index c2e6ebd..8195149 100644 --- a/test/tests/tag decorator nested.ans +++ b/test/tests/tag decorator nested.ans @@ -1,4 +1,4 @@ # 1 foo - ~ 1 # "b": [1,2] - bar ~ 1 # "a": [2,3] + ~ 1 # b=[1,2] + bar ~ 1 # a=[2,3] diff --git a/test/tests/tag decorator.ans b/test/tests/tag decorator.ans index 4619276..572cc46 100644 --- a/test/tests/tag decorator.ans +++ b/test/tests/tag decorator.ans @@ -1,3 +1,3 @@ # 1 foo - bar # "a": [2,3] + bar # a=[2,3] diff --git a/test/tests/tag operator.ans b/test/tests/tag operator.ans index e4c3bf5..90e7729 100644 --- a/test/tests/tag operator.ans +++ b/test/tests/tag operator.ans @@ -3,5 +3,5 @@ $ f a {f # 5} c -# 2:2 +# 2=2 a {f # 5} c diff --git a/test/tests/tag.ans b/test/tests/tag.ans index 2e49353..2a4853d 100644 --- a/test/tests/tag.ans +++ b/test/tests/tag.ans @@ -1,4 +1,4 @@ # 1 foo - # "a": [2,3] + # a=[2,3] bar \ No newline at end of file