Mercurial > hg-old > index.cgi
diff lwasm/pass1.c @ 340:1a6fc6ebb31c
Checkpoint
author | lost |
---|---|
date | Fri, 19 Mar 2010 02:54:43 +0000 |
parents | 04c80c51b16a |
children | 7b4123dce741 |
line wrap: on
line diff
--- a/lwasm/pass1.c Fri Mar 19 02:54:14 2010 +0000 +++ b/lwasm/pass1.c Fri Mar 19 02:54:43 2010 +0000 @@ -30,14 +30,30 @@ /* pass 1: parse the lines + +line format: + +[<symbol>] <opcode> <operand>[ <comment>] + +If <symbol> is followed by a :, whitespace may precede the symbol + +A line may optionally start with a number which must not be preceded by +white space and must be followed by a single whitespace character. After +that whitespace character, the line is parsed as if it had no line number. + */ void do_pass1(asmstate_t *as) { char *line; line_t *cl; - + char *p1; + int stpace; + char *tok, *sym; + int opnum; + for (;;) { + sym = NULL; line = input_readline(as); if (!line) break; @@ -64,10 +80,113 @@ } as -> line_tail = cl; + // blank lines don't count for anything + if (!*line) + { + goto nextline; + } + + // skip comments + if (*line == '*' || *line == ';' || *line == '#') + goto nextline; + + p1 = line; + if (isdigit(*p1)) + { + // skip line number + while (*p1 && isdigit(*p1)) + p1++; + if (!*p1 && !isspace(*p1)) + p1 = line; + else if (*p1 && isspace(*p1)) + p1++; + } + + if (!*p1) + goto nextline; + + if (*p1 == '*' || *p1 == ';' || *p1 == '#') + goto nextline; + + if (isspace(*p1)) + { + for (; *p1 && isspace(*p1); p1++) + /* do nothing */ ; + stspace = 1; + } + else + stspace = 0; + + if (*p1 == '*' || *p1 == ';' || *p1 == '#' || !*p1) + goto nextline; + + + for (tok = p1; *p1 && !isspace(*p1) && *p1 != ':'; p1++) + /* do nothing */ ; + + if (*p1 == ':' || stspace == 0) + { + // have a symbol here + sym = lw_strndup(tok, p1 - tok); + if (*p1 == ':') + p1++; + for (; *p1 && isspace(*p1); p1++) + /* do nothing */ ; + + for (tok = p1; *p1 && !isspace(*p1); p1++) + /* do nothing */ ; + } + + cl -> sym = sym; + cl -> symset = 0; + + // tok points to the opcode for the line or NUL if none + if (*tok) + { + // look up operation code + sym = lw_strndup(tok, p1 - tok); + for (; *p1 && isspace(p1); p1++) + /* do nothing */ ; + + for (opnum = 0; instab[opnum].opcode; opnum++) + { + if (!strcasecmp(instab[opnum].opcode, sym)) + break; + } + lw_free(sym); + + // p1 points to the start of the operand + + if (instab[opnum].opcode == NULL) + { + cl -> insn = -1; + if (*tok != ';' && *tok != '*') + { + // bad opcode; check for macro here + } + } + else + { + cl -> insn = opnum; + // call parse function + + if (*p1 && !isspace(*p1)) + { + // flag bad operand error + } + } + } + + if (cl -> sym && cl -> symset == 0) + { + // register symbol at line address + } + lw_expr_print(cl -> addr); printf("\n"); // now parse the line + nextline: lw_free(line); } }