all repos — nand2tetris @ c7c9a8b3eb58622f54b2ab782ad71317ffae179e

my nand2tetris progress

Parse C-type instruction jump field
x1phosura x1phosura@x1phosura.zone
Wed, 21 Dec 2022 03:57:47 -0800
commit

c7c9a8b3eb58622f54b2ab782ad71317ffae179e

parent

cc2f5559d20be2c9ba725e542991664f0fcb758b

1 files changed, 74 insertions(+), 21 deletions(-)

jump to
M projects/06/assembler1/assembler1.cprojects/06/assembler1/assembler1.c

@@ -107,27 +107,78 @@ /* returns jump bits 0b00000jjj

*/ static bool parse_c_type_jump(const char *jump_line, uint8_t *jump) { - // Note: can do 'jump' fields via lookup tables once extracted from line + size_t len; + char j0, j1, j2; + char *err_1st_char = "syntax error: jump field doesn't start with 'J'\n"; + char *err_2nd_char = "syntax error: 2nd letter in jump field incorrect\n"; + char *err_3rd_char = "syntax error: 3rd letter in jump field incorrect\n"; + DEBUG("jump_line: %s\n", jump_line); - - /* if 'J' - * if 'G' - * if 'T' - * if 'E' - * if 'E' - * if 'Q' - * if 'L' - * if 'T' - * if 'E' - * if 'N' - * if 'E' - * if 'M' - * if 'P' - * default: - * "syntax error" - */ + + for (len = 0; jump_line[len] == 'J' || jump_line[len] == 'G' || + jump_line[len] == 'T' || jump_line[len] == 'E' || + jump_line[len] == 'Q' || jump_line[len] == 'L' || + jump_line[len] == 'N' || jump_line[len] == 'M' || + jump_line[len] == 'P'; ++len) {} + if (len != 3) { + alert("syntax error: jump field incorrect length %lu\n", len); + return false; + } + + j0 = jump_line[0]; + j1 = jump_line[1]; + j2 = jump_line[2]; + + if (j0 == 'J') { // if "J__" + switch (j1) { + case 'G': // if "JG_" + if (j2 == 'T') { // if "JGT" + *jump = 0x1; + } else if (j2 == 'E') { // if "JGE" + *jump = 0x3; + } else { + alert(err_3rd_char); return false; + } + break; + case 'E': // if "JE_" + if (j2 == 'Q') { // if "JEQ" + *jump = 0x2; + } else { + alert(err_3rd_char); return false; + } + break; + case 'L': // if "JL_" + if (j2 == 'T') { // if "JLT" + *jump = 0x4; + } else if (j2 == 'E') { // if "JLE" + *jump = 0x6; + } else { + alert(err_3rd_char); return false; + } + break; + case 'N': // if "JN_" + if (j2 == 'E') { // if "JNE" + *jump = 0x5; + } else { + alert(err_3rd_char); return false; + } + break; + case 'M': // if "JM_" + if (j2 == 'P') { // if "JMP" + *jump = 0x7; + } else { + alert(err_3rd_char); return false; + } + break; + default: + alert(err_2nd_char); + return false; + } + } else { + alert(err_1st_char); + return false; + } - *jump = 0x01; // 0b00000001 return true; }

@@ -142,9 +193,9 @@ char *dest_start = NULL;

char *comp_start = NULL; char *jump_start = NULL; size_t i = 0; - uint8_t dest = 0; + uint8_t dest = 0; // default value when not present uint8_t comp = 0; - uint8_t jump = 0; + uint8_t jump = 0; // default value when not present c = line[0]; for (i = 0; c != ' ' && c != '\t' &&

@@ -154,6 +205,7 @@

if (c == '=') { if (1 <= i && i <= 3) { dest_start = &line[0]; // start of line + // this 'i+1' might be dangerous! comp_start = &line[i+1]; // after "[dest]=" } else { //syntax error

@@ -163,6 +215,7 @@ return false;

} } else if (c == ';') { if (1 <= i && i <= 7) { + // this 'i+1' might be dangerous! jump_start = &line[i+1]; // after "[comp];" } else { //syntax error