# HG changeset patch # User lost # Date 1268967283 0 # Node ID 1a6fc6ebb31c10dee852ac570f3e89d9b6cb89a2 # Parent eb230fa7d28ef52b8b19bf6f621b95e043444b42 Checkpoint diff -r eb230fa7d28e -r 1a6fc6ebb31c lwasm/lwasm.h --- a/lwasm/lwasm.h Fri Mar 19 02:54:14 2010 +0000 +++ b/lwasm/lwasm.h Fri Mar 19 02:54:43 2010 +0000 @@ -69,6 +69,7 @@ lw_expr_t addr; // assembly address of the line int len; // the "size" this line occupies (address space wise) (-1 if unknown) int insn; // number of insn in insn table + char *sym; // symbol, if any, on the line line_t *prev; line_t *next; }; diff -r eb230fa7d28e -r 1a6fc6ebb31c lwasm/pass1.c --- 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: + +[] [ ] + +If 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); } }