# HG changeset patch # User Matti Hamalainen # Date 1366128162 -10800 # Node ID 837ad9dcc3483c7b0169659a9ea69fb2e44ffdbe # Parent 391310cfba26882b8ee8e2c3ec6929bb2706696d More work on evaluator reordering pass. diff -r 391310cfba26 -r 837ad9dcc348 dmeval.c --- a/dmeval.c Tue Apr 16 17:28:32 2013 +0300 +++ b/dmeval.c Tue Apr 16 19:02:42 2013 +0300 @@ -273,7 +273,7 @@ static DMEvalNode *dm_eval_push_node(DMEvalNode **list, DMEvalNode *src) { - DMEvalNode *node = dmCalloc(1, sizeof(DMEvalNode)); + DMEvalNode *tmp, *node = dmCalloc(1, sizeof(DMEvalNode)); int i; if (node == NULL) @@ -282,10 +282,22 @@ node->op = src->op; node->val = src->val; node->id = src->id; - node->subexpr = src->subexpr; - - for (i = 0; i < DM_MAX_ARGS; i++) - node->args[i] = src->args[i]; + node->ok = src->ok; + + if (src->op == OP_SUBEXPR && src->subexpr != NULL) + { + for (tmp = src->subexpr; tmp != NULL; tmp = tmp->next) + dm_eval_push_node(&(node->subexpr), tmp); + } + + if (src->op == OP_FUNC) + { + for (i = 0; i < src->id->nargs; i++) + { + for (tmp = src->args[i]; tmp != NULL; tmp = tmp->next) + dm_eval_push_node(&(node->args[i]), tmp); + } + } return dm_eval_insert_node(list, node); } @@ -743,102 +755,22 @@ LOWEST */ - -static int dm_eval_reorder_do(DMEvalContext *ev, DMEvalNode *node, DMEvalNode **result, int pass) +static int dm_eval_reorder_pass0(DMEvalContext *ev, DMEvalNode *node, DMEvalNode **result) { DMEvalNode *list = NULL; + DMEvalNode *tmp, *sub; int i, res; - while (node != NULL) + for (; node != NULL; node = node->next) + switch (node->op) { - DMEvalNode *tmp, *sub; - - if (pass == 0) - switch (node->op) - { - case OP_SUB: - if ((tmp = dm_eval_peek_node(&list)) == NULL || tmp->op <= OP_FUNC) - { - // Add subexpression node - if ((sub = dm_eval_add_node(&list, OP_SUBEXPR)) == NULL) - return -3; - - // Add this operator into subexpression - dm_eval_add_node(&(sub->subexpr), node->op); - - // Next node - node = node->next; - if (node == NULL) - return -72; - - if (node->op == OP_FUNC || node->op == OP_SUBEXPR) - { - // It's a function or sub-expression - if ((tmp = dm_eval_push_node(&(sub->subexpr), node)) == NULL) - return -178; - - if ((res = dm_eval_reorder_do(ev, node->subexpr, &(tmp->subexpr), pass)) != 0) - return res; - } - else - dm_eval_push_node(&(sub->subexpr), node); - } - else - { - if (dm_eval_push_node(&list, node) == NULL) - return -32; - } - - node = node->next; - break; - - default: - if (dm_eval_push_node(&list, node) == NULL) - return -32; - - node = node->next; - break; - } - else - if (pass == 1) - switch (node->op) - { - case OP_FUNC: - if ((tmp = dm_eval_push_node(&list, node)) == NULL) - return -1; - - for (i = 0; i < node->id->nargs; i++) - { - if ((res = dm_eval_reorder_do(ev, node->args[i], &(tmp->args[i]), pass)) != 0) - return res; - } - node = node->next; - break; - - case OP_SUBEXPR: - if ((tmp = dm_eval_push_node(&list, node)) == NULL) - return -1; - - if ((res = dm_eval_reorder_do(ev, node->subexpr, &(tmp->subexpr), pass)) != 0) - return res; - node = node->next; - break; - - - case OP_MUL: - case OP_DIV: - case OP_MOD: - // Pop previous node, f.e. 5*3 -> 5 - if ((tmp = dm_eval_pop_node(&list)) == NULL) - return -24; - + case OP_SUB: + if ((tmp = dm_eval_peek_node(&list)) == NULL || tmp->op <= OP_FUNC) + { // Add subexpression node if ((sub = dm_eval_add_node(&list, OP_SUBEXPR)) == NULL) return -3; - // Add popped node into subexpression - dm_eval_push_node(&(sub->subexpr), tmp); - // Add this operator into subexpression dm_eval_add_node(&(sub->subexpr), node->op); @@ -847,96 +779,175 @@ if (node == NULL) return -72; - if (node->op == OP_FUNC || node->op == OP_SUBEXPR) - { - // It's a function or sub-expression - if ((tmp = dm_eval_push_node(&(sub->subexpr), node)) == NULL) - return -178; - - if ((res = dm_eval_reorder_do(ev, node->subexpr, &(tmp->subexpr), pass)) != 0) - return res; - } - else - dm_eval_push_node(&(sub->subexpr), node); + dm_eval_push_node(&(sub->subexpr), node); + } + else + if (dm_eval_push_node(&list, node) == NULL) + return -32; + + break; + + case OP_FUNC: + if ((tmp = dm_eval_push_node(&list, node)) == NULL) + return -1; + + for (i = 0; i < node->id->nargs; i++) + { + if ((res = dm_eval_reorder(ev, node->args[i], &(tmp->args[i]))) != 0) + return res; + } + break; + + case OP_SUBEXPR: + if ((tmp = dm_eval_push_node(&list, node)) == NULL) + return -1; - node = node->next; - break; - - case OP_LSHIFT: - case OP_RSHIFT: - // Bitshift operator precedence is .. different - if (dm_eval_push_node(&list, node) == NULL) - return -32; - - if ((sub = dm_eval_add_node(&list, OP_SUBEXPR)) == NULL) - return -3; + if ((res = dm_eval_reorder(ev, node->subexpr, &(tmp->subexpr))) != 0) + return res; + break; + + default: + if (dm_eval_push_node(&list, node) == NULL) + return -32; + break; + } + + *result = list; + return 0; +} - node = node->next; - if (node == NULL) - return -14; + +static int dm_eval_reorder_pass1(DMEvalContext *ev, DMEvalNode *node, DMEvalNode **result) +{ + DMEvalNode *list = NULL; + DMEvalNode *tmp, *sub; - tmp = NULL; - if ((res = dm_eval_reorder_do(ev, node, &tmp, pass)) != 0) - return res; - - sub->subexpr = tmp; - node = NULL; - break; - - - default: + for (; node != NULL; node = node->next) + switch (node->op) + { + case OP_MUL: + case OP_DIV: + case OP_MOD: + if (node->ok) + { if (dm_eval_push_node(&list, node) == NULL) return -32; + break; + } - node = node->next; - break; - } - else - if (pass == 2) - switch (node->op) - { - case OP_ADD: - // Pop previous node, f.e. 5*3 -> 5 - if ((tmp = dm_eval_pop_node(&list)) == NULL) - return -24; + // Pop previous node, f.e. 5*3 -> 5 + if ((tmp = dm_eval_pop_node(&list)) == NULL) + return -24; + + // Add subexpression node + if ((sub = dm_eval_add_node(&list, OP_SUBEXPR)) == NULL) + return -3; + + // Add popped node into subexpression + dm_eval_push_node(&(sub->subexpr), tmp); + + // Add this operator into subexpression + DMEvalNode *foo = dm_eval_add_node(&(sub->subexpr), node->op); + foo->ok = TRUE; + + // Next node + node = node->next; + if (node == NULL) + return -72; + + dm_eval_push_node(&(sub->subexpr), node); + break; - // Add subexpression node - if ((sub = dm_eval_add_node(&list, OP_SUBEXPR)) == NULL) - return -3; + default: + if (dm_eval_push_node(&list, node) == NULL) + return -32; + break; + } + + *result = list; + return 0; +} - // Add popped node into subexpression - dm_eval_push_node(&(sub->subexpr), tmp); - - // Add this operator into subexpression - dm_eval_add_node(&(sub->subexpr), node->op); +static int dm_eval_reorder_pass2(DMEvalContext *ev, DMEvalNode *node, DMEvalNode **result) +{ + DMEvalNode *list = NULL; + DMEvalNode *tmp, *sub; + int res; + + for (; node != NULL; node = node->next) + switch (node->op) + { + case OP_SUB: + case OP_ADD: + // Pop previous node, f.e. 5*3 -> 5 + if ((tmp = dm_eval_pop_node(&list)) == NULL) + return -24; + + // Add subexpression node + if ((sub = dm_eval_add_node(&list, OP_SUBEXPR)) == NULL) + return -3; - // Next node - node = node->next; - if (node == NULL) - return -72; + // Add popped node into subexpression + dm_eval_push_node(&(sub->subexpr), tmp); + + // Add this operator into subexpression + dm_eval_add_node(&(sub->subexpr), node->op); + + // Next node + node = node->next; + if (node == NULL) + return -72; + + dm_eval_push_node(&(sub->subexpr), node); + break; + + default: + if (dm_eval_push_node(&list, node) == NULL) + return -32; + break; + } + + *result = list; + return 0; +} + + +static int dm_eval_reorder_pass3(DMEvalContext *ev, DMEvalNode *node, DMEvalNode **result) +{ + DMEvalNode *list = NULL; + DMEvalNode *tmp, *sub; + int res; - if (node->op == OP_FUNC || node->op == OP_SUBEXPR) - { - // It's a function or sub-expression - if ((tmp = dm_eval_push_node(&(sub->subexpr), node)) == NULL) - return -178; - - if ((res = dm_eval_reorder_do(ev, node->subexpr, &(tmp->subexpr), pass)) != 0) - return res; - } - else - dm_eval_push_node(&(sub->subexpr), node); + while (node != NULL) + switch (node->op) + { + case OP_LSHIFT: + case OP_RSHIFT: + // Bitshift operator precedence is .. different + if (dm_eval_push_node(&list, node) == NULL) + return -32; + + if ((sub = dm_eval_add_node(&list, OP_SUBEXPR)) == NULL) + return -3; - node = node->next; - break; + node = node->next; + if (node == NULL) + return -14; + + tmp = NULL; + if ((res = dm_eval_reorder(ev, node, &tmp)) != 0) + return res; - default: - if (dm_eval_push_node(&list, node) == NULL) - return -32; + sub->subexpr = tmp; + node = NULL; + break; - node = node->next; - break; - } + default: + if (dm_eval_push_node(&list, node) == NULL) + return -32; + + node = node->next; + break; } *result = list; @@ -946,16 +957,19 @@ int dm_eval_reorder(DMEvalContext *ev, DMEvalNode *node, DMEvalNode **result) { - DMEvalNode *tmp = NULL, *tmp2 = NULL; + DMEvalNode *tmp1 = NULL, *tmp2 = NULL, *tmp3 = NULL; int res; - if ((res = dm_eval_reorder_do(ev, node, &tmp, 0)) != 0) + if ((res = dm_eval_reorder_pass0(ev, node, &tmp1)) != 0) return res; - if ((res = dm_eval_reorder_do(ev, tmp, &tmp2, 1)) != 0) + if ((res = dm_eval_reorder_pass1(ev, tmp1, &tmp2)) != 0) return res; - return dm_eval_reorder_do(ev, tmp2, result, 2); + if ((res = dm_eval_reorder_pass2(ev, tmp2, &tmp3)) != 0) + return res; + + return dm_eval_reorder_pass3(ev, tmp3, result); } diff -r 391310cfba26 -r 837ad9dcc348 dmeval.h --- a/dmeval.h Tue Apr 16 17:28:32 2013 +0300 +++ b/dmeval.h Tue Apr 16 19:02:42 2013 +0300 @@ -57,6 +57,7 @@ typedef struct DMEvalNode { + BOOL ok; int op; DMValue val; DMEvalId *id;