void stmt_list_parse(node* list) { while(list) { if(list && list->type == LIST_NODE) { node* n = list->u.list.start; if(n->type == ASSIGN_NODE) { //printf("generating assignment quad in BB %s\n", currentBlock->name); gen_assign(n); } else if(n->type == BINOP_NODE) { gen_rvalue(n, NULL); } else if(n->type == UNOP_NODE) { gen_rvalue(n, NULL); } else if(n->type == IF_NODE || n->type == IFELSE_NODE) { gen_if(n); } else if(n->type == FOR_NODE) { gen_for(n); } else if(n->type == WHILE_NODE) { gen_while(n); } else if(n->type == JUMP_NODE) { gen_jmp(n); } else if(n->type == CALL_NODE) { //Function Call int argnum = n->u.call.argnum; qnode* num = qnode_new(Q_CONSTANT); num->name = malloc(100); sprintf(num->name, "%i", argnum); num->u.value = argnum; emit(O_ARGNUM, NULL, num, NULL); if(argnum) { //Generate argument quad node* argptr = n->u.call.args; while(argptr) { emit(O_ARGDEF, NULL, gen_rvalue(argptr->u.list.start, NULL), NULL); if(argptr->next) { argptr = argptr->next; } else { break; } } } emit(O_CALL, NULL, gen_rvalue(n->u.call.function, NULL), NULL); } else if(n->type == IDENT_NODE || n->type == DEFAULT_NODE) { //do nothing } else { fprintf(stderr, "QUAD ERROR: Unrecognized Node Type %i\n", n->type); exit(1); } if(list->next) { list = list->next; } else { break; } } else { fprintf(stderr, "QUAD ERROR: Invalid Statement List\n"); break; } } }
void gen_open_library(const char * libname, const char * librarybase) { char lab[80],lablabel[80]; gen_pop_addr(1); /* address of library name in a1 */ gen_jsr("_open_library"); make_library_base(libname); gen_save32d(0,librarybase); gen_test(); make_label(lab,lablabel); gen_bne(lab); gen_jmp("_EXIT_PROG"); /* quit program if can't open library */ gen_label(lablabel); enter_XREF("_open_library"); }
static void ast_gen_r(struct ast *a) { int bpid_1, bpid_2; vm_label_t label; struct value *v; if (a == NULL) return; a->label = gptr; switch (a->type) { case AST_LOCAL: gen_push_local(a->u.local.index, a->u.local.upcount); break; case AST_VALUE: gen_push_value(a->u.value.value); if (a->u.value.value->type == VALUE_CLOSURE) { gen_set_activation(); gen_jmp_bp(&bpid_1); a->u.value.value->v.k->label = gptr; ast_gen_r(a->u.value.value->v.k->ast); gen_ret(); backpatch(bpid_1); } break; case AST_BUILTIN: if (a->u.builtin.bi->index == INDEX_BUILTIN_STORE) { struct ast *lvalue; lvalue = ast_find_local(a); gen_cow_local(lvalue->u.local.index, lvalue->u.local.upcount); } ast_gen_r(a->u.builtin.right); if (a->u.builtin.bi->arity == -1) { v = value_new_integer(ast_count_args(a->u.builtin.right)); value_deregister(v); gen_push_value(v); } gen_builtin(a->u.builtin.bi); break; case AST_APPLY: ast_gen_r(a->u.apply.right); ast_gen_r(a->u.apply.left); gen_apply(); break; case AST_ROUTINE: ast_gen_r(a->u.routine.body); break; case AST_ARG: ast_gen_r(a->u.arg.left); ast_gen_r(a->u.arg.right); break; case AST_STATEMENT: ast_gen_r(a->u.statement.left); ast_gen_r(a->u.statement.right); break; case AST_ASSIGNMENT: assert(a->u.assignment.left != NULL); assert(a->u.assignment.left->type == AST_LOCAL); ast_gen_r(a->u.assignment.right); if (a->u.assignment.defining) { /* XXX */ /* gen_init_local(a->u.assignment.left->u.local.index, a->u.assignment.left->u.local.upcount); */ } else { gen_pop_local(a->u.assignment.left->u.local.index, a->u.assignment.left->u.local.upcount); } break; case AST_CONDITIONAL: ast_gen_r(a->u.conditional.test); gen_jz_bp(&bpid_1); ast_gen_r(a->u.conditional.yes); if (a->u.conditional.no != NULL) gen_jmp_bp(&bpid_2); backpatch(bpid_1); if (a->u.conditional.no != NULL) { ast_gen_r(a->u.conditional.no); backpatch(bpid_2); } break; case AST_WHILE_LOOP: label = gptr; ast_gen_r(a->u.while_loop.test); gen_jz_bp(&bpid_1); ast_gen_r(a->u.while_loop.body); gen_jmp(label); backpatch(bpid_1); break; case AST_RETR: ast_gen_r(a->u.retr.body); gen_ret(); break; } }