diff options
author | Steve Bennett <steveb@workware.net.au> | 2010-11-01 09:03:24 +1000 |
---|---|---|
committer | Steve Bennett <steveb@workware.net.au> | 2011-05-31 15:19:23 +1000 |
commit | a73c44be97e43cc8b724c41d3550ba9e46c91ae8 (patch) | |
tree | 9f5f8be302d2f967f82123e20d371c017f964ace | |
parent | a6882165e2f2d8420b709fb458d1cd17945c8e84 (diff) | |
download | jimtcl-a73c44be97e43cc8b724c41d3550ba9e46c91ae8.zip jimtcl-a73c44be97e43cc8b724c41d3550ba9e46c91ae8.tar.gz jimtcl-a73c44be97e43cc8b724c41d3550ba9e46c91ae8.tar.bz2 |
Support $(...) expr shorthand syntax
Signed-off-by: Steve Bennett <steveb@workware.net.au>
-rw-r--r-- | jim.c | 37 | ||||
-rw-r--r-- | tests/exprsugar.test | 52 |
2 files changed, 85 insertions, 4 deletions
@@ -1065,8 +1065,10 @@ void *Jim_StackPeek(Jim_Stack *stack) #define JIM_TT_EXPR_INT 13 #define JIM_TT_EXPR_DOUBLE 14 +#define JIM_TT_EXPRSUGAR 15 /* $(expression) */ + /* Operator token types start here */ -#define JIM_TT_EXPR_OP 15 +#define JIM_TT_EXPR_OP 20 #define TOKEN_IS_SEP(type) (type >= JIM_TT_SEP && type <= JIM_TT_EOF) @@ -1352,7 +1354,7 @@ static int JimParseVar(struct JimParserCtx *pc) count--; } } - ttype = JIM_TT_DICTSUGAR; + ttype = (*pc->tstart == '(') ? JIM_TT_EXPRSUGAR : JIM_TT_DICTSUGAR; if (count == 0) { if (*pc->p != '\0') { pc->p++; @@ -4118,6 +4120,18 @@ static Jim_Obj *JimExpandDictSugar(Jim_Interp *interp, Jim_Obj *objPtr) return resObjPtr; } +static Jim_Obj *JimExpandExprSugar(Jim_Interp *interp, Jim_Obj *objPtr) +{ + Jim_Obj *resultObjPtr; + + if (Jim_EvalExpression(interp, objPtr, &resultObjPtr) == JIM_OK) { + /* Note that the result has a ref count of 1, but we need a ref count of 0 */ + resultObjPtr->refCount--; + return resultObjPtr; + } + return NULL; +} + /* ----------------------------------------------------------------------------- * CallFrame * ---------------------------------------------------------------------------*/ @@ -7530,8 +7544,13 @@ static int JimParseExpression(struct JimParserCtx *pc) case '$': if (JimParseVar(pc) == JIM_ERR) return JimParseExprOperator(pc); - else + else { + /* Don't allow expr sugar in expressions */ + if (pc->tt == JIM_TT_EXPRSUGAR) { + return JIM_ERR; + } return JIM_OK; + } break; case '0': case '1': @@ -7679,7 +7698,7 @@ const char *jim_tt_name(int type) { static const char * const tt_names[JIM_TT_EXPR_OP] = { "NIL", "STR", "ESC", "VAR", "ARY", "CMD", "SEP", "EOL", "EOF", "LIN", "WRD", "(((", ")))", "INT", - "DBL" }; + "DBL", "$()" }; if (type < JIM_TT_EXPR_OP) { return tt_names[type]; } @@ -8089,6 +8108,7 @@ static ExprByteCode *ExprCreateByteCode(Jim_Interp *interp, const ParseTokenList case JIM_TT_ESC: case JIM_TT_VAR: case JIM_TT_DICTSUGAR: + case JIM_TT_EXPRSUGAR: case JIM_TT_CMD: token->objPtr = Jim_NewStringObj(interp, t->token, t->len); token->type = t->type; @@ -9407,6 +9427,9 @@ static int JimSubstOneToken(Jim_Interp *interp, const ScriptToken *token, Jim_Ob case JIM_TT_DICTSUGAR: objPtr = JimExpandDictSugar(interp, token->objPtr); break; + case JIM_TT_EXPRSUGAR: + objPtr = JimExpandExprSugar(interp, token->objPtr); + break; case JIM_TT_CMD: switch (Jim_EvalObj(interp, token->objPtr)) { case JIM_OK: @@ -9662,6 +9685,9 @@ int Jim_EvalObj(Jim_Interp *interp, Jim_Obj *scriptObjPtr) case JIM_TT_VAR: wordObjPtr = Jim_GetVariable(interp, token[i].objPtr, JIM_ERRMSG); break; + case JIM_TT_EXPRSUGAR: + wordObjPtr = JimExpandExprSugar(interp, token[i].objPtr); + break; case JIM_TT_DICTSUGAR: wordObjPtr = JimExpandDictSugar(interp, token[i].objPtr); break; @@ -11828,6 +11854,9 @@ static int Jim_DebugCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar case JIM_TT_DICTSUGAR: type = "dictsugar"; break; + case JIM_TT_EXPRSUGAR: + type = "exprsugar"; + break; case JIM_TT_ESC: type = "subst"; break; diff --git a/tests/exprsugar.test b/tests/exprsugar.test new file mode 100644 index 0000000..9579203 --- /dev/null +++ b/tests/exprsugar.test @@ -0,0 +1,52 @@ +source [file dirname [info script]]/testing.tcl + +needs constraint jim + +# Test the expr-sugar syntax: $(...) + +test exprsugar-1.1 {Simple operations} { + set x $(2) +} 2 +test exprsugar-1.2 {Simple operations} { + set x $(-3) +} -3 +test exprsugar-1.3 {Simple operations} { + set x $(!0) +} 1 +test exprsugar-1.4 {Simple operations} { + set a 3 + set x $($a) +} 3 +test exprsugar-1.5 {Simple operations} { + set x $($a + 4) +} 7 +test exprsugar-1.6 {Simple operations} { + set x $(6 * 7 + 2) +} 44 +test exprsugar-1.7 {Simple operations} { + set a bb + set x $($a in {aa bb cc}) +} 1 +test exprsugar-1.8 {Simple operations} { + set a 1 + set x $($a ? "yes" : "no") +} yes +test exprsugar-1.9 {Simple operations} { + set a 1 + set x $([incr a]) + list $a $x +} {2 2} +# expr sugar inside an expression is an error +test exprsugar-1.10 {Simple operations} { + catch {set x $(1 + $(5 * 7))} +} 1 +test exprsugar-1.11 {Simple operations} { + unset a + set a(b) 3 + set x $(2 + $a(b)) +} 5 +test exprsugar-1.12 {Simple operations} { + set x $((2 + 4)) +} 6 + +testreport |