Diff
Not logged in

Differences From Artifact [bf69a71406]:

To Artifact [002507a013]:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
 * tclCompExpr.c --
 *
 *	This file contains the code to compile Tcl expressions.
 *
 * Copyright (c) 1997 Sun Microsystems, Inc.
 * Copyright (c) 1998-2000 by Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: tclCompExpr.c,v 1.14.2.10 2005/10/18 20:46:18 dgp Exp $
 */

#include "tclInt.h"
#include "tclCompile.h"

/*
 * Boolean variable that controls whether expression compilation tracing is











|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
 * tclCompExpr.c --
 *
 *	This file contains the code to compile Tcl expressions.
 *
 * Copyright (c) 1997 Sun Microsystems, Inc.
 * Copyright (c) 1998-2000 by Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: tclCompExpr.c,v 1.14.2.11 2005/11/03 17:52:07 dgp Exp $
 */

#include "tclInt.h"
#include "tclCompile.h"

/*
 * Boolean variable that controls whether expression compilation tracing is
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

static Tcl_HashTable opHashTable;

/*
 * Declarations for local procedures to this file:
 */

static int		CompileCondExpr _ANSI_ARGS_((
			    Tcl_Token *exprTokenPtr, ExprInfo *infoPtr,
			    CompileEnv *envPtr, Tcl_Token **endPtrPtr));
static int		CompileLandOrLorExpr _ANSI_ARGS_((
			    Tcl_Token *exprTokenPtr, int opIndex,
			    ExprInfo *infoPtr, CompileEnv *envPtr,
			    Tcl_Token **endPtrPtr));
static int		CompileMathFuncCall _ANSI_ARGS_((
			    Tcl_Token *exprTokenPtr, CONST char *funcName,
			    ExprInfo *infoPtr, CompileEnv *envPtr,
			    Tcl_Token **endPtrPtr));
static int		CompileSubExpr _ANSI_ARGS_((
			    Tcl_Token *exprTokenPtr, ExprInfo *infoPtr,
			    CompileEnv *envPtr));
static void		LogSyntaxError _ANSI_ARGS_((ExprInfo *infoPtr));

/*
 * Macro used to debug the execution of the expression compiler.
 */

#ifdef TCL_COMPILE_DEBUG
#define TRACE(exprBytes, exprLength, tokenBytes, tokenLength) \







|

|
|


|
|
|
<
|
|
<
|
|







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

static Tcl_HashTable opHashTable;

/*
 * Declarations for local procedures to this file:
 */

static int		CompileCondExpr(
			    Tcl_Token *exprTokenPtr, ExprInfo *infoPtr,
			    CompileEnv *envPtr, Tcl_Token **endPtrPtr);
static int		CompileLandOrLorExpr(
			    Tcl_Token *exprTokenPtr, int opIndex,
			    ExprInfo *infoPtr, CompileEnv *envPtr,
			    Tcl_Token **endPtrPtr);
static int		CompileMathFuncCall(Tcl_Token *exprTokenPtr,
			    CONST char *funcName, ExprInfo *infoPtr,

			    CompileEnv *envPtr, Tcl_Token **endPtrPtr);
static int		CompileSubExpr(Tcl_Token *exprTokenPtr,

			    ExprInfo *infoPtr, CompileEnv *envPtr);
static void		LogSyntaxError(ExprInfo *infoPtr);

/*
 * Macro used to debug the execution of the expression compiler.
 */

#ifdef TCL_COMPILE_DEBUG
#define TRACE(exprBytes, exprLength, tokenBytes, tokenLength) \
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
 * Side effects:
 *	Adds instructions to envPtr to evaluate the expression at runtime.
 *
 *----------------------------------------------------------------------
 */

int
TclCompileExpr(interp, script, numBytes, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    CONST char *script;		/* The source script to compile. */
    int numBytes;		/* Number of bytes in script. If < 0, the
				 * string consists of all bytes up to the
				 * first null character. */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    ExprInfo info;
    Tcl_Parse parse;
    Tcl_HashEntry *hPtr;
    int new, i, code;

    /*







|
|
|
|


|







183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
 * Side effects:
 *	Adds instructions to envPtr to evaluate the expression at runtime.
 *
 *----------------------------------------------------------------------
 */

int
TclCompileExpr(
    Tcl_Interp *interp,		/* Used for error reporting. */
    CONST char *script,		/* The source script to compile. */
    int numBytes,		/* Number of bytes in script. If < 0, the
				 * string consists of all bytes up to the
				 * first null character. */
    CompileEnv *envPtr)		/* Holds resulting instructions. */
{
    ExprInfo info;
    Tcl_Parse parse;
    Tcl_HashEntry *hPtr;
    int new, i, code;

    /*
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
 *	Cleans up the compilation environment. At the moment, just the table
 *	of expression operators is freed.
 *
 *----------------------------------------------------------------------
 */

void
TclFinalizeCompilation()
{
    Tcl_MutexLock(&opMutex);
    if (opTableInitialized) {
	Tcl_DeleteHashTable(&opHashTable);
	opTableInitialized = 0;
    }
    Tcl_MutexUnlock(&opMutex);







|







280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
 *	Cleans up the compilation environment. At the moment, just the table
 *	of expression operators is freed.
 *
 *----------------------------------------------------------------------
 */

void
TclFinalizeCompilation(void)
{
    Tcl_MutexLock(&opMutex);
    if (opTableInitialized) {
	Tcl_DeleteHashTable(&opHashTable);
	opTableInitialized = 0;
    }
    Tcl_MutexUnlock(&opMutex);
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
 * Side effects:
 *	Adds instructions to envPtr to evaluate the subexpression.
 *
 *----------------------------------------------------------------------
 */

static int
CompileSubExpr(exprTokenPtr, infoPtr, envPtr)
    Tcl_Token *exprTokenPtr;	/* Points to TCL_TOKEN_SUB_EXPR token to
				 * compile. */
    ExprInfo *infoPtr;		/* Describes the compilation state for the
				 * expression being compiled. */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    Tcl_Interp *interp = infoPtr->interp;
    Tcl_Token *tokenPtr, *endPtr, *afterSubexprPtr;
    OperatorDesc *opDescPtr;
    Tcl_HashEntry *hPtr;
    CONST char *operator;
    Tcl_DString opBuf;







|
|

|

|







311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
 * Side effects:
 *	Adds instructions to envPtr to evaluate the subexpression.
 *
 *----------------------------------------------------------------------
 */

static int
CompileSubExpr(
    Tcl_Token *exprTokenPtr,	/* Points to TCL_TOKEN_SUB_EXPR token to
				 * compile. */
    ExprInfo *infoPtr,		/* Describes the compilation state for the
				 * expression being compiled. */
    CompileEnv *envPtr)		/* Holds resulting instructions. */
{
    Tcl_Interp *interp = infoPtr->interp;
    Tcl_Token *tokenPtr, *endPtr, *afterSubexprPtr;
    OperatorDesc *opDescPtr;
    Tcl_HashEntry *hPtr;
    CONST char *operator;
    Tcl_DString opBuf;
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
	    objIndex = TclRegisterNewLiteral(envPtr, "", 0);
	}
	TclEmitPush(objIndex, envPtr);
	tokenPtr += 1;
	break;
 
    case TCL_TOKEN_BS:
	length = Tcl_UtfBackslash(tokenPtr->start, (int *) NULL, buffer);
	if (length > 0) {
	    objIndex = TclRegisterNewLiteral(envPtr, buffer, length);
	} else {
	    objIndex = TclRegisterNewLiteral(envPtr, "", 0);
	}
	TclEmitPush(objIndex, envPtr);
	tokenPtr += 1;







|







360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
	    objIndex = TclRegisterNewLiteral(envPtr, "", 0);
	}
	TclEmitPush(objIndex, envPtr);
	tokenPtr += 1;
	break;
 
    case TCL_TOKEN_BS:
	length = Tcl_UtfBackslash(tokenPtr->start, NULL, buffer);
	if (length > 0) {
	    objIndex = TclRegisterNewLiteral(envPtr, buffer, length);
	} else {
	    objIndex = TclRegisterNewLiteral(envPtr, "", 0);
	}
	TclEmitPush(objIndex, envPtr);
	tokenPtr += 1;
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
 * Side effects:
 *	Adds instructions to envPtr to evaluate the expression at runtime.
 *
 *----------------------------------------------------------------------
 */

static int
CompileLandOrLorExpr(exprTokenPtr, opIndex, infoPtr, envPtr, endPtrPtr)
    Tcl_Token *exprTokenPtr;	/* Points to TCL_TOKEN_SUB_EXPR token
				 * containing the "&&" or "||" operator. */
    int opIndex;		/* A code describing the expression operator:
				 * either OP_LAND or OP_LOR. */
    ExprInfo *infoPtr;		/* Describes the compilation state for the
				 * expression being compiled. */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
    Tcl_Token **endPtrPtr;	/* If successful, a pointer to the token just
				 * after the last token in the subexpression
				 * is stored here. */
{
    JumpFixup shortCircuitFixup;/* Used to fix up the short circuit jump after
				 * the first subexpression. */
    JumpFixup shortCircuitFixup2;
				/* Used to fix up the second jump to the







|
|

|

|

|
|







548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
 * Side effects:
 *	Adds instructions to envPtr to evaluate the expression at runtime.
 *
 *----------------------------------------------------------------------
 */

static int
CompileLandOrLorExpr(
    Tcl_Token *exprTokenPtr,	/* Points to TCL_TOKEN_SUB_EXPR token
				 * containing the "&&" or "||" operator. */
    int opIndex,		/* A code describing the expression operator:
				 * either OP_LAND or OP_LOR. */
    ExprInfo *infoPtr,		/* Describes the compilation state for the
				 * expression being compiled. */
    CompileEnv *envPtr,		/* Holds resulting instructions. */
    Tcl_Token **endPtrPtr)	/* If successful, a pointer to the token just
				 * after the last token in the subexpression
				 * is stored here. */
{
    JumpFixup shortCircuitFixup;/* Used to fix up the short circuit jump after
				 * the first subexpression. */
    JumpFixup shortCircuitFixup2;
				/* Used to fix up the second jump to the
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
 * Side effects:
 *	Adds instructions to envPtr to evaluate the expression at runtime.
 *
 *----------------------------------------------------------------------
 */

static int
CompileCondExpr(exprTokenPtr, infoPtr, envPtr, endPtrPtr)
    Tcl_Token *exprTokenPtr;	/* Points to TCL_TOKEN_SUB_EXPR token
				 * containing the "?" operator. */
    ExprInfo *infoPtr;		/* Describes the compilation state for the
				 * expression being compiled. */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
    Tcl_Token **endPtrPtr;	/* If successful, a pointer to the token just
				 * after the last token in the subexpression
				 * is stored here. */
{
    JumpFixup jumpAroundThenFixup, jumpAroundElseFixup;
				/* Used to update or replace one-byte jumps
				 * around the then and else expressions when
				 * their target PCs are determined. */







|
|

|

|
|







666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
 * Side effects:
 *	Adds instructions to envPtr to evaluate the expression at runtime.
 *
 *----------------------------------------------------------------------
 */

static int
CompileCondExpr(
    Tcl_Token *exprTokenPtr,	/* Points to TCL_TOKEN_SUB_EXPR token
				 * containing the "?" operator. */
    ExprInfo *infoPtr,		/* Describes the compilation state for the
				 * expression being compiled. */
    CompileEnv *envPtr,		/* Holds resulting instructions. */
    Tcl_Token **endPtrPtr)	/* If successful, a pointer to the token just
				 * after the last token in the subexpression
				 * is stored here. */
{
    JumpFixup jumpAroundThenFixup, jumpAroundElseFixup;
				/* Used to update or replace one-byte jumps
				 * around the then and else expressions when
				 * their target PCs are determined. */
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
 *	Adds instructions to envPtr to evaluate the math function at
 *	runtime.
 *
 *----------------------------------------------------------------------
 */

static int
CompileMathFuncCall(exprTokenPtr, funcName, infoPtr, envPtr, endPtrPtr)
    Tcl_Token *exprTokenPtr;	/* Points to TCL_TOKEN_SUB_EXPR token
				 * containing the math function call. */
    CONST char *funcName;	/* Name of the math function. */
    ExprInfo *infoPtr;		/* Describes the compilation state for the
				 * expression being compiled. */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
    Tcl_Token **endPtrPtr;	/* If successful, a pointer to the token just
				 * after the last token in the subexpression
				 * is stored here. */
{
    Tcl_DString cmdName;
    int objIndex;
    Tcl_Token *tokenPtr, *afterSubexprPtr;
    int argCount;







|
|

|
|

|
|







791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
 *	Adds instructions to envPtr to evaluate the math function at
 *	runtime.
 *
 *----------------------------------------------------------------------
 */

static int
CompileMathFuncCall(
    Tcl_Token *exprTokenPtr,	/* Points to TCL_TOKEN_SUB_EXPR token
				 * containing the math function call. */
    CONST char *funcName,	/* Name of the math function. */
    ExprInfo *infoPtr,		/* Describes the compilation state for the
				 * expression being compiled. */
    CompileEnv *envPtr,		/* Holds resulting instructions. */
    Tcl_Token **endPtrPtr)	/* If successful, a pointer to the token just
				 * after the last token in the subexpression
				 * is stored here. */
{
    Tcl_DString cmdName;
    int objIndex;
    Tcl_Token *tokenPtr, *afterSubexprPtr;
    int argCount;
873
874
875
876
877
878
879
880
881
882
883
884
885

886
887
888
889
890
891
892
893
894
895
896
897
898
 *	Sets the interpreter result to an error message describing the
 *	expression that was being compiled when the error occurred.
 *
 *----------------------------------------------------------------------
 */

static void
LogSyntaxError(infoPtr)
    ExprInfo *infoPtr;		/* Describes the compilation state for the
				 * expression being compiled. */
{
    Tcl_Obj *result =
	    Tcl_NewStringObj("syntax error in expression \"", -1);

    TclAppendLimitedToObj(result, infoPtr->expr,
	    (int)(infoPtr->lastChar - infoPtr->expr), 60, "");
    Tcl_AppendToObj(result, "\"", -1);
    Tcl_SetObjResult(infoPtr->interp, result);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|
|




>













871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
 *	Sets the interpreter result to an error message describing the
 *	expression that was being compiled when the error occurred.
 *
 *----------------------------------------------------------------------
 */

static void
LogSyntaxError(
    ExprInfo *infoPtr)		/* Describes the compilation state for the
				 * expression being compiled. */
{
    Tcl_Obj *result =
	    Tcl_NewStringObj("syntax error in expression \"", -1);

    TclAppendLimitedToObj(result, infoPtr->expr,
	    (int)(infoPtr->lastChar - infoPtr->expr), 60, "");
    Tcl_AppendToObj(result, "\"", -1);
    Tcl_SetObjResult(infoPtr->interp, result);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */