static struct Node * node_op_binary_eval(struct Node *node) { struct NodeOpBinary *self = (struct NodeOpBinary *) node; struct Node *lresult = node_eval(self->lhs); struct Node *rresult = node_eval(self->rhs); double result; switch(self->op) { case OP_BINARY_PLUS: result = node_number_get(lresult) + node_number_get(rresult); break; case OP_BINARY_MINUS: result = node_number_get(lresult) - node_number_get(rresult); break; case OP_BINARY_MULTI: result = node_number_get(lresult) * node_number_get(rresult); break; case OP_BINARY_DIVID: result = node_number_get(lresult) / node_number_get(rresult); break; } node_unref(rresult); node_unref(lresult); return node_number_new(result); }
void test_array() { START_CODE(node) IF IN RAW_PARAM(3) ARRAY_CONSTANT(array_create(3, 1,2,3)); END; THEN CATEGORY_CONSTANT(1) ELSE CATEGORY_CONSTANT(2) END; END_CODE; node_print(node); node = test_serialization(node); environment_t env = test_environment(); constant_t v = node_eval(node, &env); assert(v.c == 2); assert(v.type == CONSTANT_CATEGORY); env.row->inputs[3].category = 3; v = node_eval(node, &env); assert(v.c == 1); assert(v.type == CONSTANT_CATEGORY); row_destroy(env.row); node_destroy(node); }
void test_if() { START_CODE(node) IF GT ADD RAW_PARAM(0) RAW_PARAM(1) END; RAW_PARAM(2) END; THEN CATEGORY_CONSTANT(1) ELSE CATEGORY_CONSTANT(2) END; END_CODE; node_print(node); node = test_serialization(node); environment_t env = test_environment(); constant_t v = node_eval(node, &env); constant_print(&v);puts("\n"); v = node_eval(node, &env); assert(v.c == 2); assert(v.type == CONSTANT_CATEGORY); env.row->inputs[2].value = 2.5; v = node_eval(node, &env); assert(v.c == 1); assert(v.type == CONSTANT_CATEGORY); row_destroy(env.row); node_destroy(node); }
node_t* node_clean_arrays(node_t*n) { /* arrays are not stored in the enviroment- hence their data is not reset in between function invocations. The arrays are allocated once and their pointer is stored in the node that "creates" them (in truth it doesn't create them- corresponding eval only fills them with zeros since they're already there) For code generation, we need them to be initialized properly, hence we execute all the initializers we find in the code. */ if(!n) return n; if(n->type == &node_zero_int_array || n->type == &node_zero_float_array) { node_eval(n, 0); } int i; for(i=0;i<n->num_children;i++) { node_clean_arrays(n->child[i]); } return n; }