Implement VM branching instructions
x1phosura x1phosura@x1phosura.zone
Mon, 13 Nov 2023 03:13:14 -0800
2 files changed,
75 insertions(+),
14 deletions(-)
M
projects/08/src/codewriter.h
→
projects/08/src/codewriter.h
@@ -97,12 +97,14 @@ "0;JMP\n" // return
"\n" "(__comp_funcs_end)\n"; -char vm_init[] = "//@256\n" // starting address of stack (nothing pushed yet) - "//D=A\n" // D = 256 - "//@SP\n" // A = <constant representing address of SP> - "//M=D\n" // <memory pointed to by SP> = 256 +char vm_init[] = "@256\n" // starting address of stack (nothing pushed yet) + "D=A\n" // D = 256 + "@SP\n" // A = <constant representing address of SP> + "M=D\n" // <memory pointed to by SP> = 256 "\n%s\n"; // <- comp_vm_funcs // TODO: add initializers for argument, local, static, constant, this, that + +// TODO only output vm_stop when Main.main char vm_stop[] = "(END)\n" // starting address of stack (nothing pushed yet) "@END\n" // D = 256 "0;JMP\n"; // A = <constant representing address of SP>@@ -332,20 +334,79 @@
return true; } +static bool write_label(struct vm_instruction_t *vm_instr, FILE *fp) +{ + char label_asm[] = "(%s)\n"; + fprintf(fp, label_asm, vm_instr->arg1); + return true; +} + +static bool write_goto(struct vm_instruction_t *vm_instr, FILE *fp) +{ + char goto_asm[] = "@%s\n" + "0;JMP\n"; + fprintf(fp, goto_asm, vm_instr->arg1); + return true; +} + +static bool write_if(struct vm_instruction_t *vm_instr, FILE *fp) +{ + char if_asm[] = "@SP\n" // pop register D + "AM=M-1\n" + "D=M\n" // pop value into D register + "@%s\n" + "D;JNE\n"; + fprintf(fp, if_asm, vm_instr->arg1); + return true; +} + +static bool write_function(struct vm_instruction_t *vm_instr, FILE *fp) +{ + print_vm_instruction(vm_instr, fp); + return true; // STUB TODO implement +} + +static bool write_return(struct vm_instruction_t *vm_instr, FILE *fp) +{ + print_vm_instruction(vm_instr, fp); + return true; // STUB TODO implement +} + +static bool write_call(struct vm_instruction_t *vm_instr, FILE *fp) +{ + print_vm_instruction(vm_instr, fp); + return true; // STUB TODO implement +} + bool write_instruction(struct vm_instruction_t *vm_instr, FILE *fp) { fprintf(fp, "\n// %lu: %s\n", file_line_no, vm_instr->line); - if (vm_instr->cmd == C_ARITHMETIC) { - write_arithmetic(vm_instr, fp); - } else if (vm_instr->cmd == C_PUSH) { - write_push(vm_instr, fp); - } else if (vm_instr->cmd == C_POP) { - write_pop(vm_instr, fp); - } else { + + switch (vm_instr->cmd) { + case C_ARITHMETIC: + return write_arithmetic(vm_instr, fp); + case C_PUSH: + return write_push(vm_instr, fp); + case C_POP: + return write_pop(vm_instr, fp); + case C_LABEL: + return write_label(vm_instr, fp); + case C_GOTO: + return write_goto(vm_instr, fp); + case C_IF: + return write_if(vm_instr, fp); + case C_FUNCTION: + return write_function(vm_instr, fp); + case C_RETURN: + return write_return(vm_instr, fp); + case C_CALL: + return write_call(vm_instr, fp); + default: err("error: unrecognized instruction (%u)\n", vm_instr->cmd); return false; } - return true; + + return false; // should never reach here tbh } #endif // _CODEWRITER_H
M
projects/08/src/parser.h
→
projects/08/src/parser.h
@@ -73,9 +73,9 @@ vm_instr->arg1 = NULL;
return true; } -void print_vm_instruction(struct vm_instruction_t *vm_instr) +void print_vm_instruction(struct vm_instruction_t *vm_instr, FILE *fp) { - printf("{\n\tcmd: %d,\n\targ1: \"%s\",\n\targ2: %hu,\n}\n", + fprintf(fp, "{\n\tcmd: %d,\n\targ1: \"%s\",\n\targ2: %hu,\n}\n", vm_instr->cmd, vm_instr->arg1, vm_instr->arg2); }