all repos — nand2tetris @ aedf3d1b6e094f46428741a07e656f69bc738f7a

my nand2tetris progress

parse_a_type(): remove redundant w/s stripping
x1phosura x1phosura@x1phosura.zone
Mon, 28 Nov 2022 13:17:34 -0800
commit

aedf3d1b6e094f46428741a07e656f69bc738f7a

parent

eb26ec22607c46c22b77bde5d6670bf04b35f60e

1 files changed, 39 insertions(+), 42 deletions(-)

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

@@ -26,48 +26,39 @@ }

bool parse_a_type(const char *line, uint16_t *instruction) { - bool num_found = false; char c, a_field_str[6]; // TODO: eventually factor out use of array uint32_t a_field = 0; size_t i, a = 0; - i = 0; - while ((c = line[i]) != '\n') { - if (c == ' ' || c == '\t' || c == '/') { - if (num_found) { - num_found = false; - if (a < 7) { - a_field_str[a] = '\0'; - break; - } else { - die("fatal error: a-type value index " - "%lu out of range\n", -1); - } - } else { - ; // skip whitespace - } - } else if (num_found) { - if ('0' <= c && c <= '9') { - if (a > 4) { - alert("error: @<number> too long\n"); - return false; - } - a_field_str[a] = c; // get number - } else { - alert("syntax error: invalid char '%c' found " - "after @\n", c); + if (line[0] != '@') { + alert("error: A-type instruction doesn't start with @\n"); + return false; + } + + if (line[1] == '\n') { + alert("error: A-type instruction empty after @\n"); + return false; + } + + for (i = 1; (c = line[i]) != '\n' && a < 6; ++i) { + if ('0' <= c && c <= '9') { + if (a > 4) { + alert("error: @<number> too long\n"); return false; } - ++a; - } else if (c == '@') { - a = 0; - num_found = true; - } else { - alert("syntax error: invalid char '%c' before @\n", c); + a_field_str[a] = c; // get number + a++; + } else if ((c == ' ' || c == '\t' || c == '/') && i > 1) { + break; + } else { // any other character + alert("syntax error: invalid char '%c' found after @\n", + c); return false; } - ++i; } + + a_field_str[a] = '\0'; // exit + // TODO: extension: support negative numbers a_field = myatoi(a_field_str); if (a_field > 32767) {

@@ -81,9 +72,8 @@ }

bool parse_c_type(const char *line, uint16_t *instruction) { - DEBUG("parse_c_type()\n"); - *instruction = 0x8000; // STUB, C-type MSB == 1 anyway - return true; // STUB, C-type MSB == 1 anyway + *instruction = 0x8888; // STUB, TODO implement + return true; } // does not care about line line length; exits at first newline or after

@@ -96,12 +86,12 @@ size_t i = 0;

while ((c = line[i]) != '\n') { if (c == ' ' || c == '\t') - ; // skip whitespace + ; // skip any whitespace at start of line else if (c == '@') { - ret = parse_a_type(line, instruction); + ret = parse_a_type(&line[i], instruction); break; } else if (c >= '!' && c < '~') { - ret = parse_c_type(line, instruction); + ret = parse_c_type(&line[i], instruction); break; } else { alert("syntax error: line '%s' incorrectly formatted\n",

@@ -161,9 +151,16 @@ "@98 // test comment\n", // line 5

"// this is another comment\n", // line 6 "/ this is a broken comment\n", // line 7 "D=M;JNE\n", // line 8 - " @1337// immediate comment \n", // line 9 - "\t@13371337 // number too long \n", // line 10 - " @0x1337 // invalid char in num\n"}; // line 11 + " @1337// immediate comment \n", // line 9 + "\t@44441337 // number too long \n", // line 10 + " \t @1 // 1\n", // line 11 + "\t @2 // 2\n", // line 12 + "\t @3\n", // line 13 + "\t @4\n", // line 14 + " \t@5 // 3\n", // line 15 + " @6 // 4\n", // line 16 + "\t @7\n", // line 17 + " @0x1337 // invalid char in num\n"}; // line 18 size_t num_test_lines = (sizeof(test_lines) / sizeof(test_lines[0])); int main()