all repos — nand2tetris @ d779bea5b6dad359f8817257386a56f2fa13bc0d

my nand2tetris progress

Parse C-type instruction dest field
x1phosura x1phosura@x1phosura.zone
Wed, 21 Dec 2022 05:03:08 -0800
commit

d779bea5b6dad359f8817257386a56f2fa13bc0d

parent

c7c9a8b3eb58622f54b2ab782ad71317ffae179e

1 files changed, 65 insertions(+), 46 deletions(-)

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

@@ -75,22 +75,49 @@ /* returns dest bits 0b00000ddd

*/ static bool parse_c_type_dest(const char *dest_line, uint8_t *dest) { - DEBUG("dest_line: %s\n", dest_line); + size_t len; - /* if 'A' - * if 'D' - * if 'M' - * else if '=' - * if 'D' - * if 'M' - * else if '=' - * if 'M' - * if '=' - * default: - * "syntax error" - */ + for (len = 0; dest_line[len] != '='; ++len) {} // read until '=' - *dest = 0x03; // 0b00000011 + if (len == 3) { + if (dest_line[0] == 'A' && dest_line[1] == 'D' && + dest_line[2] == 'M') { + *dest = 0x7; + } else { + alert("syntax error: destination format incorrect\n"); + return false; + } + } else if (len == 2) { + if (dest_line[0] == 'D' && dest_line[1] == 'M') { + *dest = 0x3; + } else if (dest_line[0] == 'A' && dest_line[1] == 'M') { + *dest = 0x5; + } else if (dest_line[0] == 'A' && dest_line[1] == 'D') { + *dest = 0x6; + } else { + alert("syntax error: destination format incorrect\n"); + return false; + } + } else if (len == 1) { + switch (dest_line[0]) { + case 'M': + *dest = 0x1; + break; + case 'D': + *dest = 0x2; + break; + case 'A': + *dest = 0x4; + break; + default: + alert("syntax error: destination format incorrect\n"); + return false; + } + } else { + alert("syntax error: dest field incorrect length %lu\n", len); + return false; + } + return true; }

@@ -98,8 +125,10 @@ /* returns comp bits 0b0acccccc

*/ static bool parse_c_type_comp(const char *comp_line, uint8_t *comp) { + size_t len; DEBUG("comp_line: %s\n", comp_line); - *comp = 0x53; // 0b01010011 + + *comp = 0x53; // STUB: 0b01010011 return true; }

@@ -108,13 +137,10 @@ */

static bool parse_c_type_jump(const char *jump_line, uint8_t *jump) { 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); - 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' ||

@@ -125,46 +151,42 @@ 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" + if (jump_line[0] == 'J') { // if "J__" + switch (jump_line[1]) { + case 'G': // if "JG_" + if (jump_line[2] == 'T') { // if "JGT" *jump = 0x1; - } else if (j2 == 'E') { // if "JGE" + } else if (jump_line[2] == 'E') { // if "JGE" *jump = 0x3; } else { alert(err_3rd_char); return false; } break; - case 'E': // if "JE_" - if (j2 == 'Q') { // if "JEQ" + case 'E': // if "JE_" + if (jump_line[2] == 'Q') { // if "JEQ" *jump = 0x2; } else { alert(err_3rd_char); return false; } break; - case 'L': // if "JL_" - if (j2 == 'T') { // if "JLT" + case 'L': // if "JL_" + if (jump_line[2] == 'T') { // if "JLT" *jump = 0x4; - } else if (j2 == 'E') { // if "JLE" + } else if (jump_line[2] == 'E') { // if "JLE" *jump = 0x6; } else { alert(err_3rd_char); return false; } break; - case 'N': // if "JN_" - if (j2 == 'E') { // if "JNE" + case 'N': // if "JN_" + if (jump_line[2] == 'E') { // if "JNE" *jump = 0x5; } else { alert(err_3rd_char); return false; } break; - case 'M': // if "JM_" - if (j2 == 'P') { // if "JMP" + case 'M': // if "JM_" + if (jump_line[2] == 'P') { // if "JMP" *jump = 0x7; } else { alert(err_3rd_char); return false;

@@ -189,9 +211,9 @@ static bool parse_c_type(const char *line, uint16_t *instruction)

{ bool ret; char c; - char *dest_start = NULL; - char *comp_start = NULL; - char *jump_start = NULL; + const char *dest_start = NULL; + const char *comp_start = NULL; + const char *jump_start = NULL; size_t i = 0; uint8_t dest = 0; // default value when not present uint8_t comp = 0;

@@ -208,9 +230,8 @@ dest_start = &line[0]; // start of line

// this 'i+1' might be dangerous! comp_start = &line[i+1]; // after "[dest]=" } else { - //syntax error - alert("syntax error: destination field in line" - " incorrectly formatted\n"); + alert("syntax error: destination field" + " incorrect length\n"); return false; } } else if (c == ';') {

@@ -218,9 +239,8 @@ if (1 <= i && i <= 7) {

// this 'i+1' might be dangerous! jump_start = &line[i+1]; // after "[comp];" } else { - //syntax error - alert("syntax error: jump field in line" - " incorrectly formatted\n"); + alert("syntax error: jump field incorrect" + " length\n"); return false; } }

@@ -251,7 +271,6 @@ return false;

} } - // STUB: DM=D-M;JGT // 0b111 1010011 011 001 *instruction = 0xe000 | ((uint16_t)comp << 6) | ((uint16_t)dest << 3) | ((uint16_t)jump);