Mercurial > hg-old > index.cgi
diff lwasm/pass1.c @ 345:7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
author | lost@starbug |
---|---|
date | Thu, 25 Mar 2010 23:17:54 -0600 |
parents | 0215a0fbf61b |
children | a82c55070624 |
line wrap: on
line diff
--- a/lwasm/pass1.c Thu Mar 25 22:06:50 2010 -0600 +++ b/lwasm/pass1.c Thu Mar 25 23:17:54 2010 -0600 @@ -59,6 +59,22 @@ line = input_readline(as); if (!line) break; + if (line[0] == 1 && line[1] == 1) + { + // special internal directive + // these DO NOT appear in the output anywhere + // they are generated by the parser to pass information + // forward + for (p1 = line + 2; *p1 && !isspace(*p1); p1++) + /* do nothing */ ; + *p1++ = '\0'; + if (!strcmp(line + 2, "SETCONTEXT")) + { + as -> context = strtol(p1, NULL, 10); + } + lw_free(line); + continue; + } printf("%s\n", line); cl = lw_alloc(sizeof(line_t)); @@ -84,12 +100,15 @@ as -> line_tail = cl; // blank lines don't count for anything + // except a local symbol context break if (!*line) { + as -> context = lwasm_next_context(as); goto nextline; } // skip comments + // commends do not create a context break if (*line == '*' || *line == ';' || *line == '#') goto nextline; @@ -105,9 +124,14 @@ p1++; } + // blank line - context break if (!*p1) + { + as -> context = lwasm_next_context(as); goto nextline; + } + // comment - no context break if (*p1 == '*' || *p1 == ';' || *p1 == '#') goto nextline; @@ -120,8 +144,14 @@ else stspace = 0; - if (*p1 == '*' || *p1 == ';' || *p1 == '#' || !*p1) + if (*p1 == '*' || *p1 == ';' || *p1 == '#') goto nextline; + if (!*p1) + { + // nothing but whitespace - context break + as -> context = lwasm_next_context(as); + goto nextline; + } // find the end of the first token for (tok = p1; *p1 && !isspace(*p1) && *p1 != ':'; p1++) @@ -156,50 +186,77 @@ if (!strcasecmp(instab[opnum].opcode, sym)) break; } - lw_free(sym); // p1 points to the start of the operand + // if we're inside a macro definition and not at ENDM, + // add the line to the macro definition and continue + if (as -> inmacro && !(instab[opnum].flags & lwasm_insn_endm)) + { + add_macro_line(as, line); + goto linedone; + } + + // if skipping a condition and the operation code doesn't + // operate within a condition (not a conditional) + // do nothing + if (as -> skipcond && !(instab[opnum].flags & lwasm_insn_cond)) + goto linedone; + if (instab[opnum].opcode == NULL) { cl -> insn = -1; if (*tok != ';' && *tok != '*') { // bad opcode; check for macro here - lwasm_register_error(as, cl, "Bad opcode"); + if (expand_macro(as, cl, &p1, sym) != 0) + { + // macro expansion failed + lwasm_register_error(as, cl, "Bad opcode"); + } } } else { cl -> insn = opnum; - // call parse function - - if (*p1 && !isspace(*p1)) + // no parse func means operand doesn't matter + if (instab[opnum].parse) { - // flag bad operand error - lwasm_register_error(as, cl, "Bad operand (%s)", p1); + // call parse function + (instab[opnum].parse)(as, cl, &p1); + + if (*p1 && !isspace(*p1)) + { + // flag bad operand error + lwasm_register_error(as, cl, "Bad operand (%s)", p1); + } } } } + + linedone: + lw_free(sym); - if (cl -> sym && cl -> symset == 0) + if (!as -> skipcond && !as -> inmacro) { - printf("Register symbol %s:", sym); + if (cl -> sym && cl -> symset == 0) + { + printf("Register symbol %s:", sym); + lw_expr_print(cl -> addr); + printf("\n"); + + // register symbol at line address + if (!register_symbol(as, cl, cl -> sym, cl -> addr, symbol_flag_none)) + { + // symbol error + lwasm_register_error(as, cl, "Bad symbol '%s'", cl -> sym); + } + } + lw_expr_print(cl -> addr); printf("\n"); - - // register symbol at line address - if (!register_symbol(as, cl, cl -> sym, cl -> addr, symbol_flag_none)) - { - // symbol error - lwasm_register_error(as, cl, "Bad symbol '%s'", cl -> sym); - } } - lw_expr_print(cl -> addr); - printf("\n"); - // now parse the line - nextline: lw_free(line); }