in packages/jinja/src/parser.ts [609:663]
function parsePrimaryExpression(): Statement {
// Primary expression: number, string, identifier, function call, parenthesized expression
const token = tokens[current++];
switch (token.type) {
case TOKEN_TYPES.NumericLiteral: {
const num = token.value;
return num.includes(".") ? new FloatLiteral(Number(num)) : new IntegerLiteral(Number(num));
}
case TOKEN_TYPES.StringLiteral: {
let value = token.value;
while (is(TOKEN_TYPES.StringLiteral)) {
value += tokens[current++].value;
}
return new StringLiteral(value);
}
case TOKEN_TYPES.Identifier:
return new Identifier(token.value);
case TOKEN_TYPES.OpenParen: {
const expression = parseExpressionSequence();
expect(TOKEN_TYPES.CloseParen, "Expected closing parenthesis, got ${tokens[current].type} instead.");
return expression;
}
case TOKEN_TYPES.OpenSquareBracket: {
const values = [];
while (!is(TOKEN_TYPES.CloseSquareBracket)) {
values.push(parseExpression());
if (is(TOKEN_TYPES.Comma)) {
++current; // consume comma
}
}
++current; // consume closing square bracket
return new ArrayLiteral(values);
}
case TOKEN_TYPES.OpenCurlyBracket: {
const values = new Map();
while (!is(TOKEN_TYPES.CloseCurlyBracket)) {
const key = parseExpression();
expect(TOKEN_TYPES.Colon, "Expected colon between key and value in object literal");
const value = parseExpression();
values.set(key, value);
if (is(TOKEN_TYPES.Comma)) {
++current; // consume comma
}
}
++current; // consume closing curly bracket
return new ObjectLiteral(values);
}
default:
throw new SyntaxError(`Unexpected token: ${token.type}`);
}
}