More comments.

This commit is contained in:
Dianne Skoll
2024-06-02 21:08:04 -04:00
parent 691185f22c
commit 4e164c4268
+163 -29
View File
@@ -663,6 +663,15 @@ eval_userfunc(expr_node *node, Value *locals, Value *ans, int *nonconst)
return r; return r;
} }
/***************************************************************/
/* */
/* evaluate_expression - evaluate an expression, possibly */
/* with timeout */
/* */
/* See evaluate_expr_node for a description of arguments and */
/* return value. */
/* */
/***************************************************************/
int int
evaluate_expression(expr_node *node, Value *locals, Value *ans, int *nonconst) evaluate_expression(expr_node *node, Value *locals, Value *ans, int *nonconst)
{ {
@@ -680,10 +689,8 @@ evaluate_expression(expr_node *node, Value *locals, Value *ans, int *nonconst)
/***************************************************************/ /***************************************************************/
/* */ /* */
/* evaluate_expr_node - the top-level expression evaluation */ /* evaluate_expr_node - evaluate an expression */
/* entry point. */
/* */ /* */
/* This is the entry point for evaluating an expression. */
/* Arguments: */ /* Arguments: */
/* node - the expr_node to evaluate */ /* node - the expr_node to evaluate */
/* locals - an array of arguments to a user-defined */ /* locals - an array of arguments to a user-defined */
@@ -803,9 +810,14 @@ static char const *how_to_op(int how)
} }
} }
/* /***************************************************************/
* All of the functions that implement operators /* */
*/ /* compare - evaluate a comparison operator. */
/* */
/* In addition to the usual arguments, "how" specifies */
/* specifically which comparison operator we're evaluating. */
/* */
/***************************************************************/
static int static int
compare(expr_node *node, Value *locals, Value *ans, int *nonconst, int how) compare(expr_node *node, Value *locals, Value *ans, int *nonconst, int how)
{ {
@@ -865,28 +877,67 @@ compare(expr_node *node, Value *locals, Value *ans, int *nonconst, int how)
return OK; return OK;
} }
/***************************************************************/
/* */
/* compare_eq - evaluate the "==" operator */
/* */
/***************************************************************/
static int compare_eq(expr_node *node, Value *locals, Value *ans, int *nonconst) { static int compare_eq(expr_node *node, Value *locals, Value *ans, int *nonconst) {
return compare(node, locals, ans, nonconst, EQ); return compare(node, locals, ans, nonconst, EQ);
} }
/***************************************************************/
/* */
/* compare_ne evaluate the "!=" operator */
/* */
/***************************************************************/
static int compare_ne(expr_node *node, Value *locals, Value *ans, int *nonconst) { static int compare_ne(expr_node *node, Value *locals, Value *ans, int *nonconst) {
return compare(node, locals, ans, nonconst, NE); return compare(node, locals, ans, nonconst, NE);
} }
/***************************************************************/
/* */
/* compare_le - evaluate the "<=" operator */
/* */
/***************************************************************/
static int compare_le(expr_node *node, Value *locals, Value *ans, int *nonconst) { static int compare_le(expr_node *node, Value *locals, Value *ans, int *nonconst) {
return compare(node, locals, ans, nonconst, LE); return compare(node, locals, ans, nonconst, LE);
} }
/***************************************************************/
/* */
/* compare_ge - evaluate the ">=" operator */
/* */
/***************************************************************/
static int compare_ge(expr_node *node, Value *locals, Value *ans, int *nonconst) { static int compare_ge(expr_node *node, Value *locals, Value *ans, int *nonconst) {
return compare(node, locals, ans, nonconst, GE); return compare(node, locals, ans, nonconst, GE);
} }
/***************************************************************/
/* */
/* compare_lt - evaluate the "<" operator */
/* */
/***************************************************************/
static int compare_lt(expr_node *node, Value *locals, Value *ans, int *nonconst) { static int compare_lt(expr_node *node, Value *locals, Value *ans, int *nonconst) {
return compare(node, locals, ans, nonconst, LT); return compare(node, locals, ans, nonconst, LT);
} }
/***************************************************************/
/* */
/* compare_gt - evaluate the ">" operator */
/* */
/***************************************************************/
static int compare_gt(expr_node *node, Value *locals, Value *ans, int *nonconst) { static int compare_gt(expr_node *node, Value *locals, Value *ans, int *nonconst) {
return compare(node, locals, ans, nonconst, GT); return compare(node, locals, ans, nonconst, GT);
} }
static int /***************************************************************/
add(expr_node *node, Value *locals, Value *ans, int *nonconst) /* */
/* add - evaluate the "+" operator */
/* */
/***************************************************************/
static int add(expr_node *node, Value *locals, Value *ans, int *nonconst)
{ {
int r; int r;
Value v1, v2; Value v1, v2;
@@ -1014,8 +1065,12 @@ add(expr_node *node, Value *locals, Value *ans, int *nonconst)
return E_BAD_TYPE; return E_BAD_TYPE;
} }
static int /***************************************************************/
subtract(expr_node *node, Value *locals, Value *ans, int *nonconst) /* */
/* subtract - evaluate the binary "-" operator */
/* */
/***************************************************************/
static int subtract(expr_node *node, Value *locals, Value *ans, int *nonconst)
{ {
int r; int r;
Value v1, v2; Value v1, v2;
@@ -1098,8 +1153,12 @@ subtract(expr_node *node, Value *locals, Value *ans, int *nonconst)
return E_BAD_TYPE; return E_BAD_TYPE;
} }
static int /***************************************************************/
multiply(expr_node *node, Value *locals, Value *ans, int *nonconst) /* */
/* multiply - evaluate the "*" operator */
/* */
/***************************************************************/
static int multiply(expr_node *node, Value *locals, Value *ans, int *nonconst)
{ {
int r; int r;
Value v1, v2; Value v1, v2;
@@ -1199,8 +1258,12 @@ multiply(expr_node *node, Value *locals, Value *ans, int *nonconst)
return E_BAD_TYPE; return E_BAD_TYPE;
} }
static int /***************************************************************/
divide(expr_node *node, Value *locals, Value *ans, int *nonconst) /* */
/* divide - evaluate the "/" operator */
/* */
/***************************************************************/
static int divide(expr_node *node, Value *locals, Value *ans, int *nonconst)
{ {
int r; int r;
Value v1, v2; Value v1, v2;
@@ -1233,8 +1296,12 @@ divide(expr_node *node, Value *locals, Value *ans, int *nonconst)
return E_BAD_TYPE; return E_BAD_TYPE;
} }
static int /***************************************************************/
do_mod(expr_node *node, Value *locals, Value *ans, int *nonconst) /* */
/* domod - evaluate the "%" operator */
/* */
/***************************************************************/
static int do_mod(expr_node *node, Value *locals, Value *ans, int *nonconst)
{ {
int r; int r;
Value v1, v2; Value v1, v2;
@@ -1268,8 +1335,12 @@ do_mod(expr_node *node, Value *locals, Value *ans, int *nonconst)
return E_BAD_TYPE; return E_BAD_TYPE;
} }
static int /***************************************************************/
logical_not(expr_node *node, Value *locals, Value *ans, int *nonconst) /* */
/* logical_not - evaluate the unary "!" operator */
/* */
/***************************************************************/
static int logical_not(expr_node *node, Value *locals, Value *ans, int *nonconst)
{ {
int r; int r;
Value v1; Value v1;
@@ -1287,8 +1358,12 @@ logical_not(expr_node *node, Value *locals, Value *ans, int *nonconst)
return OK; return OK;
} }
static int /***************************************************************/
unary_minus(expr_node *node, Value *locals, Value *ans, int *nonconst) /* */
/* unary_minus - evaluate the unary "-" operator */
/* */
/***************************************************************/
static int unary_minus(expr_node *node, Value *locals, Value *ans, int *nonconst)
{ {
int r; int r;
Value v1; Value v1;
@@ -1306,11 +1381,19 @@ unary_minus(expr_node *node, Value *locals, Value *ans, int *nonconst)
return OK; return OK;
} }
static int /***************************************************************/
logical_or(expr_node *node, Value *locals, Value *ans, int *nonconst) /* */
/* logical_or - evaluate the short-circuit || operator */
/* */
/***************************************************************/
static int logical_or(expr_node *node, Value *locals, Value *ans, int *nonconst)
{ {
Value v; Value v;
/* Evaluate first arg */
int r = evaluate_expr_node(node->child, locals, &v, nonconst); int r = evaluate_expr_node(node->child, locals, &v, nonconst);
/* Bail on error */
if (r != OK) return r; if (r != OK) return r;
if (v.type == STR_TYPE) { if (v.type == STR_TYPE) {
@@ -1318,11 +1401,15 @@ logical_or(expr_node *node, Value *locals, Value *ans, int *nonconst)
DestroyValue(v); DestroyValue(v);
return E_BAD_TYPE; return E_BAD_TYPE;
} }
/* If first arg is true, return it */
if (v.v.val) { if (v.v.val) {
*ans = v; *ans = v;
DBG(debug_evaluation_binop(ans, OK, &v, NULL, "||")); DBG(debug_evaluation_binop(ans, OK, &v, NULL, "||"));
return OK; return OK;
} }
/* Otherwise, evaluate and return second arg */
r = evaluate_expr_node(node->child->sibling, locals, ans, nonconst); r = evaluate_expr_node(node->child->sibling, locals, ans, nonconst);
if (r == OK && ans->type == STR_TYPE) { if (r == OK && ans->type == STR_TYPE) {
DBG(debug_evaluation_binop(ans, E_BAD_TYPE, &v, ans, "||")); DBG(debug_evaluation_binop(ans, E_BAD_TYPE, &v, ans, "||"));
@@ -1333,11 +1420,19 @@ logical_or(expr_node *node, Value *locals, Value *ans, int *nonconst)
return r; return r;
} }
static int /***************************************************************/
logical_and(expr_node *node, Value *locals, Value *ans, int *nonconst) /* */
/* logical_and - evaluate the short-circuit && operator */
/* */
/***************************************************************/
static int logical_and(expr_node *node, Value *locals, Value *ans, int *nonconst)
{ {
Value v; Value v;
/* Evaluate first arg */
int r = evaluate_expr_node(node->child, locals, &v, nonconst); int r = evaluate_expr_node(node->child, locals, &v, nonconst);
/* Bail on error */
if (r != OK) return r; if (r != OK) return r;
if (v.type == STR_TYPE) { if (v.type == STR_TYPE) {
@@ -1345,12 +1440,16 @@ logical_and(expr_node *node, Value *locals, Value *ans, int *nonconst)
DestroyValue(v); DestroyValue(v);
return E_BAD_TYPE; return E_BAD_TYPE;
} }
/* If first arg is false, return it */
if (!v.v.val) { if (!v.v.val) {
ans->type = v.type; ans->type = v.type;
ans->v.val = 0; ans->v.val = 0;
DBG(debug_evaluation_binop(ans, OK, &v, NULL, "&&")); DBG(debug_evaluation_binop(ans, OK, &v, NULL, "&&"));
return OK; return OK;
} }
/* Otherwise, evaluate and return second arg */
r = evaluate_expr_node(node->child->sibling, locals, ans, nonconst); r = evaluate_expr_node(node->child->sibling, locals, ans, nonconst);
if (r == OK && ans->type == STR_TYPE) { if (r == OK && ans->type == STR_TYPE) {
DBG(debug_evaluation_binop(ans, E_BAD_TYPE, &v, NULL, "&&")); DBG(debug_evaluation_binop(ans, E_BAD_TYPE, &v, NULL, "&&"));
@@ -1559,9 +1658,15 @@ static int peek_expr_token(DynamicBuffer *buf, char const *in)
return parse_expr_token_aux(buf, &in); return parse_expr_token_aux(buf, &in);
} }
/* Recursively free an expression tree */ /***************************************************************/
expr_node * /* */
free_expr_tree(expr_node *node) /* free_expr_tree */
/* */
/* Recursively free the expr_node tree rooted at node */
/* Always returns NULL */
/* */
/***************************************************************/
expr_node * free_expr_tree(expr_node *node)
{ {
if (node) { if (node) {
ExprNodesUsed--; ExprNodesUsed--;
@@ -1580,6 +1685,14 @@ free_expr_tree(expr_node *node)
return NULL; return NULL;
} }
/***************************************************************/
/* */
/* set_long_name - set a long name in an expr_node */
/* */
/* Set the name field in an expr_node that's too long to fit */
/* in u.name -- instead, set in u.value.v.str */
/* */
/***************************************************************/
static int set_long_name(expr_node *node, char const *s) static int set_long_name(expr_node *node, char const *s)
{ {
char *buf; char *buf;
@@ -1595,8 +1708,29 @@ static int set_long_name(expr_node *node, char const *s)
return OK; return OK;
} }
static expr_node * /***************************************************************/
parse_function_call(char const **e, int *r, Var *locals) /* */
/* pares_function_call - parse a function call */
/* */
/* Starting from *e, parse a function call and return the */
/* parsed expr_node tree */
/* */
/* All parsing functions have the following arguments and */
/* return value: */
/* */
/* e - the current parse pointer. *e points to the */
/* character we're readin, and *e is updated as we parse */
/* */
/* r - holds the return code. Set to OK if all is well */
/* or a non-zero error code on error */
/* */
/* locals - an array of Vars representing named arguments */
/* for a user-defined function */
/* */
/* Returns an expr_node on success, NULL on failure. */
/* */
/***************************************************************/
static expr_node * parse_function_call(char const **e, int *r, Var *locals)
{ {
expr_node *node = alloc_expr_node(r); expr_node *node = alloc_expr_node(r);
expr_node *arg; expr_node *arg;