diff options
author | Kevin B Kenny <kennykb@acm.org> | 2005-05-10 18:33:37 (GMT) |
---|---|---|
committer | Kevin B Kenny <kennykb@acm.org> | 2005-05-10 18:33:37 (GMT) |
commit | 76e3b5eed61a674bce7f9c1e18380842dcff3fbf (patch) | |
tree | 2f108341f2c542f48532e6057d79bfa551a4245f /generic/tclParseExpr.c | |
parent | 5b510b75ec4a1d6fb55691bcf55dbf4b0b936624 (diff) | |
download | tcl-76e3b5eed61a674bce7f9c1e18380842dcff3fbf.zip tcl-76e3b5eed61a674bce7f9c1e18380842dcff3fbf.tar.gz tcl-76e3b5eed61a674bce7f9c1e18380842dcff3fbf.tar.bz2 |
Merged kennykb-numerics-branch back to the head; TIPs 132 and 232
Diffstat (limited to 'generic/tclParseExpr.c')
-rw-r--r-- | generic/tclParseExpr.c | 69 |
1 files changed, 26 insertions, 43 deletions
diff --git a/generic/tclParseExpr.c b/generic/tclParseExpr.c index 61860f6..c6a478e 100644 --- a/generic/tclParseExpr.c +++ b/generic/tclParseExpr.c @@ -13,7 +13,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclParseExpr.c,v 1.24 2005/05/03 18:08:19 dgp Exp $ + * RCS: @(#) $Id: tclParseExpr.c,v 1.25 2005/05/10 18:34:47 kennykb Exp $ */ #include "tclInt.h" @@ -1451,43 +1451,32 @@ ParsePrimaryExpr(infoPtr) return code; } if (infoPtr->lexeme != OPEN_PAREN) { - /* - * Guess what kind of error we have by trying to tell - * whether we have a function or variable name here. - * Alas, this makes the parser more tightly bound with the - * rest of the interpreter, but that is the only way to - * give a sensible message here. Still, it is not too - * serious as this is only done when generating an error. - */ - Interp *iPtr = (Interp *) infoPtr->parsePtr->interp; - Tcl_DString functionName; - Tcl_HashEntry *hPtr; /* - * Look up the name as a function name. We need a writable - * copy (DString) so we can terminate it with a NULL for - * the benefit of Tcl_FindHashEntry which operates on - * NULL-terminated string keys. + * Either there's a math function without a (, or a + * variable name without a '$'. */ - Tcl_DStringInit(&functionName); - hPtr = Tcl_FindHashEntry(&iPtr->mathFuncTable, - Tcl_DStringAppend(&functionName, tokenPtr->start, - tokenPtr->size)); - Tcl_DStringFree(&functionName); - /* - * Assume that we have an attempted variable reference - * unless we've got a function name, as the set of - * potential function names is typically much smaller. - */ - if (hPtr != NULL) { - LogSyntaxError(infoPtr, - "expected parenthesis enclosing function arguments"); - } else { - LogSyntaxError(infoPtr, - "variable references require preceding $"); - } + Tcl_Obj* errMsg + = Tcl_NewStringObj( "syntax error in expression \"", -1 ); + TclAppendLimitedToObj( errMsg, + infoPtr->originalExpr, + (int) (infoPtr->lastChar + - infoPtr->originalExpr ), + 63, + NULL ); + Tcl_AppendToObj( errMsg, "\": the word \"", -1 ); + Tcl_AppendToObj( errMsg, tokenPtr->start, tokenPtr->size ); + Tcl_AppendToObj( errMsg, + "\" requires a preceding $ if it's a variable ", + -1 ); + Tcl_AppendToObj( errMsg, + "or function arguments if it's a function", -1 ); + Tcl_SetObjResult( infoPtr->parsePtr->interp, errMsg ); + infoPtr->parsePtr->errorType = TCL_PARSE_SYNTAX; + infoPtr->parsePtr->term = infoPtr->start; return TCL_ERROR; + } code = GetLexeme(infoPtr); /* skip over '(' */ if (code != TCL_OK) { @@ -1666,23 +1655,17 @@ GetLexeme(infoPtr) * so we can set an terminating NULL to keep strtod from * scanning too far. */ - char *startPtr, *termPtr; + char *startPtr; + CONST char *termPtr; double doubleValue; Tcl_DString toParse; errno = 0; Tcl_DStringInit(&toParse); startPtr = Tcl_DStringAppend(&toParse, src, length); - doubleValue = strtod(startPtr, &termPtr); + doubleValue = TclStrToD(startPtr, &termPtr); Tcl_DStringFree(&toParse); if (termPtr != startPtr) { - if (errno != 0) { - if (interp != NULL) { - TclExprFloatError(interp, doubleValue); - } - parsePtr->errorType = TCL_PARSE_BAD_NUMBER; - return TCL_ERROR; - } /* * startPtr was the start of a valid double, copied @@ -2077,7 +2060,7 @@ ParseMaxDoubleLength(string, end) case 'C': case 'D': case 'E': case 'F': case 'I': case 'N': case 'P': case 'X': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'i': case 'n': case 'p': case 'x': - case '.': case '+': case '-': + case '.': case '+': case '-': case '(': case ' ': case ')': p++; break; default: |