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
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
|
/*
* The constant field is a boolean flag marking which subexpressions are
* completely known at compile time, and are eligible for computing then
* rather than waiting until run time.
*/
/*
* Each lexeme belongs to one of four categories, which determine its place in
* the parse tree. We use the two high bits of the (unsigned char) value to
* store a NODE_TYPE code.
*/
#define NODE_TYPE 0xC0
/*
* 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
* 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
* 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
* 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. */
/* Uncategorized lexemes */
#define PLUS 1 /* Ambiguous. Resolves to UNARY_PLUS or
* BINARY_PLUS according to context. */
#define MINUS 2 /* Ambiguous. Resolves to UNARY_MINUS or
* BINARY_MINUS according to context. */
#define BAREWORD 3 /* Ambiguous. Resolves to BOOLEAN or to
* FUNCTION or a parse error according to
* context and value. */
#define INCOMPLETE 4 /* A parse error. Used only when the single
* "=" is encountered. */
#define 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
* expression, whichever comes first. */
/* Leaf lexemes */
#define NUMBER (LEAF | 1)
/* For literal numbers */
#define SCRIPT (LEAF | 2)
/* Script substitution; [foo] */
#define BOOLEAN (LEAF | BAREWORD)
/* For literal booleans */
#define BRACED (LEAF | 4)
/* Braced string; {foo bar} */
#define VARIABLE (LEAF | 5)
/* Variable substitution; $x */
#define QUOTED (LEAF | 6)
/* Quoted string; "foo $bar [soom]" */
#define 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 */
#define UNARY_PLUS (UNARY | PLUS)
#define UNARY_MINUS (UNARY | MINUS)
#define 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
* 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,
* 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)
/* Binary operator lexemes */
#define BINARY_PLUS (BINARY | PLUS)
#define BINARY_MINUS (BINARY | MINUS)
#define 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)
#define QUESTION (BINARY | 12)
/* These two lexemes make up the */
#define 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)
#define 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)
#define 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)
#define 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
|
<
<
<
<
<
<
<
<
>
>
>
>
>
>
>
|
|
|
>
>
|
|
|
|
|
|
|
|
<
|
<
|
<
|
<
|
<
|
<
|
<
|
|
|
|
|
<
|
<
|
|
|
|
|
|
<
|
|
|
|
|
|
|
|
<
|
|
<
|
|
|
|
|
|
|
|
|
|
|
<
|
|
|
<
|
|
|
|
|
<
|
>
|
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
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
|
/*
* The constant field is a boolean flag marking which subexpressions are
* completely known at compile time, and are eligible for computing then
* rather than waiting until run time.
*/
/*
* 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.
*/
enum LexemeTypes {
/*
* Each lexeme belongs to one of four categories, which determine its place
* in the parse tree. We use the two high bits of the (unsigned char) value
* to store a NODE_TYPE code.
*/
NODE_TYPE = 0xC0,
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. */
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. */
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 LexemeCodes {
/* Uncategorized lexemes */
PLUS = 1, /* Ambiguous. Resolves to UNARY_PLUS or
* BINARY_PLUS according to context. */
MINUS = 2, /* Ambiguous. Resolves to UNARY_MINUS or
* BINARY_MINUS according to context. */
BAREWORD = 3, /* Ambiguous. Resolves to BOOL_LIT or to
* FUNCTION or a parse error according to
* context and value. */
INCOMPLETE = 4, /* A parse error. Used only when the single
* "=" is encountered. */
INVALID = 5, /* A parse error. Used when any punctuation
* appears that's not a supported operator. */
COMMENT = 6, /* Comment. Lasts to end of line or end of
* expression, whichever comes first. */
/* Leaf lexemes */
NUMBER = LEAF | 1, /* For literal numbers */
SCRIPT = LEAF | 2, /* Script substitution; [foo] */
BOOL_LIT = LEAF | BAREWORD, /* For literal booleans */
BRACED = LEAF | 4, /* Braced string; {foo bar} */
VARIABLE = LEAF | 5, /* Variable substitution; $x */
QUOTED = LEAF | 6, /* Quoted string; "foo $bar [soom]" */
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_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. */
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. */
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. */
NOT = UNARY | 6,
BIT_NOT = UNARY | 7,
/* Binary operator lexemes */
BINARY_PLUS = BINARY | PLUS,
BINARY_MINUS = BINARY | MINUS,
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(). */
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,
QUESTION = BINARY | 12, /* These two lexemes make up the */
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. */
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,
EXPON = BINARY | 24, /* Unlike the other binary operators, EXPON is
* right associative and this distinction is
* coded directly in ParseExpr(). */
IN_LIST = BINARY | 25,
NOT_IN_LIST = BINARY | 26,
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. */
STR_LT = BINARY | 28,
STR_GT = BINARY | 29,
STR_LEQ = BINARY | 30,
STR_GEQ = BINARY | 31,
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
|