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:
*/
|