function parsePrimaryExpression()

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}`);
		}
	}