memoryExpr method
Implementation
MathExpr memoryExpr() {
MathExpr lhs = literal();
Token op = peek();
const memOps = [
TokenType.kDot,
TokenType.kColon,
TokenType.kLBracket,
TokenType.kLParen,
];
while (memOps.contains(op.type)) {
lhs = switch (op.type) {
TokenType.kDot => MemoryAccess.field(op, lhs, advanceAndThen(rawExpr)),
TokenType.kLBracket => () {
final arg = advanceAndThen(math);
consume(TokenType.kRBracket, 'Expecting closing bracket.');
return MemoryAccess.table(op, lhs, arg);
}(),
TokenType.kColon => () {
advance();
// Special case: the colon operator forwards the lhs object
// into a function arg list as the new first argument.
// Therefore, we need to be sugar that a function expression
// follows and becomes our rhsExpr node.
//
// functioncall ::= prefixexp ':' Name args
final MathExpr funcName = literal();
final parenToken = consume(
TokenType.kLParen,
'Expected function call after colon ":" operator.',
);
final args = argList(terminal: TokenType.kRParen);
consume(TokenType.kRParen, 'Expecting closing parentheses.');
final rhsExpr = MemoryAccess.call(parenToken, funcName, args);
// With the function node packed together, map this to lhs.
final callee = lhs;
final colon = op;
return MemoryAccess.call(colon, callee, [rhsExpr]);
}(),
TokenType.kLParen => () {
advance();
final args = argList(terminal: TokenType.kRParen);
consume(TokenType.kRParen, 'Expecting closing parentheses.');
return MemoryAccess.call(op, lhs, args);
}(),
_ => lhs,
};
op = peek();
}
return lhs;
}