// throw string void err_throw_str(const char *err) { int caught = 0; int throw_sp = prog_stack_count; int try_sp = err_find_try(throw_sp); int reset_sp; if (!prog_error && try_sp != -1) { bcip_t catch_ip = prog_stack[try_sp].x.vtry.catch_ip; // position after kwCATCH code_jump(catch_ip + 1); // skip "end try" address code_getaddr(); // fetch next catch in the current block catch_ip = code_getaddr(); caught = err_throw_catch(err); reset_sp = try_sp; while (!caught && (catch_ip != INVALID_ADDR || try_sp != -1)) { // find in the current block while (!caught && catch_ip != INVALID_ADDR) { code_jump(catch_ip + 1); code_getaddr(); catch_ip = code_getaddr(); caught = err_throw_catch(err); } // find in the next outer block if (!caught && try_sp != -1) { try_sp = err_find_try(try_sp); if (try_sp != -1) { reset_sp = try_sp; catch_ip = prog_stack[try_sp].x.vtry.catch_ip; code_jump(catch_ip + 1); code_getaddr(); catch_ip = code_getaddr(); caught = err_throw_catch(err); } } } // cleanup the stack stknode_t node; int sp; for (sp = throw_sp; sp > reset_sp; sp--) { code_pop_and_free(&node); } if (node.type != kwTRY) { err_stackmess(); } } if (!caught) { prog_error = 0x80; err_common_msg(WORD_RTE, prog_file, prog_line, err); } error_caught = caught; }
void code_c_command(char source[], char code[]) { strcat(code,"111"); char comp_of_source[5]; comp(source,comp_of_source); char dest_of_source[5]; dest(source,dest_of_source); char jump_of_source[5]; jump(source,jump_of_source); code_comp(comp_of_source,code); code_dest(dest_of_source,code); code_jump(jump_of_source,code); code[MAX_CODE_LEN]='\n'; code[MAX_CODE_LEN+1]='\0'; }
void code_tac(FILE *file, RegDesc *registers, Tac *current) { switch (current->op) { case TAC_BEGINPROGRAM: code_main(file); code_begin_function(file, current->result); break; case TAC_BEGINFUNCTION: code_begin_function(file, current->result); break; case TAC_ENDFUNCTION: code_end_function(file, registers); break; case TAC_RETURN: code_return(file, registers, current->result); break; case TAC_ENDPROGRAM: code_end_function(file, registers); break; case TAC_GOTO: code_jump(file, registers, JUMP, current->location->result, NULL); break; case TAC_IFZ: code_jump(file, registers, JUMP_NE, current->location->result, current->condition); break; case TAC_IFNZ: code_jump(file, registers, JUMP_E, current->location->result, current->condition); break; case TAC_ADD: code_binary(file, registers, ADD, current->result, current->operand1, current->operand2); break; case TAC_SUBTRACT: code_binary(file, registers, SUBTRACT, current->result, current->operand1, current->operand2); break; case TAC_MULTIPLY: code_binary(file, registers, MULTIPLY, current->result, current->operand1, current->operand2); break; case TAC_DIVIDE: code_binary(file, registers, DIVIDE, current->result, current->operand1, current->operand2); break; case TAC_NOT: //FIX 5-19-2011 - INVERT is not what we want - thats a bit wise invert //Since we are using booleans, just xor them //code_unary(file, registers, INVERT, current->result, current->operand1); code_binary(file, registers, LOGIC_XOR, current->result, current->operand1, symbol_one); break; case TAC_NEGATIVE: code_unary(file, registers, NEGATE, current->result, current->operand1); break; case TAC_AND: code_binary(file, registers, LOGIC_AND, current->result, current->operand1, current->operand2); break; case TAC_OR: code_binary(file, registers, LOGIC_OR, current->result, current->operand1, current->operand2); break; case TAC_MOD: code_binary(file, registers, ATT_MOD, current->result, current->operand1, current->operand2); break; case TAC_COPY: code_copy(file, registers, current->result, current->operand1); break; case TAC_ARG: code_arg(file, registers, current->result); break; case TAC_CALL://On a TAC call, the function is the operand, and the return is the result code_call(file, registers, current->operand1, current->result); break; case TAC_LABEL: debug("Code_Label - Symbol: %s", symbol_to_string(current->result)); code_flush_all(file, registers); fprintf(file, "%s:\n", current->result->name); break; case TAC_GT: code_compare(file, registers, IS_GREATER, current->result, current->operand1, current->operand2); break; case TAC_LT: code_compare(file, registers, IS_LESS, current->result, current->operand1, current->operand2); break; case TAC_GTE: code_compare(file, registers, IS_GREATER_EQUAL, current->result, current->operand1, current->operand2); break; case TAC_LTE: code_compare(file, registers, IS_LESS_EQUAL, current->result, current->operand1, current->operand2); break; case TAC_EQUAL: code_compare(file, registers, IS_EQUAL, current->result, current->operand1, current->operand2); break; case TAC_NOTEQUAL: code_compare(file, registers, IS_NOT_EQUAL, current->result, current->operand1, current->operand2); break; case TAC_VARIABLE: //do nothing break; case TAC_NOP: //Do nothing break; default: die("Unrecognized TAC: %d", current->op); break; } }