diff --git a/src/funcs.c b/src/funcs.c index 2ae5dcc8..9f44b67d 100644 --- a/src/funcs.c +++ b/src/funcs.c @@ -193,7 +193,7 @@ static int FTypeof (func_info *); static int FTzconvert (func_info *); static int FUTCToLocal (func_info *); static int FUpper (func_info *); -static int FValue (func_info *); +static int FValue (expr_node *, Value *, Value *, int *); static int FVersion (func_info *); static int FWeekno (func_info *); static int FWkday (func_info *); @@ -365,7 +365,7 @@ BuiltinFunc Func[] = { { "tzconvert", 2, 3, 0, FTzconvert, NULL }, { "upper", 1, 1, 1, FUpper, NULL }, { "utctolocal", 1, 1, 1, FUTCToLocal, NULL }, - { "value", 1, 2, 0, FValue, NULL }, + { "value", 1, 2, 0, NULL, FValue }, /* NEW-STYLE */ { "version", 0, 0, 1, FVersion, NULL }, { "weekno", 0, 3, 0, FWeekno, NULL }, { "wkday", 1, 1, 1, FWkday, NULL }, @@ -1488,6 +1488,7 @@ static int FChoose(expr_node *node, Value *locals, Value *ans, int *nonconst) PUT(GetErr(E_BAD_TYPE)); OUT(); } + DestroyValue(v); Eprint("choose(): %s", GetErr(E_BAD_TYPE)); return E_BAD_TYPE; } @@ -1695,26 +1696,83 @@ static int FGetenv(func_info *info) /* it is returned if variable is undefined. */ /* */ /***************************************************************/ -static int FValue(func_info *info) +static int FValue(expr_node *node, Value *locals, Value *ans, int *nonconst) { + DynamicBuffer DebugBuf; + expr_node *cur; + int r; + Value varname; Var *v; - ASSERT_TYPE(0, STR_TYPE); - switch(Nargs) { - case 1: - return GetVarValue(ARGSTR(0), &RetVal); + *nonconst = 1; + DBG(DBufInit(&DebugBuf)); - case 2: - v = FindVar(ARGSTR(0), 0); - if (!v) { - DCOPYVAL(RetVal, ARG(1)); - return OK; - } else { - v->used_since_set = 1; - return CopyValue(&RetVal, &v->v); + cur = node->child; + r = evaluate_expr_node(cur, locals, &varname, nonconst); + if (r != OK) { + DBG(DBufFree(&DebugBuf)); + return r; + } + + DBG(PUT("value(")); + DBG(PUT(PrintValue(&varname, NULL))); + if (node->num_kids == 1) { + DBG(PUT(") => ")); + } else { + DBG(PUT(", ")); + } + if (varname.type != STR_TYPE) { + if (DebugFlag & DB_PRTEXPR) { + if (node->num_kids == 2) { + PUT("?) => "); + } + PUT(GetErr(E_BAD_TYPE)); + OUT(); + } + DestroyValue(varname); + return E_BAD_TYPE; + } + + v = FindVar(varname.v.str, 0); + if (!v) { + r = E_NOSUCH_VAR; + } else { + r = OK; + v->used_since_set = 1; + CopyValue(ans, &v->v); + } + DestroyValue(varname); + if (r == OK || node->num_kids == 1) { + if (DebugFlag & DB_PRTEXPR) { + if (node->num_kids == 2) { + PUT("?) => "); + } + if (r != OK) { + PUT(GetErr(r)); + } else { + PUT(PrintValue(ans, NULL)); + } + OUT(); + } + return r; + } + + r = evaluate_expr_node(cur->sibling, locals, ans, nonconst); + if (DebugFlag & DB_PRTEXPR) { + if (node->num_kids == 2) { + if (r != OK) { + PUT(GetErr(r)); + PUT(") => "); + PUT(GetErr(r)); + } else { + PUT(PrintValue(ans, NULL)); + PUT(") => "); + PUT(PrintValue(ans, NULL)); + } + OUT(); } } - return OK; + return r; } /***************************************************************/ diff --git a/tests/test.cmp b/tests/test.cmp index e4fb221c..f0adbff2 100644 --- a/tests/test.cmp +++ b/tests/test.cmp @@ -16554,10 +16554,26 @@ shell("ls") => RUN disabled ../tests/test.rem(1588): shell(): RUN disabled RUN disabled +# "value" should use lazy evaluation +set a value(4:33) +value(04:33) => Type mismatch +../tests/test.rem(1591): Type mismatch +set a value('2020-01-01', 42) +value(2020-01-01, ?) => Type mismatch +../tests/test.rem(1592): Type mismatch +set a value("nosuchvar") +value("nosuchvar") => Undefined variable +../tests/test.rem(1593): Undefined variable +set a value("nosuchvar", 42) +value("nosuchvar", 42) => 42 +set a value("a", 42) +value("a", ?) => 42 +set a value("a") +value("a") => 42 DEBUG -x DEBUG -e -../tests/test.rem(1596): eval(): Too many recursive function calls +../tests/test.rem(1603): eval(): Too many recursive function calls Base: 1991-02-09 Base: 1991-02-09 Variable hash table statistics: diff --git a/tests/test.rem b/tests/test.rem index b2bd6ab3..98480318 100644 --- a/tests/test.rem +++ b/tests/test.rem @@ -1587,6 +1587,13 @@ FUNSET i set a "eval(\"1\")+ shell(\"ls\")" set b eval(a) +# "value" should use lazy evaluation +set a value(4:33) +set a value('2020-01-01', 42) +set a value("nosuchvar") +set a value("nosuchvar", 42) +set a value("a", 42) +set a value("a") DEBUG -x DEBUG -e