File size: 4,919 Bytes
94753b6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ca548dc
94753b6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32d7cd6
 
 
 
 
 
 
ca548dc
 
 
 
 
 
 
32d7cd6
 
 
 
 
 
 
94753b6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32d7cd6
94753b6
 
 
 
 
43f8c77
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94753b6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43f8c77
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
import type { Token } from "./lexer";

/**
 * Statements do not result in a value at runtime. They contain one or more expressions internally.
 */
export class Statement {
	type = "Statement";
}

/**
 * Defines a block which contains many statements. Each chat template corresponds to one Program.
 */
export class Program extends Statement {
	override type = "Program";

	constructor(public body: Statement[]) {
		super();
	}
}

export class If extends Statement {
	override type = "If";

	constructor(
		public test: Expression,
		public body: Statement[],
		public alternate: Statement[]
	) {
		super();
	}
}

export class For extends Statement {
	override type = "For";

	constructor(
		public loopvar: Identifier | TupleLiteral,
		public iterable: Expression,
		public body: Statement[]
	) {
		super();
	}
}

export class SetStatement extends Statement {
	override type = "Set";
	constructor(
		public assignee: Expression,
		public value: Expression
	) {
		super();
	}
}

/**
 * Expressions will result in a value at runtime (unlike statements).
 */
export class Expression extends Statement {
	override type = "Expression";
}

export class MemberExpression extends Expression {
	override type = "MemberExpression";

	constructor(
		public object: Expression,
		public property: Expression,
		public computed: boolean
	) {
		super();
	}
}

export class CallExpression extends Expression {
	override type = "CallExpression";

	constructor(
		public callee: Expression,
		public args: Expression[]
	) {
		super();
	}
}

/**
 * Represents a user-defined variable or symbol in the template.
 */
export class Identifier extends Expression {
	override type = "Identifier";

	/**
	 * @param {string} value The name of the identifier
	 */
	constructor(public value: string) {
		super();
	}
}

/**
 * Abstract base class for all Literal expressions.
 * Should not be instantiated directly.
 */
abstract class Literal<T> extends Expression {
	override type = "Literal";

	constructor(public value: T) {
		super();
	}
}

/**
 * Represents a numeric constant in the template.
 */
export class NumericLiteral extends Literal<number> {
	override type = "NumericLiteral";
}

/**
 * Represents a text constant in the template.
 */
export class StringLiteral extends Literal<string> {
	override type = "StringLiteral";
}

/**
 * Represents a boolean constant in the template.
 */
export class BooleanLiteral extends Literal<boolean> {
	override type = "BooleanLiteral";
}

/**
 * Represents an array literal in the template.
 */
export class ArrayLiteral extends Literal<Expression[]> {
	override type = "ArrayLiteral";
}

/**
 * Represents a tuple literal in the template.
 */
export class TupleLiteral extends Literal<Expression[]> {
	override type = "TupleLiteral";
}

/**
 * Represents an object literal in the template.
 */
export class ObjectLiteral extends Literal<Map<Expression, Expression>> {
	override type = "ObjectLiteral";
}

/**
 * An operation with two sides, separated by an operator.
 * Note: Either side can be a Complex Expression, with order
 * of operations being determined by the operator.
 */
export class BinaryExpression extends Expression {
	override type = "BinaryExpression";

	constructor(
		public operator: Token,
		public left: Expression,
		public right: Expression
	) {
		super();
	}
}

/**
 * An operation with two sides, separated by the | operator.
 * Operator precedence: https://github.com/pallets/jinja/issues/379#issuecomment-168076202
 */
export class FilterExpression extends Expression {
	override type = "FilterExpression";

	constructor(
		public operand: Expression,
		public filter: Identifier | CallExpression
	) {
		super();
	}
}

/**
 * An operation with two sides, separated by the "is" operator.
 */
export class TestExpression extends Expression {
	override type = "TestExpression";

	constructor(
		public operand: Expression,
		public negate: boolean,
		public test: Identifier // TODO: Add support for non-identifier tests
	) {
		super();
	}
}

/**
 * An operation with one side (operator on the left).
 */
export class UnaryExpression extends Expression {
	override type = "UnaryExpression";

	constructor(
		public operator: Token,
		public argument: Expression
	) {
		super();
	}
}

/**
 * Logical negation of an expression.
 */
export class LogicalNegationExpression extends Expression {
	override type = "LogicalNegationExpression";

	constructor(public argument: Expression) {
		super();
	}
}

export class SliceExpression extends Expression {
	override type = "SliceExpression";

	constructor(
		public start: Expression | undefined = undefined,
		public stop: Expression | undefined = undefined,
		public step: Expression | undefined = undefined
	) {
		super();
	}
}

export class KeywordArgumentExpression extends Expression {
	override type = "KeywordArgumentExpression";

	constructor(
		public key: Identifier,
		public value: Expression
	) {
		super();
	}
}