diff --git a/anselme/ast/Environment.lua b/anselme/ast/Environment.lua index 336babc..cbff40b 100644 --- a/anselme/ast/Environment.lua +++ b/anselme/ast/Environment.lua @@ -31,12 +31,9 @@ local VariableMetadata = ast.abstract.Runtime { return self.symbol end, set = function(self, state, value) - if self.symbol.constant then - error(("trying to change the value of constant %s"):format(self.symbol.string:format(state)), 0) - end if self.symbol.value_check then local r = self.symbol.value_check:call(state, ArgumentTuple:new(value)) - if not r:truthy() then error(("value check failure for %s; %s does not satisfy %s"):format(self.symbol.string:format(state), value, self.symbol.value_check:format(state)), 0) end + if not r:truthy() then error(("can not set %s = %s; %s value check failed"):format(self.symbol.string:format(state), value, self.symbol.value_check:format_short(state)), 0) end end if self.symbol.alias then local assign_args = ArgumentTuple:new() diff --git a/anselme/ast/Symbol.lua b/anselme/ast/Symbol.lua index 0cc25d1..a768486 100644 --- a/anselme/ast/Symbol.lua +++ b/anselme/ast/Symbol.lua @@ -8,7 +8,6 @@ Symbol = ast.abstract.Node { type = "symbol", string = nil, - constant = nil, -- bool alias = nil, -- bool exported = nil, -- bool value_check = nil, -- exp @@ -18,7 +17,6 @@ Symbol = ast.abstract.Node { init = function(self, str, modifiers) modifiers = modifiers or {} self.string = str - self.constant = modifiers.constant self.value_check = modifiers.value_check self.alias = modifiers.alias self.confined_to_branch = modifiers.confined_to_branch @@ -26,7 +24,7 @@ Symbol = ast.abstract.Node { end, with = function(self, modifiers) modifiers = modifiers or {} - for _, k in ipairs{"constant", "value_check", "alias", "exported", "confined_to_branch"} do + for _, k in ipairs{"value_check", "alias", "exported", "confined_to_branch"} do if modifiers[k] == nil then modifiers[k] = self[k] end @@ -48,9 +46,6 @@ Symbol = ast.abstract.Node { _hash = function(self) local prefix = "" - if self.constant then - prefix = prefix .. ":" - end if self.alias then prefix = prefix .. "&" end @@ -66,9 +61,6 @@ Symbol = ast.abstract.Node { _format = function(self, state, prio, ...) local s = ":" - if self.constant then - s = s .. ":" - end if self.alias then s = s .. "&" end diff --git a/anselme/parser/expression/primary/function_definition.lua b/anselme/parser/expression/primary/function_definition.lua index f11009d..392b475 100644 --- a/anselme/parser/expression/primary/function_definition.lua +++ b/anselme/parser/expression/primary/function_definition.lua @@ -159,19 +159,18 @@ end return primary { match = function(self, str) - return str:match("^%::?&?@?%$") + return str:match("^%:&?@?%$") end, parse = function(self, source, options, str) local source_start = source:clone() - local mod_const, mod_alias, mod_exported, rem = source:consume(str:match("^(%:(:?)(&?)(@?)%$)(.-)$")) + local mod_alias, mod_exported, rem = source:consume(str:match("^(%:(&?)(@?)%$)(.-)$")) -- get modifiers - local constant, exported, alias - if mod_const == ":" then constant = true end + local exported, alias if mod_alias == "&" then alias = true end if mod_exported == "@" then exported = true end - local modifiers = { constant = constant, exported = exported, alias = alias } + local modifiers = { exported = exported, alias = alias } -- search for a valid signature local symbol, parameters diff --git a/anselme/parser/expression/primary/symbol.lua b/anselme/parser/expression/primary/symbol.lua index 7e20b2f..529825f 100644 --- a/anselme/parser/expression/primary/symbol.lua +++ b/anselme/parser/expression/primary/symbol.lua @@ -8,18 +8,17 @@ local Nil = ast.Nil return primary { match = function(self, str) - if str:match("^%::?&?@?") then + if str:match("^%:&?@?") then return identifier:match(str:match("^%::?&?@?(.-)$")) end return false end, parse = function(self, source, options, str) - local mod_const, mod_alias, mod_export, rem = source:consume(str:match("^(%:(:?)(&?)(@?))(.-)$")) - local constant, alias, value_check_exp, exported + local mod_alias, mod_export, rem = source:consume(str:match("^(%:(&?)(@?))(.-)$")) + local alias, value_check_exp, exported -- get modifier - if mod_const == ":" then constant = true end if mod_alias == "&" then alias = true end if mod_export == "@" then exported = true end @@ -35,6 +34,6 @@ return primary { value_check_exp = exp.arguments.positional[2] end - return ident:to_symbol{ constant = constant, alias = alias, exported = exported, value_check = value_check_exp }:set_source(source), rem + return ident:to_symbol{ alias = alias, exported = exported, value_check = value_check_exp }:set_source(source), rem end } diff --git a/anselme/state/ScopeStack.lua b/anselme/state/ScopeStack.lua index 8f48204..1f513e7 100644 --- a/anselme/state/ScopeStack.lua +++ b/anselme/state/ScopeStack.lua @@ -47,7 +47,7 @@ local ScopeStack = class { -- for lua functions: define_lua("name", "(x, y, z=5)", function(x, y, z) ... end), where arguments and return values of the function are automatically converted between anselme and lua values -- for other lua values: define_lua("name", value) -- for anselme AST: define_lua("name", value) - -- name can be prefixed with symbol modifiers, for example ":name" for a constant variable + -- name can be prefixed with symbol modifiers, for example "@name" for an exported variable -- if `raw_mode` is true, no anselme-to/from-lua conversion will be performed in the function -- the function will receive the state followed by AST nodes as arguments, and is expected to return an AST node define_lua = function(self, name, value, func, raw_mode) diff --git a/anselme/state/State.lua b/anselme/state/State.lua index 938066a..6c5ebaf 100644 --- a/anselme/state/State.lua +++ b/anselme/state/State.lua @@ -104,7 +104,7 @@ State = class { -- * for other lua values: `define("name", value)` -- * for anselme AST: `define("name", value)` -- - -- `name` can be prefixed with symbol modifiers, for example ":name" for a constant variable. + -- `name` can be prefixed with symbol modifiers, for example "@name" for an exported variable. -- -- If `raw_mode` is true, no anselme-to/from-lua conversion will be performed in the function. -- The function will receive the state followed by AST nodes as arguments, and is expected to return an AST node. diff --git a/anselme/stdlib/assignment.lua b/anselme/stdlib/assignment.lua index 6acec3f..7b63a34 100644 --- a/anselme/stdlib/assignment.lua +++ b/anselme/stdlib/assignment.lua @@ -2,6 +2,13 @@ local ast = require("anselme.ast") local Nil, Boolean, LuaCall, ParameterTuple, FunctionParameter, Identifier, Overloadable, Overload, Call, Quote = ast.Nil, ast.Boolean, ast.LuaCall, ast.ParameterTuple, ast.FunctionParameter, ast.Identifier, ast.abstract.Overloadable, ast.Overload, ast.Call, ast.Quote return { + { + "constant", "(exp)", + function(state, exp) + return Boolean:new(false) + end + }, + { "is tuple", "(exp)", function(state, exp) diff --git a/doc/api.md b/doc/api.md index 431cf64..691d1bb 100644 --- a/doc/api.md +++ b/doc/api.md @@ -172,7 +172,7 @@ Define a value in the global scope, converting it from Lua to Anselme if needed. * for other lua values: `define("name", value)` * for anselme AST: `define("name", value)` -`name` can be prefixed with symbol modifiers, for example ":name" for a constant variable. +`name` can be prefixed with symbol modifiers, for example "@name" for an exported variable. If `raw_mode` is true, no anselme-to/from-lua conversion will be performed in the function. The function will receive the state followed by AST nodes as arguments, and is expected to return an AST node. diff --git a/test/results/constant variable.ans b/test/results/constant variable.ans index a0e0e68..59e001f 100644 --- a/test/results/constant variable.ans +++ b/test/results/constant variable.ans @@ -1,7 +1,7 @@ --# run #-- --- error --- -trying to change the value of constant a +can not set a = 52; constant value check failed ↳ from test/tests/constant variable.ans:5:3 in call: a = 52 - ↳ from test/tests/constant variable.ans:1:1 in block: ::a = 3… + ↳ from test/tests/constant variable.ans:1:1 in block: :a::constant = 3… --# saved #-- {} \ No newline at end of file diff --git a/test/results/constrained variable assignement.ans b/test/results/constrained variable assignement.ans index f16e4a9..57f899d 100644 --- a/test/results/constrained variable assignement.ans +++ b/test/results/constrained variable assignement.ans @@ -4,7 +4,7 @@ --- text --- | {}"" {}"type(12, \"kg\")" {}"" | --- error --- -value check failure for weigh; 32 does not satisfy $(x) type(x) == t +can not set weigh = 32; $(x) type(x) == t value check failed ↳ from test/tests/constrained variable assignement.ans:9:7 in call: weigh = 32 ↳ from test/tests/constrained variable assignement.ans:1:1 in block: :weigh::is("kg") = type(5, "kg")… --# saved #-- diff --git a/test/results/symbol alias constant.ans b/test/results/symbol alias constant.ans index f5559c6..22a5526 100644 --- a/test/results/symbol alias constant.ans +++ b/test/results/symbol alias constant.ans @@ -5,7 +5,7 @@ --- text --- | {}"d=" {}"2" {}" (2)" | --- error --- -trying to change the value of constant d +can not set d = 5; constant value check failed ↳ from test/tests/symbol alias constant.ans:12:3 in call: d = 5 ↳ from test/tests/symbol alias constant.ans:1:1 in block: :l = *[1, 2, 3]… --# saved #-- diff --git a/test/tests/constant variable list.ans b/test/tests/constant variable list.ans index 144a31f..564ab7b 100644 --- a/test/tests/constant variable list.ans +++ b/test/tests/constant variable list.ans @@ -1,4 +1,4 @@ -::a = *[3] +:a::constant = *[3] |{a} diff --git a/test/tests/constant variable.ans b/test/tests/constant variable.ans index be2f533..39c575b 100644 --- a/test/tests/constant variable.ans +++ b/test/tests/constant variable.ans @@ -1,4 +1,4 @@ -::a = 3 +:a::constant = 3 {a} diff --git a/test/tests/equality operator.ans b/test/tests/equality operator.ans index 0fe785c..14c3589 100644 --- a/test/tests/equality operator.ans +++ b/test/tests/equality operator.ans @@ -1,4 +1,4 @@ -::a = [1:2] +:a::constant = [1:2] |false = {a == [5:2]} @@ -6,7 +6,7 @@ |true = {a == [1:2]} -::b = [1,2,3] +:b::constant = [1,2,3] |false = {b == a} @@ -24,6 +24,6 @@ |true = {c!to tuple == b} -::d = [1,2,3] +:d::constant = [1,2,3] |true = {d == b} diff --git a/test/tests/symbol alias constant.ans b/test/tests/symbol alias constant.ans index e28d8e5..97dfb12 100644 --- a/test/tests/symbol alias constant.ans +++ b/test/tests/symbol alias constant.ans @@ -1,11 +1,11 @@ :l = *[1,2,3] -::&c => l(2) +:&c::constant => l(2) | c={c} (2) | l={l} (*[1,2,3]) -::&d = "{l(2)}" +:&d::constant = "{l(2)}" | d={c} (2)