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
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
|
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
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
|
-
-
+
+
-
+
-
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
+
-
-
-
+
+
+
-
-
+
-
-
+
-
-
+
+
-
+
-
-
+
+
-
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
+
-
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
+
-
-
+
+
-
-
+
-
-
-
-
+
+
+
+
-
-
+
+
|
* The four category values are LEAF, UNARY, and BINARY, explained below, and
* "uncategorized", which is used either temporarily, until context determines
* which of the other three categories is correct, or for lexemes like
* INVALID, which aren't really lexemes at all, but indicators of a parsing
* error. Note that the codes must be distinct to distinguish categories, but
* need not take the form of a bit array.
*/
#define BINARY 0x40 /* This lexeme is a binary operator. An OpNode
enum NodeCategories {
BINARY = 0x40, /* This lexeme is a binary operator. An OpNode
* representing it should go into the parse
* tree, and two operands should be parsed for
* it in the expression. */
#define UNARY 0x80 /* This lexeme is a unary operator. An OpNode
UNARY = 0x80, /* This lexeme is a unary operator. An OpNode
* representing it should go into the parse
* tree, and one operand should be parsed for
* it in the expression. */
#define LEAF 0xC0 /* This lexeme is a leaf operand in the parse
LEAF = 0xC0 /* This lexeme is a leaf operand in the parse
* tree. No OpNode will be placed in the tree
* for it. Either a literal value will be
* appended to the list of literals in this
* expression, or appropriate Tcl_Tokens will
* be appended in a Tcl_Parse struct to
* represent those leaves that require some
* form of substitution. */
};
enum TclLexemes {
/* Uncategorized lexemes */
/* Uncategorized lexemes */
#define PLUS 1 /* Ambiguous. Resolves to UNARY_PLUS or
PLUS = 1, /* Ambiguous. Resolves to UNARY_PLUS or
* BINARY_PLUS according to context. */
#define MINUS 2 /* Ambiguous. Resolves to UNARY_MINUS or
MINUS = 2, /* Ambiguous. Resolves to UNARY_MINUS or
* BINARY_MINUS according to context. */
#define BAREWORD 3 /* Ambiguous. Resolves to BOOLEAN or to
BAREWORD = 3, /* Ambiguous. Resolves to BOOLWORD or to
* FUNCTION or a parse error according to
* context and value. */
#define INCOMPLETE 4 /* A parse error. Used only when the single
INCOMPLETE = 4, /* A parse error. Used only when the single
* "=" is encountered. */
#define INVALID 5 /* A parse error. Used when any punctuation
INVALID = 5, /* A parse error. Used when any punctuation
* appears that's not a supported operator. */
#define COMMENT 6 /* Comment. Lasts to end of line or end of
COMMENT = 6, /* Comment. Lasts to end of line or end of
* expression, whichever comes first. */
/* Leaf lexemes */
/* Leaf lexemes */
#define NUMBER (LEAF | 1)
/* For literal numbers */
NUMBER = (LEAF | 1), /* For literal numbers */
#define SCRIPT (LEAF | 2)
/* Script substitution; [foo] */
SCRIPT = (LEAF | 2), /* Script substitution; [foo] */
#define BOOLEAN (LEAF | BAREWORD)
/* For literal booleans */
BOOLWORD = (LEAF | BAREWORD),/* For literal booleans (false, true, etc.) */
#define BRACED (LEAF | 4)
/* Braced string; {foo bar} */
BRACED = (LEAF | 4), /* Braced string; {foo bar} */
#define VARIABLE (LEAF | 5)
/* Variable substitution; $x */
VARIABLE = (LEAF | 5), /* Variable substitution; $x */
#define QUOTED (LEAF | 6)
/* Quoted string; "foo $bar [soom]" */
QUOTED = (LEAF | 6), /* Quoted string; "foo $bar [soom]" */
#define EMPTY (LEAF | 7)
/* Used only for an empty argument list to a
EMPTY = (LEAF | 7), /* Used only for an empty argument list to a
* function. Represents the empty string
* within parens in the expression: rand() */
/* Unary operator lexemes */
/* Unary operator lexemes */
#define UNARY_PLUS (UNARY | PLUS)
#define UNARY_MINUS (UNARY | MINUS)
#define FUNCTION (UNARY | BAREWORD)
UNARY_PLUS = (UNARY | PLUS),
UNARY_MINUS = (UNARY | MINUS),
FUNCTION = (UNARY | BAREWORD),
/* This is a bit of "creative interpretation"
* on the part of the parser. A function call
* is parsed into the parse tree according to
* the perspective that the function name is a
* unary operator and its argument list,
* enclosed in parens, is its operand. The
* additional requirements not implied
* generally by treatment as a unary operator
* -- for example, the requirement that the
* operand be enclosed in parens -- are hard
* coded in the relevant portions of
* ParseExpr(). We trade off the need to
* include such exceptional handling in the
* code against the need we would otherwise
* have for more lexeme categories. */
#define START (UNARY | 4)
/* This lexeme isn't parsed from the
START = (UNARY | 4), /* This lexeme isn't parsed from the
* expression text at all. It represents the
* start of the expression and sits at the
* root of the parse tree where it serves as
* the start/end point of traversals. */
#define OPEN_PAREN (UNARY | 5)
/* Another bit of creative interpretation,
OPEN_PAREN = (UNARY | 5), /* Another bit of creative interpretation,
* where we treat "(" as a unary operator with
* the sub-expression between it and its
* matching ")" as its operand. See
* CLOSE_PAREN below. */
#define NOT (UNARY | 6)
#define BIT_NOT (UNARY | 7)
NOT = (UNARY | 6),
BIT_NOT = (UNARY | 7),
/* Binary operator lexemes */
/* Binary operator lexemes */
#define BINARY_PLUS (BINARY | PLUS)
#define BINARY_MINUS (BINARY | MINUS)
BINARY_PLUS = (BINARY | PLUS),
BINARY_MINUS = (BINARY | MINUS),
#define COMMA (BINARY | 3)
/* The "," operator is a low precedence binary
COMMA = (BINARY | 3), /* The "," operator is a low precedence binary
* operator that separates the arguments in a
* function call. The additional constraint
* that this operator can only legally appear
* at the right places within a function call
* argument list are hard coded within
* ParseExpr(). */
#define MULT (BINARY | 4)
#define DIVIDE (BINARY | 5)
#define MOD (BINARY | 6)
#define LESS (BINARY | 7)
#define GREATER (BINARY | 8)
#define BIT_AND (BINARY | 9)
#define BIT_XOR (BINARY | 10)
#define BIT_OR (BINARY | 11)
* ParseExpr(). */
MULT = (BINARY | 4),
DIVIDE = (BINARY | 5),
MOD = (BINARY | 6),
LESS = (BINARY | 7),
GREATER = (BINARY | 8),
BIT_AND = (BINARY | 9),
BIT_XOR = (BINARY | 10),
BIT_OR = (BINARY | 11),
#define QUESTION (BINARY | 12)
/* These two lexemes make up the */
QUESTION = (BINARY | 12), /* These two lexemes make up the */
#define COLON (BINARY | 13)
/* ternary conditional operator, $x ? $y : $z.
COLON = (BINARY | 13), /* ternary conditional operator, $x ? $y : $z.
* We treat them as two binary operators to
* avoid another lexeme category, and code the
* additional constraints directly in
* ParseExpr(). For instance, the right
* operand of a "?" operator must be a ":"
* operator. */
#define LEFT_SHIFT (BINARY | 14)
#define RIGHT_SHIFT (BINARY | 15)
#define LEQ (BINARY | 16)
#define GEQ (BINARY | 17)
#define EQUAL (BINARY | 18)
#define NEQ (BINARY | 19)
#define AND (BINARY | 20)
#define OR (BINARY | 21)
#define STREQ (BINARY | 22)
#define STRNEQ (BINARY | 23)
LEFT_SHIFT = (BINARY | 14),
RIGHT_SHIFT = (BINARY | 15),
LEQ = (BINARY | 16),
GEQ = (BINARY | 17),
EQUAL = (BINARY | 18),
NEQ = (BINARY | 19),
AND = (BINARY | 20),
OR = (BINARY | 21),
STREQ = (BINARY | 22),
STRNEQ = (BINARY | 23),
#define EXPON (BINARY | 24)
/* Unlike the other binary operators, EXPON is
EXPON = (BINARY | 24), /* Unlike the other binary operators, EXPON is
* right associative and this distinction is
* coded directly in ParseExpr(). */
#define IN_LIST (BINARY | 25)
#define NOT_IN_LIST (BINARY | 26)
IN_LIST = (BINARY | 25),
NOT_IN_LIST = (BINARY | 26),
#define CLOSE_PAREN (BINARY | 27)
/* By categorizing the CLOSE_PAREN lexeme as a
CLOSE_PAREN = (BINARY | 27),/* By categorizing the CLOSE_PAREN lexeme as a
* BINARY operator, the normal parsing rules
* for binary operators assure that a close
* paren will not directly follow another
* operator, and the machinery already in
* place to connect operands to operators
* according to precedence performs most of
* the work of matching open and close parens
* for us. In the end though, a close paren is
* not really a binary operator, and some
* special coding in ParseExpr() make sure we
* never put an actual CLOSE_PAREN node in the
* parse tree. The sub-expression between
* parens becomes the single argument of the
* matching OPEN_PAREN unary operator. */
#define STR_LT (BINARY | 28)
#define STR_GT (BINARY | 29)
#define STR_LEQ (BINARY | 30)
#define STR_GEQ (BINARY | 31)
STR_LT = (BINARY | 28),
STR_GT = (BINARY | 29),
STR_LEQ = (BINARY | 30),
STR_GEQ = (BINARY | 31),
#define END (BINARY | 32)
/* This lexeme represents the end of the
END = (BINARY | 32) /* This lexeme represents the end of the
* string being parsed. Treating it as a
* binary operator follows the same logic as
* the CLOSE_PAREN lexeme and END pairs with
* START, in the same way that CLOSE_PAREN
* pairs with OPEN_PAREN. */
};
/*
* When ParseExpr() builds the parse tree it must choose which operands to
* connect to which operators. This is done according to operator precedence.
* The greater an operator's precedence the greater claim it has to link to an
* available operand. The Precedence enumeration lists the precedence values
* used by Tcl expression operators, from lowest to highest claim. Each
|