mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-30 04:47:06 +02:00
More comments.
This commit is contained in:
+163
-29
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user