diff --git a/ps3/src/tree.c b/ps3/src/tree.c index 812f35f..996341e 100644 --- a/ps3/src/tree.c +++ b/ps3/src/tree.c @@ -131,8 +131,8 @@ static void node_print(node_t* node, int nesting) static node_t* convert_operator(node_t* node) { assert(node->type == OPERATOR); - assert(node->children[0] && node->children[1]); if (strcmp(node->data.operator, "or") == 0) { + assert(node->children[0] && node->children[1]); node_t *one = node_create(NUMBER_LITERAL, 0); one->data.number_literal = 1; node_t *converted_op = node_create(OPERATOR, 3, node->children[0], one, node->children[1]); @@ -140,6 +140,7 @@ static node_t* convert_operator(node_t* node) node_finalize(node); node = converted_op; } else if (strcmp(node->data.operator, "and") == 0) { + assert(node->children[0] && node->children[1]); node_t *zero = node_create(NUMBER_LITERAL, 0); zero->data.number_literal = 0; node_t *converted_op = node_create(OPERATOR, 3, node->children[0], node->children[1], zero); @@ -158,92 +159,65 @@ static node_t* constant_fold_operator(node_t* node) assert(node->type == OPERATOR); for (int i = 0; i < node->n_children; i++) assert(node->children[i]->type == NUMBER_LITERAL); - - node_t *a, *b, *c; + + node_t *a, *b, *c, *result; if (node->n_children == 1) { a = node->children[0]; + result = node_create(NUMBER_LITERAL, 0); if (strcmp(node->data.operator, "-") == 0) { - free(node->data.operator); - node->type = NUMBER_LITERAL; - node->data.number_literal = -a->data.number_literal; + result->data.number_literal = -a->data.number_literal; } else if (strcmp(node->data.operator, "!") == 0) { - free(node->data.operator); - node->type = NUMBER_LITERAL; - node->data.number_literal = !a->data.number_literal; + result->data.number_literal = !a->data.number_literal; } else { fprintf(stderr, "folding: unexpected unary operator"); exit(1); } - destroy_subtree(a); } else if (node->n_children == 2) { a = node->children[0]; b = node->children[1]; + result = node_create(NUMBER_LITERAL, 0); if (strcmp(node->data.operator, "==") == 0) { - free(node->data.operator); - node->type = NUMBER_LITERAL; - node->data.number_literal = a->data.number_literal == b->data.number_literal; + result->data.number_literal = a->data.number_literal == b->data.number_literal; } else if (strcmp(node->data.operator, "!=") == 0) { - free(node->data.operator); - node->type = NUMBER_LITERAL; - node->data.number_literal = a->data.number_literal != b->data.number_literal; + result->data.number_literal = a->data.number_literal != b->data.number_literal; } else if (strcmp(node->data.operator, "<") == 0) { - free(node->data.operator); - node->type = NUMBER_LITERAL; - node->data.number_literal = a->data.number_literal < b->data.number_literal; + result->data.number_literal = a->data.number_literal < b->data.number_literal; } else if (strcmp(node->data.operator, "<=") == 0) { - free(node->data.operator); - node->type = NUMBER_LITERAL; - node->data.number_literal = a->data.number_literal <= b->data.number_literal; + result->data.number_literal = a->data.number_literal <= b->data.number_literal; } else if (strcmp(node->data.operator, ">") == 0) { - free(node->data.operator); - node->type = NUMBER_LITERAL; - node->data.number_literal = a->data.number_literal > b->data.number_literal; + result->data.number_literal = a->data.number_literal > b->data.number_literal; } else if (strcmp(node->data.operator, ">=") == 0) { - free(node->data.operator); - node->type = NUMBER_LITERAL; - node->data.number_literal = a->data.number_literal >= b->data.number_literal; + result->data.number_literal = a->data.number_literal >= b->data.number_literal; } else if (strcmp(node->data.operator, "+") == 0) { - free(node->data.operator); - node->type = NUMBER_LITERAL; - node->data.number_literal = a->data.number_literal + b->data.number_literal; + result->data.number_literal = a->data.number_literal + b->data.number_literal; } else if (strcmp(node->data.operator, "-") == 0) { - free(node->data.operator); - node->type = NUMBER_LITERAL; - node->data.number_literal = a->data.number_literal - b->data.number_literal; + result->data.number_literal = a->data.number_literal - b->data.number_literal; } else if (strcmp(node->data.operator, "*") == 0) { - free(node->data.operator); - node->type = NUMBER_LITERAL; - node->data.number_literal = a->data.number_literal * b->data.number_literal; + result->data.number_literal = a->data.number_literal * b->data.number_literal; } else if (strcmp(node->data.operator, "/") == 0) { - free(node->data.operator); - node->type = NUMBER_LITERAL; - node->data.number_literal = a->data.number_literal / b->data.number_literal; + result->data.number_literal = a->data.number_literal / b->data.number_literal; } else { fprintf(stderr, "folding: unexpected binary operator"); exit(1); } - destroy_subtree(a); - destroy_subtree(b); } else if (node->n_children == 3) { a = node->children[0]; b = node->children[1]; c = node->children[2]; + result = node_create(NUMBER_LITERAL, 0); if (strcmp(node->data.operator, "?:") == 0) { - free(node->data.operator); - node->type = NUMBER_LITERAL; - node->data.number_literal = a->data.number_literal ? b->data.number_literal : c->data.number_literal; + result->data.number_literal = a->data.number_literal ? b->data.number_literal : c->data.number_literal; } else { fprintf(stderr, "folding: unexpected trinary operator"); exit(1); } - destroy_subtree(a); - destroy_subtree(b); - destroy_subtree(c); } else { fprintf(stderr, "folding: unexpected number of children: %d", node->n_children); } - return node; + destroy_subtree(node); + + return result; } // Convert PRINTLN_STATEMENT into PRINT_STATEMENT by appending an extra "\n"