mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-16 22:38:37 +02:00
Make "value()" evaluate its second argument lazily.
If the variable whose name is the first argument exists, don't bother evaluating the second argument.
This commit is contained in:
90
src/funcs.c
90
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;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user