void ast_print(ast_tree * t, int len) { int i = 0; ast_tree *child; if(len == 0 && t->children_num != 0) printf("root|>:\n"); for(i = 0; i < t->children_num; i++){ child = t->children[i]; if(strstr(child->tag, "error")){ printf("error: %s\n", child->contents); return; } } for(i = 0; i < t->children_num; i++){ child = t->children[i]; if(strstr(child->tag, "symbol") || strstr(child->tag, "char")) printf("%*s%s: \'%s\'\n", len+2, " ", child->tag, child->contents); if(strstr(child->tag, "num")) printf("%*s%s: \'%G\'\n", len+2, " ", child->tag, child->num); if(strstr(child->tag, "sexpr")){ printf("%*ssexpr|>:\n",len+2, " "); ast_print(child, len + 2); } if(strstr(child->tag, "qexpr")){ printf("%*sqexpr|>\n",len + 2, " "); ast_print(child, len + 2); } } }
// Check some number of children, all using the same rules. // The given max and min counts are inclusive. Pass -1 for no maximum limit. static bool check_children(ast_t* ast, check_state_t* state, const check_fn_t *rules, size_t min_count, size_t max_count, errors_t* errors) { assert(ast != NULL); assert(state != NULL); assert(min_count <= max_count); size_t found_count = 0; while(found_count < max_count && state->child != NULL) { // See if next child is suitable check_res_t r = check_from_list(state->child, rules, errors); if(r == CHK_ERROR) // Propogate error return false; if(r == CHK_NOT_FOUND) // End of list break; // Child found state->child = ast_sibling(state->child); state->child_index++; found_count++; } // There are no more matching children if(found_count >= min_count) return true; // Didn't find enough matching children if(state->child == NULL) { error_preamble(ast); printf("found " __zu " child%s, expected more\n", state->child_index, (state->child_index == 1) ? "" : "ren"); ast_error(state->errors, ast, "Here"); ast_print(ast); #ifdef IMMEDIATE_FAIL assert(false); #endif } else { error_preamble(ast); printf("child " __zu " has invalid id %d\n", state->child_index, ast_id(state->child)); ast_error(state->errors, ast, "Here"); ast_print(ast); #ifdef IMMEDIATE_FAIL assert(false); #endif } return false; }
int main(void) { ast_t * a; int jval; jit_t * jit; GC_INIT(); GREG g; ast_init(); sym_tab_init(); types_init(); scope_init(); loc_tab_init(); intrinsics_init(); jit = llvm_init(); ZZ_init(jit); yyinit(&g); printf("Welcome to Bacon v0.1\n\n"); printf("> "); while (1) { if (!(jval = setjmp(exc))) { if (!yyparse(&g)) { printf("Error parsing\n"); abort(); } else if (root) { #if DEBUG1 printf("\n"); ast_print(root, 0); #endif inference(root); #if DEBUG2 printf("\n"); /*ast2_print(root, 0);*/ #endif exec_root(jit, root); root = NULL; } } else if (jval == 1) root = NULL; else /* jval == 2 */ break; printf("\n> "); } llvm_cleanup(jit); yydeinit(&g); printf("\n"); return 0; }
int main(int argc, char *argv[]){ char* filename; if(argc == 3 && strcmp(argv[1], "-print") == 0){ filename = argv[2]; /* open the file for reading */ yyin = fopen(filename, "r"); /* parse the file */ return ast_print(); // return code associated with the parse } else if(argc == 3 && strcmp(argv[1], "-resolve") == 0){ filename = argv[2]; /* open the file for reading */ yyin = fopen(filename, "r"); /* resolve the names in the AST */ return resolve(); } else if(argc == 3 && strcmp(argv[1], "-typecheck") == 0){ filename = argv[2]; /* open the file for reading */ yyin = fopen(filename, "r"); /* Check the types in the AST */ return typecheck(); } else { return 2; } }
static ast_result_t syntax_compile_error(ast_t* ast) { ast_t* parent = ast_parent(ast); assert(ast_id(parent) == TK_SEQ); if(ast_id(ast_parent(parent)) != TK_IFDEF) { ast_error(ast, "a compile error must be in an ifdef"); return AST_ERROR; } // AST must be of the form: // (compile_error (seq "Reason")) ast_t* reason_seq = ast_child(ast); if(ast_id(reason_seq) != TK_SEQ || ast_id(ast_child(reason_seq)) != TK_STRING) { ast_print(ast); ast_error(ast, "a compile error must have a string literal reason for the error"); return AST_ERROR; } ast_t* child = ast_child(parent); if((child != ast) || (ast_sibling(child) != NULL) || (ast_childcount(reason_seq) != 1)) { ast_error(ast, "a compile error must be the entire ifdef clause"); return AST_ERROR; } return AST_OK; }
static bool compile_package(const char* path, pass_opt_t* opt, bool print_program_ast, bool print_package_ast) { ast_t* program = program_load(path, opt); if(program == NULL) return false; if(print_program_ast) ast_print(program); if(print_package_ast) ast_print(ast_child(program)); bool ok = generate_passes(program, opt); ast_free(program); return ok; }
int main(void) { GC_INIT(); GREG g; int jval, jval2; char c; sym_tab_init(); ast_init(); type_init(); scope_init(); rel_assign_init(); jit_t * jit = llvm_init(); yyinit(&g); printf("Welcome to Cesium v 0.2\n"); printf("To exit press CTRL-D\n\n"); printf("> "); while (1) { if (!(jval = setjmp(exc))) { if (!yyparse(&g)) { printf("Error parsing\n"); abort(); } else if (root != NULL) { rel_stack_init(); rel_assign_mark(); scope_mark(); annotate_ast(root); if (TRACE) ast_print(root, 0); unify(rel_stack, rel_assign); if (TRACE) print_assigns(rel_assign); exec_root(jit, root); if (root->tag != AST_FNDEC) rel_assign_rewind(); } } else if (jval == 1) root = NULL; else if (jval == 2) break; printf("\n> "); } yydeinit(&g); llvm_cleanup(jit); return 0; }
// Check whether the given entity members are legal in their entity static bool check_members(ast_t* members, int entity_def_index) { assert(members != NULL); assert(entity_def_index >= 0 && entity_def_index < DEF_ENTITY_COUNT); bool r = true; const permission_def_t* def = &_entity_def[entity_def_index]; ast_t* member = ast_child(members); while(member != NULL) { switch(ast_id(member)) { case TK_FLET: case TK_FVAR: case TK_EMBED: if(def->permissions[ENTITY_FIELD] == 'N') { ast_error(member, "Can't have fields in %s", def->desc); r = false; } if(!check_id_field(ast_child(member))) r = false; break; case TK_NEW: if(!check_method(member, entity_def_index + DEF_NEW)) r = false; break; case TK_BE: { if(!check_method(member, entity_def_index + DEF_BE)) r = false; break; } case TK_FUN: { if(!check_method(member, entity_def_index + DEF_FUN)) r = false; break; } default: ast_print(members); assert(0); return false; } member = ast_sibling(member); } return r; }
void ast_print(struct ast *tree, int indent) { for (unsigned i = 0; i < indent; ++i) putchar(' '); enum ast_type t = tree->type; if (t == AST_IDENTIFIER) printf("%s (%s)\n", ast_type_names[t], tree->val.s); else if (t == AST_CONSTANT) printf("%s (%d)\n", ast_type_names[t], tree->val.i); else printf("%s\n", ast_type_names[t]); for (unsigned i = 0; i < tree->n_childs; ++i) ast_print(tree->childs[i], indent + 1); }
void ast_print(ast_t * ast, int indent) { int i; ast_t * a; for (i = 0; i < indent; i++) printf(" "); printf("~ "); switch (ast->tag) { case AST_NONE: printf("none\n"); break; case AST_ZZ: case AST_INT: case AST_UINT: case AST_DOUBLE: case AST_CHAR: case AST_STRING: printf("%s\n", ast->sym->name); break; case AST_TUPLE: case AST_LTUPLE: printf("tuple\n"); break; case AST_BINOP: printf("%s\n", ast->sym->name); ast_print(ast->child, indent + 3); ast_print(ast->child->next, indent + 3); break; case AST_LIDENT: case AST_IDENT: printf("%s\n", ast->sym->name); break; case AST_IF_ELSE_EXPR: case AST_IF_ELSE_STMT: printf("if\n"); ast_print(ast->child, indent + 3); ast_print(ast->child->next, indent); ast_print(ast->child->next->next, indent); break; case AST_IF_STMT: printf("if\n"); ast_print(ast->child, indent + 3); ast_print(ast->child->next, indent); break; case AST_WHILE_STMT: printf("while\n"); ast_print(ast->child, indent + 3); ast_print(ast->child->next, indent); break; case AST_BREAK: printf("break\n"); break; case AST_BLOCK: printf("block\n"); a = ast->child; while (a != NULL) { ast_print(a, indent + 3); a = a->next; } break; case AST_THEN: printf("then\n"); a = ast->child; while (a != NULL) { ast_print(a, indent + 3); a = a->next; } break; case AST_ELSE: printf("else\n"); a = ast->child; while (a != NULL) { ast_print(a, indent + 3); a = a->next; } break; case AST_DO: printf("do\n"); a = ast->child; while (a != NULL) { ast_print(a, indent + 3); a = a->next; } break; case AST_DATA_SLOT: printf("%s\n", ast->child->sym->name); break; case AST_TYPE_NAME: printf("type_name\n"); break; case AST_REF_TYPE_NAME: printf("ref type_name\n"); break; case AST_TUPLE_TYPE: printf("tuple_type\n"); break; case AST_DATA_STMT: printf("data %s\n", ast->child->sym->name); a = ast->child->next->child; while (a != NULL) { ast_print(a, indent + 3); a = a->next; } break; case AST_ASSIGNMENT: printf("assign\n"); ast_print(ast->child, indent + 3); ast_print(ast->child->next, indent + 3); break; case AST_APPL: case AST_LAPPL: printf("appl\n"); a = ast->child->next; while (a != NULL) { ast_print(a, indent + 3); a = a->next; } break; case AST_ARRAY_CONSTRUCTOR: printf("array_constructor"); ast_print(ast->child, indent + 3); ast_print(ast->child->next, indent + 3); case AST_ARRAY_TYPE: printf("array"); ast_print(ast->child, indent + 3); break; case AST_SLOT: case AST_LSLOT: printf("slot\n"); ast_print(ast->child, indent + 3); ast_print(ast->child->next, indent + 3); break; case AST_LOCN: case AST_LLOCN: printf("location\n"); ast_print(ast->child, indent + 3); ast_print(ast->child->next, indent + 3); break; case AST_PARAM: printf("%s\n", ast->child->sym->name); break; case AST_FN_STMT: printf("fn %s\n", ast->child->sym->name); a = ast->child->next->child; while (a != NULL) { ast_print(a, indent + 3); a = a->next; } a = ast->child->next->next; ast_print(a, indent + 3); break; case AST_RETURN: printf("return\n"); ast_print(ast->child, indent + 3); break; default: printf("%d\n", ast->tag); exception("invalid AST tag in ast_print\n"); } }
// Check whether the given entity members are legal in their entity static bool check_members(pass_opt_t* opt, ast_t* members, int entity_def_index) { assert(members != NULL); assert(entity_def_index >= 0 && entity_def_index < DEF_ENTITY_COUNT); bool r = true; const permission_def_t* def = &_entity_def[entity_def_index]; ast_t* member = ast_child(members); while(member != NULL) { switch(ast_id(member)) { case TK_FLET: case TK_FVAR: case TK_EMBED: { if(def->permissions[ENTITY_FIELD] == 'N') { ast_error(opt->check.errors, member, "Can't have fields in %s", def->desc); r = false; } if((ast_id(ast_parent(members)) == TK_OBJECT) && \ (ast_id(ast_childidx(member, 2)) == TK_NONE)) { ast_error(opt->check.errors, member, "object literal fields must be initialized"); r = false; } if(!check_id_field(opt, ast_child(member))) r = false; ast_t* delegate_type = ast_childidx(member, 3); if(ast_id(delegate_type) != TK_NONE && !check_provides_type(opt, delegate_type, "delegate")) r = false; break; } case TK_NEW: if(!check_method(opt, member, entity_def_index + DEF_NEW)) r = false; break; case TK_BE: { if(!check_method(opt, member, entity_def_index + DEF_BE)) r = false; break; } case TK_FUN: { if(!check_method(opt, member, entity_def_index + DEF_FUN)) r = false; break; } default: ast_print(members); assert(0); return false; } member = ast_sibling(member); } return r; }
// Check the extra information. This includes: // * legal data pointer // * legal scope symbol table // * no extra children static check_res_t check_extras(ast_t* ast, check_state_t* state, errors_t* errors) { assert(ast != NULL); assert(state != NULL); ast_t* type_field = ast_type(ast); if(type_field != NULL) { if(state->type == NULL) { error_preamble(ast); printf("unexpected type\n"); ast_error(state->errors, ast, "Here"); ast_print(ast); #ifdef IMMEDIATE_FAIL assert(false); #endif return CHK_ERROR; } check_res_t r = state->type(type_field, errors); if(r == CHK_ERROR) // Propogate error return CHK_ERROR; if(r == CHK_NOT_FOUND) { error_preamble(ast); printf("type field has invalid id %d\n", ast_id(type_field)); ast_error(state->errors, ast, "Here"); ast_print(ast); #ifdef IMMEDIATE_FAIL assert(false); #endif return CHK_ERROR; } } if(state->child != NULL) { error_preamble(ast); printf("child " __zu " (id %d, %s) unexpected\n", state->child_index, ast_id(state->child), ast_get_print(state->child)); ast_error(state->errors, ast, "Here"); ast_print(ast); #ifdef IMMEDIATE_FAIL assert(false); #endif return CHK_ERROR; } if(ast_data(ast) != NULL && !state->has_data) { error_preamble(ast); printf("unexpected data %p\n", ast_data(ast)); ast_error(state->errors, ast, "Here"); ast_print(ast); #ifdef IMMEDIATE_FAIL assert(false); #endif return CHK_ERROR; } if(ast_has_scope(ast) && !state->is_scope) { error_preamble(ast); printf("unexpected scope\n"); ast_error(state->errors, ast, "Here"); ast_print(ast); #ifdef IMMEDIATE_FAIL assert(false); #endif return CHK_ERROR; } if(!ast_has_scope(ast) && state->is_scope) { error_preamble(ast); printf("expected scope not found\n"); ast_error(state->errors, ast, "Here"); ast_print(ast); #ifdef IMMEDIATE_FAIL assert(false); #endif return CHK_ERROR; } return CHK_OK; }
void ast_print(node * ast) { //print dat shet char * type = NULL; int unaryTypeVal; int leftBinTypeVal; int rightBinTypeVal; if(ast == NULL) return; switch(ast->kind) { // Working case SCOPE_NODE: fprintf(dumpFile, "\n(SCOPE \n"); // call to get (DECLARATIONS...) (STATEMENTS...)); ast_print(ast->scope_expr.left); // go to declarations fprintf(dumpFile, "(STATEMENTS\n"); ast_print(ast->scope_expr.right); // go to statements // close STATEMENTS, SCOPE fprintf(dumpFile, ")\n"); //fprintf(dumpFile, ")\n"); fprintf(dumpFile, ")\n"); break; case DECLARATIONS_NODE: //fprintf(dumpFile, "(DECLARATIONS\n"); ast_print(ast->declarations_expr.left); // come back to declarations if(ast->declarations_expr.left == NULL) fprintf(dumpFile, "(DECLARATIONS\n"); ast_print(ast->declarations_expr.right); // go to declaration fprintf(dumpFile, ")\n"); //fprintf(dumpFile, "\n)\n"); break; case DECLARATION_NODE: type = getType(ast->declaration_expr.type); //fprintf(dumpFile, "id: %s\n", ast->declaration_expr.id); if(ast->declaration_expr.constant == -1) // right hand side is a literal fprintf(dumpFile, "(DECLARATION %s %s)\n", ast->declaration_expr.id, type); else if(ast->declaration_expr.constant == -2) // right hand side is an expression form { fprintf(dumpFile, "(DECLARATION %s %s ", ast->declaration_expr.id, type); // the right hand side expression will be printed in the next recursive call ast_print(ast->declaration_expr.right); } else if(ast->declaration_expr.constant == CONST) { fprintf(dumpFile, "(DECLARATION const %s %s ", ast->declaration_expr.id, type); // the right hand side expression will be printed in the next recursive call ast_print(ast->declaration_expr.right); } break; case INT_NODE: //printf("INT_NODE --->\n"); fprintf(dumpFile, "%d ", ast->int_expr.val); break; case BOOL_NODE: if(ast->bool_expr.val == TRUE_C) fprintf(dumpFile, "true "); else if(ast->bool_expr.val == FALSE_C) fprintf(dumpFile, "false "); break; case FLOAT_NODE: fprintf(dumpFile, "%f ", ast->float_expr.val); break; case VAR_NODE: // Got stuff TODO // Could be: // ID // ID '[' INT_C ']' if(ast->var_expr.arr == -1) fprintf(dumpFile, "%s ", ast->var_expr.id); else fprintf(dumpFile, "(INDEX int %s %d", ast->var_expr.id, ast->var_expr.arr); //printf("<---VAR_NODE\t"); break; case EXPRESSION_NODE: ast_print(ast->expression_expr.expr); //fprintf(dumpFile, "<---EXPRESSION_NODE\n"); break; case VARIABLE_NODE: ast_print(ast->variable_expr.expr); //fprintf(dumpFile, "<---EXPRESSION_NODE\n"); break; case UNARY_EXPRESSION_NODE: // TODO This makes no sense //fprintf(dumpFile, "op: %d\n", ast->unary_expr.op); if(ast->unary_expr.op == UMINUS) // op is unary minus { // get the int associated with type using burrow unaryTypeVal = burrow(ast->unary_expr.right); //printf("typeVal is:%d\n", unaryTypeVal); // then get the string for the type type = getType(unaryTypeVal); fprintf(dumpFile, "(UNARY %s - ", type); ast_print(ast->unary_expr.right); fprintf(dumpFile, ") "); } else if(ast->unary_expr.op == 33) // op is unary ! { fprintf(dumpFile, "(UNARY bool ! "); ast_print(ast->unary_expr.right); fprintf(dumpFile, ") "); } break; case BINARY_EXPRESSION_NODE: //ast_print(ast->binary_expr.left); //printf("binary op:%d\n", ast->binary_expr.op); if(ast->binary_expr.op == 43) // for + { leftBinTypeVal = burrow(ast->binary_expr.left); rightBinTypeVal = burrow(ast->binary_expr.right); //printf("rightBinTypeVal:%d\n", rightBinTypeVal); //printf("leftBinTypeVal:%d, rightBinTypeVal:%d\n", leftBinTypeVal, rightBinTypeVal); if(leftBinTypeVal != -1 && rightBinTypeVal != -1 && leftBinTypeVal == rightBinTypeVal) { type = getType(leftBinTypeVal); fprintf(dumpFile, "(BINARY %s + ", type); } else // type mismatch fprintf(dumpFile, "(BINARY INVALID + "); ast_print(ast->binary_expr.left); ast_print(ast->binary_expr.right); fprintf(dumpFile, ") "); } else if(ast->binary_expr.op == 45) // for - { leftBinTypeVal = burrow(ast->binary_expr.left); rightBinTypeVal = burrow(ast->binary_expr.right); //printf("leftBinTypeVal:%d, rightBinTypeVal:%d\n", leftBinTypeVal, rightBinTypeVal); if(leftBinTypeVal != -1 && rightBinTypeVal != -1 && leftBinTypeVal == rightBinTypeVal) { type = getType(leftBinTypeVal); fprintf(dumpFile, "(BINARY %s - ", type); } else // type mismatch fprintf(dumpFile, "(BINARY INVALID - "); ast_print(ast->binary_expr.left); ast_print(ast->binary_expr.right); fprintf(dumpFile, ") "); } else if(ast->binary_expr.op == 42) // for * { leftBinTypeVal = burrow(ast->binary_expr.left); rightBinTypeVal = burrow(ast->binary_expr.right); //printf("leftBinTypeVal:%d, rightBinTypeVal:%d\n", leftBinTypeVal, rightBinTypeVal); if(leftBinTypeVal != -1 && rightBinTypeVal != -1 && leftBinTypeVal == rightBinTypeVal) { type = getType(leftBinTypeVal); fprintf(dumpFile, "(BINARY %s * ", type); } else // type mismatch fprintf(dumpFile, "(BINARY INVALID * "); ast_print(ast->binary_expr.left); ast_print(ast->binary_expr.right); fprintf(dumpFile, ") "); } else if(ast->binary_expr.op == 47) // for / { leftBinTypeVal = burrow(ast->binary_expr.left); rightBinTypeVal = burrow(ast->binary_expr.right); //printf("leftBinTypeVal:%d, rightBinTypeVal:%d\n", leftBinTypeVal, rightBinTypeVal); if(leftBinTypeVal != -1 && rightBinTypeVal != -1 && leftBinTypeVal == rightBinTypeVal) { type = getType(leftBinTypeVal); fprintf(dumpFile, "(BINARY %s / ", type); } else // type mismatch fprintf(dumpFile, "(BINARY INVALID / "); ast_print(ast->binary_expr.left); ast_print(ast->binary_expr.right); fprintf(dumpFile, ") "); } else if(ast->binary_expr.op == 94) // case for POW { leftBinTypeVal = burrow(ast->binary_expr.left); rightBinTypeVal = burrow(ast->binary_expr.right); //printf("leftBinTypeVal:%d, rightBinTypeVal:%d\n", leftBinTypeVal, rightBinTypeVal); if(leftBinTypeVal != -1 && rightBinTypeVal != -1 && leftBinTypeVal == rightBinTypeVal) { type = getType(leftBinTypeVal); fprintf(dumpFile, "(BINARY %s ^ ", type); } else // type mismatch fprintf(dumpFile, "(BINARY INVALID ^ "); ast_print(ast->binary_expr.left); ast_print(ast->binary_expr.right); fprintf(dumpFile, ") "); } else if(ast->binary_expr.op == AND) { leftBinTypeVal = burrow(ast->binary_expr.left); //printf("leftBinTypeVal:%d\n", leftBinTypeVal); rightBinTypeVal = burrow(ast->binary_expr.right); //printf("leftBinTypeVal:%d, rightBinTypeVal:%d\n", leftBinTypeVal, rightBinTypeVal); if(leftBinTypeVal != -1 && rightBinTypeVal != -1 && leftBinTypeVal == rightBinTypeVal) { type = getType(leftBinTypeVal); if(strcmp(type, "bool") == 0) fprintf(dumpFile, "(BINARY bool AND "); else fprintf(dumpFile, "(BINARY INVALID AND "); } else // type mismatch fprintf(dumpFile, "(BINARY INVALID AND "); ast_print(ast->binary_expr.left); ast_print(ast->binary_expr.right); fprintf(dumpFile, ") "); } else if(ast->binary_expr.op == OR) { leftBinTypeVal = burrow(ast->binary_expr.left); //printf("leftBinTypeVal:%d\n", leftBinTypeVal); rightBinTypeVal = burrow(ast->binary_expr.right); //printf("leftBinTypeVal:%d, rightBinTypeVal:%d\n", leftBinTypeVal, rightBinTypeVal); if(leftBinTypeVal != -1 && rightBinTypeVal != -1 && leftBinTypeVal == rightBinTypeVal) { type = getType(leftBinTypeVal); if(strcmp(type, "bool") == 0) fprintf(dumpFile, "(BINARY bool OR "); else // type mismatch fprintf(dumpFile, "(BINARY INVALID GEQ "); } else // type mismatch fprintf(dumpFile, "(BINARY INVALID OR "); ast_print(ast->binary_expr.left); ast_print(ast->binary_expr.right); fprintf(dumpFile, ") "); } else if(ast->binary_expr.op == NEQ) { leftBinTypeVal = burrow(ast->binary_expr.left); //printf("leftBinTypeVal:%d\n", leftBinTypeVal); rightBinTypeVal = burrow(ast->binary_expr.right); //printf("leftBinTypeVal:%d, rightBinTypeVal:%d\n", leftBinTypeVal, rightBinTypeVal); if(leftBinTypeVal != -1 && rightBinTypeVal != -1 && leftBinTypeVal == rightBinTypeVal) { type = getType(leftBinTypeVal); fprintf(dumpFile, "(BINARY bool NEQ "); } else // type mismatch fprintf(dumpFile, "(BINARY INVALID NEQ "); ast_print(ast->binary_expr.left); ast_print(ast->binary_expr.right); fprintf(dumpFile, ") "); } else if(ast->binary_expr.op == EQ) { leftBinTypeVal = burrow(ast->binary_expr.left); //printf("leftBinTypeVal:%d\n", leftBinTypeVal); rightBinTypeVal = burrow(ast->binary_expr.right); //printf("leftBinTypeVal:%d, rightBinTypeVal:%d\n", leftBinTypeVal, rightBinTypeVal); if(leftBinTypeVal != -1 && rightBinTypeVal != -1 && leftBinTypeVal == rightBinTypeVal) { type = getType(leftBinTypeVal); fprintf(dumpFile, "(BINARY bool EQ "); } else // type mismatch fprintf(dumpFile, "(BINARY INVALID EQ "); ast_print(ast->binary_expr.left); ast_print(ast->binary_expr.right); fprintf(dumpFile, ") "); } else if(ast->binary_expr.op == 60) // LESS THAN { leftBinTypeVal = burrow(ast->binary_expr.left); //printf("leftBinTypeVal:%d\n", leftBinTypeVal); rightBinTypeVal = burrow(ast->binary_expr.right); //printf("leftBinTypeVal:%d, rightBinTypeVal:%d\n", leftBinTypeVal, rightBinTypeVal); if(leftBinTypeVal != -1 && rightBinTypeVal != -1 && leftBinTypeVal == rightBinTypeVal) { type = getType(leftBinTypeVal); fprintf(dumpFile, "(BINARY bool < "); } else // type mismatch fprintf(dumpFile, "(BINARY INVALID < "); ast_print(ast->binary_expr.left); ast_print(ast->binary_expr.right); fprintf(dumpFile, ") "); } else if(ast->binary_expr.op == 62) // GREATER THAN { leftBinTypeVal = burrow(ast->binary_expr.left); //printf("leftBinTypeVal:%d\n", leftBinTypeVal); rightBinTypeVal = burrow(ast->binary_expr.right); //printf("leftBinTypeVal:%d, rightBinTypeVal:%d\n", leftBinTypeVal, rightBinTypeVal); if(leftBinTypeVal != -1 && rightBinTypeVal != -1 && leftBinTypeVal == rightBinTypeVal) { type = getType(leftBinTypeVal); fprintf(dumpFile, "(BINARY bool > "); } else // type mismatch fprintf(dumpFile, "(BINARY INVALID > "); ast_print(ast->binary_expr.left); ast_print(ast->binary_expr.right); fprintf(dumpFile, ") "); } else if(ast->binary_expr.op == LEQ) { leftBinTypeVal = burrow(ast->binary_expr.left); //printf("leftBinTypeVal:%d\n", leftBinTypeVal); rightBinTypeVal = burrow(ast->binary_expr.right); //printf("leftBinTypeVal:%d, rightBinTypeVal:%d\n", leftBinTypeVal, rightBinTypeVal); if(leftBinTypeVal != -1 && rightBinTypeVal != -1 && leftBinTypeVal == rightBinTypeVal) { type = getType(leftBinTypeVal); fprintf(dumpFile, "(BINARY bool LEQ "); } else // type mismatch fprintf(dumpFile, "(BINARY INVALID LEQ "); ast_print(ast->binary_expr.left); ast_print(ast->binary_expr.right); fprintf(dumpFile, ") "); } else if(ast->binary_expr.op == GEQ) { leftBinTypeVal = burrow(ast->binary_expr.left); //printf("leftBinTypeVal:%d\n", leftBinTypeVal); rightBinTypeVal = burrow(ast->binary_expr.right); //printf("leftBinTypeVal:%d, rightBinTypeVal:%d\n", leftBinTypeVal, rightBinTypeVal); if(leftBinTypeVal != -1 && rightBinTypeVal != -1 && leftBinTypeVal == rightBinTypeVal) { type = getType(leftBinTypeVal); fprintf(dumpFile, "(BINARY bool GEQ "); } else // type mismatch fprintf(dumpFile, "(BINARY INVALID GEQ "); ast_print(ast->binary_expr.left); ast_print(ast->binary_expr.right); fprintf(dumpFile, ") "); } break; case NESTED_SCOPE_NODE: scope_ast = scope_ast + 1; b[scope_ast] = ast->nest_scope_expr.variables; //fprintf(dumpFile, "(NESTED SCOPE\n"); ast_print(ast->nest_scope_expr.scope); //fprintf(dumpFile, ")\n"); break; case CONSTRUCTOR_NODE: //ast_print(ast->construt_expr.left); type = getType(ast->construt_expr.type); //fprintf(dumpFile, "type: %d\n", ast->construt_expr.type); //fprintf(dumpFile, "CONSTRUCTOR_NODE\n"); fprintf(dumpFile, "(CALL %s", type); ast_print(ast->construt_expr.right); // get the arguments break; case ARGUMENTS_NODE: //fprintf(dumpFile, "ARGUMENTS_NODE\n"); ast_print(ast->arguments_expr.left); if(ast->arguments_expr.left) fprintf(dumpFile, ", "); ast_print(ast->arguments_expr.right); break; case ARGUMENTS_OPT_NODE: //fprintf(dumpFile, "ARGUMENTS_OPT_NODE\n"); fprintf(dumpFile, "("); ast_print(ast->arguments_opt_expr.argum); fprintf(dumpFile, ")"); fprintf(dumpFile, ")"); break; case STATEMENT_NODE: //fprintf(dumpFile, "(STATEMENTS\n"); ast_print(ast->statement_expr.left); ast_print(ast->statement_expr.right); //fprintf(dumpFile, ")\n"); break; case ASSIGNMENT_NODE: //ast_print(ast->assign_expr.left); unaryTypeVal = burrow(ast->assign_expr.left); type = getType(unaryTypeVal); //printf("type: %s\n", type); //printf("ast->assign_expr.left->var_expr.id: %s\n", ast->assign_expr.left->var_expr.id); //printf("ast->assign_expr.left->expression_expr.expr: %s\n", ast->assign_expr.left->expression_expr.expr); fprintf(dumpFile, "(ASSIGN %s %s ", type, ast->assign_expr.left->var_expr.id); //ast_print(ast->assign_expr.left->expression_expr.expr); ast_print(ast->assign_expr.right); fprintf(dumpFile, ")\n"); break; case IF_STATEMENT_NODE: //fprintf(dumpFile, "IF_STATEMENT_NODE\n"); if(ast->if_expr.if_comparison && ast->if_expr.if_statement){ if(ast->if_expr.else_statement){ fprintf(dumpFile, "(IF "); ast_print(ast->if_expr.if_comparison); ast_print(ast->if_expr.if_statement); ast_print(ast->if_expr.else_statement); } else { fprintf(dumpFile, "(IF "); ast_print(ast->if_expr.if_comparison); ast_print(ast->if_expr.if_statement); } } break; case FUNCTION_NODE: type = getType(ast->func_expr.func); fprintf(dumpFile, "(CALL %s ", type); ast_print(ast->func_expr.arguments); fprintf(dumpFile, "\n"); //fprintf(dumpFile, "<--FUNCTION_NODE\n"); break; default: fprintf(dumpFile, "DEFAULT\n"); break; } return; }
void ast_print(FILE *f, AstNode *node, int indent) { for (int i = 0; i < indent; i += 1) { fprintf(f, " "); } assert(node->type == NodeTypeRoot || *node->parent_field == node); switch (node->type) { case NodeTypeRoot: fprintf(f, "%s\n", node_type_str(node->type)); for (int i = 0; i < node->data.root.top_level_decls.length; i += 1) { AstNode *child = node->data.root.top_level_decls.at(i); ast_print(f, child, indent + 2); } break; case NodeTypeRootExportDecl: fprintf(f, "%s %s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.root_export_decl.type), buf_ptr(&node->data.root_export_decl.name)); break; case NodeTypeFnDef: { fprintf(f, "%s\n", node_type_str(node->type)); AstNode *child = node->data.fn_def.fn_proto; ast_print(f, child, indent + 2); ast_print(f, node->data.fn_def.body, indent + 2); break; } case NodeTypeFnProto: { Buf *name_buf = &node->data.fn_proto.name; fprintf(f, "%s '%s'\n", node_type_str(node->type), buf_ptr(name_buf)); for (int i = 0; i < node->data.fn_proto.params.length; i += 1) { AstNode *child = node->data.fn_proto.params.at(i); ast_print(f, child, indent + 2); } ast_print(f, node->data.fn_proto.return_type, indent + 2); break; } case NodeTypeBlock: { fprintf(f, "%s\n", node_type_str(node->type)); for (int i = 0; i < node->data.block.statements.length; i += 1) { AstNode *child = node->data.block.statements.at(i); ast_print(f, child, indent + 2); } break; } case NodeTypeParamDecl: { Buf *name_buf = &node->data.param_decl.name; fprintf(f, "%s '%s'\n", node_type_str(node->type), buf_ptr(name_buf)); ast_print(f, node->data.param_decl.type, indent + 2); break; } case NodeTypeReturnExpr: { const char *prefix_str = return_prefix_str(node->data.return_expr.kind); fprintf(f, "%s%s\n", prefix_str, node_type_str(node->type)); if (node->data.return_expr.expr) ast_print(f, node->data.return_expr.expr, indent + 2); break; } case NodeTypeDefer: { const char *prefix_str = return_prefix_str(node->data.defer.kind); fprintf(f, "%s%s\n", prefix_str, node_type_str(node->type)); if (node->data.defer.expr) ast_print(f, node->data.defer.expr, indent + 2); break; } case NodeTypeVariableDeclaration: { Buf *name_buf = &node->data.variable_declaration.symbol; fprintf(f, "%s '%s'\n", node_type_str(node->type), buf_ptr(name_buf)); if (node->data.variable_declaration.type) ast_print(f, node->data.variable_declaration.type, indent + 2); if (node->data.variable_declaration.expr) ast_print(f, node->data.variable_declaration.expr, indent + 2); break; } case NodeTypeTypeDecl: { Buf *name_buf = &node->data.type_decl.symbol; fprintf(f, "%s '%s'\n", node_type_str(node->type), buf_ptr(name_buf)); ast_print(f, node->data.type_decl.child_type, indent + 2); break; } case NodeTypeErrorValueDecl: { Buf *name_buf = &node->data.error_value_decl.name; fprintf(f, "%s '%s'\n", node_type_str(node->type), buf_ptr(name_buf)); break; } case NodeTypeFnDecl: fprintf(f, "%s\n", node_type_str(node->type)); ast_print(f, node->data.fn_decl.fn_proto, indent + 2); break; case NodeTypeBinOpExpr: fprintf(f, "%s %s\n", node_type_str(node->type), bin_op_str(node->data.bin_op_expr.bin_op)); ast_print(f, node->data.bin_op_expr.op1, indent + 2); ast_print(f, node->data.bin_op_expr.op2, indent + 2); break; case NodeTypeUnwrapErrorExpr: fprintf(f, "%s\n", node_type_str(node->type)); ast_print(f, node->data.unwrap_err_expr.op1, indent + 2); if (node->data.unwrap_err_expr.symbol) { ast_print(f, node->data.unwrap_err_expr.symbol, indent + 2); } ast_print(f, node->data.unwrap_err_expr.op2, indent + 2); break; case NodeTypeFnCallExpr: fprintf(f, "%s\n", node_type_str(node->type)); ast_print(f, node->data.fn_call_expr.fn_ref_expr, indent + 2); for (int i = 0; i < node->data.fn_call_expr.params.length; i += 1) { AstNode *child = node->data.fn_call_expr.params.at(i); ast_print(f, child, indent + 2); } break; case NodeTypeArrayAccessExpr: fprintf(f, "%s\n", node_type_str(node->type)); ast_print(f, node->data.array_access_expr.array_ref_expr, indent + 2); ast_print(f, node->data.array_access_expr.subscript, indent + 2); break; case NodeTypeSliceExpr: fprintf(f, "%s\n", node_type_str(node->type)); ast_print(f, node->data.slice_expr.array_ref_expr, indent + 2); ast_print(f, node->data.slice_expr.start, indent + 2); if (node->data.slice_expr.end) { ast_print(f, node->data.slice_expr.end, indent + 2); } break; case NodeTypeDirective: fprintf(f, "%s\n", node_type_str(node->type)); ast_print(f, node->data.directive.expr, indent + 2); break; case NodeTypePrefixOpExpr: fprintf(f, "%s %s\n", node_type_str(node->type), prefix_op_str(node->data.prefix_op_expr.prefix_op)); ast_print(f, node->data.prefix_op_expr.primary_expr, indent + 2); break; case NodeTypeNumberLiteral: { NumLit kind = node->data.number_literal.kind; const char *name = node_type_str(node->type); if (kind == NumLitUInt) { fprintf(f, "%s uint %" PRIu64 "\n", name, node->data.number_literal.data.x_uint); } else { fprintf(f, "%s float %f\n", name, node->data.number_literal.data.x_float); } break; } case NodeTypeStringLiteral: { const char *c = node->data.string_literal.c ? "c" : ""; fprintf(f, "StringLiteral %s'%s'\n", c, buf_ptr(&node->data.string_literal.buf)); break; } case NodeTypeCharLiteral: { fprintf(f, "%s '%c'\n", node_type_str(node->type), node->data.char_literal.value); break; } case NodeTypeSymbol: fprintf(f, "Symbol %s\n", buf_ptr(&node->data.symbol_expr.symbol)); break; case NodeTypeImport: fprintf(f, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.import.path)); break; case NodeTypeCImport: fprintf(f, "%s\n", node_type_str(node->type)); ast_print(f, node->data.c_import.block, indent + 2); break; case NodeTypeBoolLiteral: fprintf(f, "%s '%s'\n", node_type_str(node->type), node->data.bool_literal.value ? "true" : "false"); break; case NodeTypeNullLiteral: fprintf(f, "%s\n", node_type_str(node->type)); break; case NodeTypeIfBoolExpr: fprintf(f, "%s\n", node_type_str(node->type)); if (node->data.if_bool_expr.condition) ast_print(f, node->data.if_bool_expr.condition, indent + 2); ast_print(f, node->data.if_bool_expr.then_block, indent + 2); if (node->data.if_bool_expr.else_node) ast_print(f, node->data.if_bool_expr.else_node, indent + 2); break; case NodeTypeIfVarExpr: { Buf *name_buf = &node->data.if_var_expr.var_decl.symbol; fprintf(f, "%s '%s'\n", node_type_str(node->type), buf_ptr(name_buf)); if (node->data.if_var_expr.var_decl.type) ast_print(f, node->data.if_var_expr.var_decl.type, indent + 2); if (node->data.if_var_expr.var_decl.expr) ast_print(f, node->data.if_var_expr.var_decl.expr, indent + 2); ast_print(f, node->data.if_var_expr.then_block, indent + 2); if (node->data.if_var_expr.else_node) ast_print(f, node->data.if_var_expr.else_node, indent + 2); break; } case NodeTypeWhileExpr: fprintf(f, "%s\n", node_type_str(node->type)); ast_print(f, node->data.while_expr.condition, indent + 2); ast_print(f, node->data.while_expr.body, indent + 2); break; case NodeTypeForExpr: fprintf(f, "%s\n", node_type_str(node->type)); ast_print(f, node->data.for_expr.elem_node, indent + 2); ast_print(f, node->data.for_expr.array_expr, indent + 2); if (node->data.for_expr.index_node) { ast_print(f, node->data.for_expr.index_node, indent + 2); } ast_print(f, node->data.for_expr.body, indent + 2); break; case NodeTypeSwitchExpr: fprintf(f, "%s\n", node_type_str(node->type)); ast_print(f, node->data.switch_expr.expr, indent + 2); for (int i = 0; i < node->data.switch_expr.prongs.length; i += 1) { AstNode *child_node = node->data.switch_expr.prongs.at(i); ast_print(f, child_node, indent + 2); } break; case NodeTypeSwitchProng: fprintf(f, "%s\n", node_type_str(node->type)); for (int i = 0; i < node->data.switch_prong.items.length; i += 1) { AstNode *child_node = node->data.switch_prong.items.at(i); ast_print(f, child_node, indent + 2); } if (node->data.switch_prong.var_symbol) { ast_print(f, node->data.switch_prong.var_symbol, indent + 2); } ast_print(f, node->data.switch_prong.expr, indent + 2); break; case NodeTypeSwitchRange: fprintf(f, "%s\n", node_type_str(node->type)); ast_print(f, node->data.switch_range.start, indent + 2); ast_print(f, node->data.switch_range.end, indent + 2); break; case NodeTypeLabel: fprintf(f, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.label.name)); break; case NodeTypeGoto: fprintf(f, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.goto_expr.name)); break; case NodeTypeBreak: fprintf(f, "%s\n", node_type_str(node->type)); break; case NodeTypeContinue: fprintf(f, "%s\n", node_type_str(node->type)); break; case NodeTypeUndefinedLiteral: fprintf(f, "%s\n", node_type_str(node->type)); break; case NodeTypeAsmExpr: fprintf(f, "%s\n", node_type_str(node->type)); break; case NodeTypeFieldAccessExpr: fprintf(f, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.field_access_expr.field_name)); ast_print(f, node->data.field_access_expr.struct_expr, indent + 2); break; case NodeTypeStructDecl: fprintf(f, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.struct_decl.name)); for (int i = 0; i < node->data.struct_decl.fields.length; i += 1) { AstNode *child = node->data.struct_decl.fields.at(i); ast_print(f, child, indent + 2); } for (int i = 0; i < node->data.struct_decl.fns.length; i += 1) { AstNode *child = node->data.struct_decl.fns.at(i); ast_print(f, child, indent + 2); } break; case NodeTypeStructField: fprintf(f, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.struct_field.name)); if (node->data.struct_field.type) { ast_print(f, node->data.struct_field.type, indent + 2); } break; case NodeTypeStructValueField: fprintf(f, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.struct_val_field.name)); ast_print(f, node->data.struct_val_field.expr, indent + 2); break; case NodeTypeContainerInitExpr: fprintf(f, "%s\n", node_type_str(node->type)); ast_print(f, node->data.container_init_expr.type, indent + 2); for (int i = 0; i < node->data.container_init_expr.entries.length; i += 1) { AstNode *child = node->data.container_init_expr.entries.at(i); ast_print(f, child, indent + 2); } break; case NodeTypeArrayType: { const char *const_str = node->data.array_type.is_const ? "const" : "var"; fprintf(f, "%s %s\n", node_type_str(node->type), const_str); if (node->data.array_type.size) { ast_print(f, node->data.array_type.size, indent + 2); } ast_print(f, node->data.array_type.child_type, indent + 2); break; } case NodeTypeErrorType: fprintf(f, "%s\n", node_type_str(node->type)); break; case NodeTypeTypeLiteral: fprintf(f, "%s\n", node_type_str(node->type)); break; } }
void main(int argc, char *argv[]){ FILE *fp; FILE *fp2; buffer B; FILE *filename,*filename2; ast a; FPTR fptr; SPTR sptr; // printf("Hello inside main\n"); sptr=symbol_table_create(20,20); fptr=global(sptr); // printf("DOne\n"); char testcopy[]="testcopy.txt"; parse_Tree PT; int T[52][49]; filename=fopen(argv[2],"w"); // filename2=fopen(argv[3],"w"); fp2=fopen("testcopy.txt","r"); fp=fopen(argv[1],"r"); int num; printf("Enter the desired Option !!\n\n"); do{ printf(" 1 : Select Option 1 for Lexical Analysis \n 2 : Select Option 2 for Parse Tree \n 3 : Select Option 3 for Abstract Syntax Tree \n 4 : Select Option 4 for Symbol Table \n 5 : Select Option 5 for Semantic Analysis \n 6 : Select Option 6 for Code Generation\n"); scanf("%d",&num); switch(num){ case 1: //line_number=1; //int k=BUFFERSIZE; buf=0; ahead=0; token_info TI; printf("***************************LEXICAL ANALYSIS***************************\n\n"); printf(" LEXEME_NAME | TOKEN_NAME | LINE_NUMBER |\n\n"); fprintf(filename,"***************************LEXICAL ANALYSIS***************************\n\n"); fprintf(filename," LEXEME_NAME | TOKEN_NAME | LINE_NUMBER |\n\n"); TI=find_next_token(fp,B); while(strcmp(TI.lexeme_name,"$")!=0){ printf("| %15s | %15s | %d\n",TI.lexeme_name,TI.token_name,TI.line); fprintf(filename,"| %15s | %15s | %d\n",TI.lexeme_name,TI.token_name,TI.line); TI=find_next_token(fp,B); } TI=find_next_token(fp,B); printf("| %15s | %15s | %d\n",TI.lexeme_name,TI.token_name,TI.line); fprintf(filename,"| %15s | %15s | %d\n",TI.lexeme_name,TI.token_name,TI.line); printf("\n\n\n"); break; case 2: create_parsing_table(T); PT=parse_input(argv[1],T); // printf("end of parsing\n"); PT->temp=PT->head; // printf("end of parsing2222\n"); printf("*************************************Printing the Parse Tree*************************************\n\n\n"); printf("| LEXEME_NAME| TOKEN_NAME | PARENT_NODE | IS_LEAF_NODE | LINE NUMBER |\n\n\n"); fprintf(filename,"**********************************Printing the Parse Tree**********************************\n\n\n"); fprintf(filename,"| LEXEME_NAME | TOKEN_NAME | PARENT_NODE | IS_LEAF_NODE | LINE NUMBER |\n\n\n"); parse_tree_print(PT,filename); return; case 3: create_parsing_table(T); PT=parse_input(argv[1],T); // printf("end of parsing\n"); PT->temp=PT->head; create_ast(PT,a); printf("*************************************Printing the AST Tree *************************************\n\n\n"); printf(" |LEXEME_NAME |TOKEN_NAME |PARENT_NODE |IS_LEAF_NODE |LINE NUMBER\n\n\n"); fprintf(filename,"*************************************Printing the AST Tree*************************************\n\n\n"); fprintf(filename," |LEXEME_NAME |TOKEN_NAME |PARENT_NODE |IS_LEAF_NODE |LINE NUMBER\n\n\n"); ast_print(PT,filename); return; case 4: //printf("Hello inside case 4\n"); create_parsing_table(T); PT=parse_input(argv[1],T); // printf("end of parsing\n"); PT->temp=PT->head; create_ast(PT,a); //ast_print(PT,filename2); PT->temp=PT->head; add_functions(sptr,fptr,PT); printf("\n\n***********************************************Printing the Symbol Table*************************************************\n\n\n"); printf(" LEXEME_NAME | TOKEN_NAME | SCOPE | DATA_TYPE | SIZE | OFFSET | LINE NUMBER\n\n\n"); fprintf(filename,"*************************************Printing the Symbol Table***************************************\n\n\n"); fprintf(filename," LEXEME_NAME | TOKEN_NAME | SCOPE | DATA_TYPE | SIZE | OFFSET | LINE NUMBER\n\n\n"); symbol_table_print(sptr,filename); printf("\n\n"); fprintf(filename,"\n\n"); return; case 5: //printf("Hello inside case 4\n"); create_parsing_table(T); PT=parse_input(argv[1],T); // printf("end of parsing\n"); PT->temp=PT->head; create_ast(PT,a); //ast_print(PT,filename2); PT->temp=PT->head; add_functions(sptr,fptr,PT); PT->temp=PT->head; check_semantic(PT,fptr,sptr); return; case 6 : create_parsing_table(T); PT=parse_input(argv[1],T); // printf("end of parsing\n"); PT->temp=PT->head; create_ast(PT,a); //ast_print(PT,filename2); PT->temp=PT->head; add_functions(sptr,fptr,PT); PT->temp=PT->head; assembly_code(PT,sptr,filename); return; default: printf("\nWrong choice!!!Enter Between 1 to 4"); } } while(1); fclose(fp); fclose(filename); // fclose(filename2); fclose(fp2); return 0; }
/*********************************************************************** * Main program for the Compiler **********************************************************************/ int main (int argc, char *argv[]) { getOpts (argc, argv); /* Set up and apply command line options */ /*********************************************************************** * Compiler Initialization. * * If explicit initialization of any phase of the compilation is needed, * calls to initialization routines in the applicable modules are placed * here. **********************************************************************/ errorOccurred = FALSE; /*********************************************************************** * Start the Compilation **********************************************************************/ if (dumpSource) sourceDump(); /* Phase 1: Scanner. In phase 2 and after the following code should be * removed */ /* while (yylex()) if (errorOccurred) break; */ /* Phase 2: Parser -- should allocate an AST, storing the reference in the * global variable "ast", and build the AST there. */ if(1 == yyparse()) { return 0; // parse failed } build_table(ast); insert_predef(); //display(); if(semantic_check(ast)==-1){ //printf(); fprintf(stderr, "SYMANTIC CHECK FAILED\n"); } /* Phase 3: Call the AST dumping routine if requested */ if (dumpAST) ast_print(ast); /* Phase 4: Add code to call the code generation routine */ /* TODO: call your code generation routine here */ if (errorOccurred) fprintf(outputFile,"Failed to compile\n"); else // genCode(ast); ; /*********************************************************************** * Post Compilation Cleanup **********************************************************************/ /* Make calls to any cleanup or finalization routines here. */ ast_free(ast); /* Clean up files if necessary */ if (inputFile != DEFAULT_INPUT_FILE) fclose (inputFile); if (errorFile != DEFAULT_ERROR_FILE) fclose (errorFile); if (dumpFile != DEFAULT_DUMP_FILE) fclose (dumpFile); if (traceFile != DEFAULT_TRACE_FILE) fclose (traceFile); if (outputFile != DEFAULT_OUTPUT_FILE) fclose (outputFile); if (runInputFile != DEFAULT_RUN_INPUT_FILE) fclose (runInputFile); return 0; }