os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/generic/tclParseExpr.c
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 /* 
     2  * tclParseExpr.c --
     3  *
     4  *	This file contains procedures that parse Tcl expressions. They
     5  *	do so in a general-purpose fashion that can be used for many
     6  *	different purposes, including compilation, direct execution,
     7  *	code analysis, etc.
     8  *
     9  * Copyright (c) 1997 Sun Microsystems, Inc.
    10  * Copyright (c) 1998-2000 by Scriptics Corporation.
    11  * Portions Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiaries. All rights reserved.  
    12  * Contributions from Don Porter, NIST, 2002.  (not subject to US copyright)
    13  *
    14  * See the file "license.terms" for information on usage and redistribution
    15  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
    16  *
    17  * RCS: @(#) $Id: tclParseExpr.c,v 1.17.2.2 2005/05/20 17:19:10 vasiljevic Exp $
    18  */
    19 
    20 #include "tclInt.h"
    21 
    22 /*
    23  * The stuff below is a bit of a hack so that this file can be used in
    24  * environments that include no UNIX, i.e. no errno: just arrange to use
    25  * the errno from tclExecute.c here.
    26  */
    27 
    28 #ifndef TCL_GENERIC_ONLY
    29 #include "tclPort.h"
    30 #else
    31 #define NO_ERRNO_H
    32 #endif
    33 
    34 #ifdef NO_ERRNO_H
    35 extern int errno;			/* Use errno from tclExecute.c. */
    36 #define ERANGE 34
    37 #endif
    38 
    39 /*
    40  * Boolean variable that controls whether expression parse tracing
    41  * is enabled.
    42  */
    43 
    44 #ifdef TCL_COMPILE_DEBUG
    45 static int traceParseExpr = 0;
    46 #endif /* TCL_COMPILE_DEBUG */
    47 
    48 /*
    49  * The ParseInfo structure holds state while parsing an expression.
    50  * A pointer to an ParseInfo record is passed among the routines in
    51  * this module.
    52  */
    53 
    54 typedef struct ParseInfo {
    55     Tcl_Parse *parsePtr;	/* Points to structure to fill in with
    56 				 * information about the expression. */
    57     int lexeme;			/* Type of last lexeme scanned in expr.
    58 				 * See below for definitions. Corresponds to
    59 				 * size characters beginning at start. */
    60     CONST char *start;		/* First character in lexeme. */
    61     int size;			/* Number of bytes in lexeme. */
    62     CONST char *next;		/* Position of the next character to be
    63 				 * scanned in the expression string. */
    64     CONST char *prevEnd;	/* Points to the character just after the
    65 				 * last one in the previous lexeme. Used to
    66 				 * compute size of subexpression tokens. */
    67     CONST char *originalExpr;	/* Points to the start of the expression
    68 				 * originally passed to Tcl_ParseExpr. */
    69     CONST char *lastChar;	/* Points just after last byte of expr. */
    70 } ParseInfo;
    71 
    72 /*
    73  * Definitions of the different lexemes that appear in expressions. The
    74  * order of these must match the corresponding entries in the
    75  * operatorStrings array below.
    76  *
    77  * Basic lexemes:
    78  */
    79 
    80 #define LITERAL		0
    81 #define FUNC_NAME	1
    82 #define OPEN_BRACKET	2
    83 #define OPEN_BRACE	3
    84 #define OPEN_PAREN	4
    85 #define CLOSE_PAREN	5
    86 #define DOLLAR		6
    87 #define QUOTE		7
    88 #define COMMA		8
    89 #define END		9
    90 #define UNKNOWN		10
    91 #define UNKNOWN_CHAR	11
    92 
    93 /*
    94  * Binary numeric operators:
    95  */
    96 
    97 #define MULT		12
    98 #define DIVIDE		13
    99 #define MOD		14
   100 #define PLUS		15
   101 #define MINUS		16
   102 #define LEFT_SHIFT	17
   103 #define RIGHT_SHIFT	18
   104 #define LESS		19
   105 #define GREATER		20
   106 #define LEQ		21
   107 #define GEQ		22
   108 #define EQUAL		23
   109 #define NEQ		24
   110 #define BIT_AND		25
   111 #define BIT_XOR		26
   112 #define BIT_OR		27
   113 #define AND		28
   114 #define OR		29
   115 #define QUESTY		30
   116 #define COLON		31
   117 
   118 /*
   119  * Unary operators. Unary minus and plus are represented by the (binary)
   120  * lexemes MINUS and PLUS.
   121  */
   122 
   123 #define NOT		32
   124 #define BIT_NOT		33
   125 
   126 /*
   127  * Binary string operators:
   128  */
   129 
   130 #define STREQ		34
   131 #define STRNEQ		35
   132 
   133 /*
   134  * Mapping from lexemes to strings; used for debugging messages. These
   135  * entries must match the order and number of the lexeme definitions above.
   136  */
   137 
   138 static char *lexemeStrings[] = {
   139     "LITERAL", "FUNCNAME",
   140     "[", "{", "(", ")", "$", "\"", ",", "END", "UNKNOWN", "UNKNOWN_CHAR",
   141     "*", "/", "%", "+", "-",
   142     "<<", ">>", "<", ">", "<=", ">=", "==", "!=",
   143     "&", "^", "|", "&&", "||", "?", ":",
   144     "!", "~", "eq", "ne",
   145 };
   146 
   147 /*
   148  * Declarations for local procedures to this file:
   149  */
   150 
   151 static int		GetLexeme _ANSI_ARGS_((ParseInfo *infoPtr));
   152 static void		LogSyntaxError _ANSI_ARGS_((ParseInfo *infoPtr,
   153 				CONST char *extraInfo));
   154 static int		ParseAddExpr _ANSI_ARGS_((ParseInfo *infoPtr));
   155 static int		ParseBitAndExpr _ANSI_ARGS_((ParseInfo *infoPtr));
   156 static int		ParseBitOrExpr _ANSI_ARGS_((ParseInfo *infoPtr));
   157 static int		ParseBitXorExpr _ANSI_ARGS_((ParseInfo *infoPtr));
   158 static int		ParseCondExpr _ANSI_ARGS_((ParseInfo *infoPtr));
   159 static int		ParseEqualityExpr _ANSI_ARGS_((ParseInfo *infoPtr));
   160 static int		ParseLandExpr _ANSI_ARGS_((ParseInfo *infoPtr));
   161 static int		ParseLorExpr _ANSI_ARGS_((ParseInfo *infoPtr));
   162 static int		ParseMaxDoubleLength _ANSI_ARGS_((CONST char *string,
   163 				CONST char *end));
   164 static int		ParseMultiplyExpr _ANSI_ARGS_((ParseInfo *infoPtr));
   165 static int		ParsePrimaryExpr _ANSI_ARGS_((ParseInfo *infoPtr));
   166 static int		ParseRelationalExpr _ANSI_ARGS_((ParseInfo *infoPtr));
   167 static int		ParseShiftExpr _ANSI_ARGS_((ParseInfo *infoPtr));
   168 static int		ParseUnaryExpr _ANSI_ARGS_((ParseInfo *infoPtr));
   169 static void		PrependSubExprTokens _ANSI_ARGS_((CONST char *op,
   170 				int opBytes, CONST char *src, int srcBytes,
   171 				int firstIndex, ParseInfo *infoPtr));
   172 
   173 /*
   174  * Macro used to debug the execution of the recursive descent parser used
   175  * to parse expressions.
   176  */
   177 
   178 #ifdef TCL_COMPILE_DEBUG
   179 #define HERE(production, level) \
   180     if (traceParseExpr) { \
   181 	fprintf(stderr, "%*s%s: lexeme=%s, next=\"%.20s\"\n", \
   182 		(level), " ", (production), \
   183 		lexemeStrings[infoPtr->lexeme], infoPtr->next); \
   184     }
   185 #else
   186 #define HERE(production, level)
   187 #endif /* TCL_COMPILE_DEBUG */
   188 
   189 /*
   190  *----------------------------------------------------------------------
   191  *
   192  * Tcl_ParseExpr --
   193  *
   194  *	Given a string, this procedure parses the first Tcl expression
   195  *	in the string and returns information about the structure of
   196  *	the expression. This procedure is the top-level interface to the
   197  *	the expression parsing module.  No more that numBytes bytes will
   198  *	be scanned.
   199  *
   200  * Results:
   201  *	The return value is TCL_OK if the command was parsed successfully
   202  *	and TCL_ERROR otherwise. If an error occurs and interp isn't NULL
   203  *	then an error message is left in its result. On a successful return,
   204  *	parsePtr is filled in with information about the expression that 
   205  *	was parsed.
   206  *
   207  * Side effects:
   208  *	If there is insufficient space in parsePtr to hold all the
   209  *	information about the expression, then additional space is
   210  *	malloc-ed. If the procedure returns TCL_OK then the caller must
   211  *	eventually invoke Tcl_FreeParse to release any additional space
   212  *	that was allocated.
   213  *
   214  *----------------------------------------------------------------------
   215  */
   216 
   217 EXPORT_C int
   218 Tcl_ParseExpr(interp, string, numBytes, parsePtr)
   219     Tcl_Interp *interp;		/* Used for error reporting. */
   220     CONST char *string;		/* The source string to parse. */
   221     int numBytes;		/* Number of bytes in string. If < 0, the
   222 				 * string consists of all bytes up to the
   223 				 * first null character. */
   224     Tcl_Parse *parsePtr;	/* Structure to fill with information about
   225 				 * the parsed expression; any previous
   226 				 * information in the structure is
   227 				 * ignored. */
   228 {
   229     ParseInfo info;
   230     int code;
   231 
   232     if (numBytes < 0) {
   233 	numBytes = (string? strlen(string) : 0);
   234     }
   235 #ifdef TCL_COMPILE_DEBUG
   236     if (traceParseExpr) {
   237 	fprintf(stderr, "Tcl_ParseExpr: string=\"%.*s\"\n",
   238 	        numBytes, string);
   239     }
   240 #endif /* TCL_COMPILE_DEBUG */
   241     
   242     parsePtr->commentStart = NULL;
   243     parsePtr->commentSize = 0;
   244     parsePtr->commandStart = NULL;
   245     parsePtr->commandSize = 0;
   246     parsePtr->numWords = 0;
   247     parsePtr->tokenPtr = parsePtr->staticTokens;
   248     parsePtr->numTokens = 0;
   249     parsePtr->tokensAvailable = NUM_STATIC_TOKENS;
   250     parsePtr->string = string;
   251     parsePtr->end = (string + numBytes);
   252     parsePtr->interp = interp;
   253     parsePtr->term = string;
   254     parsePtr->incomplete = 0;
   255 
   256     /*
   257      * Initialize the ParseInfo structure that holds state while parsing
   258      * the expression.
   259      */
   260 
   261     info.parsePtr = parsePtr;
   262     info.lexeme = UNKNOWN;
   263     info.start = NULL;
   264     info.size = 0;
   265     info.next = string;
   266     info.prevEnd = string;
   267     info.originalExpr = string;
   268     info.lastChar = (string + numBytes); /* just after last char of expr */
   269 
   270     /*
   271      * Get the first lexeme then parse the expression.
   272      */
   273 
   274     code = GetLexeme(&info);
   275     if (code != TCL_OK) {
   276 	goto error;
   277     }
   278     code = ParseCondExpr(&info);
   279     if (code != TCL_OK) {
   280 	goto error;
   281     }
   282     if (info.lexeme != END) {
   283 	LogSyntaxError(&info, "extra tokens at end of expression");
   284 	goto error;
   285     }
   286     return TCL_OK;
   287     
   288     error:
   289     if (parsePtr->tokenPtr != parsePtr->staticTokens) {
   290 	ckfree((char *) parsePtr->tokenPtr);
   291     }
   292     return TCL_ERROR;
   293 }
   294 
   295 /*
   296  *----------------------------------------------------------------------
   297  *
   298  * ParseCondExpr --
   299  *
   300  *	This procedure parses a Tcl conditional expression:
   301  *	condExpr ::= lorExpr ['?' condExpr ':' condExpr]
   302  *
   303  *	Note that this is the topmost recursive-descent parsing routine used
   304  *	by Tcl_ParseExpr to parse expressions. This avoids an extra procedure
   305  *	call since such a procedure would only return the result of calling
   306  *	ParseCondExpr. Other recursive-descent procedures that need to parse
   307  *	complete expressions also call ParseCondExpr.
   308  *
   309  * Results:
   310  *	The return value is TCL_OK on a successful parse and TCL_ERROR
   311  *	on failure. If TCL_ERROR is returned, then the interpreter's result
   312  *	contains an error message.
   313  *
   314  * Side effects:
   315  *	If there is insufficient space in parsePtr to hold all the
   316  *	information about the subexpression, then additional space is
   317  *	malloc-ed.
   318  *
   319  *----------------------------------------------------------------------
   320  */
   321 
   322 static int
   323 ParseCondExpr(infoPtr)
   324     ParseInfo *infoPtr;		/* Holds the parse state for the
   325 				 * expression being parsed. */
   326 {
   327     Tcl_Parse *parsePtr = infoPtr->parsePtr;
   328     Tcl_Token *tokenPtr, *firstTokenPtr, *condTokenPtr;
   329     int firstIndex, numToMove, code;
   330     CONST char *srcStart;
   331     
   332     HERE("condExpr", 1);
   333     srcStart = infoPtr->start;
   334     firstIndex = parsePtr->numTokens;
   335     
   336     code = ParseLorExpr(infoPtr);
   337     if (code != TCL_OK) {
   338 	return code;
   339     }
   340     
   341     if (infoPtr->lexeme == QUESTY) {
   342 	/*
   343 	 * Emit two tokens: one TCL_TOKEN_SUB_EXPR token for the entire
   344 	 * conditional expression, and a TCL_TOKEN_OPERATOR token for 
   345 	 * the "?" operator. Note that these two tokens must be inserted
   346 	 * before the LOR operand tokens generated above.
   347 	 */
   348 
   349 	if ((parsePtr->numTokens + 1) >= parsePtr->tokensAvailable) {
   350 	    TclExpandTokenArray(parsePtr);
   351 	}
   352 	firstTokenPtr = &parsePtr->tokenPtr[firstIndex];
   353 	tokenPtr = (firstTokenPtr + 2);
   354 	numToMove = (parsePtr->numTokens - firstIndex);
   355 	memmove((VOID *) tokenPtr, (VOID *) firstTokenPtr,
   356 	        (size_t) (numToMove * sizeof(Tcl_Token)));
   357 	parsePtr->numTokens += 2;
   358 	
   359 	tokenPtr = firstTokenPtr;
   360 	tokenPtr->type = TCL_TOKEN_SUB_EXPR;
   361 	tokenPtr->start = srcStart;
   362 	
   363 	tokenPtr++;
   364 	tokenPtr->type = TCL_TOKEN_OPERATOR;
   365 	tokenPtr->start = infoPtr->start;
   366 	tokenPtr->size = 1;
   367 	tokenPtr->numComponents = 0;
   368     
   369 	/*
   370 	 * Skip over the '?'.
   371 	 */
   372 	
   373 	code = GetLexeme(infoPtr); 
   374 	if (code != TCL_OK) {
   375 	    return code;
   376 	}
   377 
   378 	/*
   379 	 * Parse the "then" expression.
   380 	 */
   381 
   382 	code = ParseCondExpr(infoPtr);
   383 	if (code != TCL_OK) {
   384 	    return code;
   385 	}
   386 	if (infoPtr->lexeme != COLON) {
   387 	    LogSyntaxError(infoPtr, "missing colon from ternary conditional");
   388 	    return TCL_ERROR;
   389 	}
   390 	code = GetLexeme(infoPtr); /* skip over the ':' */
   391 	if (code != TCL_OK) {
   392 	    return code;
   393 	}
   394 
   395 	/*
   396 	 * Parse the "else" expression.
   397 	 */
   398 
   399 	code = ParseCondExpr(infoPtr);
   400 	if (code != TCL_OK) {
   401 	    return code;
   402 	}
   403 
   404 	/*
   405 	 * Now set the size-related fields in the '?' subexpression token.
   406 	 */
   407 
   408 	condTokenPtr = &parsePtr->tokenPtr[firstIndex];
   409 	condTokenPtr->size = (infoPtr->prevEnd - srcStart);
   410 	condTokenPtr->numComponents = parsePtr->numTokens - (firstIndex+1);
   411     }
   412     return TCL_OK;
   413 }
   414 
   415 /*
   416  *----------------------------------------------------------------------
   417  *
   418  * ParseLorExpr --
   419  *
   420  *	This procedure parses a Tcl logical or expression:
   421  *	lorExpr ::= landExpr {'||' landExpr}
   422  *
   423  * Results:
   424  *	The return value is TCL_OK on a successful parse and TCL_ERROR
   425  *	on failure. If TCL_ERROR is returned, then the interpreter's result
   426  *	contains an error message.
   427  *
   428  * Side effects:
   429  *	If there is insufficient space in parsePtr to hold all the
   430  *	information about the subexpression, then additional space is
   431  *	malloc-ed.
   432  *
   433  *----------------------------------------------------------------------
   434  */
   435 
   436 static int
   437 ParseLorExpr(infoPtr)
   438     ParseInfo *infoPtr;		/* Holds the parse state for the
   439 				 * expression being parsed. */
   440 {
   441     Tcl_Parse *parsePtr = infoPtr->parsePtr;
   442     int firstIndex, code;
   443     CONST char *srcStart, *operator;
   444     
   445     HERE("lorExpr", 2);
   446     srcStart = infoPtr->start;
   447     firstIndex = parsePtr->numTokens;
   448     
   449     code = ParseLandExpr(infoPtr);
   450     if (code != TCL_OK) {
   451 	return code;
   452     }
   453 
   454     while (infoPtr->lexeme == OR) {
   455 	operator = infoPtr->start;
   456 	code = GetLexeme(infoPtr); /* skip over the '||' */
   457 	if (code != TCL_OK) {
   458 	    return code;
   459 	}
   460 	code = ParseLandExpr(infoPtr);
   461 	if (code != TCL_OK) {
   462 	    return code;
   463 	}
   464 
   465 	/*
   466 	 * Generate tokens for the LOR subexpression and the '||' operator.
   467 	 */
   468 
   469 	PrependSubExprTokens(operator, 2, srcStart,
   470 	        (infoPtr->prevEnd - srcStart), firstIndex, infoPtr);
   471     }
   472     return TCL_OK;
   473 }
   474 
   475 /*
   476  *----------------------------------------------------------------------
   477  *
   478  * ParseLandExpr --
   479  *
   480  *	This procedure parses a Tcl logical and expression:
   481  *	landExpr ::= bitOrExpr {'&&' bitOrExpr}
   482  *
   483  * Results:
   484  *	The return value is TCL_OK on a successful parse and TCL_ERROR
   485  *	on failure. If TCL_ERROR is returned, then the interpreter's result
   486  *	contains an error message.
   487  *
   488  * Side effects:
   489  *	If there is insufficient space in parsePtr to hold all the
   490  *	information about the subexpression, then additional space is
   491  *	malloc-ed.
   492  *
   493  *----------------------------------------------------------------------
   494  */
   495 
   496 static int
   497 ParseLandExpr(infoPtr)
   498     ParseInfo *infoPtr;		/* Holds the parse state for the
   499 				 * expression being parsed. */
   500 {
   501     Tcl_Parse *parsePtr = infoPtr->parsePtr;
   502     int firstIndex, code;
   503     CONST char *srcStart, *operator;
   504 
   505     HERE("landExpr", 3);
   506     srcStart = infoPtr->start;
   507     firstIndex = parsePtr->numTokens;
   508     
   509     code = ParseBitOrExpr(infoPtr);
   510     if (code != TCL_OK) {
   511 	return code;
   512     }
   513 
   514     while (infoPtr->lexeme == AND) {
   515 	operator = infoPtr->start;
   516 	code = GetLexeme(infoPtr); /* skip over the '&&' */
   517 	if (code != TCL_OK) {
   518 	    return code;
   519 	}
   520 	code = ParseBitOrExpr(infoPtr);
   521 	if (code != TCL_OK) {
   522 	    return code;
   523 	}
   524 
   525 	/*
   526 	 * Generate tokens for the LAND subexpression and the '&&' operator.
   527 	 */
   528 
   529 	PrependSubExprTokens(operator, 2, srcStart,
   530 	        (infoPtr->prevEnd - srcStart), firstIndex, infoPtr);
   531     }
   532     return TCL_OK;
   533 }
   534 
   535 /*
   536  *----------------------------------------------------------------------
   537  *
   538  * ParseBitOrExpr --
   539  *
   540  *	This procedure parses a Tcl bitwise or expression:
   541  *	bitOrExpr ::= bitXorExpr {'|' bitXorExpr}
   542  *
   543  * Results:
   544  *	The return value is TCL_OK on a successful parse and TCL_ERROR
   545  *	on failure. If TCL_ERROR is returned, then the interpreter's result
   546  *	contains an error message.
   547  *
   548  * Side effects:
   549  *	If there is insufficient space in parsePtr to hold all the
   550  *	information about the subexpression, then additional space is
   551  *	malloc-ed.
   552  *
   553  *----------------------------------------------------------------------
   554  */
   555 
   556 static int
   557 ParseBitOrExpr(infoPtr)
   558     ParseInfo *infoPtr;		/* Holds the parse state for the
   559 				 * expression being parsed. */
   560 {
   561     Tcl_Parse *parsePtr = infoPtr->parsePtr;
   562     int firstIndex, code;
   563     CONST char *srcStart, *operator;
   564 
   565     HERE("bitOrExpr", 4);
   566     srcStart = infoPtr->start;
   567     firstIndex = parsePtr->numTokens;
   568     
   569     code = ParseBitXorExpr(infoPtr);
   570     if (code != TCL_OK) {
   571 	return code;
   572     }
   573     
   574     while (infoPtr->lexeme == BIT_OR) {
   575 	operator = infoPtr->start;
   576 	code = GetLexeme(infoPtr); /* skip over the '|' */
   577 	if (code != TCL_OK) {
   578 	    return code;
   579 	}
   580 
   581 	code = ParseBitXorExpr(infoPtr);
   582 	if (code != TCL_OK) {
   583 	    return code;
   584 	}
   585 	
   586 	/*
   587 	 * Generate tokens for the BITOR subexpression and the '|' operator.
   588 	 */
   589 
   590 	PrependSubExprTokens(operator, 1, srcStart,
   591 	        (infoPtr->prevEnd - srcStart), firstIndex, infoPtr);
   592     }
   593     return TCL_OK;
   594 }
   595 
   596 /*
   597  *----------------------------------------------------------------------
   598  *
   599  * ParseBitXorExpr --
   600  *
   601  *	This procedure parses a Tcl bitwise exclusive or expression:
   602  *	bitXorExpr ::= bitAndExpr {'^' bitAndExpr}
   603  *
   604  * Results:
   605  *	The return value is TCL_OK on a successful parse and TCL_ERROR
   606  *	on failure. If TCL_ERROR is returned, then the interpreter's result
   607  *	contains an error message.
   608  *
   609  * Side effects:
   610  *	If there is insufficient space in parsePtr to hold all the
   611  *	information about the subexpression, then additional space is
   612  *	malloc-ed.
   613  *
   614  *----------------------------------------------------------------------
   615  */
   616 
   617 static int
   618 ParseBitXorExpr(infoPtr)
   619     ParseInfo *infoPtr;		/* Holds the parse state for the
   620 				 * expression being parsed. */
   621 {
   622     Tcl_Parse *parsePtr = infoPtr->parsePtr;
   623     int firstIndex, code;
   624     CONST char *srcStart, *operator;
   625 
   626     HERE("bitXorExpr", 5);
   627     srcStart = infoPtr->start;
   628     firstIndex = parsePtr->numTokens;
   629     
   630     code = ParseBitAndExpr(infoPtr);
   631     if (code != TCL_OK) {
   632 	return code;
   633     }
   634     
   635     while (infoPtr->lexeme == BIT_XOR) {
   636 	operator = infoPtr->start;
   637 	code = GetLexeme(infoPtr); /* skip over the '^' */
   638 	if (code != TCL_OK) {
   639 	    return code;
   640 	}
   641 
   642 	code = ParseBitAndExpr(infoPtr);
   643 	if (code != TCL_OK) {
   644 	    return code;
   645 	}
   646 	
   647 	/*
   648 	 * Generate tokens for the XOR subexpression and the '^' operator.
   649 	 */
   650 
   651 	PrependSubExprTokens(operator, 1, srcStart,
   652 	        (infoPtr->prevEnd - srcStart), firstIndex, infoPtr);
   653     }
   654     return TCL_OK;
   655 }
   656 
   657 /*
   658  *----------------------------------------------------------------------
   659  *
   660  * ParseBitAndExpr --
   661  *
   662  *	This procedure parses a Tcl bitwise and expression:
   663  *	bitAndExpr ::= equalityExpr {'&' equalityExpr}
   664  *
   665  * Results:
   666  *	The return value is TCL_OK on a successful parse and TCL_ERROR
   667  *	on failure. If TCL_ERROR is returned, then the interpreter's result
   668  *	contains an error message.
   669  *
   670  * Side effects:
   671  *	If there is insufficient space in parsePtr to hold all the
   672  *	information about the subexpression, then additional space is
   673  *	malloc-ed.
   674  *
   675  *----------------------------------------------------------------------
   676  */
   677 
   678 static int
   679 ParseBitAndExpr(infoPtr)
   680     ParseInfo *infoPtr;		/* Holds the parse state for the
   681 				 * expression being parsed. */
   682 {
   683     Tcl_Parse *parsePtr = infoPtr->parsePtr;
   684     int firstIndex, code;
   685     CONST char *srcStart, *operator;
   686 
   687     HERE("bitAndExpr", 6);
   688     srcStart = infoPtr->start;
   689     firstIndex = parsePtr->numTokens;
   690     
   691     code = ParseEqualityExpr(infoPtr);
   692     if (code != TCL_OK) {
   693 	return code;
   694     }
   695     
   696     while (infoPtr->lexeme == BIT_AND) {
   697 	operator = infoPtr->start;
   698 	code = GetLexeme(infoPtr); /* skip over the '&' */
   699 	if (code != TCL_OK) {
   700 	    return code;
   701 	}
   702 	code = ParseEqualityExpr(infoPtr);
   703 	if (code != TCL_OK) {
   704 	    return code;
   705 	}
   706 	
   707 	/*
   708 	 * Generate tokens for the BITAND subexpression and '&' operator.
   709 	 */
   710 
   711 	PrependSubExprTokens(operator, 1, srcStart,
   712 	        (infoPtr->prevEnd - srcStart), firstIndex, infoPtr);
   713     }
   714     return TCL_OK;
   715 }
   716 
   717 /*
   718  *----------------------------------------------------------------------
   719  *
   720  * ParseEqualityExpr --
   721  *
   722  *	This procedure parses a Tcl equality (inequality) expression:
   723  *	equalityExpr ::= relationalExpr
   724  *		{('==' | '!=' | 'ne' | 'eq') relationalExpr}
   725  *
   726  * Results:
   727  *	The return value is TCL_OK on a successful parse and TCL_ERROR
   728  *	on failure. If TCL_ERROR is returned, then the interpreter's result
   729  *	contains an error message.
   730  *
   731  * Side effects:
   732  *	If there is insufficient space in parsePtr to hold all the
   733  *	information about the subexpression, then additional space is
   734  *	malloc-ed.
   735  *
   736  *----------------------------------------------------------------------
   737  */
   738 
   739 static int
   740 ParseEqualityExpr(infoPtr)
   741     ParseInfo *infoPtr;		/* Holds the parse state for the
   742 				 * expression being parsed. */
   743 {
   744     Tcl_Parse *parsePtr = infoPtr->parsePtr;
   745     int firstIndex, lexeme, code;
   746     CONST char *srcStart, *operator;
   747 
   748     HERE("equalityExpr", 7);
   749     srcStart = infoPtr->start;
   750     firstIndex = parsePtr->numTokens;
   751     
   752     code = ParseRelationalExpr(infoPtr);
   753     if (code != TCL_OK) {
   754 	return code;
   755     }
   756 
   757     lexeme = infoPtr->lexeme;
   758     while ((lexeme == EQUAL) || (lexeme == NEQ)
   759 	    || (lexeme == STREQ) || (lexeme == STRNEQ)) {
   760 	operator = infoPtr->start;
   761 	code = GetLexeme(infoPtr); /* skip over ==, !=, 'eq' or 'ne'  */
   762 	if (code != TCL_OK) {
   763 	    return code;
   764 	}
   765 	code = ParseRelationalExpr(infoPtr);
   766 	if (code != TCL_OK) {
   767 	    return code;
   768 	}
   769 
   770 	/*
   771 	 * Generate tokens for the subexpression and '==', '!=', 'eq' or 'ne'
   772 	 * operator.
   773 	 */
   774 
   775 	PrependSubExprTokens(operator, 2, srcStart,
   776 	        (infoPtr->prevEnd - srcStart), firstIndex, infoPtr);
   777 	lexeme = infoPtr->lexeme;
   778     }
   779     return TCL_OK;
   780 }
   781 
   782 /*
   783  *----------------------------------------------------------------------
   784  *
   785  * ParseRelationalExpr --
   786  *
   787  *	This procedure parses a Tcl relational expression:
   788  *	relationalExpr ::= shiftExpr {('<' | '>' | '<=' | '>=') shiftExpr}
   789  *
   790  * Results:
   791  *	The return value is TCL_OK on a successful parse and TCL_ERROR
   792  *	on failure. If TCL_ERROR is returned, then the interpreter's result
   793  *	contains an error message.
   794  *
   795  * Side effects:
   796  *	If there is insufficient space in parsePtr to hold all the
   797  *	information about the subexpression, then additional space is
   798  *	malloc-ed.
   799  *
   800  *----------------------------------------------------------------------
   801  */
   802 
   803 static int
   804 ParseRelationalExpr(infoPtr)
   805     ParseInfo *infoPtr;		/* Holds the parse state for the
   806 				 * expression being parsed. */
   807 {
   808     Tcl_Parse *parsePtr = infoPtr->parsePtr;
   809     int firstIndex, lexeme, operatorSize, code;
   810     CONST char *srcStart, *operator;
   811 
   812     HERE("relationalExpr", 8);
   813     srcStart = infoPtr->start;
   814     firstIndex = parsePtr->numTokens;
   815     
   816     code = ParseShiftExpr(infoPtr);
   817     if (code != TCL_OK) {
   818 	return code;
   819     }
   820 
   821     lexeme = infoPtr->lexeme;
   822     while ((lexeme == LESS) || (lexeme == GREATER) || (lexeme == LEQ)
   823             || (lexeme == GEQ)) {
   824 	operator = infoPtr->start;
   825 	if ((lexeme == LEQ) || (lexeme == GEQ)) {
   826 	    operatorSize = 2;
   827 	} else {
   828 	    operatorSize = 1;
   829 	}
   830 	code = GetLexeme(infoPtr); /* skip over the operator */
   831 	if (code != TCL_OK) {
   832 	    return code;
   833 	}
   834 	code = ParseShiftExpr(infoPtr);
   835 	if (code != TCL_OK) {
   836 	    return code;
   837 	}
   838 
   839 	/*
   840 	 * Generate tokens for the subexpression and the operator.
   841 	 */
   842 
   843 	PrependSubExprTokens(operator, operatorSize, srcStart,
   844 	        (infoPtr->prevEnd - srcStart), firstIndex, infoPtr);
   845 	lexeme = infoPtr->lexeme;
   846     }
   847     return TCL_OK;
   848 }
   849 
   850 /*
   851  *----------------------------------------------------------------------
   852  *
   853  * ParseShiftExpr --
   854  *
   855  *	This procedure parses a Tcl shift expression:
   856  *	shiftExpr ::= addExpr {('<<' | '>>') addExpr}
   857  *
   858  * Results:
   859  *	The return value is TCL_OK on a successful parse and TCL_ERROR
   860  *	on failure. If TCL_ERROR is returned, then the interpreter's result
   861  *	contains an error message.
   862  *
   863  * Side effects:
   864  *	If there is insufficient space in parsePtr to hold all the
   865  *	information about the subexpression, then additional space is
   866  *	malloc-ed.
   867  *
   868  *----------------------------------------------------------------------
   869  */
   870 
   871 static int
   872 ParseShiftExpr(infoPtr)
   873     ParseInfo *infoPtr;		/* Holds the parse state for the
   874 				 * expression being parsed. */
   875 {
   876     Tcl_Parse *parsePtr = infoPtr->parsePtr;
   877     int firstIndex, lexeme, code;
   878     CONST char *srcStart, *operator;
   879 
   880     HERE("shiftExpr", 9);
   881     srcStart = infoPtr->start;
   882     firstIndex = parsePtr->numTokens;
   883     
   884     code = ParseAddExpr(infoPtr);
   885     if (code != TCL_OK) {
   886 	return code;
   887     }
   888 
   889     lexeme = infoPtr->lexeme;
   890     while ((lexeme == LEFT_SHIFT) || (lexeme == RIGHT_SHIFT)) {
   891 	operator = infoPtr->start;
   892 	code = GetLexeme(infoPtr); /* skip over << or >> */
   893 	if (code != TCL_OK) {
   894 	    return code;
   895 	}
   896 	code = ParseAddExpr(infoPtr);
   897 	if (code != TCL_OK) {
   898 	    return code;
   899 	}
   900 
   901 	/*
   902 	 * Generate tokens for the subexpression and '<<' or '>>' operator.
   903 	 */
   904 
   905 	PrependSubExprTokens(operator, 2, srcStart,
   906 	        (infoPtr->prevEnd - srcStart), firstIndex, infoPtr);
   907 	lexeme = infoPtr->lexeme;
   908     }
   909     return TCL_OK;
   910 }
   911 
   912 /*
   913  *----------------------------------------------------------------------
   914  *
   915  * ParseAddExpr --
   916  *
   917  *	This procedure parses a Tcl addition expression:
   918  *	addExpr ::= multiplyExpr {('+' | '-') multiplyExpr}
   919  *
   920  * Results:
   921  *	The return value is TCL_OK on a successful parse and TCL_ERROR
   922  *	on failure. If TCL_ERROR is returned, then the interpreter's result
   923  *	contains an error message.
   924  *
   925  * Side effects:
   926  *	If there is insufficient space in parsePtr to hold all the
   927  *	information about the subexpression, then additional space is
   928  *	malloc-ed.
   929  *
   930  *----------------------------------------------------------------------
   931  */
   932 
   933 static int
   934 ParseAddExpr(infoPtr)
   935     ParseInfo *infoPtr;		/* Holds the parse state for the
   936 				 * expression being parsed. */
   937 {
   938     Tcl_Parse *parsePtr = infoPtr->parsePtr;
   939     int firstIndex, lexeme, code;
   940     CONST char *srcStart, *operator;
   941 
   942     HERE("addExpr", 10);
   943     srcStart = infoPtr->start;
   944     firstIndex = parsePtr->numTokens;
   945     
   946     code = ParseMultiplyExpr(infoPtr);
   947     if (code != TCL_OK) {
   948 	return code;
   949     }
   950 
   951     lexeme = infoPtr->lexeme;
   952     while ((lexeme == PLUS) || (lexeme == MINUS)) {
   953 	operator = infoPtr->start;
   954 	code = GetLexeme(infoPtr); /* skip over + or - */
   955 	if (code != TCL_OK) {
   956 	    return code;
   957 	}
   958 	code = ParseMultiplyExpr(infoPtr);
   959 	if (code != TCL_OK) {
   960 	    return code;
   961 	}
   962 
   963 	/*
   964 	 * Generate tokens for the subexpression and '+' or '-' operator.
   965 	 */
   966 
   967 	PrependSubExprTokens(operator, 1, srcStart,
   968 	        (infoPtr->prevEnd - srcStart), firstIndex, infoPtr);
   969 	lexeme = infoPtr->lexeme;
   970     }
   971     return TCL_OK;
   972 }
   973 
   974 /*
   975  *----------------------------------------------------------------------
   976  *
   977  * ParseMultiplyExpr --
   978  *
   979  *	This procedure parses a Tcl multiply expression:
   980  *	multiplyExpr ::= unaryExpr {('*' | '/' | '%') unaryExpr}
   981  *
   982  * Results:
   983  *	The return value is TCL_OK on a successful parse and TCL_ERROR
   984  *	on failure. If TCL_ERROR is returned, then the interpreter's result
   985  *	contains an error message.
   986  *
   987  * Side effects:
   988  *	If there is insufficient space in parsePtr to hold all the
   989  *	information about the subexpression, then additional space is
   990  *	malloc-ed.
   991  *
   992  *----------------------------------------------------------------------
   993  */
   994 
   995 static int
   996 ParseMultiplyExpr(infoPtr)
   997     ParseInfo *infoPtr;		/* Holds the parse state for the
   998 				 * expression being parsed. */
   999 {
  1000     Tcl_Parse *parsePtr = infoPtr->parsePtr;
  1001     int firstIndex, lexeme, code;
  1002     CONST char *srcStart, *operator;
  1003 
  1004     HERE("multiplyExpr", 11);
  1005     srcStart = infoPtr->start;
  1006     firstIndex = parsePtr->numTokens;
  1007     
  1008     code = ParseUnaryExpr(infoPtr);
  1009     if (code != TCL_OK) {
  1010 	return code;
  1011     }
  1012 
  1013     lexeme = infoPtr->lexeme;
  1014     while ((lexeme == MULT) || (lexeme == DIVIDE) || (lexeme == MOD)) {
  1015 	operator = infoPtr->start;
  1016 	code = GetLexeme(infoPtr); /* skip over * or / or % */
  1017 	if (code != TCL_OK) {
  1018 	    return code;
  1019 	}
  1020 	code = ParseUnaryExpr(infoPtr);
  1021 	if (code != TCL_OK) {
  1022 	    return code;
  1023 	}
  1024 
  1025 	/*
  1026 	 * Generate tokens for the subexpression and * or / or % operator.
  1027 	 */
  1028 
  1029 	PrependSubExprTokens(operator, 1, srcStart,
  1030 	        (infoPtr->prevEnd - srcStart), firstIndex, infoPtr);
  1031 	lexeme = infoPtr->lexeme;
  1032     }
  1033     return TCL_OK;
  1034 }
  1035 
  1036 /*
  1037  *----------------------------------------------------------------------
  1038  *
  1039  * ParseUnaryExpr --
  1040  *
  1041  *	This procedure parses a Tcl unary expression:
  1042  *	unaryExpr ::= ('+' | '-' | '~' | '!') unaryExpr | primaryExpr
  1043  *
  1044  * Results:
  1045  *	The return value is TCL_OK on a successful parse and TCL_ERROR
  1046  *	on failure. If TCL_ERROR is returned, then the interpreter's result
  1047  *	contains an error message.
  1048  *
  1049  * Side effects:
  1050  *	If there is insufficient space in parsePtr to hold all the
  1051  *	information about the subexpression, then additional space is
  1052  *	malloc-ed.
  1053  *
  1054  *----------------------------------------------------------------------
  1055  */
  1056 
  1057 static int
  1058 ParseUnaryExpr(infoPtr)
  1059     ParseInfo *infoPtr;		/* Holds the parse state for the
  1060 				 * expression being parsed. */
  1061 {
  1062     Tcl_Parse *parsePtr = infoPtr->parsePtr;
  1063     int firstIndex, lexeme, code;
  1064     CONST char *srcStart, *operator;
  1065 
  1066     HERE("unaryExpr", 12);
  1067     srcStart = infoPtr->start;
  1068     firstIndex = parsePtr->numTokens;
  1069     
  1070     lexeme = infoPtr->lexeme;
  1071     if ((lexeme == PLUS) || (lexeme == MINUS) || (lexeme == BIT_NOT)
  1072             || (lexeme == NOT)) {
  1073 	operator = infoPtr->start;
  1074 	code = GetLexeme(infoPtr); /* skip over the unary operator */
  1075 	if (code != TCL_OK) {
  1076 	    return code;
  1077 	}
  1078 	code = ParseUnaryExpr(infoPtr);
  1079 	if (code != TCL_OK) {
  1080 	    return code;
  1081 	}
  1082 
  1083 	/*
  1084 	 * Generate tokens for the subexpression and the operator.
  1085 	 */
  1086 
  1087 	PrependSubExprTokens(operator, 1, srcStart,
  1088 	        (infoPtr->prevEnd - srcStart), firstIndex, infoPtr);
  1089     } else {			/* must be a primaryExpr */
  1090 	code = ParsePrimaryExpr(infoPtr);
  1091 	if (code != TCL_OK) {
  1092 	    return code;
  1093 	}
  1094     }
  1095     return TCL_OK;
  1096 }
  1097 
  1098 /*
  1099  *----------------------------------------------------------------------
  1100  *
  1101  * ParsePrimaryExpr --
  1102  *
  1103  *	This procedure parses a Tcl primary expression:
  1104  *	primaryExpr ::= literal | varReference | quotedString |
  1105  *			'[' command ']' | mathFuncCall | '(' condExpr ')'
  1106  *
  1107  * Results:
  1108  *	The return value is TCL_OK on a successful parse and TCL_ERROR
  1109  *	on failure. If TCL_ERROR is returned, then the interpreter's result
  1110  *	contains an error message.
  1111  *
  1112  * Side effects:
  1113  *	If there is insufficient space in parsePtr to hold all the
  1114  *	information about the subexpression, then additional space is
  1115  *	malloc-ed.
  1116  *
  1117  *----------------------------------------------------------------------
  1118  */
  1119 
  1120 static int
  1121 ParsePrimaryExpr(infoPtr)
  1122     ParseInfo *infoPtr;		/* Holds the parse state for the
  1123 				 * expression being parsed. */
  1124 {
  1125     Tcl_Parse *parsePtr = infoPtr->parsePtr;
  1126     Tcl_Interp *interp = parsePtr->interp;
  1127     Tcl_Token *tokenPtr, *exprTokenPtr;
  1128     Tcl_Parse nested;
  1129     CONST char *dollarPtr, *stringStart, *termPtr, *src;
  1130     int lexeme, exprIndex, firstIndex, numToMove, code;
  1131 
  1132     /*
  1133      * We simply recurse on parenthesized subexpressions.
  1134      */
  1135 
  1136     HERE("primaryExpr", 13);
  1137     lexeme = infoPtr->lexeme;
  1138     if (lexeme == OPEN_PAREN) {
  1139 	code = GetLexeme(infoPtr); /* skip over the '(' */
  1140 	if (code != TCL_OK) {
  1141 	    return code;
  1142 	}
  1143 	code = ParseCondExpr(infoPtr);
  1144 	if (code != TCL_OK) {
  1145 	    return code;
  1146 	}
  1147 	if (infoPtr->lexeme != CLOSE_PAREN) {
  1148 	    LogSyntaxError(infoPtr, "looking for close parenthesis");
  1149 	    return TCL_ERROR;
  1150 	}
  1151 	code = GetLexeme(infoPtr); /* skip over the ')' */
  1152 	if (code != TCL_OK) {
  1153 	    return code;
  1154 	}
  1155 	return TCL_OK;
  1156     }
  1157 
  1158     /*
  1159      * Start a TCL_TOKEN_SUB_EXPR token for the primary.
  1160      */
  1161 
  1162     if (parsePtr->numTokens == parsePtr->tokensAvailable) {
  1163 	TclExpandTokenArray(parsePtr);
  1164     }
  1165     exprIndex = parsePtr->numTokens;
  1166     exprTokenPtr = &parsePtr->tokenPtr[exprIndex];
  1167     exprTokenPtr->type = TCL_TOKEN_SUB_EXPR;
  1168     exprTokenPtr->start = infoPtr->start;
  1169     parsePtr->numTokens++;
  1170 
  1171     /*
  1172      * Process the primary then finish setting the fields of the
  1173      * TCL_TOKEN_SUB_EXPR token. Note that we can't use the pointer now
  1174      * stored in "exprTokenPtr" in the code below since the token array
  1175      * might be reallocated.
  1176      */
  1177 
  1178     firstIndex = parsePtr->numTokens;
  1179     switch (lexeme) {
  1180     case LITERAL:
  1181 	/*
  1182 	 * Int or double number.
  1183 	 */
  1184 	
  1185 	tokenizeLiteral:
  1186 	if (parsePtr->numTokens == parsePtr->tokensAvailable) {
  1187 	    TclExpandTokenArray(parsePtr);
  1188 	}
  1189 	tokenPtr = &parsePtr->tokenPtr[parsePtr->numTokens];
  1190 	tokenPtr->type = TCL_TOKEN_TEXT;
  1191 	tokenPtr->start = infoPtr->start;
  1192 	tokenPtr->size = infoPtr->size;
  1193 	tokenPtr->numComponents = 0;
  1194 	parsePtr->numTokens++;
  1195 
  1196 	exprTokenPtr = &parsePtr->tokenPtr[exprIndex];
  1197 	exprTokenPtr->size = infoPtr->size;
  1198 	exprTokenPtr->numComponents = 1;
  1199 	break;
  1200 
  1201     case DOLLAR:
  1202 	/*
  1203 	 * $var variable reference.
  1204 	 */
  1205 	
  1206 	dollarPtr = (infoPtr->next - 1);
  1207 	code = Tcl_ParseVarName(interp, dollarPtr,
  1208 	        (infoPtr->lastChar - dollarPtr), parsePtr, 1);
  1209 	if (code != TCL_OK) {
  1210 	    return code;
  1211 	}
  1212 	infoPtr->next = dollarPtr + parsePtr->tokenPtr[firstIndex].size;
  1213 
  1214 	exprTokenPtr = &parsePtr->tokenPtr[exprIndex];
  1215 	exprTokenPtr->size = parsePtr->tokenPtr[firstIndex].size;
  1216 	exprTokenPtr->numComponents =
  1217 	        (parsePtr->tokenPtr[firstIndex].numComponents + 1);
  1218 	break;
  1219 	
  1220     case QUOTE:
  1221 	/*
  1222 	 * '"' string '"'
  1223 	 */
  1224 	
  1225 	stringStart = infoPtr->next;
  1226 	code = Tcl_ParseQuotedString(interp, infoPtr->start,
  1227 	        (infoPtr->lastChar - stringStart), parsePtr, 1, &termPtr);
  1228 	if (code != TCL_OK) {
  1229 	    return code;
  1230 	}
  1231 	infoPtr->next = termPtr;
  1232 
  1233 	exprTokenPtr = &parsePtr->tokenPtr[exprIndex];
  1234 	exprTokenPtr->size = (termPtr - exprTokenPtr->start);
  1235 	exprTokenPtr->numComponents = parsePtr->numTokens - firstIndex;
  1236 
  1237 	/*
  1238 	 * If parsing the quoted string resulted in more than one token,
  1239 	 * insert a TCL_TOKEN_WORD token before them. This indicates that
  1240 	 * the quoted string represents a concatenation of multiple tokens.
  1241 	 */
  1242 
  1243 	if (exprTokenPtr->numComponents > 1) {
  1244 	    if (parsePtr->numTokens >= parsePtr->tokensAvailable) {
  1245 		TclExpandTokenArray(parsePtr);
  1246 	    }
  1247 	    tokenPtr = &parsePtr->tokenPtr[firstIndex];
  1248 	    numToMove = (parsePtr->numTokens - firstIndex);
  1249 	    memmove((VOID *) (tokenPtr + 1), (VOID *) tokenPtr,
  1250 	            (size_t) (numToMove * sizeof(Tcl_Token)));
  1251 	    parsePtr->numTokens++;
  1252 
  1253 	    exprTokenPtr = &parsePtr->tokenPtr[exprIndex];
  1254 	    exprTokenPtr->numComponents++;
  1255 
  1256 	    tokenPtr->type = TCL_TOKEN_WORD;
  1257 	    tokenPtr->start = exprTokenPtr->start;
  1258 	    tokenPtr->size = exprTokenPtr->size;
  1259 	    tokenPtr->numComponents = (exprTokenPtr->numComponents - 1);
  1260 	}
  1261 	break;
  1262 	
  1263     case OPEN_BRACKET:
  1264 	/*
  1265 	 * '[' command {command} ']'
  1266 	 */
  1267 
  1268 	if (parsePtr->numTokens == parsePtr->tokensAvailable) {
  1269 	    TclExpandTokenArray(parsePtr);
  1270 	}
  1271 	tokenPtr = &parsePtr->tokenPtr[parsePtr->numTokens];
  1272 	tokenPtr->type = TCL_TOKEN_COMMAND;
  1273 	tokenPtr->start = infoPtr->start;
  1274 	tokenPtr->numComponents = 0;
  1275 	parsePtr->numTokens++;
  1276 
  1277 	/*
  1278 	 * Call Tcl_ParseCommand repeatedly to parse the nested command(s)
  1279 	 * to find their end, then throw away that parse information.
  1280 	 */
  1281 	
  1282 	src = infoPtr->next;
  1283 	while (1) {
  1284 	    if (Tcl_ParseCommand(interp, src, (parsePtr->end - src), 1,
  1285 		    &nested) != TCL_OK) {
  1286 		parsePtr->term = nested.term;
  1287 		parsePtr->errorType = nested.errorType;
  1288 		parsePtr->incomplete = nested.incomplete;
  1289 		return TCL_ERROR;
  1290 	    }
  1291 	    src = (nested.commandStart + nested.commandSize);
  1292 
  1293 	    /*
  1294 	     * This is equivalent to Tcl_FreeParse(&nested), but
  1295 	     * presumably inlined here for sake of runtime optimization
  1296 	     */
  1297 
  1298 	    if (nested.tokenPtr != nested.staticTokens) {
  1299 		ckfree((char *) nested.tokenPtr);
  1300 	    }
  1301 
  1302 	    /*
  1303 	     * Check for the closing ']' that ends the command substitution.
  1304 	     * It must have been the last character of the parsed command.
  1305 	     */
  1306 
  1307 	    if ((nested.term < parsePtr->end) && (*nested.term == ']') 
  1308 		    && !nested.incomplete) {
  1309 		break;
  1310 	    }
  1311 	    if (src == parsePtr->end) {
  1312 		if (parsePtr->interp != NULL) {
  1313 		    Tcl_SetResult(interp, "missing close-bracket",
  1314 			    TCL_STATIC);
  1315 		}
  1316 		parsePtr->term = tokenPtr->start;
  1317 		parsePtr->errorType = TCL_PARSE_MISSING_BRACKET;
  1318 		parsePtr->incomplete = 1;
  1319 		return TCL_ERROR;
  1320 	    }
  1321 	}
  1322 	tokenPtr->size = (src - tokenPtr->start);
  1323 	infoPtr->next = src;
  1324 
  1325 	exprTokenPtr = &parsePtr->tokenPtr[exprIndex];
  1326 	exprTokenPtr->size = (src - tokenPtr->start);
  1327 	exprTokenPtr->numComponents = 1;
  1328 	break;
  1329 
  1330     case OPEN_BRACE:
  1331 	/*
  1332 	 * '{' string '}'
  1333 	 */
  1334 
  1335 	code = Tcl_ParseBraces(interp, infoPtr->start,
  1336 	        (infoPtr->lastChar - infoPtr->start), parsePtr, 1,
  1337 		&termPtr);
  1338 	if (code != TCL_OK) {
  1339 	    return code;
  1340 	}
  1341 	infoPtr->next = termPtr;
  1342 
  1343 	exprTokenPtr = &parsePtr->tokenPtr[exprIndex];
  1344 	exprTokenPtr->size = (termPtr - infoPtr->start);
  1345 	exprTokenPtr->numComponents = parsePtr->numTokens - firstIndex;
  1346 
  1347 	/*
  1348 	 * If parsing the braced string resulted in more than one token,
  1349 	 * insert a TCL_TOKEN_WORD token before them. This indicates that
  1350 	 * the braced string represents a concatenation of multiple tokens.
  1351 	 */
  1352 
  1353 	if (exprTokenPtr->numComponents > 1) {
  1354 	    if (parsePtr->numTokens >= parsePtr->tokensAvailable) {
  1355 		TclExpandTokenArray(parsePtr);
  1356 	    }
  1357 	    tokenPtr = &parsePtr->tokenPtr[firstIndex];
  1358 	    numToMove = (parsePtr->numTokens - firstIndex);
  1359 	    memmove((VOID *) (tokenPtr + 1), (VOID *) tokenPtr,
  1360 	            (size_t) (numToMove * sizeof(Tcl_Token)));
  1361 	    parsePtr->numTokens++;
  1362 
  1363 	    exprTokenPtr = &parsePtr->tokenPtr[exprIndex];
  1364 	    exprTokenPtr->numComponents++;
  1365 	    
  1366 	    tokenPtr->type = TCL_TOKEN_WORD;
  1367 	    tokenPtr->start = exprTokenPtr->start;
  1368 	    tokenPtr->size = exprTokenPtr->size;
  1369 	    tokenPtr->numComponents = exprTokenPtr->numComponents-1;
  1370 	}
  1371 	break;
  1372 	
  1373     case STREQ:
  1374     case STRNEQ:
  1375     case FUNC_NAME: {
  1376 	/*
  1377 	 * math_func '(' expr {',' expr} ')'
  1378 	 */
  1379 
  1380 	ParseInfo savedInfo = *infoPtr;
  1381 	
  1382 	code = GetLexeme(infoPtr); /* skip over function name */
  1383 	if (code != TCL_OK) {
  1384 	    return code;
  1385 	}
  1386 	if (infoPtr->lexeme != OPEN_PAREN) {
  1387 	    int code;
  1388 	    Tcl_DString functionName;
  1389 	    Tcl_HashEntry *hPtr;
  1390 	    Interp *iPtr = (Interp *) infoPtr->parsePtr->interp;
  1391 	    Tcl_Obj *objPtr = Tcl_NewStringObj(savedInfo.start, savedInfo.size);
  1392 
  1393 	    /* Check for boolean literals (true, false, yes, no, on, off) */
  1394 	    Tcl_IncrRefCount(objPtr);
  1395 	    code = Tcl_ConvertToType(NULL, objPtr, &tclBooleanType);
  1396 	    Tcl_DecrRefCount(objPtr);
  1397 	    if (code == TCL_OK) {
  1398 		*infoPtr = savedInfo;
  1399 		goto tokenizeLiteral;
  1400 	    }
  1401 
  1402 	    /*
  1403 	     * Guess what kind of error we have by trying to tell
  1404 	     * whether we have a function or variable name here.
  1405 	     * Alas, this makes the parser more tightly bound with the
  1406 	     * rest of the interpreter, but that is the only way to
  1407 	     * give a sensible message here.  Still, it is not too
  1408 	     * serious as this is only done when generating an error.
  1409 	     */
  1410 
  1411 	    /*
  1412 	     * Look up the name as a function name.  We need a writable
  1413 	     * copy (DString) so we can terminate it with a NULL for
  1414 	     * the benefit of Tcl_FindHashEntry which operates on
  1415 	     * NULL-terminated string keys.
  1416 	     */
  1417 	    Tcl_DStringInit(&functionName);
  1418 	    hPtr = Tcl_FindHashEntry(&iPtr->mathFuncTable, 
  1419 	    	Tcl_DStringAppend(&functionName,
  1420 			savedInfo.start, savedInfo.size));
  1421 	    Tcl_DStringFree(&functionName);
  1422 
  1423 	    /*
  1424 	     * Assume that we have an attempted variable reference
  1425 	     * unless we've got a function name, as the set of
  1426 	     * potential function names is typically much smaller.
  1427 	     */
  1428 	    if (hPtr != NULL) {
  1429 		LogSyntaxError(infoPtr,
  1430 			"expected parenthesis enclosing function arguments");
  1431 	    } else {
  1432 		LogSyntaxError(infoPtr,
  1433 			"variable references require preceding $");
  1434 	    }
  1435 	    return TCL_ERROR;
  1436 	}
  1437 
  1438 	if (parsePtr->numTokens == parsePtr->tokensAvailable) {
  1439 	    TclExpandTokenArray(parsePtr);
  1440 	}
  1441 	tokenPtr = &parsePtr->tokenPtr[parsePtr->numTokens];
  1442 	tokenPtr->type = TCL_TOKEN_OPERATOR;
  1443 	tokenPtr->start = savedInfo.start;
  1444 	tokenPtr->size = savedInfo.size;
  1445 	tokenPtr->numComponents = 0;
  1446 	parsePtr->numTokens++;
  1447 	
  1448 	code = GetLexeme(infoPtr); /* skip over '(' */
  1449 	if (code != TCL_OK) {
  1450 	    return code;
  1451 	}
  1452 
  1453 	while (infoPtr->lexeme != CLOSE_PAREN) {
  1454 	    code = ParseCondExpr(infoPtr);
  1455 	    if (code != TCL_OK) {
  1456 		return code;
  1457 	    }
  1458 	    
  1459 	    if (infoPtr->lexeme == COMMA) {
  1460 		code = GetLexeme(infoPtr); /* skip over , */
  1461 		if (code != TCL_OK) {
  1462 		    return code;
  1463 		}
  1464 	    } else if (infoPtr->lexeme != CLOSE_PAREN) {
  1465 		LogSyntaxError(infoPtr,
  1466 			"missing close parenthesis at end of function call");
  1467 		return TCL_ERROR;
  1468 	    }
  1469 	}
  1470 
  1471 	exprTokenPtr = &parsePtr->tokenPtr[exprIndex];
  1472 	exprTokenPtr->size = (infoPtr->next - exprTokenPtr->start);
  1473 	exprTokenPtr->numComponents = parsePtr->numTokens - firstIndex;
  1474 	break;
  1475     }
  1476 
  1477     case COMMA:
  1478 	LogSyntaxError(infoPtr,
  1479 		"commas can only separate function arguments");
  1480 	return TCL_ERROR;
  1481     case END:
  1482 	LogSyntaxError(infoPtr, "premature end of expression");
  1483 	return TCL_ERROR;
  1484     case UNKNOWN:
  1485 	LogSyntaxError(infoPtr, "single equality character not legal in expressions");
  1486 	return TCL_ERROR;
  1487     case UNKNOWN_CHAR:
  1488 	LogSyntaxError(infoPtr, "character not legal in expressions");
  1489 	return TCL_ERROR;
  1490     case QUESTY:
  1491 	LogSyntaxError(infoPtr, "unexpected ternary 'then' separator");
  1492 	return TCL_ERROR;
  1493     case COLON:
  1494 	LogSyntaxError(infoPtr, "unexpected ternary 'else' separator");
  1495 	return TCL_ERROR;
  1496     case CLOSE_PAREN:
  1497 	LogSyntaxError(infoPtr, "unexpected close parenthesis");
  1498 	return TCL_ERROR;
  1499 
  1500     default: {
  1501 	char buf[64];
  1502 
  1503 	sprintf(buf, "unexpected operator %s", lexemeStrings[lexeme]);
  1504 	LogSyntaxError(infoPtr, buf);
  1505 	return TCL_ERROR;
  1506 	}
  1507     }
  1508 
  1509     /*
  1510      * Advance to the next lexeme before returning.
  1511      */
  1512     
  1513     code = GetLexeme(infoPtr);
  1514     if (code != TCL_OK) {
  1515 	return code;
  1516     }
  1517     parsePtr->term = infoPtr->next;
  1518     return TCL_OK;
  1519 }
  1520 
  1521 /*
  1522  *----------------------------------------------------------------------
  1523  *
  1524  * GetLexeme --
  1525  *
  1526  *	Lexical scanner for Tcl expressions: scans a single operator or
  1527  *	other syntactic element from an expression string.
  1528  *
  1529  * Results:
  1530  *	TCL_OK is returned unless an error occurred. In that case a standard
  1531  *	Tcl error code is returned and, if infoPtr->parsePtr->interp is
  1532  *	non-NULL, the interpreter's result is set to hold an error
  1533  *	message. TCL_ERROR is returned if an integer overflow, or a
  1534  *	floating-point overflow or underflow occurred while reading in a
  1535  *	number. If the lexical analysis is successful, infoPtr->lexeme
  1536  *	refers to the next symbol in the expression string, and
  1537  *	infoPtr->next is advanced past the lexeme. Also, if the lexeme is a
  1538  *	LITERAL or FUNC_NAME, then infoPtr->start is set to the first
  1539  *	character of the lexeme; otherwise it is set NULL.
  1540  *
  1541  * Side effects:
  1542  *	If there is insufficient space in parsePtr to hold all the
  1543  *	information about the subexpression, then additional space is
  1544  *	malloc-ed..
  1545  *
  1546  *----------------------------------------------------------------------
  1547  */
  1548 
  1549 static int
  1550 GetLexeme(infoPtr)
  1551     ParseInfo *infoPtr;		/* Holds state needed to parse the expr,
  1552 				 * including the resulting lexeme. */
  1553 {
  1554     register CONST char *src;	/* Points to current source char. */
  1555     char c;
  1556     int offset, length, numBytes;
  1557     Tcl_Parse *parsePtr = infoPtr->parsePtr;
  1558     Tcl_Interp *interp = parsePtr->interp;
  1559     Tcl_UniChar ch;
  1560 
  1561     /*
  1562      * Record where the previous lexeme ended. Since we always read one
  1563      * lexeme ahead during parsing, this helps us know the source length of
  1564      * subexpression tokens.
  1565      */
  1566 
  1567     infoPtr->prevEnd = infoPtr->next;
  1568 
  1569     /*
  1570      * Scan over leading white space at the start of a lexeme. 
  1571      */
  1572 
  1573     src = infoPtr->next;
  1574     numBytes = parsePtr->end - src;
  1575     do {
  1576 	char type;
  1577 	int scanned = TclParseWhiteSpace(src, numBytes, parsePtr, &type);
  1578 	src += scanned; numBytes -= scanned;
  1579     } while  (numBytes && (*src == '\n') && (src++,numBytes--));
  1580     parsePtr->term = src;
  1581     if (numBytes == 0) {
  1582 	infoPtr->lexeme = END;
  1583 	infoPtr->next = src;
  1584 	return TCL_OK;
  1585     }
  1586 
  1587     /*
  1588      * Try to parse the lexeme first as an integer or floating-point
  1589      * number. Don't check for a number if the first character c is
  1590      * "+" or "-". If we did, we might treat a binary operator as unary
  1591      * by mistake, which would eventually cause a syntax error.
  1592      */
  1593 
  1594     c = *src;
  1595     if ((c != '+') && (c != '-')) {
  1596 	CONST char *end = infoPtr->lastChar;
  1597 	if ((length = TclParseInteger(src, (end - src)))) {
  1598 	    /*
  1599 	     * First length bytes look like an integer.  Verify by
  1600 	     * attempting the conversion to the largest integer we have.
  1601 	     */
  1602 	    int code;
  1603 	    Tcl_WideInt wide;
  1604 	    Tcl_Obj *value = Tcl_NewStringObj(src, length);
  1605 
  1606 	    Tcl_IncrRefCount(value);
  1607 	    code = Tcl_GetWideIntFromObj(interp, value, &wide);
  1608 	    Tcl_DecrRefCount(value);
  1609 	    if (code == TCL_ERROR) {
  1610 		parsePtr->errorType = TCL_PARSE_BAD_NUMBER;
  1611 		return TCL_ERROR;
  1612 	    }
  1613             infoPtr->lexeme = LITERAL;
  1614 	    infoPtr->start = src;
  1615 	    infoPtr->size = length;
  1616             infoPtr->next = (src + length);
  1617 	    parsePtr->term = infoPtr->next;
  1618             return TCL_OK;
  1619 	} else if ((length = ParseMaxDoubleLength(src, end))) {
  1620 	    /*
  1621 	     * There are length characters that could be a double.
  1622 	     * Let strtod() tells us for sure.  Need a writable copy
  1623 	     * so we can set an terminating NULL to keep strtod from
  1624 	     * scanning too far.
  1625 	     */
  1626 	    char *startPtr, *termPtr;
  1627 	    double doubleValue;
  1628 	    Tcl_DString toParse;
  1629 
  1630 	    errno = 0;
  1631 	    Tcl_DStringInit(&toParse);
  1632 	    startPtr = Tcl_DStringAppend(&toParse, src, length);
  1633 	    doubleValue = strtod(startPtr, &termPtr);
  1634 	    Tcl_DStringFree(&toParse);
  1635 	    if (termPtr != startPtr) {
  1636 		if (errno != 0) {
  1637 		    if (interp != NULL) {
  1638 			TclExprFloatError(interp, doubleValue);
  1639 		    }
  1640 		    parsePtr->errorType = TCL_PARSE_BAD_NUMBER;
  1641 		    return TCL_ERROR;
  1642 		}
  1643 		
  1644 		/*
  1645                  * startPtr was the start of a valid double, copied
  1646 		 * from src.
  1647                  */
  1648 		
  1649 		infoPtr->lexeme = LITERAL;
  1650 		infoPtr->start = src;
  1651 		if ((termPtr - startPtr) > length) {
  1652 		    infoPtr->size = length;
  1653 		} else {
  1654 		    infoPtr->size = (termPtr - startPtr);
  1655 		}
  1656 		infoPtr->next = src + infoPtr->size;
  1657 		parsePtr->term = infoPtr->next;
  1658 		return TCL_OK;
  1659 	    }
  1660 	}
  1661     }
  1662 
  1663     /*
  1664      * Not an integer or double literal. Initialize the lexeme's fields
  1665      * assuming the common case of a single character lexeme.
  1666      */
  1667 
  1668     infoPtr->start = src;
  1669     infoPtr->size = 1;
  1670     infoPtr->next = src+1;
  1671     parsePtr->term = infoPtr->next;
  1672     
  1673     switch (*src) {
  1674 	case '[':
  1675 	    infoPtr->lexeme = OPEN_BRACKET;
  1676 	    return TCL_OK;
  1677 
  1678         case '{':
  1679 	    infoPtr->lexeme = OPEN_BRACE;
  1680 	    return TCL_OK;
  1681 
  1682 	case '(':
  1683 	    infoPtr->lexeme = OPEN_PAREN;
  1684 	    return TCL_OK;
  1685 
  1686 	case ')':
  1687 	    infoPtr->lexeme = CLOSE_PAREN;
  1688 	    return TCL_OK;
  1689 
  1690 	case '$':
  1691 	    infoPtr->lexeme = DOLLAR;
  1692 	    return TCL_OK;
  1693 
  1694 	case '\"':
  1695 	    infoPtr->lexeme = QUOTE;
  1696 	    return TCL_OK;
  1697 
  1698 	case ',':
  1699 	    infoPtr->lexeme = COMMA;
  1700 	    return TCL_OK;
  1701 
  1702 	case '*':
  1703 	    infoPtr->lexeme = MULT;
  1704 	    return TCL_OK;
  1705 
  1706 	case '/':
  1707 	    infoPtr->lexeme = DIVIDE;
  1708 	    return TCL_OK;
  1709 
  1710 	case '%':
  1711 	    infoPtr->lexeme = MOD;
  1712 	    return TCL_OK;
  1713 
  1714 	case '+':
  1715 	    infoPtr->lexeme = PLUS;
  1716 	    return TCL_OK;
  1717 
  1718 	case '-':
  1719 	    infoPtr->lexeme = MINUS;
  1720 	    return TCL_OK;
  1721 
  1722 	case '?':
  1723 	    infoPtr->lexeme = QUESTY;
  1724 	    return TCL_OK;
  1725 
  1726 	case ':':
  1727 	    infoPtr->lexeme = COLON;
  1728 	    return TCL_OK;
  1729 
  1730 	case '<':
  1731 	    infoPtr->lexeme = LESS;
  1732 	    if ((infoPtr->lastChar - src) > 1) {
  1733 		switch (src[1]) {
  1734 		    case '<':
  1735 			infoPtr->lexeme = LEFT_SHIFT;
  1736 			infoPtr->size = 2;
  1737 			infoPtr->next = src+2;
  1738 			break;
  1739 		    case '=':
  1740 			infoPtr->lexeme = LEQ;
  1741 			infoPtr->size = 2;
  1742 			infoPtr->next = src+2;
  1743 			break;
  1744 		}
  1745 	    }
  1746 	    parsePtr->term = infoPtr->next;
  1747 	    return TCL_OK;
  1748 
  1749 	case '>':
  1750 	    infoPtr->lexeme = GREATER;
  1751 	    if ((infoPtr->lastChar - src) > 1) {
  1752 		switch (src[1]) {
  1753 		    case '>':
  1754 			infoPtr->lexeme = RIGHT_SHIFT;
  1755 			infoPtr->size = 2;
  1756 			infoPtr->next = src+2;
  1757 			break;
  1758 		    case '=':
  1759 			infoPtr->lexeme = GEQ;
  1760 			infoPtr->size = 2;
  1761 			infoPtr->next = src+2;
  1762 			break;
  1763 		}
  1764 	    }
  1765 	    parsePtr->term = infoPtr->next;
  1766 	    return TCL_OK;
  1767 
  1768 	case '=':
  1769 	    infoPtr->lexeme = UNKNOWN;
  1770 	    if ((src[1] == '=') && ((infoPtr->lastChar - src) > 1)) {
  1771 		infoPtr->lexeme = EQUAL;
  1772 		infoPtr->size = 2;
  1773 		infoPtr->next = src+2;
  1774 	    }
  1775 	    parsePtr->term = infoPtr->next;
  1776 	    return TCL_OK;
  1777 
  1778 	case '!':
  1779 	    infoPtr->lexeme = NOT;
  1780 	    if ((src[1] == '=') && ((infoPtr->lastChar - src) > 1)) {
  1781 		infoPtr->lexeme = NEQ;
  1782 		infoPtr->size = 2;
  1783 		infoPtr->next = src+2;
  1784 	    }
  1785 	    parsePtr->term = infoPtr->next;
  1786 	    return TCL_OK;
  1787 
  1788 	case '&':
  1789 	    infoPtr->lexeme = BIT_AND;
  1790 	    if ((src[1] == '&') && ((infoPtr->lastChar - src) > 1)) {
  1791 		infoPtr->lexeme = AND;
  1792 		infoPtr->size = 2;
  1793 		infoPtr->next = src+2;
  1794 	    }
  1795 	    parsePtr->term = infoPtr->next;
  1796 	    return TCL_OK;
  1797 
  1798 	case '^':
  1799 	    infoPtr->lexeme = BIT_XOR;
  1800 	    return TCL_OK;
  1801 
  1802 	case '|':
  1803 	    infoPtr->lexeme = BIT_OR;
  1804 	    if ((src[1] == '|') && ((infoPtr->lastChar - src) > 1)) {
  1805 		infoPtr->lexeme = OR;
  1806 		infoPtr->size = 2;
  1807 		infoPtr->next = src+2;
  1808 	    }
  1809 	    parsePtr->term = infoPtr->next;
  1810 	    return TCL_OK;
  1811 
  1812 	case '~':
  1813 	    infoPtr->lexeme = BIT_NOT;
  1814 	    return TCL_OK;
  1815 
  1816 	case 'e':
  1817 	    if ((src[1] == 'q') && ((infoPtr->lastChar - src) > 1)) {
  1818 		infoPtr->lexeme = STREQ;
  1819 		infoPtr->size = 2;
  1820 		infoPtr->next = src+2;
  1821 		parsePtr->term = infoPtr->next;
  1822 		return TCL_OK;
  1823 	    } else {
  1824 		goto checkFuncName;
  1825 	    }
  1826 
  1827 	case 'n':
  1828 	    if ((src[1] == 'e') && ((infoPtr->lastChar - src) > 1)) {
  1829 		infoPtr->lexeme = STRNEQ;
  1830 		infoPtr->size = 2;
  1831 		infoPtr->next = src+2;
  1832 		parsePtr->term = infoPtr->next;
  1833 		return TCL_OK;
  1834 	    } else {
  1835 		goto checkFuncName;
  1836 	    }
  1837 
  1838 	default:
  1839 	checkFuncName:
  1840 	    length = (infoPtr->lastChar - src);
  1841 	    if (Tcl_UtfCharComplete(src, length)) {
  1842 		offset = Tcl_UtfToUniChar(src, &ch);
  1843 	    } else {
  1844 		char utfBytes[TCL_UTF_MAX];
  1845 		memcpy(utfBytes, src, (size_t) length);
  1846 		utfBytes[length] = '\0';
  1847 		offset = Tcl_UtfToUniChar(utfBytes, &ch);
  1848 	    }
  1849 	    c = UCHAR(ch);
  1850 	    if (isalpha(UCHAR(c))) {	/* INTL: ISO only. */
  1851 		infoPtr->lexeme = FUNC_NAME;
  1852 		while (isalnum(UCHAR(c)) || (c == '_')) { /* INTL: ISO only. */
  1853 		    src += offset; length -= offset;
  1854 		    if (Tcl_UtfCharComplete(src, length)) {
  1855 			offset = Tcl_UtfToUniChar(src, &ch);
  1856 		    } else {
  1857 			char utfBytes[TCL_UTF_MAX];
  1858 			memcpy(utfBytes, src, (size_t) length);
  1859 			utfBytes[length] = '\0';
  1860 			offset = Tcl_UtfToUniChar(utfBytes, &ch);
  1861 		    }
  1862 		    c = UCHAR(ch);
  1863 		}
  1864 		infoPtr->size = (src - infoPtr->start);
  1865 		infoPtr->next = src;
  1866 		parsePtr->term = infoPtr->next;
  1867 		return TCL_OK;
  1868 	    }
  1869 	    infoPtr->lexeme = UNKNOWN_CHAR;
  1870 	    return TCL_OK;
  1871     }
  1872 }
  1873 
  1874 /*
  1875  *----------------------------------------------------------------------
  1876  *
  1877  * TclParseInteger --
  1878  *
  1879  *	Scans up to numBytes bytes starting at src, and checks whether
  1880  *	the leading bytes look like an integer's string representation.
  1881  *
  1882  * Results:
  1883  *	Returns 0 if the leading bytes do not look like an integer.
  1884  *	Otherwise, returns the number of bytes examined that look
  1885  *	like an integer.  This may be less than numBytes if the integer
  1886  *	is only the leading part of the string.
  1887  *
  1888  * Side effects:
  1889  *	None.
  1890  *
  1891  *----------------------------------------------------------------------
  1892  */
  1893 
  1894 int
  1895 TclParseInteger(string, numBytes)
  1896     register CONST char *string;/* The string to examine. */
  1897     register int numBytes;	/* Max number of bytes to scan. */
  1898 {
  1899     register CONST char *p = string;
  1900 
  1901     /* Take care of introductory "0x" */
  1902     if ((numBytes > 1) && (p[0] == '0') && ((p[1] == 'x') || (p[1] == 'X'))) {
  1903 	int scanned;
  1904 	Tcl_UniChar ch;
  1905 	p+=2; numBytes -= 2;
  1906  	scanned = TclParseHex(p, numBytes, &ch);
  1907 	if (scanned) {
  1908 	    return scanned + 2;
  1909 	}
  1910 
  1911 	/* Recognize the 0 as valid integer, but x is left behind */
  1912 	return 1;
  1913     }
  1914     while (numBytes && isdigit(UCHAR(*p))) {	/* INTL: digit */
  1915 	numBytes--; p++;
  1916     }
  1917     if (numBytes == 0) {
  1918         return (p - string);
  1919     }
  1920     if ((*p != '.') && (*p != 'e') && (*p != 'E')) {
  1921         return (p - string);
  1922     }
  1923     return 0;
  1924 }
  1925 
  1926 /*
  1927  *----------------------------------------------------------------------
  1928  *
  1929  * ParseMaxDoubleLength --
  1930  *
  1931  *      Scans a sequence of bytes checking that the characters could
  1932  *	be in a string rep of a double.
  1933  *
  1934  * Results:
  1935  *	Returns the number of bytes starting with string, runing to, but
  1936  *	not including end, all of which could be part of a string rep.
  1937  *	of a double.  Only character identity is used, no actual
  1938  *	parsing is done.
  1939  *
  1940  *	The legal bytes are '0' - '9', 'A' - 'F', 'a' - 'f', 
  1941  *	'.', '+', '-', 'i', 'I', 'n', 'N', 'p', 'P', 'x',  and 'X'.
  1942  *	This covers the values "Inf" and "Nan" as well as the
  1943  *	decimal and hexadecimal representations recognized by a
  1944  *	C99-compliant strtod().
  1945  *
  1946  * Side effects:
  1947  *	None.
  1948  *
  1949  *----------------------------------------------------------------------
  1950  */
  1951 
  1952 static int
  1953 ParseMaxDoubleLength(string, end)
  1954     register CONST char *string;/* The string to examine. */
  1955     CONST char *end;		/* Point to the first character past the end
  1956 				 * of the string we are examining. */
  1957 {
  1958     CONST char *p = string;
  1959     while (p < end) {
  1960 	switch (*p) {
  1961 	    case '0': case '1': case '2': case '3': case '4': case '5':
  1962 	    case '6': case '7': case '8': case '9': case 'A': case 'B':
  1963 	    case 'C': case 'D': case 'E': case 'F': case 'I': case 'N':
  1964 	    case 'P': case 'X': case 'a': case 'b': case 'c': case 'd':
  1965 	    case 'e': case 'f': case 'i': case 'n': case 'p': case 'x':
  1966 	    case '.': case '+': case '-':
  1967 		p++;
  1968 		break;
  1969 	    default:
  1970 		goto done;
  1971 	}
  1972     }
  1973     done:
  1974     return (p - string);
  1975 }
  1976 
  1977 /*
  1978  *----------------------------------------------------------------------
  1979  *
  1980  * PrependSubExprTokens --
  1981  *
  1982  *	This procedure is called after the operands of an subexpression have
  1983  *	been parsed. It generates two tokens: a TCL_TOKEN_SUB_EXPR token for
  1984  *	the subexpression, and a TCL_TOKEN_OPERATOR token for its operator.
  1985  *	These two tokens are inserted before the operand tokens.
  1986  *
  1987  * Results:
  1988  *	None.
  1989  *
  1990  * Side effects:
  1991  *	If there is insufficient space in parsePtr to hold the new tokens,
  1992  *	additional space is malloc-ed.
  1993  *
  1994  *----------------------------------------------------------------------
  1995  */
  1996 
  1997 static void
  1998 PrependSubExprTokens(op, opBytes, src, srcBytes, firstIndex, infoPtr)
  1999     CONST char *op;		/* Points to first byte of the operator
  2000 				 * in the source script. */
  2001     int opBytes;		/* Number of bytes in the operator. */
  2002     CONST char *src;		/* Points to first byte of the subexpression
  2003 				 * in the source script. */
  2004     int srcBytes;		/* Number of bytes in subexpression's
  2005 				 * source. */
  2006     int firstIndex;		/* Index of first token already emitted for
  2007 				 * operator's first (or only) operand. */
  2008     ParseInfo *infoPtr;		/* Holds the parse state for the
  2009 				 * expression being parsed. */
  2010 {
  2011     Tcl_Parse *parsePtr = infoPtr->parsePtr;
  2012     Tcl_Token *tokenPtr, *firstTokenPtr;
  2013     int numToMove;
  2014 
  2015     if ((parsePtr->numTokens + 1) >= parsePtr->tokensAvailable) {
  2016 	TclExpandTokenArray(parsePtr);
  2017     }
  2018     firstTokenPtr = &parsePtr->tokenPtr[firstIndex];
  2019     tokenPtr = (firstTokenPtr + 2);
  2020     numToMove = (parsePtr->numTokens - firstIndex);
  2021     memmove((VOID *) tokenPtr, (VOID *) firstTokenPtr,
  2022             (size_t) (numToMove * sizeof(Tcl_Token)));
  2023     parsePtr->numTokens += 2;
  2024     
  2025     tokenPtr = firstTokenPtr;
  2026     tokenPtr->type = TCL_TOKEN_SUB_EXPR;
  2027     tokenPtr->start = src;
  2028     tokenPtr->size = srcBytes;
  2029     tokenPtr->numComponents = parsePtr->numTokens - (firstIndex + 1);
  2030     
  2031     tokenPtr++;
  2032     tokenPtr->type = TCL_TOKEN_OPERATOR;
  2033     tokenPtr->start = op;
  2034     tokenPtr->size = opBytes;
  2035     tokenPtr->numComponents = 0;
  2036 }
  2037 
  2038 /*
  2039  *----------------------------------------------------------------------
  2040  *
  2041  * LogSyntaxError --
  2042  *
  2043  *	This procedure is invoked after an error occurs when parsing an
  2044  *	expression. It sets the interpreter result to an error message
  2045  *	describing the error.
  2046  *
  2047  * Results:
  2048  *	None.
  2049  *
  2050  * Side effects:
  2051  *	Sets the interpreter result to an error message describing the
  2052  *	expression that was being parsed when the error occurred, and why
  2053  *	the parser considers that to be a syntax error at all.
  2054  *
  2055  *----------------------------------------------------------------------
  2056  */
  2057 
  2058 static void
  2059 LogSyntaxError(infoPtr, extraInfo)
  2060     ParseInfo *infoPtr;		/* Holds the parse state for the
  2061 				 * expression being parsed. */
  2062     CONST char *extraInfo;	/* String to provide extra information
  2063 				 * about the syntax error. */
  2064 {
  2065     int numBytes = (infoPtr->lastChar - infoPtr->originalExpr);
  2066     char buffer[100];
  2067 
  2068     if (numBytes > 60) {
  2069 	sprintf(buffer, "syntax error in expression \"%.60s...\"",
  2070 		infoPtr->originalExpr);
  2071     } else {
  2072 	sprintf(buffer, "syntax error in expression \"%.*s\"",
  2073 		numBytes, infoPtr->originalExpr);
  2074     }
  2075     Tcl_ResetResult(infoPtr->parsePtr->interp);
  2076     Tcl_AppendStringsToObj(Tcl_GetObjResult(infoPtr->parsePtr->interp),
  2077 	    buffer, ": ", extraInfo, (char *) NULL);
  2078     infoPtr->parsePtr->errorType = TCL_PARSE_SYNTAX;
  2079     infoPtr->parsePtr->term = infoPtr->start;
  2080 }