summaryrefslogtreecommitdiffstats
path: root/generic/tclParseExpr.c
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2001-12-06 10:59:17 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2001-12-06 10:59:17 (GMT)
commit6425a01b7a2896172c65f9883f0b56792a6fd263 (patch)
treee6c39593e08b79465eac7aa0dd4828dc16e96440 /generic/tclParseExpr.c
parent5c1a1598d524e7cdba42a48aef9949ffd3802fd6 (diff)
downloadtcl-6425a01b7a2896172c65f9883f0b56792a6fd263.zip
tcl-6425a01b7a2896172c65f9883f0b56792a6fd263.tar.gz
tcl-6425a01b7a2896172c65f9883f0b56792a6fd263.tar.bz2
More expr syntax error improvements
Diffstat (limited to 'generic/tclParseExpr.c')
-rw-r--r--generic/tclParseExpr.c58
1 files changed, 43 insertions, 15 deletions
diff --git a/generic/tclParseExpr.c b/generic/tclParseExpr.c
index fa50209..defdecf 100644
--- a/generic/tclParseExpr.c
+++ b/generic/tclParseExpr.c
@@ -12,7 +12,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.10 2001/12/04 15:36:29 dkf Exp $
+ * RCS: @(#) $Id: tclParseExpr.c,v 1.11 2001/12/06 10:59:17 dkf Exp $
*/
#include "tclInt.h"
@@ -133,7 +133,6 @@ typedef struct ParseInfo {
* entries must match the order and number of the lexeme definitions above.
*/
-#ifdef TCL_COMPILE_DEBUG
static char *lexemeStrings[] = {
"LITERAL", "FUNCNAME",
"[", "{", "(", ")", "$", "\"", ",", "END", "UNKNOWN", "UNKNOWN_CHAR",
@@ -142,7 +141,6 @@ static char *lexemeStrings[] = {
"&", "^", "|", "&&", "||", "?", ":",
"!", "~", "eq", "ne",
};
-#endif /* TCL_COMPILE_DEBUG */
/*
* Declarations for local procedures to this file:
@@ -1387,8 +1385,39 @@ ParsePrimaryExpr(infoPtr)
return code;
}
if (infoPtr->lexeme != OPEN_PAREN) {
- LogSyntaxError(infoPtr,
- "expected a parenthesis enclosing function arguments");
+ /*
+ * 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;
+ char savedChar;
+ Tcl_HashEntry *hPtr;
+
+ /*
+ * Look up the name as a function name; note that this
+ * requires the expression to be in writable memory.
+ */
+ savedChar = tokenPtr->start[tokenPtr->size];
+ tokenPtr->start[tokenPtr->size] = '\0';
+ hPtr = Tcl_FindHashEntry(&iPtr->mathFuncTable, tokenPtr->start);
+ tokenPtr->start[tokenPtr->size] = savedChar;
+
+ /*
+ * 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 $");
+ }
return TCL_ERROR;
}
code = GetLexeme(infoPtr); /* skip over '(' */
@@ -1438,18 +1467,17 @@ ParsePrimaryExpr(infoPtr)
case COLON:
LogSyntaxError(infoPtr, "unexpected ternary 'else' separator");
return TCL_ERROR;
+ case CLOSE_PAREN:
+ LogSyntaxError(infoPtr, "unexpected close parenthesis");
+ return TCL_ERROR;
- default:
-#ifdef TCL_COMPILE_DEBUG
- {
- char buf[64];
- sprintf(buf, "unexpected operator %s", lexemeStrings[lexeme]);
- LogSyntaxError(infoPtr, buf);
- }
-#else
- LogSyntaxError(infoPtr, "unexpected operator");
-#endif
+ default: {
+ char buf[64];
+
+ sprintf(buf, "unexpected operator %s", lexemeStrings[lexeme]);
+ LogSyntaxError(infoPtr, buf);
return TCL_ERROR;
+ }
}
/*