1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
/*
* tclCompExpr.c --
*
* This file contains the code to parse and compile Tcl expressions
* and implementations of the Tcl commands corresponding to expression
* operators, such as the command ::tcl::mathop::+ .
*
* Contributions from Don Porter, NIST, 2006-2007. (not subject to US copyright)
*
* 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.82 2007/08/27 15:12:38 dgp Exp $
*/
#include "tclInt.h"
#include "tclCompile.h" /* CompileEnv */
/*
* Expression parsing takes place in the routine ParseExpr(). It takes a
|
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
/*
* tclCompExpr.c --
*
* This file contains the code to parse and compile Tcl expressions
* and implementations of the Tcl commands corresponding to expression
* operators, such as the command ::tcl::mathop::+ .
*
* Contributions from Don Porter, NIST, 2006-2007. (not subject to US copyright)
*
* 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.83 2007/08/27 19:56:51 dgp Exp $
*/
#include "tclInt.h"
#include "tclCompile.h" /* CompileEnv */
/*
* Expression parsing takes place in the routine ParseExpr(). It takes a
|
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
|
*
* Side effects:
* Adds instructions to envPtr to evaluate the expression at runtime.
*
*----------------------------------------------------------------------
*/
/* TODO: Convert this to return void. Generate error throwing bytecode
* for syntax errors instead of failing to compile. */
int
TclCompileExpr(
Tcl_Interp *interp, /* Used for error reporting. */
const char *script, /* The source script to compile. */
int numBytes, /* Number of bytes in script. */
CompileEnv *envPtr) /* Holds resulting instructions. */
{
OpNode *opTree = NULL; /* Will point to the tree of operators */
|
<
<
|
|
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
|
*
* Side effects:
* Adds instructions to envPtr to evaluate the expression at runtime.
*
*----------------------------------------------------------------------
*/
void
TclCompileExpr(
Tcl_Interp *interp, /* Used for error reporting. */
const char *script, /* The source script to compile. */
int numBytes, /* Number of bytes in script. */
CompileEnv *envPtr) /* Holds resulting instructions. */
{
OpNode *opTree = NULL; /* Will point to the tree of operators */
|
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
|
TclAdvanceLines(&envPtr->line, script,
script + TclParseAllWhiteSpace(script, numBytes));
Tcl_ListObjGetElements(NULL, litList, &objc, (Tcl_Obj ***)&litObjv);
Tcl_ListObjGetElements(NULL, funcList, &objc, &funcObjv);
CompileExprTree(interp, opTree, 0, &litObjv, funcObjv,
parsePtr->tokenPtr, envPtr, 1 /* optimize */);
}
Tcl_FreeParse(parsePtr);
TclStackFree(interp, parsePtr);
Tcl_DecrRefCount(funcList);
Tcl_DecrRefCount(litList);
ckfree((char *) opTree);
return code;
}
/*
*----------------------------------------------------------------------
*
* ExecConstantExprTree --
* Compiles and executes bytecode for the subexpression tree at index
|
>
>
<
|
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
|
TclAdvanceLines(&envPtr->line, script,
script + TclParseAllWhiteSpace(script, numBytes));
Tcl_ListObjGetElements(NULL, litList, &objc, (Tcl_Obj ***)&litObjv);
Tcl_ListObjGetElements(NULL, funcList, &objc, &funcObjv);
CompileExprTree(interp, opTree, 0, &litObjv, funcObjv,
parsePtr->tokenPtr, envPtr, 1 /* optimize */);
} else {
TclCompileSyntaxError(interp, envPtr);
}
Tcl_FreeParse(parsePtr);
TclStackFree(interp, parsePtr);
Tcl_DecrRefCount(funcList);
Tcl_DecrRefCount(litList);
ckfree((char *) opTree);
}
/*
*----------------------------------------------------------------------
*
* ExecConstantExprTree --
* Compiles and executes bytecode for the subexpression tree at index
|
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
|
if (optimize && nodes[next].constant) {
Tcl_InterpState save = Tcl_SaveInterpState(interp, TCL_OK);
if (ExecConstantExprTree(interp, nodes, next, litObjvPtr)
== TCL_OK) {
TclEmitPush(TclAddLiteralObj(envPtr,
Tcl_GetObjResult(interp), NULL), envPtr);
} else {
char *cmd;
int length;
Tcl_Obj *returnCmd;
Tcl_Parse *parsePtr = (Tcl_Parse *)
TclStackAlloc(interp, sizeof(Tcl_Parse));
TclNewLiteralStringObj(returnCmd, "return ");
Tcl_IncrRefCount(returnCmd);
Tcl_AppendObjToObj(returnCmd,
Tcl_GetReturnOptions(interp, TCL_ERROR));
Tcl_ListObjAppendElement(NULL, returnCmd,
Tcl_GetObjResult(interp));
cmd = Tcl_GetStringFromObj(returnCmd, &length);
Tcl_ParseCommand(interp, cmd, length, 0, parsePtr);
TclCompileReturnCmd(interp, parsePtr, envPtr);
Tcl_DecrRefCount(returnCmd);
Tcl_FreeParse(parsePtr);
TclStackFree(interp, parsePtr);
}
Tcl_RestoreInterpState(interp, save);
convert = 0;
} else {
nodePtr = nodes + next;
}
}
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
|
if (optimize && nodes[next].constant) {
Tcl_InterpState save = Tcl_SaveInterpState(interp, TCL_OK);
if (ExecConstantExprTree(interp, nodes, next, litObjvPtr)
== TCL_OK) {
TclEmitPush(TclAddLiteralObj(envPtr,
Tcl_GetObjResult(interp), NULL), envPtr);
} else {
TclCompileSyntaxError(interp, envPtr);
}
Tcl_RestoreInterpState(interp, save);
convert = 0;
} else {
nodePtr = nodes + next;
}
}
|