]> git.webhop.me Git - lcd4linux.git/commitdiff
short circuit evaluation ported from volker_dev (r820,r822,r824)
authormichael <michael@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>
Wed, 31 Dec 2008 06:05:08 +0000 (06:05 +0000)
committermichael <michael@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>
Wed, 31 Dec 2008 06:05:08 +0000 (06:05 +0000)
git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@917 3ae390bd-cb1e-0410-b409-cd5a39f66f1f

evaluator.c

index 32d3af685b1d060962b5823b54d73602a196e9e3..c4dc78c8e732092d7220d58bfe0f9363723588ac 100644 (file)
@@ -972,10 +972,6 @@ static int EvalTree(NODE * Root)
     char *s1, *s2;
     RESULT *param[10];
 
-    for (i = 0; i < Root->Children; i++) {
-       EvalTree(Root->Child[i]);
-    }
-
     switch (Root->Token) {
 
     case T_NUMBER:
@@ -991,9 +987,12 @@ static int EvalTree(NODE * Root)
        DelResult(Root->Result);
        /* prepare parameter list */
        argc = Root->Children;
-       if (argc > 10)
+       if (argc > 10) {
+           error("evaluator: more than 10 children (operands) not supported!");
            argc = 10;
+       }
        for (i = 0; i < argc; i++) {
+           EvalTree(Root->Child[i]);
            param[i] = Root->Child[i]->Result;
        }
        if (Root->Function->argc < 0) {
@@ -1010,13 +1009,16 @@ static int EvalTree(NODE * Root)
        switch (Root->Operator) {
 
        case O_LST:             /* expression list: result is last expression */
-           i = Root->Children - 1;
+           for (i = 0; i < Root->Children; i++) {
+               EvalTree(Root->Child[i]);
+           }
            type = Root->Child[i]->Result->type;
            number = Root->Child[i]->Result->number;
            string = Root->Child[i]->Result->string;
            break;
 
        case O_SET:             /* variable assignment */
+           EvalTree(Root->Child[0]);
            CopyResult(&Root->Variable->value, Root->Child[0]->Result);
            type = Root->Child[0]->Result->type;
            number = Root->Child[0]->Result->number;
@@ -1024,7 +1026,9 @@ static int EvalTree(NODE * Root)
            break;
 
        case O_CND:             /* conditional expression */
+           EvalTree(Root->Child[0]);
            i = 1 + (R2N(Root->Child[0]->Result) == 0.0);
+           EvalTree(Root->Child[i]);
            type = Root->Child[i]->Result->type;
            number = Root->Child[i]->Result->number;
            string = Root->Child[i]->Result->string;
@@ -1032,61 +1036,92 @@ static int EvalTree(NODE * Root)
 
        case O_OR:              /* logical OR */
            type = R_NUMBER;
-           number = ((R2N(Root->Child[0]->Result) != 0.0) || (R2N(Root->Child[1]->Result) != 0.0));
+           EvalTree(Root->Child[0]);
+           if (R2N(Root->Child[0]->Result) == 0.0) {
+               EvalTree(Root->Child[1]);
+               number = (R2N(Root->Child[1]->Result) != 0.0);
+           } else {
+               number = 1.0;
+           }
            break;
 
        case O_AND:             /* logical AND */
            type = R_NUMBER;
-           number = ((R2N(Root->Child[0]->Result) != 0.0) && (R2N(Root->Child[1]->Result) != 0.0));
+           EvalTree(Root->Child[0]);
+           if (R2N(Root->Child[0]->Result) != 0.0) {
+               EvalTree(Root->Child[1]);
+               number = (R2N(Root->Child[1]->Result) != 0.0);
+           } else {
+               number = 0.0;
+           }
            break;
 
        case O_EQ:              /* numeric equal */
            type = R_NUMBER;
+           EvalTree(Root->Child[0]);
+           EvalTree(Root->Child[1]);
            number = (R2N(Root->Child[0]->Result) == R2N(Root->Child[1]->Result));
            break;
 
        case O_NE:              /* numeric not equal */
            type = R_NUMBER;
+           EvalTree(Root->Child[0]);
+           EvalTree(Root->Child[1]);
            number = (R2N(Root->Child[0]->Result) != R2N(Root->Child[1]->Result));
            break;
 
        case O_LT:              /* numeric less than */
            type = R_NUMBER;
+           EvalTree(Root->Child[0]);
+           EvalTree(Root->Child[1]);
            number = (R2N(Root->Child[0]->Result) < R2N(Root->Child[1]->Result));
            break;
 
        case O_LE:              /* numeric less equal */
            type = R_NUMBER;
+           EvalTree(Root->Child[0]);
+           EvalTree(Root->Child[1]);
            number = (R2N(Root->Child[0]->Result) <= R2N(Root->Child[1]->Result));
            break;
 
        case O_GT:              /* numeric greater than */
            type = R_NUMBER;
+           EvalTree(Root->Child[0]);
+           EvalTree(Root->Child[1]);
            number = (R2N(Root->Child[0]->Result) > R2N(Root->Child[1]->Result));
            break;
 
        case O_GE:              /* numeric greater equal */
            type = R_NUMBER;
+           EvalTree(Root->Child[0]);
+           EvalTree(Root->Child[1]);
            number = (R2N(Root->Child[0]->Result) >= R2N(Root->Child[1]->Result));
            break;
 
        case O_ADD:             /* addition */
            type = R_NUMBER;
+           EvalTree(Root->Child[0]);
+           EvalTree(Root->Child[1]);
            number = R2N(Root->Child[0]->Result) + R2N(Root->Child[1]->Result);
            break;
 
        case O_SUB:             /* subtraction */
            type = R_NUMBER;
+           EvalTree(Root->Child[0]);
+           EvalTree(Root->Child[1]);
            number = R2N(Root->Child[0]->Result) - R2N(Root->Child[1]->Result);
            break;
 
        case O_SGN:             /* sign */
            type = R_NUMBER;
+           EvalTree(Root->Child[0]);
            number = -R2N(Root->Child[0]->Result);
            break;
 
        case O_CAT:             /* string concatenation */
            type = R_STRING;
+           EvalTree(Root->Child[0]);
+           EvalTree(Root->Child[1]);
            s1 = R2S(Root->Child[0]->Result);
            s2 = R2S(Root->Child[1]->Result);
            string = malloc(strlen(s1) + strlen(s2) + 1);
@@ -1097,11 +1132,15 @@ static int EvalTree(NODE * Root)
 
        case O_MUL:             /* multiplication */
            type = R_NUMBER;
+           EvalTree(Root->Child[0]);
+           EvalTree(Root->Child[1]);
            number = R2N(Root->Child[0]->Result) * R2N(Root->Child[1]->Result);
            break;
 
        case O_DIV:             /* division */
            type = R_NUMBER;
+           EvalTree(Root->Child[0]);
+           EvalTree(Root->Child[1]);
            dummy = R2N(Root->Child[1]->Result);
            if (dummy == 0) {
                error("Evaluator: warning: division by zero");
@@ -1113,6 +1152,8 @@ static int EvalTree(NODE * Root)
 
        case O_MOD:             /* modulo */
            type = R_NUMBER;
+           EvalTree(Root->Child[0]);
+           EvalTree(Root->Child[1]);
            dummy = R2N(Root->Child[1]->Result);
            if (dummy == 0) {
                error("Evaluator: warning: division by zero");
@@ -1124,11 +1165,14 @@ static int EvalTree(NODE * Root)
 
        case O_POW:             /* x^y */
            type = R_NUMBER;
+           EvalTree(Root->Child[0]);
+           EvalTree(Root->Child[1]);
            number = pow(R2N(Root->Child[0]->Result), R2N(Root->Child[1]->Result));
            break;
 
        case O_NOT:             /* logical NOT */
            type = R_NUMBER;
+           EvalTree(Root->Child[0]);
            number = (R2N(Root->Child[0]->Result) == 0.0);
            break;