Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
import { describe, expect, it } from "vitest"; | |
import { tokenize } from "../src/lexer"; | |
import { parse } from "../src/parser"; | |
import { Environment, Interpreter } from "../src/runtime"; | |
const TEST_STRINGS = { | |
// Text nodes | |
NO_TEMPLATE: `Hello world!`, | |
TEXT_NODES: `0{{ 'A' }}1{{ 'B' }}{{ 'C' }}2{{ 'D' }}3`, | |
// Logical operators | |
LOGICAL_AND: `{{ true and true }}{{ true and false }}{{ false and true }}{{ false and false }}`, | |
LOGICAL_OR: `{{ true or true }}{{ true or false }}{{ false or true }}{{ false or false }}`, | |
LOGICAL_NOT: `{{ not true }}{{ not false }}`, | |
LOGICAL_NOT_NOT: `{{ not not true }}{{ not not false }}`, | |
LOGICAL_AND_OR: `{{ true and true or false }}{{ true and false or true }}{{ false and true or true }}{{ false and false or true }}{{ false and false or false }}`, | |
LOGICAL_AND_NOT: `{{ true and not true }}{{ true and not false }}{{ false and not true }}{{ false and not false }}`, | |
LOGICAL_OR_NOT: `{{ true or not true }}{{ true or not false }}{{ false or not true }}{{ false or not false }}`, | |
LOGICAL_COMBINED: `{{ 1 == 2 and 2 == 2 }}{{ 1 == 2 or 2 == 2}}`, | |
// If statements | |
IF_ONLY: `{% if 1 == 1 %}{{ 'A' }}{% endif %}{{ 'B' }}`, | |
IF_ELSE_ONLY: `{% if 1 == 2 %}{{ 'A' }}{% else %}{{ 'B' }}{% endif %}{{ 'C' }}`, | |
IF_ELIF_ELSE: `{% if 1 == 2 %}{{ 'A' }}{{ 'B' }}{{ 'C' }}{% elif 1 == 2 %}{{ 'D' }}{% elif 1 == 3 %}{{ 'E' }}{{ 'F' }}{% else %}{{ 'G' }}{{ 'H' }}{{ 'I' }}{% endif %}{{ 'J' }}`, | |
NESTED_STATEMENTS: `{% set a = 0 %}{% set b = 0 %}{% set c = 0 %}{% set d = 0 %}{% if 1 == 1 %}{% set a = 2 %}{% set b = 3 %}{% elif 1 == 2 %}{% set c = 4 %}{% else %}{% set d = 5 %}{% endif %}{{ a }}{{ b }}{{ c }}{{ d }}`, | |
// For loops | |
FOR_LOOP: `{% for message in messages %}{{ message['content'] }}{% endfor %}`, | |
FOR_LOOP_UNPACKING: `|{% for x, y in [ [1, 2], [3, 4] ] %}|{{ x + ' ' + y }}|{% endfor %}|`, | |
// Set variables | |
VARIABLES: `{% set x = 'Hello' %}{% set y = 'World' %}{{ x + ' ' + y }}`, | |
// Numbers | |
NUMBERS: `|{{ 5 }}|{{ -5 }}|{{ add(3, -1) }}|{{ (3 - 1) + (a - 5) - (a + 5)}}|`, | |
// Binary expressions | |
BINOP_EXPR: `{{ 1 % 2 }}{{ 1 < 2 }}{{ 1 > 2 }}{{ 1 >= 2 }}{{ 2 <= 2 }}{{ 2 == 2 }}{{ 2 != 3 }}{{ 2 + 3 }}`, | |
// Strings | |
STRINGS: `{{ 'Bye' }}{{ bos_token + '[INST] ' }}`, | |
STRINGS_1: `|{{ "test" }}|{{ "a" + 'b' + "c" }}|{{ '"' + "'" }}|{{ '\\'' }}|{{ "\\"" }}|`, | |
STRINGS_2: `|{{ "" | length }}|{{ "a" | length }}|{{ '' | length }}|{{ 'a' | length }}|`, | |
// Function calls | |
FUNCTIONS: `{{ func() }}{{ func(apple) }}{{ func(x, 'test', 2, false) }}`, | |
// Object properties | |
PROPERTIES: `{{ obj.x + obj.y }}{{ obj['x'] + obj.y }}`, | |
// Object methods | |
OBJ_METHODS: `{{ obj.x(x, y) }}{{ ' ' + obj.x() + ' ' }}{{ obj.z[x](x, y) }}`, | |
STRING_METHODS: `{{ ' A '.strip() }}{% set x = ' B ' %}{{ x.strip() }}{% set y = ' aBcD ' %}{{ y.upper() }}{{ y.lower() }}`, | |
STRING_METHODS_2: `{{ 'test test'.title() }}`, | |
// String indexing and slicing | |
STRING_SLICING: `|{{ x[0] }}|{{ x[:] }}|{{ x[:3] }}|{{ x[1:4] }}|{{ x[1:-1] }}|{{ x[1::2] }}|{{ x[5::-1] }}|`, | |
// Array indexing and slicing | |
ARRAY_SLICING: `|{{ strings[0] }}|{% for s in strings[:] %}{{ s }}{% endfor %}|{% for s in strings[:3] %}{{ s }}{% endfor %}|{% for s in strings[1:4] %}{{ s }}{% endfor %}|{% for s in strings[1:-1] %}{{ s }}{% endfor %}|{% for s in strings[1::2] %}{{ s }}{% endfor %}|{% for s in strings[5::-1] %}{{ s }}{% endfor %}|`, | |
// Membership operators | |
MEMBERSHIP: `|{{ 0 in arr }}|{{ 1 in arr }}|{{ true in arr }}|{{ false in arr }}|{{ 'a' in arr }}|{{ 'b' in arr }}|`, | |
MEMBERSHIP_NEGATION_1: `|{{ not 0 in arr }}|{{ not 1 in arr }}|{{ not true in arr }}|{{ not false in arr }}|{{ not 'a' in arr }}|{{ not 'b' in arr }}|`, | |
MEMBERSHIP_NEGATION_2: `|{{ 0 not in arr }}|{{ 1 not in arr }}|{{ true not in arr }}|{{ false not in arr }}|{{ 'a' not in arr }}|{{ 'b' not in arr }}|`, | |
// Escaped characters | |
ESCAPED_CHARS: `{{ '\\n' }}{{ '\\t' }}{{ '\\'' }}{{ '\\"' }}{{ '\\\\' }}{{ '|\\n|\\t|\\'|\\"|\\\\|' }}`, | |
// Substring inclusion | |
SUBSTRING_INCLUSION: `|{{ '' in 'abc' }}|{{ 'a' in 'abc' }}|{{ 'd' in 'abc' }}|{{ 'ab' in 'abc' }}|{{ 'ac' in 'abc' }}|{{ 'abc' in 'abc' }}|{{ 'abcd' in 'abc' }}|`, | |
// Filter operator | |
FILTER_OPERATOR: `{{ arr | length }}{{ 1 + arr | length }}{{ 2 + arr | sort | length }}{{ (arr | sort)[0] }}`, | |
FILTER_OPERATOR_2: `|{{ 'abc' | length }}|{{ 'aBcD' | upper }}|{{ 'aBcD' | lower }}|{{ 'test test' | capitalize}}|{{ 'test test' | title }}|{{ ' a b ' | trim }}|{{ ' A B ' | trim | lower | length }}|`, | |
FILTER_OPERATOR_3: `|{{ -1 | abs }}|{{ 1 | abs }}|`, | |
FILTER_OPERATOR_4: `{{ items | selectattr('key') | length }}`, | |
FILTER_OPERATOR_5: `{{ messages | selectattr('role', 'equalto', 'system') | length }}`, | |
FILTER_OPERATOR_6: `|{{ obj | length }}|{{ (obj | items)[1:] | length }}|`, | |
// Logical operators between non-Booleans | |
BOOLEAN_NUMERICAL: `|{{ 1 and 2 }}|{{ 1 and 0 }}|{{ 0 and 1 }}|{{ 0 and 0 }}|{{ 1 or 2 }}|{{ 1 or 0 }}|{{ 0 or 1 }}|{{ 0 or 0 }}|{{ not 1 }}|{{ not 0 }}|`, | |
BOOLEAN_STRINGS: `|{{ 'a' and 'b' }}|{{ 'a' and '' }}|{{ '' and 'a' }}|{{ '' and '' }}|{{ 'a' or 'b' }}|{{ 'a' or '' }}|{{ '' or 'a' }}|{{ '' or '' }}|{{ not 'a' }}|{{ not '' }}|`, | |
BOOLEAN_MIXED: `|{{ true and 1 }}|{{ true and 0 }}|{{ false and 1 }}|{{ false and 0 }}|{{ true or 1 }}|{{ true or 0 }}|{{ false or 1 }}|{{ false or 0 }}|`, | |
BOOLEAN_MIXED_2: `|{{ true and '' }}|{{ true and 'a' }}|{{ false or '' }}|{{ false or 'a' }}|{{ '' and true }}|{{ 'a' and true }}|{{ '' or false }}|{{ 'a' or false }}|`, | |
BOOLEAN_MIXED_IF: `{% if '' %}{{ 'A' }}{% endif %}{% if 'a' %}{{ 'B' }}{% endif %}{% if true and '' %}{{ 'C' }}{% endif %}{% if true and 'a' %}{{ 'D' }}{% endif %}`, | |
// Tests (is operator) | |
IS_OPERATOR: `|{{ unknown_var is defined }}|{{ unknown_var is not defined }}|{{ known_var is defined }}|{{ known_var is not defined }}|`, | |
IS_OPERATOR_2: `|{{ true is true }}|{{ true is not true }}|{{ true is false }}|{{ true is not false }}|{{ true is boolean }}|{{ 1 is boolean }}|`, | |
IS_OPERATOR_3: `|{{ 1 is odd }}|{{ 2 is odd }}|{{ 1 is even }}|{{ 2 is even }}|{{ 2 is number }}|{{ '2' is number }}|{{ 2 is integer }}|{{ '2' is integer }}|`, | |
IS_OPERATOR_4: `|{{ func is callable }}|{{ 2 is callable }}|{{ 1 is iterable }}|{{ 'hello' is iterable }}|`, | |
IS_OPERATOR_5: `|{{ 'a' is lower }}|{{ 'A' is lower }}|{{ 'a' is upper }}|{{ 'A' is upper }}|`, | |
// Short-circuit evaluation | |
SHORT_CIRCUIT: `{{ false and raise_exception('This should not be printed') }}`, | |
SHORT_CIRCUIT_1: `{{ true or raise_exception('This should not be printed') }}`, | |
// Namespaces | |
NAMESPACE: `{% set ns = namespace() %}{% set ns.foo = 'bar' %}{{ ns.foo }}`, | |
NAMESPACE_1: `{% set ns = namespace(default=false) %}{{ ns.default }}`, | |
NAMESPACE_2: `{% set ns = namespace(default=false, number=1+1) %}|{{ ns.default }}|{{ ns.number }}|`, | |
// Object operators | |
OBJECT_OPERATORS: `|{{ 'known' in obj }}|{{ 'known' not in obj }}|{{ 'unknown' in obj }}|{{ 'unknown' not in obj }}|`, | |
OBJECT_OPERATORS_1: `|{{ obj.get('known') }}|{{ obj.get('unknown') is none }}|{{ obj.get('unknown') is defined }}|`, | |
OBJECT_OPERATORS_2: `|{% for x, y in obj.items() %}|{{ x + ' ' + y }}|{% endfor %}|`, | |
// Scope | |
SCOPE: `{% set ns = namespace(found=false) %}{% for num in nums %}{% if num == 1 %}{{ 'found=' }}{% set ns.found = true %}{% endif %}{% endfor %}{{ ns.found }}`, | |
SCOPE_1: `{% set found = false %}{% for num in nums %}{% if num == 1 %}{{ 'found=' }}{% set found = true %}{% endif %}{% endfor %}{{ found }}`, | |
// Undefined | |
UNDEFINED_VARIABLES: `{{ undefined_variable }}`, | |
UNDEFINED_ACCESS: `{{ object.undefined_attribute }}`, | |
// Ternary operator | |
TERNARY_OPERATOR: `|{{ 'a' if true else 'b' }}|{{ 'a' if false else 'b' }}|{{ 'a' if 1 + 1 == 2 else 'b' }}|{{ 'a' if 1 + 1 == 3 or 1 * 2 == 3 else 'b' }}|`, | |
// Array literals | |
ARRAY_LITERALS: `{{ [1, true, 'hello', [1, 2, 3, 4], var] | length }}`, | |
// Tuple literals | |
TUPLE_LITERALS: `{{ (1, (1, 2)) | length }}`, | |
// Object literals | |
OBJECT_LITERALS: `{{ { 'key': 'value', key: 'value2', "key3": [1, {'foo': 'bar'} ] }['key'] }}`, | |
// Array operators | |
ARRAY_OPERATORS: `{{ ([1, 2, 3] + [4, 5, 6]) | length }}`, | |
}; | |
const TEST_PARSED = { | |
// Text nodes | |
NO_TEMPLATE: [{ value: "Hello world!", type: "Text" }], | |
TEXT_NODES: [ | |
{ value: "0", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "A", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "1", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "B", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "C", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "2", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "D", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "3", type: "Text" }, | |
], | |
// Logical operators | |
LOGICAL_AND: [ | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "and", type: "And" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "and", type: "And" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "and", type: "And" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "and", type: "And" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
LOGICAL_OR: [ | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "or", type: "Or" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "or", type: "Or" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "or", type: "Or" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "or", type: "Or" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
LOGICAL_NOT: [ | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "not", type: "UnaryOperator" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "not", type: "UnaryOperator" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
LOGICAL_NOT_NOT: [ | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "not", type: "UnaryOperator" }, | |
{ value: "not", type: "UnaryOperator" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "not", type: "UnaryOperator" }, | |
{ value: "not", type: "UnaryOperator" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
LOGICAL_AND_OR: [ | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "and", type: "And" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "or", type: "Or" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "and", type: "And" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "or", type: "Or" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "and", type: "And" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "or", type: "Or" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "and", type: "And" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "or", type: "Or" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "and", type: "And" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "or", type: "Or" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
LOGICAL_AND_NOT: [ | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "and", type: "And" }, | |
{ value: "not", type: "UnaryOperator" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "and", type: "And" }, | |
{ value: "not", type: "UnaryOperator" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "and", type: "And" }, | |
{ value: "not", type: "UnaryOperator" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "and", type: "And" }, | |
{ value: "not", type: "UnaryOperator" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
LOGICAL_OR_NOT: [ | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "or", type: "Or" }, | |
{ value: "not", type: "UnaryOperator" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "or", type: "Or" }, | |
{ value: "not", type: "UnaryOperator" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "or", type: "Or" }, | |
{ value: "not", type: "UnaryOperator" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "or", type: "Or" }, | |
{ value: "not", type: "UnaryOperator" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
LOGICAL_COMBINED: [ | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "==", type: "ComparisonBinaryOperator" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: "and", type: "And" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: "==", type: "ComparisonBinaryOperator" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "==", type: "ComparisonBinaryOperator" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: "or", type: "Or" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: "==", type: "ComparisonBinaryOperator" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
// If statements | |
IF_ONLY: [ | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "if", type: "If" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "==", type: "ComparisonBinaryOperator" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "A", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "endif", type: "EndIf" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "B", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
IF_ELSE_ONLY: [ | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "if", type: "If" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "==", type: "ComparisonBinaryOperator" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "A", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "else", type: "Else" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "B", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "endif", type: "EndIf" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "C", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
IF_ELIF_ELSE: [ | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "if", type: "If" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "==", type: "ComparisonBinaryOperator" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "A", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "B", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "C", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "elif", type: "ElseIf" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "==", type: "ComparisonBinaryOperator" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "D", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "elif", type: "ElseIf" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "==", type: "ComparisonBinaryOperator" }, | |
{ value: "3", type: "NumericLiteral" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "E", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "F", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "else", type: "Else" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "G", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "H", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "I", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "endif", type: "EndIf" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "J", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
NESTED_STATEMENTS: [ | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "set", type: "Set" }, | |
{ value: "a", type: "Identifier" }, | |
{ value: "=", type: "Equals" }, | |
{ value: "0", type: "NumericLiteral" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "set", type: "Set" }, | |
{ value: "b", type: "Identifier" }, | |
{ value: "=", type: "Equals" }, | |
{ value: "0", type: "NumericLiteral" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "set", type: "Set" }, | |
{ value: "c", type: "Identifier" }, | |
{ value: "=", type: "Equals" }, | |
{ value: "0", type: "NumericLiteral" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "set", type: "Set" }, | |
{ value: "d", type: "Identifier" }, | |
{ value: "=", type: "Equals" }, | |
{ value: "0", type: "NumericLiteral" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "if", type: "If" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "==", type: "ComparisonBinaryOperator" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "set", type: "Set" }, | |
{ value: "a", type: "Identifier" }, | |
{ value: "=", type: "Equals" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "set", type: "Set" }, | |
{ value: "b", type: "Identifier" }, | |
{ value: "=", type: "Equals" }, | |
{ value: "3", type: "NumericLiteral" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "elif", type: "ElseIf" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "==", type: "ComparisonBinaryOperator" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "set", type: "Set" }, | |
{ value: "c", type: "Identifier" }, | |
{ value: "=", type: "Equals" }, | |
{ value: "4", type: "NumericLiteral" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "else", type: "Else" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "set", type: "Set" }, | |
{ value: "d", type: "Identifier" }, | |
{ value: "=", type: "Equals" }, | |
{ value: "5", type: "NumericLiteral" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "endif", type: "EndIf" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "a", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "b", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "c", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "d", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
// For loops | |
FOR_LOOP: [ | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "for", type: "For" }, | |
{ value: "message", type: "Identifier" }, | |
{ value: "in", type: "In" }, | |
{ value: "messages", type: "Identifier" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "message", type: "Identifier" }, | |
{ value: "[", type: "OpenSquareBracket" }, | |
{ value: "content", type: "StringLiteral" }, | |
{ value: "]", type: "CloseSquareBracket" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "endfor", type: "EndFor" }, | |
{ value: "%}", type: "CloseStatement" }, | |
], | |
FOR_LOOP_UNPACKING: [ | |
{ value: "|", type: "Text" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "for", type: "For" }, | |
{ value: "x", type: "Identifier" }, | |
{ value: ",", type: "Comma" }, | |
{ value: "y", type: "Identifier" }, | |
{ value: "in", type: "In" }, | |
{ value: "[", type: "OpenSquareBracket" }, | |
{ value: "[", type: "OpenSquareBracket" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: ",", type: "Comma" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: "]", type: "CloseSquareBracket" }, | |
{ value: ",", type: "Comma" }, | |
{ value: "[", type: "OpenSquareBracket" }, | |
{ value: "3", type: "NumericLiteral" }, | |
{ value: ",", type: "Comma" }, | |
{ value: "4", type: "NumericLiteral" }, | |
{ value: "]", type: "CloseSquareBracket" }, | |
{ value: "]", type: "CloseSquareBracket" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "x", type: "Identifier" }, | |
{ value: "+", type: "AdditiveBinaryOperator" }, | |
{ value: " ", type: "StringLiteral" }, | |
{ value: "+", type: "AdditiveBinaryOperator" }, | |
{ value: "y", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "endfor", type: "EndFor" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "|", type: "Text" }, | |
], | |
// Set variables | |
VARIABLES: [ | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "set", type: "Set" }, | |
{ value: "x", type: "Identifier" }, | |
{ value: "=", type: "Equals" }, | |
{ value: "Hello", type: "StringLiteral" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "set", type: "Set" }, | |
{ value: "y", type: "Identifier" }, | |
{ value: "=", type: "Equals" }, | |
{ value: "World", type: "StringLiteral" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "x", type: "Identifier" }, | |
{ value: "+", type: "AdditiveBinaryOperator" }, | |
{ value: " ", type: "StringLiteral" }, | |
{ value: "+", type: "AdditiveBinaryOperator" }, | |
{ value: "y", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
// Numbers | |
NUMBERS: [ | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "5", type: "NumericLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "-5", type: "NumericLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "add", type: "Identifier" }, | |
{ value: "(", type: "OpenParen" }, | |
{ value: "3", type: "NumericLiteral" }, | |
{ value: ",", type: "Comma" }, | |
{ value: "-1", type: "NumericLiteral" }, | |
{ value: ")", type: "CloseParen" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "(", type: "OpenParen" }, | |
{ value: "3", type: "NumericLiteral" }, | |
{ value: "-", type: "AdditiveBinaryOperator" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: ")", type: "CloseParen" }, | |
{ value: "+", type: "AdditiveBinaryOperator" }, | |
{ value: "(", type: "OpenParen" }, | |
{ value: "a", type: "Identifier" }, | |
{ value: "-", type: "AdditiveBinaryOperator" }, | |
{ value: "5", type: "NumericLiteral" }, | |
{ value: ")", type: "CloseParen" }, | |
{ value: "-", type: "AdditiveBinaryOperator" }, | |
{ value: "(", type: "OpenParen" }, | |
{ value: "a", type: "Identifier" }, | |
{ value: "+", type: "AdditiveBinaryOperator" }, | |
{ value: "5", type: "NumericLiteral" }, | |
{ value: ")", type: "CloseParen" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
], | |
// Binary expressions | |
BINOP_EXPR: [ | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "%", type: "MultiplicativeBinaryOperator" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "<", type: "ComparisonBinaryOperator" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: ">", type: "ComparisonBinaryOperator" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: ">=", type: "ComparisonBinaryOperator" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: "<=", type: "ComparisonBinaryOperator" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: "==", type: "ComparisonBinaryOperator" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: "!=", type: "ComparisonBinaryOperator" }, | |
{ value: "3", type: "NumericLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: "+", type: "AdditiveBinaryOperator" }, | |
{ value: "3", type: "NumericLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
// Strings | |
STRINGS: [ | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "Bye", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "bos_token", type: "Identifier" }, | |
{ value: "+", type: "AdditiveBinaryOperator" }, | |
{ value: "[INST] ", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
STRINGS_1: [ | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "test", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "a", type: "StringLiteral" }, | |
{ value: "+", type: "AdditiveBinaryOperator" }, | |
{ value: "b", type: "StringLiteral" }, | |
{ value: "+", type: "AdditiveBinaryOperator" }, | |
{ value: "c", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: '"', type: "StringLiteral" }, | |
{ value: "+", type: "AdditiveBinaryOperator" }, | |
{ value: "'", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "'", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: '"', type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
], | |
STRINGS_2: [ | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "", type: "StringLiteral" }, | |
{ value: "|", type: "Pipe" }, | |
{ value: "length", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "a", type: "StringLiteral" }, | |
{ value: "|", type: "Pipe" }, | |
{ value: "length", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "", type: "StringLiteral" }, | |
{ value: "|", type: "Pipe" }, | |
{ value: "length", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "a", type: "StringLiteral" }, | |
{ value: "|", type: "Pipe" }, | |
{ value: "length", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
], | |
// Function calls | |
FUNCTIONS: [ | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "func", type: "Identifier" }, | |
{ value: "(", type: "OpenParen" }, | |
{ value: ")", type: "CloseParen" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "func", type: "Identifier" }, | |
{ value: "(", type: "OpenParen" }, | |
{ value: "apple", type: "Identifier" }, | |
{ value: ")", type: "CloseParen" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "func", type: "Identifier" }, | |
{ value: "(", type: "OpenParen" }, | |
{ value: "x", type: "Identifier" }, | |
{ value: ",", type: "Comma" }, | |
{ value: "test", type: "StringLiteral" }, | |
{ value: ",", type: "Comma" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: ",", type: "Comma" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: ")", type: "CloseParen" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
// Object properties | |
PROPERTIES: [ | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "obj", type: "Identifier" }, | |
{ value: ".", type: "Dot" }, | |
{ value: "x", type: "Identifier" }, | |
{ value: "+", type: "AdditiveBinaryOperator" }, | |
{ value: "obj", type: "Identifier" }, | |
{ value: ".", type: "Dot" }, | |
{ value: "y", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "obj", type: "Identifier" }, | |
{ value: "[", type: "OpenSquareBracket" }, | |
{ value: "x", type: "StringLiteral" }, | |
{ value: "]", type: "CloseSquareBracket" }, | |
{ value: "+", type: "AdditiveBinaryOperator" }, | |
{ value: "obj", type: "Identifier" }, | |
{ value: ".", type: "Dot" }, | |
{ value: "y", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
// Object methods | |
OBJ_METHODS: [ | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "obj", type: "Identifier" }, | |
{ value: ".", type: "Dot" }, | |
{ value: "x", type: "Identifier" }, | |
{ value: "(", type: "OpenParen" }, | |
{ value: "x", type: "Identifier" }, | |
{ value: ",", type: "Comma" }, | |
{ value: "y", type: "Identifier" }, | |
{ value: ")", type: "CloseParen" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: " ", type: "StringLiteral" }, | |
{ value: "+", type: "AdditiveBinaryOperator" }, | |
{ value: "obj", type: "Identifier" }, | |
{ value: ".", type: "Dot" }, | |
{ value: "x", type: "Identifier" }, | |
{ value: "(", type: "OpenParen" }, | |
{ value: ")", type: "CloseParen" }, | |
{ value: "+", type: "AdditiveBinaryOperator" }, | |
{ value: " ", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "obj", type: "Identifier" }, | |
{ value: ".", type: "Dot" }, | |
{ value: "z", type: "Identifier" }, | |
{ value: "[", type: "OpenSquareBracket" }, | |
{ value: "x", type: "Identifier" }, | |
{ value: "]", type: "CloseSquareBracket" }, | |
{ value: "(", type: "OpenParen" }, | |
{ value: "x", type: "Identifier" }, | |
{ value: ",", type: "Comma" }, | |
{ value: "y", type: "Identifier" }, | |
{ value: ")", type: "CloseParen" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
// String methods | |
STRING_METHODS: [ | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: " A ", type: "StringLiteral" }, | |
{ value: ".", type: "Dot" }, | |
{ value: "strip", type: "Identifier" }, | |
{ value: "(", type: "OpenParen" }, | |
{ value: ")", type: "CloseParen" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "set", type: "Set" }, | |
{ value: "x", type: "Identifier" }, | |
{ value: "=", type: "Equals" }, | |
{ value: " B ", type: "StringLiteral" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "x", type: "Identifier" }, | |
{ value: ".", type: "Dot" }, | |
{ value: "strip", type: "Identifier" }, | |
{ value: "(", type: "OpenParen" }, | |
{ value: ")", type: "CloseParen" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "set", type: "Set" }, | |
{ value: "y", type: "Identifier" }, | |
{ value: "=", type: "Equals" }, | |
{ value: " aBcD ", type: "StringLiteral" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "y", type: "Identifier" }, | |
{ value: ".", type: "Dot" }, | |
{ value: "upper", type: "Identifier" }, | |
{ value: "(", type: "OpenParen" }, | |
{ value: ")", type: "CloseParen" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "y", type: "Identifier" }, | |
{ value: ".", type: "Dot" }, | |
{ value: "lower", type: "Identifier" }, | |
{ value: "(", type: "OpenParen" }, | |
{ value: ")", type: "CloseParen" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
STRING_METHODS_2: [ | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "test test", type: "StringLiteral" }, | |
{ value: ".", type: "Dot" }, | |
{ value: "title", type: "Identifier" }, | |
{ value: "(", type: "OpenParen" }, | |
{ value: ")", type: "CloseParen" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
// String indexing and slicing | |
STRING_SLICING: [ | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "x", type: "Identifier" }, | |
{ value: "[", type: "OpenSquareBracket" }, | |
{ value: "0", type: "NumericLiteral" }, | |
{ value: "]", type: "CloseSquareBracket" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "x", type: "Identifier" }, | |
{ value: "[", type: "OpenSquareBracket" }, | |
{ value: ":", type: "Colon" }, | |
{ value: "]", type: "CloseSquareBracket" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "x", type: "Identifier" }, | |
{ value: "[", type: "OpenSquareBracket" }, | |
{ value: ":", type: "Colon" }, | |
{ value: "3", type: "NumericLiteral" }, | |
{ value: "]", type: "CloseSquareBracket" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "x", type: "Identifier" }, | |
{ value: "[", type: "OpenSquareBracket" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: ":", type: "Colon" }, | |
{ value: "4", type: "NumericLiteral" }, | |
{ value: "]", type: "CloseSquareBracket" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "x", type: "Identifier" }, | |
{ value: "[", type: "OpenSquareBracket" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: ":", type: "Colon" }, | |
{ value: "-1", type: "NumericLiteral" }, | |
{ value: "]", type: "CloseSquareBracket" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "x", type: "Identifier" }, | |
{ value: "[", type: "OpenSquareBracket" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: ":", type: "Colon" }, | |
{ value: ":", type: "Colon" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: "]", type: "CloseSquareBracket" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "x", type: "Identifier" }, | |
{ value: "[", type: "OpenSquareBracket" }, | |
{ value: "5", type: "NumericLiteral" }, | |
{ value: ":", type: "Colon" }, | |
{ value: ":", type: "Colon" }, | |
{ value: "-1", type: "NumericLiteral" }, | |
{ value: "]", type: "CloseSquareBracket" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
], | |
// Array indexing and slicing | |
ARRAY_SLICING: [ | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "strings", type: "Identifier" }, | |
{ value: "[", type: "OpenSquareBracket" }, | |
{ value: "0", type: "NumericLiteral" }, | |
{ value: "]", type: "CloseSquareBracket" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "for", type: "For" }, | |
{ value: "s", type: "Identifier" }, | |
{ value: "in", type: "In" }, | |
{ value: "strings", type: "Identifier" }, | |
{ value: "[", type: "OpenSquareBracket" }, | |
{ value: ":", type: "Colon" }, | |
{ value: "]", type: "CloseSquareBracket" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "s", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "endfor", type: "EndFor" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "for", type: "For" }, | |
{ value: "s", type: "Identifier" }, | |
{ value: "in", type: "In" }, | |
{ value: "strings", type: "Identifier" }, | |
{ value: "[", type: "OpenSquareBracket" }, | |
{ value: ":", type: "Colon" }, | |
{ value: "3", type: "NumericLiteral" }, | |
{ value: "]", type: "CloseSquareBracket" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "s", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "endfor", type: "EndFor" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "for", type: "For" }, | |
{ value: "s", type: "Identifier" }, | |
{ value: "in", type: "In" }, | |
{ value: "strings", type: "Identifier" }, | |
{ value: "[", type: "OpenSquareBracket" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: ":", type: "Colon" }, | |
{ value: "4", type: "NumericLiteral" }, | |
{ value: "]", type: "CloseSquareBracket" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "s", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "endfor", type: "EndFor" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "for", type: "For" }, | |
{ value: "s", type: "Identifier" }, | |
{ value: "in", type: "In" }, | |
{ value: "strings", type: "Identifier" }, | |
{ value: "[", type: "OpenSquareBracket" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: ":", type: "Colon" }, | |
{ value: "-1", type: "NumericLiteral" }, | |
{ value: "]", type: "CloseSquareBracket" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "s", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "endfor", type: "EndFor" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "for", type: "For" }, | |
{ value: "s", type: "Identifier" }, | |
{ value: "in", type: "In" }, | |
{ value: "strings", type: "Identifier" }, | |
{ value: "[", type: "OpenSquareBracket" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: ":", type: "Colon" }, | |
{ value: ":", type: "Colon" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: "]", type: "CloseSquareBracket" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "s", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "endfor", type: "EndFor" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "for", type: "For" }, | |
{ value: "s", type: "Identifier" }, | |
{ value: "in", type: "In" }, | |
{ value: "strings", type: "Identifier" }, | |
{ value: "[", type: "OpenSquareBracket" }, | |
{ value: "5", type: "NumericLiteral" }, | |
{ value: ":", type: "Colon" }, | |
{ value: ":", type: "Colon" }, | |
{ value: "-1", type: "NumericLiteral" }, | |
{ value: "]", type: "CloseSquareBracket" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "s", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "endfor", type: "EndFor" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "|", type: "Text" }, | |
], | |
// Membership operators | |
MEMBERSHIP: [ | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "0", type: "NumericLiteral" }, | |
{ value: "in", type: "In" }, | |
{ value: "arr", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "in", type: "In" }, | |
{ value: "arr", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "in", type: "In" }, | |
{ value: "arr", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "in", type: "In" }, | |
{ value: "arr", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "a", type: "StringLiteral" }, | |
{ value: "in", type: "In" }, | |
{ value: "arr", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "b", type: "StringLiteral" }, | |
{ value: "in", type: "In" }, | |
{ value: "arr", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
], | |
MEMBERSHIP_NEGATION_1: [ | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "not", type: "UnaryOperator" }, | |
{ value: "0", type: "NumericLiteral" }, | |
{ value: "in", type: "In" }, | |
{ value: "arr", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "not", type: "UnaryOperator" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "in", type: "In" }, | |
{ value: "arr", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "not", type: "UnaryOperator" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "in", type: "In" }, | |
{ value: "arr", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "not", type: "UnaryOperator" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "in", type: "In" }, | |
{ value: "arr", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "not", type: "UnaryOperator" }, | |
{ value: "a", type: "StringLiteral" }, | |
{ value: "in", type: "In" }, | |
{ value: "arr", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "not", type: "UnaryOperator" }, | |
{ value: "b", type: "StringLiteral" }, | |
{ value: "in", type: "In" }, | |
{ value: "arr", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
], | |
MEMBERSHIP_NEGATION_2: [ | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "0", type: "NumericLiteral" }, | |
{ value: "not in", type: "NotIn" }, | |
{ value: "arr", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "not in", type: "NotIn" }, | |
{ value: "arr", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "not in", type: "NotIn" }, | |
{ value: "arr", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "not in", type: "NotIn" }, | |
{ value: "arr", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "a", type: "StringLiteral" }, | |
{ value: "not in", type: "NotIn" }, | |
{ value: "arr", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "b", type: "StringLiteral" }, | |
{ value: "not in", type: "NotIn" }, | |
{ value: "arr", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
], | |
// Escaped characters | |
ESCAPED_CHARS: [ | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "\n", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "\t", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "'", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: '"', type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "\\", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: `|\n|\t|'|"|\\|`, type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
// Substring inclusion | |
SUBSTRING_INCLUSION: [ | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "", type: "StringLiteral" }, | |
{ value: "in", type: "In" }, | |
{ value: "abc", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "a", type: "StringLiteral" }, | |
{ value: "in", type: "In" }, | |
{ value: "abc", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "d", type: "StringLiteral" }, | |
{ value: "in", type: "In" }, | |
{ value: "abc", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "ab", type: "StringLiteral" }, | |
{ value: "in", type: "In" }, | |
{ value: "abc", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "ac", type: "StringLiteral" }, | |
{ value: "in", type: "In" }, | |
{ value: "abc", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "abc", type: "StringLiteral" }, | |
{ value: "in", type: "In" }, | |
{ value: "abc", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "abcd", type: "StringLiteral" }, | |
{ value: "in", type: "In" }, | |
{ value: "abc", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
], | |
// Filter operator | |
FILTER_OPERATOR: [ | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "arr", type: "Identifier" }, | |
{ value: "|", type: "Pipe" }, | |
{ value: "length", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "+", type: "AdditiveBinaryOperator" }, | |
{ value: "arr", type: "Identifier" }, | |
{ value: "|", type: "Pipe" }, | |
{ value: "length", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: "+", type: "AdditiveBinaryOperator" }, | |
{ value: "arr", type: "Identifier" }, | |
{ value: "|", type: "Pipe" }, | |
{ value: "sort", type: "Identifier" }, | |
{ value: "|", type: "Pipe" }, | |
{ value: "length", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "(", type: "OpenParen" }, | |
{ value: "arr", type: "Identifier" }, | |
{ value: "|", type: "Pipe" }, | |
{ value: "sort", type: "Identifier" }, | |
{ value: ")", type: "CloseParen" }, | |
{ value: "[", type: "OpenSquareBracket" }, | |
{ value: "0", type: "NumericLiteral" }, | |
{ value: "]", type: "CloseSquareBracket" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
FILTER_OPERATOR_2: [ | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "abc", type: "StringLiteral" }, | |
{ value: "|", type: "Pipe" }, | |
{ value: "length", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "aBcD", type: "StringLiteral" }, | |
{ value: "|", type: "Pipe" }, | |
{ value: "upper", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "aBcD", type: "StringLiteral" }, | |
{ value: "|", type: "Pipe" }, | |
{ value: "lower", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "test test", type: "StringLiteral" }, | |
{ value: "|", type: "Pipe" }, | |
{ value: "capitalize", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "test test", type: "StringLiteral" }, | |
{ value: "|", type: "Pipe" }, | |
{ value: "title", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: " a b ", type: "StringLiteral" }, | |
{ value: "|", type: "Pipe" }, | |
{ value: "trim", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: " A B ", type: "StringLiteral" }, | |
{ value: "|", type: "Pipe" }, | |
{ value: "trim", type: "Identifier" }, | |
{ value: "|", type: "Pipe" }, | |
{ value: "lower", type: "Identifier" }, | |
{ value: "|", type: "Pipe" }, | |
{ value: "length", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
], | |
FILTER_OPERATOR_3: [ | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "-1", type: "NumericLiteral" }, | |
{ value: "|", type: "Pipe" }, | |
{ value: "abs", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "|", type: "Pipe" }, | |
{ value: "abs", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
], | |
FILTER_OPERATOR_4: [ | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "items", type: "Identifier" }, | |
{ value: "|", type: "Pipe" }, | |
{ value: "selectattr", type: "Identifier" }, | |
{ value: "(", type: "OpenParen" }, | |
{ value: "key", type: "StringLiteral" }, | |
{ value: ")", type: "CloseParen" }, | |
{ value: "|", type: "Pipe" }, | |
{ value: "length", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
FILTER_OPERATOR_5: [ | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "messages", type: "Identifier" }, | |
{ value: "|", type: "Pipe" }, | |
{ value: "selectattr", type: "Identifier" }, | |
{ value: "(", type: "OpenParen" }, | |
{ value: "role", type: "StringLiteral" }, | |
{ value: ",", type: "Comma" }, | |
{ value: "equalto", type: "StringLiteral" }, | |
{ value: ",", type: "Comma" }, | |
{ value: "system", type: "StringLiteral" }, | |
{ value: ")", type: "CloseParen" }, | |
{ value: "|", type: "Pipe" }, | |
{ value: "length", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
FILTER_OPERATOR_6: [ | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "obj", type: "Identifier" }, | |
{ value: "|", type: "Pipe" }, | |
{ value: "length", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "(", type: "OpenParen" }, | |
{ value: "obj", type: "Identifier" }, | |
{ value: "|", type: "Pipe" }, | |
{ value: "items", type: "Identifier" }, | |
{ value: ")", type: "CloseParen" }, | |
{ value: "[", type: "OpenSquareBracket" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: ":", type: "Colon" }, | |
{ value: "]", type: "CloseSquareBracket" }, | |
{ value: "|", type: "Pipe" }, | |
{ value: "length", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
], | |
// Logical operators between non-Booleans | |
BOOLEAN_NUMERICAL: [ | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "and", type: "And" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "and", type: "And" }, | |
{ value: "0", type: "NumericLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "0", type: "NumericLiteral" }, | |
{ value: "and", type: "And" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "0", type: "NumericLiteral" }, | |
{ value: "and", type: "And" }, | |
{ value: "0", type: "NumericLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "or", type: "Or" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "or", type: "Or" }, | |
{ value: "0", type: "NumericLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "0", type: "NumericLiteral" }, | |
{ value: "or", type: "Or" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "0", type: "NumericLiteral" }, | |
{ value: "or", type: "Or" }, | |
{ value: "0", type: "NumericLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "not", type: "UnaryOperator" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "not", type: "UnaryOperator" }, | |
{ value: "0", type: "NumericLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
], | |
BOOLEAN_STRINGS: [ | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "a", type: "StringLiteral" }, | |
{ value: "and", type: "And" }, | |
{ value: "b", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "a", type: "StringLiteral" }, | |
{ value: "and", type: "And" }, | |
{ value: "", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "", type: "StringLiteral" }, | |
{ value: "and", type: "And" }, | |
{ value: "a", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "", type: "StringLiteral" }, | |
{ value: "and", type: "And" }, | |
{ value: "", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "a", type: "StringLiteral" }, | |
{ value: "or", type: "Or" }, | |
{ value: "b", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "a", type: "StringLiteral" }, | |
{ value: "or", type: "Or" }, | |
{ value: "", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "", type: "StringLiteral" }, | |
{ value: "or", type: "Or" }, | |
{ value: "a", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "", type: "StringLiteral" }, | |
{ value: "or", type: "Or" }, | |
{ value: "", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "not", type: "UnaryOperator" }, | |
{ value: "a", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "not", type: "UnaryOperator" }, | |
{ value: "", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
], | |
BOOLEAN_MIXED: [ | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "and", type: "And" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "and", type: "And" }, | |
{ value: "0", type: "NumericLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "and", type: "And" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "and", type: "And" }, | |
{ value: "0", type: "NumericLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "or", type: "Or" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "or", type: "Or" }, | |
{ value: "0", type: "NumericLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "or", type: "Or" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "or", type: "Or" }, | |
{ value: "0", type: "NumericLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
], | |
BOOLEAN_MIXED_2: [ | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "and", type: "And" }, | |
{ value: "", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "and", type: "And" }, | |
{ value: "a", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "or", type: "Or" }, | |
{ value: "", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "or", type: "Or" }, | |
{ value: "a", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "", type: "StringLiteral" }, | |
{ value: "and", type: "And" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "a", type: "StringLiteral" }, | |
{ value: "and", type: "And" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "", type: "StringLiteral" }, | |
{ value: "or", type: "Or" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "a", type: "StringLiteral" }, | |
{ value: "or", type: "Or" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
], | |
BOOLEAN_MIXED_IF: [ | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "if", type: "If" }, | |
{ value: "", type: "StringLiteral" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "A", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "endif", type: "EndIf" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "if", type: "If" }, | |
{ value: "a", type: "StringLiteral" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "B", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "endif", type: "EndIf" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "if", type: "If" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "and", type: "And" }, | |
{ value: "", type: "StringLiteral" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "C", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "endif", type: "EndIf" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "if", type: "If" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "and", type: "And" }, | |
{ value: "a", type: "StringLiteral" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "D", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "endif", type: "EndIf" }, | |
{ value: "%}", type: "CloseStatement" }, | |
], | |
// Tests (is operator) | |
IS_OPERATOR: [ | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "unknown_var", type: "Identifier" }, | |
{ value: "is", type: "Is" }, | |
{ value: "defined", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "unknown_var", type: "Identifier" }, | |
{ value: "is", type: "Is" }, | |
{ value: "not", type: "UnaryOperator" }, | |
{ value: "defined", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "known_var", type: "Identifier" }, | |
{ value: "is", type: "Is" }, | |
{ value: "defined", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "known_var", type: "Identifier" }, | |
{ value: "is", type: "Is" }, | |
{ value: "not", type: "UnaryOperator" }, | |
{ value: "defined", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
], | |
IS_OPERATOR_2: [ | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "is", type: "Is" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "is", type: "Is" }, | |
{ value: "not", type: "UnaryOperator" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "is", type: "Is" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "is", type: "Is" }, | |
{ value: "not", type: "UnaryOperator" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "is", type: "Is" }, | |
{ value: "boolean", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "is", type: "Is" }, | |
{ value: "boolean", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
], | |
IS_OPERATOR_3: [ | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "is", type: "Is" }, | |
{ value: "odd", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: "is", type: "Is" }, | |
{ value: "odd", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "is", type: "Is" }, | |
{ value: "even", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: "is", type: "Is" }, | |
{ value: "even", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: "is", type: "Is" }, | |
{ value: "number", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "2", type: "StringLiteral" }, | |
{ value: "is", type: "Is" }, | |
{ value: "number", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: "is", type: "Is" }, | |
{ value: "integer", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "2", type: "StringLiteral" }, | |
{ value: "is", type: "Is" }, | |
{ value: "integer", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
], | |
IS_OPERATOR_4: [ | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "func", type: "Identifier" }, | |
{ value: "is", type: "Is" }, | |
{ value: "callable", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: "is", type: "Is" }, | |
{ value: "callable", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "is", type: "Is" }, | |
{ value: "iterable", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "hello", type: "StringLiteral" }, | |
{ value: "is", type: "Is" }, | |
{ value: "iterable", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
], | |
IS_OPERATOR_5: [ | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "a", type: "StringLiteral" }, | |
{ value: "is", type: "Is" }, | |
{ value: "lower", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "A", type: "StringLiteral" }, | |
{ value: "is", type: "Is" }, | |
{ value: "lower", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "a", type: "StringLiteral" }, | |
{ value: "is", type: "Is" }, | |
{ value: "upper", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "A", type: "StringLiteral" }, | |
{ value: "is", type: "Is" }, | |
{ value: "upper", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
], | |
// Short-circuit evaluation | |
SHORT_CIRCUIT: [ | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "and", type: "And" }, | |
{ value: "raise_exception", type: "Identifier" }, | |
{ value: "(", type: "OpenParen" }, | |
{ value: "This should not be printed", type: "StringLiteral" }, | |
{ value: ")", type: "CloseParen" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
SHORT_CIRCUIT_1: [ | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "or", type: "Or" }, | |
{ value: "raise_exception", type: "Identifier" }, | |
{ value: "(", type: "OpenParen" }, | |
{ value: "This should not be printed", type: "StringLiteral" }, | |
{ value: ")", type: "CloseParen" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
// Namespaces | |
NAMESPACE: [ | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "set", type: "Set" }, | |
{ value: "ns", type: "Identifier" }, | |
{ value: "=", type: "Equals" }, | |
{ value: "namespace", type: "Identifier" }, | |
{ value: "(", type: "OpenParen" }, | |
{ value: ")", type: "CloseParen" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "set", type: "Set" }, | |
{ value: "ns", type: "Identifier" }, | |
{ value: ".", type: "Dot" }, | |
{ value: "foo", type: "Identifier" }, | |
{ value: "=", type: "Equals" }, | |
{ value: "bar", type: "StringLiteral" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "ns", type: "Identifier" }, | |
{ value: ".", type: "Dot" }, | |
{ value: "foo", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
NAMESPACE_1: [ | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "set", type: "Set" }, | |
{ value: "ns", type: "Identifier" }, | |
{ value: "=", type: "Equals" }, | |
{ value: "namespace", type: "Identifier" }, | |
{ value: "(", type: "OpenParen" }, | |
{ value: "default", type: "Identifier" }, | |
{ value: "=", type: "Equals" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: ")", type: "CloseParen" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "ns", type: "Identifier" }, | |
{ value: ".", type: "Dot" }, | |
{ value: "default", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
NAMESPACE_2: [ | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "set", type: "Set" }, | |
{ value: "ns", type: "Identifier" }, | |
{ value: "=", type: "Equals" }, | |
{ value: "namespace", type: "Identifier" }, | |
{ value: "(", type: "OpenParen" }, | |
{ value: "default", type: "Identifier" }, | |
{ value: "=", type: "Equals" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: ",", type: "Comma" }, | |
{ value: "number", type: "Identifier" }, | |
{ value: "=", type: "Equals" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "+", type: "AdditiveBinaryOperator" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: ")", type: "CloseParen" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "ns", type: "Identifier" }, | |
{ value: ".", type: "Dot" }, | |
{ value: "default", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "ns", type: "Identifier" }, | |
{ value: ".", type: "Dot" }, | |
{ value: "number", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
], | |
// Object operators | |
OBJECT_OPERATORS: [ | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "known", type: "StringLiteral" }, | |
{ value: "in", type: "In" }, | |
{ value: "obj", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "known", type: "StringLiteral" }, | |
{ value: "not in", type: "NotIn" }, | |
{ value: "obj", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "unknown", type: "StringLiteral" }, | |
{ value: "in", type: "In" }, | |
{ value: "obj", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "unknown", type: "StringLiteral" }, | |
{ value: "not in", type: "NotIn" }, | |
{ value: "obj", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
], | |
OBJECT_OPERATORS_1: [ | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "obj", type: "Identifier" }, | |
{ value: ".", type: "Dot" }, | |
{ value: "get", type: "Identifier" }, | |
{ value: "(", type: "OpenParen" }, | |
{ value: "known", type: "StringLiteral" }, | |
{ value: ")", type: "CloseParen" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "obj", type: "Identifier" }, | |
{ value: ".", type: "Dot" }, | |
{ value: "get", type: "Identifier" }, | |
{ value: "(", type: "OpenParen" }, | |
{ value: "unknown", type: "StringLiteral" }, | |
{ value: ")", type: "CloseParen" }, | |
{ value: "is", type: "Is" }, | |
{ value: "none", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "obj", type: "Identifier" }, | |
{ value: ".", type: "Dot" }, | |
{ value: "get", type: "Identifier" }, | |
{ value: "(", type: "OpenParen" }, | |
{ value: "unknown", type: "StringLiteral" }, | |
{ value: ")", type: "CloseParen" }, | |
{ value: "is", type: "Is" }, | |
{ value: "defined", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
], | |
OBJECT_OPERATORS_2: [ | |
{ value: "|", type: "Text" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "for", type: "For" }, | |
{ value: "x", type: "Identifier" }, | |
{ value: ",", type: "Comma" }, | |
{ value: "y", type: "Identifier" }, | |
{ value: "in", type: "In" }, | |
{ value: "obj", type: "Identifier" }, | |
{ value: ".", type: "Dot" }, | |
{ value: "items", type: "Identifier" }, | |
{ value: "(", type: "OpenParen" }, | |
{ value: ")", type: "CloseParen" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "x", type: "Identifier" }, | |
{ value: "+", type: "AdditiveBinaryOperator" }, | |
{ value: " ", type: "StringLiteral" }, | |
{ value: "+", type: "AdditiveBinaryOperator" }, | |
{ value: "y", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "endfor", type: "EndFor" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "|", type: "Text" }, | |
], | |
// Scope | |
SCOPE: [ | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "set", type: "Set" }, | |
{ value: "ns", type: "Identifier" }, | |
{ value: "=", type: "Equals" }, | |
{ value: "namespace", type: "Identifier" }, | |
{ value: "(", type: "OpenParen" }, | |
{ value: "found", type: "Identifier" }, | |
{ value: "=", type: "Equals" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: ")", type: "CloseParen" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "for", type: "For" }, | |
{ value: "num", type: "Identifier" }, | |
{ value: "in", type: "In" }, | |
{ value: "nums", type: "Identifier" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "if", type: "If" }, | |
{ value: "num", type: "Identifier" }, | |
{ value: "==", type: "ComparisonBinaryOperator" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "found=", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "set", type: "Set" }, | |
{ value: "ns", type: "Identifier" }, | |
{ value: ".", type: "Dot" }, | |
{ value: "found", type: "Identifier" }, | |
{ value: "=", type: "Equals" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "endif", type: "EndIf" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "endfor", type: "EndFor" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "ns", type: "Identifier" }, | |
{ value: ".", type: "Dot" }, | |
{ value: "found", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
SCOPE_1: [ | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "set", type: "Set" }, | |
{ value: "found", type: "Identifier" }, | |
{ value: "=", type: "Equals" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "for", type: "For" }, | |
{ value: "num", type: "Identifier" }, | |
{ value: "in", type: "In" }, | |
{ value: "nums", type: "Identifier" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "if", type: "If" }, | |
{ value: "num", type: "Identifier" }, | |
{ value: "==", type: "ComparisonBinaryOperator" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "found=", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "set", type: "Set" }, | |
{ value: "found", type: "Identifier" }, | |
{ value: "=", type: "Equals" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "endif", type: "EndIf" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{%", type: "OpenStatement" }, | |
{ value: "endfor", type: "EndFor" }, | |
{ value: "%}", type: "CloseStatement" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "found", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
// Undefined | |
UNDEFINED_VARIABLES: [ | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "undefined_variable", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
UNDEFINED_ACCESS: [ | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "object", type: "Identifier" }, | |
{ value: ".", type: "Dot" }, | |
{ value: "undefined_attribute", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
// Ternary operator | |
TERNARY_OPERATOR: [ | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "a", type: "StringLiteral" }, | |
{ value: "if", type: "If" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: "else", type: "Else" }, | |
{ value: "b", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "a", type: "StringLiteral" }, | |
{ value: "if", type: "If" }, | |
{ value: "false", type: "BooleanLiteral" }, | |
{ value: "else", type: "Else" }, | |
{ value: "b", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "a", type: "StringLiteral" }, | |
{ value: "if", type: "If" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "+", type: "AdditiveBinaryOperator" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "==", type: "ComparisonBinaryOperator" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: "else", type: "Else" }, | |
{ value: "b", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "a", type: "StringLiteral" }, | |
{ value: "if", type: "If" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "+", type: "AdditiveBinaryOperator" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "==", type: "ComparisonBinaryOperator" }, | |
{ value: "3", type: "NumericLiteral" }, | |
{ value: "or", type: "Or" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: "*", type: "MultiplicativeBinaryOperator" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: "==", type: "ComparisonBinaryOperator" }, | |
{ value: "3", type: "NumericLiteral" }, | |
{ value: "else", type: "Else" }, | |
{ value: "b", type: "StringLiteral" }, | |
{ value: "}}", type: "CloseExpression" }, | |
{ value: "|", type: "Text" }, | |
], | |
// Array literals | |
ARRAY_LITERALS: [ | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "[", type: "OpenSquareBracket" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: ",", type: "Comma" }, | |
{ value: "true", type: "BooleanLiteral" }, | |
{ value: ",", type: "Comma" }, | |
{ value: "hello", type: "StringLiteral" }, | |
{ value: ",", type: "Comma" }, | |
{ value: "[", type: "OpenSquareBracket" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: ",", type: "Comma" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: ",", type: "Comma" }, | |
{ value: "3", type: "NumericLiteral" }, | |
{ value: ",", type: "Comma" }, | |
{ value: "4", type: "NumericLiteral" }, | |
{ value: "]", type: "CloseSquareBracket" }, | |
{ value: ",", type: "Comma" }, | |
{ value: "var", type: "Identifier" }, | |
{ value: "]", type: "CloseSquareBracket" }, | |
{ value: "|", type: "Pipe" }, | |
{ value: "length", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
// Tuple literals | |
TUPLE_LITERALS: [ | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "(", type: "OpenParen" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: ",", type: "Comma" }, | |
{ value: "(", type: "OpenParen" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: ",", type: "Comma" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: ")", type: "CloseParen" }, | |
{ value: ")", type: "CloseParen" }, | |
{ value: "|", type: "Pipe" }, | |
{ value: "length", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
// Object literals | |
OBJECT_LITERALS: [ | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "{", type: "OpenCurlyBracket" }, | |
{ value: "key", type: "StringLiteral" }, | |
{ value: ":", type: "Colon" }, | |
{ value: "value", type: "StringLiteral" }, | |
{ value: ",", type: "Comma" }, | |
{ value: "key", type: "Identifier" }, | |
{ value: ":", type: "Colon" }, | |
{ value: "value2", type: "StringLiteral" }, | |
{ value: ",", type: "Comma" }, | |
{ value: "key3", type: "StringLiteral" }, | |
{ value: ":", type: "Colon" }, | |
{ value: "[", type: "OpenSquareBracket" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: ",", type: "Comma" }, | |
{ value: "{", type: "OpenCurlyBracket" }, | |
{ value: "foo", type: "StringLiteral" }, | |
{ value: ":", type: "Colon" }, | |
{ value: "bar", type: "StringLiteral" }, | |
{ value: "}", type: "CloseCurlyBracket" }, | |
{ value: "]", type: "CloseSquareBracket" }, | |
{ value: "}", type: "CloseCurlyBracket" }, | |
{ value: "[", type: "OpenSquareBracket" }, | |
{ value: "key", type: "StringLiteral" }, | |
{ value: "]", type: "CloseSquareBracket" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
// Array operators | |
ARRAY_OPERATORS: [ | |
{ value: "{{", type: "OpenExpression" }, | |
{ value: "(", type: "OpenParen" }, | |
{ value: "[", type: "OpenSquareBracket" }, | |
{ value: "1", type: "NumericLiteral" }, | |
{ value: ",", type: "Comma" }, | |
{ value: "2", type: "NumericLiteral" }, | |
{ value: ",", type: "Comma" }, | |
{ value: "3", type: "NumericLiteral" }, | |
{ value: "]", type: "CloseSquareBracket" }, | |
{ value: "+", type: "AdditiveBinaryOperator" }, | |
{ value: "[", type: "OpenSquareBracket" }, | |
{ value: "4", type: "NumericLiteral" }, | |
{ value: ",", type: "Comma" }, | |
{ value: "5", type: "NumericLiteral" }, | |
{ value: ",", type: "Comma" }, | |
{ value: "6", type: "NumericLiteral" }, | |
{ value: "]", type: "CloseSquareBracket" }, | |
{ value: ")", type: "CloseParen" }, | |
{ value: "|", type: "Pipe" }, | |
{ value: "length", type: "Identifier" }, | |
{ value: "}}", type: "CloseExpression" }, | |
], | |
}; | |
const TEST_CONTEXT = { | |
// Text nodes | |
NO_TEMPLATE: {}, | |
TEXT_NODES: {}, | |
// Logical operators | |
LOGICAL_AND: {}, | |
LOGICAL_OR: {}, | |
LOGICAL_NOT: {}, | |
LOGICAL_NOT_NOT: {}, | |
LOGICAL_AND_OR: {}, | |
LOGICAL_AND_NOT: {}, | |
LOGICAL_OR_NOT: {}, | |
LOGICAL_COMBINED: {}, | |
// If statements | |
IF_ONLY: {}, | |
IF_ELSE_ONLY: {}, | |
IF_ELIF_ELSE: {}, | |
NESTED_STATEMENTS: {}, | |
// For loops | |
FOR_LOOP: { | |
messages: [ | |
{ role: "user", content: "A" }, | |
{ role: "assistant", content: "B" }, | |
{ role: "user", content: "C" }, | |
], | |
}, | |
FOR_LOOP_UNPACKING: {}, | |
// Set variables | |
VARIABLES: {}, | |
// Numbers | |
NUMBERS: { | |
a: 0, | |
add: (x, y) => x + y, | |
}, | |
// Binary expressions | |
BINOP_EXPR: {}, | |
// Strings | |
STRINGS: { | |
bos_token: "<s>", | |
}, | |
STRINGS_1: {}, | |
STRINGS_2: {}, | |
// Function calls | |
FUNCTIONS: { | |
x: 10, | |
apple: "apple", | |
func: (...args) => args.length, | |
}, | |
// Object properties | |
PROPERTIES: { | |
obj: { x: 10, y: 20 }, | |
}, | |
// Object methods | |
OBJ_METHODS: { | |
x: "A", | |
y: "B", | |
obj: { | |
x: (...args) => args.join(""), | |
z: { | |
A: (...args) => args.join("_"), | |
}, | |
}, | |
}, | |
// String methods | |
STRING_METHODS: {}, | |
STRING_METHODS_2: {}, | |
// String indexing and slicing | |
STRING_SLICING: { | |
x: "0123456789", | |
}, | |
// Array indexing and slicing | |
ARRAY_SLICING: { | |
strings: ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"], | |
}, | |
// Membership operators | |
MEMBERSHIP: { | |
arr: [0, true, "a"], | |
}, | |
MEMBERSHIP_NEGATION_1: { | |
arr: [0, true, "a"], | |
}, | |
MEMBERSHIP_NEGATION_2: { | |
arr: [0, true, "a"], | |
}, | |
// Escaped characters | |
ESCAPED_CHARS: {}, | |
// Substring inclusion | |
SUBSTRING_INCLUSION: {}, | |
// Filter operator | |
FILTER_OPERATOR: { | |
arr: [3, 2, 1], | |
}, | |
FILTER_OPERATOR_2: {}, | |
FILTER_OPERATOR_3: {}, | |
FILTER_OPERATOR_4: { | |
items: [{ key: "a" }, { key: 0 }, { key: 1 }, {}, { key: false }], | |
}, | |
FILTER_OPERATOR_5: { | |
messages: [{ role: "system" }, { role: "user" }, { role: "assistant" }], | |
}, | |
FILTER_OPERATOR_6: { | |
obj: { a: 1, b: 2, c: 3 }, | |
}, | |
// Logical operators between non-Booleans | |
BOOLEAN_NUMERICAL: {}, | |
BOOLEAN_STRINGS: {}, | |
BOOLEAN_MIXED: {}, | |
BOOLEAN_MIXED_2: {}, | |
BOOLEAN_MIXED_IF: {}, | |
// Tests (is operator) | |
IS_OPERATOR: { | |
known_var: "Hello World", | |
}, | |
IS_OPERATOR_2: {}, | |
IS_OPERATOR_3: {}, | |
IS_OPERATOR_4: { | |
func: () => {}, | |
}, | |
IS_OPERATOR_5: {}, | |
// Short-circuit evaluation | |
SHORT_CIRCUIT: {}, | |
SHORT_CIRCUIT_1: {}, | |
// Namespaces | |
NAMESPACE: {}, | |
NAMESPACE_1: {}, | |
NAMESPACE_2: {}, | |
// Object operators | |
OBJECT_OPERATORS: { | |
obj: { | |
known: true, | |
}, | |
}, | |
OBJECT_OPERATORS_1: { | |
obj: { | |
known: true, | |
}, | |
}, | |
OBJECT_OPERATORS_2: { | |
obj: { a: 1, b: 2, c: 3 }, | |
}, | |
// Scope | |
SCOPE: { nums: [1, 2, 3] }, | |
SCOPE_1: { nums: [1, 2, 3] }, | |
// Undefined | |
UNDEFINED_VARIABLES: {}, | |
UNDEFINED_ACCESS: { object: {} }, | |
// Ternary operator | |
TERNARY_OPERATOR: {}, | |
// Array literals | |
ARRAY_LITERALS: { var: true }, | |
// Tuple literals | |
TUPLE_LITERALS: {}, | |
// Object literals | |
OBJECT_LITERALS: { | |
key: "key2", | |
}, | |
// Array operators | |
ARRAY_OPERATORS: {}, | |
}; | |
const EXPECTED_OUTPUTS = { | |
// Text nodes | |
NO_TEMPLATE: `Hello world!`, | |
TEXT_NODES: `0A1BC2D3`, | |
// Logical operators | |
LOGICAL_AND: `truefalsefalsefalse`, | |
LOGICAL_OR: `truetruetruefalse`, | |
LOGICAL_NOT: `falsetrue`, | |
LOGICAL_NOT_NOT: `truefalse`, | |
LOGICAL_AND_OR: `truetruetruetruefalse`, | |
LOGICAL_AND_NOT: `falsetruefalsefalse`, | |
LOGICAL_OR_NOT: `truetruefalsetrue`, | |
LOGICAL_COMBINED: `falsetrue`, | |
// If statements | |
IF_ONLY: "AB", | |
IF_ELSE_ONLY: "BC", | |
IF_ELIF_ELSE: "GHIJ", | |
NESTED_STATEMENTS: "2300", | |
// For loops | |
FOR_LOOP: "ABC", | |
FOR_LOOP_UNPACKING: "||1 2||3 4||", | |
// Set variables | |
VARIABLES: "Hello World", | |
// Numbers | |
NUMBERS: "|5|-5|2|-8|", | |
// Binary expressions | |
BINOP_EXPR: "1truefalsefalsetruetruetrue5", | |
// Strings | |
STRINGS: "Bye<s>[INST] ", | |
STRINGS_1: `|test|abc|"'|'|"|`, | |
STRINGS_2: `|0|1|0|1|`, | |
// Function calls | |
FUNCTIONS: "014", | |
// Object properties | |
PROPERTIES: "3030", | |
// Object methods | |
OBJ_METHODS: "AB A_B", | |
STRING_METHODS: "AB ABCD abcd ", | |
STRING_METHODS_2: "Test Test", | |
// String indexing and slicing | |
STRING_SLICING: "|0|0123456789|012|123|12345678|13579|543210|", | |
// Array indexing and slicing | |
ARRAY_SLICING: "|0|0123456789|012|123|12345678|13579|543210|", | |
// Membership operators | |
MEMBERSHIP: "|true|false|true|false|true|false|", | |
MEMBERSHIP_NEGATION_1: "|false|true|false|true|false|true|", | |
MEMBERSHIP_NEGATION_2: "|false|true|false|true|false|true|", | |
// Escaped characters | |
ESCAPED_CHARS: `\n\t'"\\|\n|\t|'|"|\\|`, | |
// Substring inclusion | |
SUBSTRING_INCLUSION: `|true|true|false|true|false|true|false|`, | |
// Filter operator | |
FILTER_OPERATOR: `3451`, | |
FILTER_OPERATOR_2: `|3|ABCD|abcd|Test test|Test Test|a b|4|`, | |
FILTER_OPERATOR_3: `|1|1|`, | |
FILTER_OPERATOR_4: `2`, | |
FILTER_OPERATOR_5: `1`, | |
FILTER_OPERATOR_6: `|3|2|`, | |
// Logical operators between non-Booleans | |
BOOLEAN_NUMERICAL: `|2|0|0|0|1|1|1|0|false|true|`, | |
BOOLEAN_STRINGS: `|b||||a|a|a||false|true|`, | |
BOOLEAN_MIXED: `|1|0|false|false|true|true|1|0|`, | |
BOOLEAN_MIXED_2: `||a||a||true|false|a|`, | |
BOOLEAN_MIXED_IF: `BD`, | |
// Tests (is operator) | |
IS_OPERATOR: `|false|true|true|false|`, | |
IS_OPERATOR_2: `|true|false|false|true|true|false|`, | |
IS_OPERATOR_3: `|true|false|false|true|true|false|true|false|`, | |
IS_OPERATOR_4: `|true|false|false|true|`, | |
IS_OPERATOR_5: `|true|false|false|true|`, | |
// Short-circuit evaluation | |
SHORT_CIRCUIT: `false`, | |
SHORT_CIRCUIT_1: `true`, | |
// Namespaces | |
NAMESPACE: `bar`, | |
NAMESPACE_1: `false`, | |
NAMESPACE_2: `|false|2|`, | |
// Object operators | |
OBJECT_OPERATORS: `|true|false|false|true|`, | |
OBJECT_OPERATORS_1: `|true|true|true|`, | |
OBJECT_OPERATORS_2: `||a 1||b 2||c 3||`, | |
// Scope | |
SCOPE: `found=true`, | |
SCOPE_1: `found=false`, | |
// Undefined | |
UNDEFINED_VARIABLES: ``, | |
UNDEFINED_ACCESS: ``, | |
// Ternary operator | |
TERNARY_OPERATOR: `|a|b|a|b|`, | |
// Array literals | |
ARRAY_LITERALS: `5`, | |
// Tuple literals | |
TUPLE_LITERALS: `2`, | |
// Object literals | |
OBJECT_LITERALS: `value`, | |
// Array operators | |
ARRAY_OPERATORS: `6`, | |
}; | |
describe("Templates", () => { | |
describe("Lexing", () => { | |
it("should tokenize an input string", () => { | |
for (const [name, text] of Object.entries(TEST_STRINGS)) { | |
const tokens = tokenize(text); | |
if (!TEST_PARSED[name]) { | |
throw new Error(`Test case "${name}" not found`); | |
} | |
if (tokens.length !== TEST_PARSED[name].length) { | |
console.log(tokens); | |
} | |
// console.log(tokens); | |
expect(tokens).toMatchObject(TEST_PARSED[name]); | |
} | |
}); | |
// TODO add failure cases | |
}); | |
describe("Parsing and intepretation", () => { | |
const AST_CACHE = new Map(); | |
it("should generate an AST", () => { | |
// NOTE: In this test case, we just check that no error occurs | |
for (const [name, text] of Object.entries(TEST_PARSED)) { | |
const ast = parse(text); | |
AST_CACHE.set(name, ast); | |
} | |
}); | |
it("should interpret an AST", () => { | |
for (const [name, ast] of AST_CACHE.entries()) { | |
if (TEST_CONTEXT[name] === undefined || EXPECTED_OUTPUTS[name] === undefined) { | |
console.warn(`Skipping test case "${name}" due to missing context or expected output`); | |
continue; | |
} | |
const env = new Environment(); | |
// Declare global variables | |
env.set("false", false); | |
env.set("true", true); | |
// Add user-defined variables | |
for (const [key, value] of Object.entries(TEST_CONTEXT[name])) { | |
env.set(key, value); | |
} | |
const interpreter = new Interpreter(env); | |
const result = interpreter.run(ast); | |
expect(result.value).toEqual(EXPECTED_OUTPUTS[name]); | |
} | |
}); | |
}); | |
}); | |
describe("Error checking", () => { | |
describe("Lexing errors", () => { | |
it("Missing closing curly brace", () => { | |
const text = "{{ variable"; | |
expect(() => tokenize(text)).toThrowError(); | |
}); | |
it("Unclosed string literal", () => { | |
const text = `{{ 'unclosed string }}`; | |
expect(() => tokenize(text)).toThrowError(); | |
}); | |
it("Unexpected character", () => { | |
const text = "{{ invalid ! invalid }}"; | |
expect(() => tokenize(text)).toThrowError(); | |
}); | |
it("Invalid quote character", () => { | |
const text = "{{ \u2018text\u2019 }}"; | |
expect(() => tokenize(text)).toThrowError(); | |
}); | |
}); | |
describe("Parsing errors", () => { | |
it("Unclosed statement", () => { | |
const text = "{{ variable }}{{"; | |
const tokens = tokenize(text); | |
expect(() => parse(tokens)).toThrowError(); | |
}); | |
it("Unclosed expression", () => { | |
const text = "{% if condition %}\n Content"; | |
const tokens = tokenize(text); | |
expect(() => parse(tokens)).toThrowError(); | |
}); | |
it("Unmatched control structure", () => { | |
const text = "{% if condition %}\n Content\n{% endif %}\n{% endfor %}"; | |
const tokens = tokenize(text); | |
expect(() => parse(tokens)).toThrowError(); | |
}); | |
it("Missing variable in for loop", () => { | |
const text = "{% for %}\n Content\n{% endfor %}"; | |
const tokens = tokenize(text); | |
expect(() => parse(tokens)).toThrowError(); | |
}); | |
it("Unclosed parentheses in expression", () => { | |
const text = "{{ (variable + 1 }}"; | |
const tokens = tokenize(text); | |
expect(() => parse(tokens)).toThrowError(); | |
}); | |
it("Invalid variable name", () => { | |
const text = "{{ 1variable }}"; | |
const tokens = tokenize(text); | |
expect(() => parse(tokens)).toThrowError(); | |
}); | |
it("Invalid control structure usage", () => { | |
const text = "{% if %}Content{% endif %}"; | |
const tokens = tokenize(text); | |
expect(() => parse(tokens)).toThrowError(); | |
}); | |
}); | |
describe("Runtime errors", () => { | |
it("Undefined function call", () => { | |
const env = new Environment(); | |
const interpreter = new Interpreter(env); | |
const tokens = tokenize("{{ undefined_function() }}"); | |
const ast = parse(tokens); | |
expect(() => interpreter.run(ast)).toThrowError(); | |
}); | |
it("Incorrect function call", () => { | |
const env = new Environment(); | |
env.set("true", true); | |
const interpreter = new Interpreter(env); | |
const tokens = tokenize("{{ true() }}"); | |
const ast = parse(tokens); | |
expect(() => interpreter.run(ast)).toThrowError(); | |
}); | |
it("Looping over non-iterable", () => { | |
const env = new Environment(); | |
const interpreter = new Interpreter(env); | |
env.set("non_iterable", 10); | |
const tokens = tokenize("{% for item in non_iterable %}{{ item }}{% endfor %}"); | |
const ast = parse(tokens); | |
expect(() => interpreter.run(ast)).toThrowError(); | |
}); | |
it("Invalid variable assignment", () => { | |
const env = new Environment(); | |
const interpreter = new Interpreter(env); | |
const tokens = tokenize("{% set 42 = variable %}"); | |
const ast = parse(tokens); | |
expect(() => interpreter.run(ast)).toThrowError(); | |
}); | |
}); | |
}); | |