Description
The data model proposed in #393 defines Expression
as follows:
interface Expression {
type: 'expression';
body: Literal | VariableRef | FunctionRef | Reserved;
}
A FunctionRef
can also have a Literal
or a VariableRef
as an argument, and in fact, due to how our syntax is designed, I'd argue that the function's argument is more important than the function. (E.g. it comes first in the syntax.)
I'd like to suggest an alternative way to structure our expressions, to more closely map to our syntax:
expression = "{" [s] ((operand [s annotation]) / annotation) [s] "}"
Let's special-case argument-less functions rather than function-less operands.
Instead of Literal | VariableRef | FunctionRef
here and operand?: Literal | VariableRef
inside FunctionRef
, we can do:
type Expression = OperandExpr | FunctionExpr;
interface OperandExpr {
operand: Literal | VariableRef;
annotation?: FunctionExpr;
}
interface FunctionExpr {
name: string;
options: Map<string, Literal | VariableRef>;
}
FWIW, this is how I implemented expressions in stasm/message2:
https://github.com/stasm/message2/blob/4abf43f2023b6e20d8ee1d462684d0741ece791b/syntax/ast.ts#L44-L70
Originally posted by @stasm in #393 (comment)