diff --git a/anselme/ast/Identifier.lua b/anselme/ast/Identifier.lua index 436b973..704a2dc 100644 --- a/anselme/ast/Identifier.lua +++ b/anselme/ast/Identifier.lua @@ -4,6 +4,7 @@ local Symbol, String local Identifier Identifier = ast.abstract.Node { type = "identifier", + parenthesied = false, -- true if identifier was wrapped in parentheses name = nil, diff --git a/anselme/parser/expression/primary/parenthesis.lua b/anselme/parser/expression/primary/parenthesis.lua index c050daa..cad8e27 100644 --- a/anselme/parser/expression/primary/parenthesis.lua +++ b/anselme/parser/expression/primary/parenthesis.lua @@ -3,7 +3,7 @@ local primary = require("anselme.parser.expression.primary.primary") local ast = require("anselme.ast") -local Nil = ast.Nil +local Nil, Identifier = ast.Nil, ast.Identifier local expression_to_ast = require("anselme.parser.expression.to_ast") @@ -27,6 +27,9 @@ return primary { if not s then error("invalid expression inside parentheses: "..exp, 0) end rem = source:consume_leading_whitespace(opts, rem) if not rem:match("^%)") then error(("unexpected %q at end of parenthesis"):format(rem:match("^[^\n]*")), 0) end + if Identifier:is(exp) then + exp.parenthesied = true + end end rem = source:consume(rem:match("^(%))(.*)$")) diff --git a/anselme/parser/expression/secondary/infix/pair.lua b/anselme/parser/expression/secondary/infix/pair.lua index 60b547c..f9837e9 100644 --- a/anselme/parser/expression/secondary/infix/pair.lua +++ b/anselme/parser/expression/secondary/infix/pair.lua @@ -2,8 +2,18 @@ local infix = require("anselme.parser.expression.secondary.infix.infix") local operator_priority = require("anselme.common").operator_priority +local ast = require("anselme.ast") +local Call, Identifier, ArgumentTuple = ast.Call, ast.Identifier, ast.ArgumentTuple + return infix { operator = ":", identifier = "_:_", - priority = operator_priority["_:_"] + priority = operator_priority["_:_"], + + build_ast = function(self, left, right) + if Identifier:is(left) and not left.parenthesied then + left = left:to_string() + end + return Call:new(Identifier:new(self.identifier), ArgumentTuple:new(left, right)) + end } diff --git a/doc/language.md b/doc/language.md index 61c6344..c3fdd66 100644 --- a/doc/language.md +++ b/doc/language.md @@ -415,10 +415,15 @@ The `break` and `continue` functions from the standard library also return retur Pairs associate two arbitrary values. -Pairs are built using the `_:_` identifier, with the left argument giving the name and the right the value of the pair. +Pairs are built using the `_:_` identifier, with the left argument giving the name and the right the value of the pair. If the left argument is an identifier, it will be converted to a string for convenience. ``` -"name":"value" +"name":"value" -- is the same as +name:"value" + +-- if you need to use the value associated with the `name` variable instead, the identifier can be wrapped in parentheses +:name = "key" +(name):"value" ``` ### Tuple diff --git a/test/results/pair operator.ans b/test/results/pair operator.ans index 63475ea..31d99cc 100644 --- a/test/results/pair operator.ans +++ b/test/results/pair operator.ans @@ -1,7 +1,7 @@ --# run #-- --- text --- -| {}"" {}"[\"test\":1, 3:\"p\", \"test\":\"foo\", \"ho\":\"ah\", \"test\":\"test\"]" {}"" | | {}"" {}"[\"name\":1, 3:\"p\", \"test\":\"foo\", \"ho\":\"ah\", \"name\":\"test\"]" {}"" | +| {}"" {}"[\"name\":1, 3:\"p\", \"name\":\"foo\", \"ho\":\"ah\", \"name\":\"test\"]" {}"" | --- return --- () --# saved #-- diff --git a/test/tests/function call struct.ans b/test/tests/function call struct.ans index e3ec8f2..4e549e6 100644 --- a/test/tests/function call struct.ans +++ b/test/tests/function call struct.ans @@ -1,4 +1,4 @@ :f = $(l) |{l} -f{4:3,true:6,"l":8} +f{4:3,(true):6,"l":8}