# HG changeset patch # User lost@starbug # Date 1269576410 21600 # Node ID 0215a0fbf61bbf4d910f2a938298c3c20c2ba40e # Parent b4157778d354e5b07cebac8ad5073af8d647aa71 Added assembly error system and additional checks for symbol syntax diff -r b4157778d354 -r 0215a0fbf61b lwasm/lwasm.c --- a/lwasm/lwasm.c Thu Mar 25 20:51:34 2010 -0600 +++ b/lwasm/lwasm.c Thu Mar 25 22:06:50 2010 -0600 @@ -19,14 +19,19 @@ this program. If not, see . */ +#define ___lwasm_c_seen___ + #include +#include +#include + #include +#include +#include #include "lwasm.h" -#define NULL 0; - lw_expr_t lwasm_evaluate_var(char *var) { return NULL; @@ -47,3 +52,28 @@ } return NULL; } + +void lwasm_register_error(asmstate_t *as, line_t *l, const char *msg, ...) +{ + lwasm_error_t *e; + va_list args; + char errbuff[1024]; + int r; + + if (!l) + return; + + va_start(args, msg); + + e = lw_alloc(sizeof(lwasm_error_t)); + + e -> next = l -> err; + l -> err = e; + + as -> errorcount++; + + r = vsnprintf(errbuff, 1024, msg, args); + e -> mess = lw_strdup(errbuff); + + va_end(args); +} diff -r b4157778d354 -r 0215a0fbf61b lwasm/lwasm.h --- a/lwasm/lwasm.h Thu Mar 25 20:51:34 2010 -0600 +++ b/lwasm/lwasm.h Thu Mar 25 22:06:50 2010 -0600 @@ -63,6 +63,13 @@ PRAGMA_IMPORTUNDEFEXPORT = 0x0010 // imports symbol if undefined upon export }; +typedef struct lwasm_error_s lwasm_error_t; +struct lwasm_error_s +{ + char *mess; // actual error message + lwasm_error_t *next; // ptr to next error +}; + typedef struct line_s line_t; struct line_s { @@ -71,8 +78,9 @@ int insn; // number of insn in insn table int symset; // set if the line symbol was consumed by the instruction char *sym; // symbol, if any, on the line - line_t *prev; - line_t *next; + lwasm_error_t *err; // list of errors + line_t *prev; // previous line + line_t *next; // next line }; enum @@ -103,6 +111,7 @@ int debug_level; // level of debugging requested int flags; // assembly flags int pragmas; // pragmas currently in effect + int errorcount; // number of errors encountered line_t *line_head; // start of lines list line_t *line_tail; // tail of lines list @@ -121,9 +130,16 @@ #ifndef ___symbol_c_seen___ -extern struct symtabe *register_symbol(asmstate_t *as, char *sym, lw_expr_t value, int flags); -extern struct symtabe *lookup_symbol(asmstate_t *as, char *sym, int context, int version); +extern struct symtabe *register_symbol(asmstate_t *as, line_t *cl, char *sym, lw_expr_t value, int flags); +extern struct symtabe *lookup_symbol(asmstate_t *as, line_t *cl, char *sym, int context, int version); #endif +#ifndef ___lwasm_c_seen___ + +extern void lwasm_register_error(asmstate_t *as, line_t *cl, const char *msg, ...); + +#endif + + #endif /* ___lwasm_h_seen___ */ diff -r b4157778d354 -r 0215a0fbf61b lwasm/pass1.c --- a/lwasm/pass1.c Thu Mar 25 20:51:34 2010 -0600 +++ b/lwasm/pass1.c Thu Mar 25 22:06:50 2010 -0600 @@ -66,6 +66,7 @@ cl -> prev = as -> line_tail; cl -> len = -1; cl -> insn = -1; + cl -> err = NULL; if (!as -> line_tail) { as -> line_head = cl; @@ -165,6 +166,7 @@ if (*tok != ';' && *tok != '*') { // bad opcode; check for macro here + lwasm_register_error(as, cl, "Bad opcode"); } } else @@ -175,6 +177,7 @@ if (*p1 && !isspace(*p1)) { // flag bad operand error + lwasm_register_error(as, cl, "Bad operand (%s)", p1); } } } @@ -186,9 +189,10 @@ printf("\n"); // register symbol at line address - if (!register_symbol(as, cl -> sym, cl -> addr, symbol_flag_none)) + if (!register_symbol(as, cl, cl -> sym, cl -> addr, symbol_flag_none)) { // symbol error + lwasm_register_error(as, cl, "Bad symbol '%s'", cl -> sym); } } diff -r b4157778d354 -r 0215a0fbf61b lwasm/symbol.c --- a/lwasm/symbol.c Thu Mar 25 20:51:34 2010 -0600 +++ b/lwasm/symbol.c Thu Mar 25 22:06:50 2010 -0600 @@ -29,17 +29,44 @@ #include "lwasm.h" -struct symtabe *register_symbol(asmstate_t *as, char *sym, lw_expr_t val, int flags) +// these are allowed chars BELOW 0x80 +#define SSYMCHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_@$" +#define SYMCHARS SSYMCHARS ".?0123456789" + +struct symtabe *register_symbol(asmstate_t *as, line_t *cl, char *sym, lw_expr_t val, int flags) { struct symtabe *se; int islocal = 0; int context = -1; int version = -1; + char *cp; - if (strchr(sym, '@') || strchr(sym, '?')) - islocal = 1; - if (!(as -> pragmas & PRAGMA_DOLLARNOTLOCAL) && strchr(sym, '$')) - islocal = 1; + if (*sym < 0x80 && !strchr(SSYMCHARS, *sym)) + { + lwasm_register_error(as, cl, "Bad symbol (%s)", sym); + return NULL; + } + + if ((*sym == '$' || *sym == '@') && (sym[1] >= '0' && sym[1] <= '9')) + { + lwasm_register_error(as, cl, "Bad symbol (%s)", sym); + return NULL; + } + + for (cp = sym; *cp; cp++) + { + if (*cp == '@' || *cp == '?') + islocal = 1; + if (*cp == '$' && !(as -> pragmas & PRAGMA_DOLLARNOTLOCAL)) + islocal = 1; + + // bad symbol + if (*cp < 0x80 && !strchr(SYMCHARS, *cp)) + { + lwasm_register_error(as, cl, "Bad symbol (%s)", sym); + return NULL; + } + } if (islocal) context = as -> context; @@ -63,6 +90,7 @@ if (se) { // multiply defined symbol + lwasm_register_error(as, cl, "Multiply defined symbol (%s)", sym); return NULL; } @@ -81,7 +109,7 @@ return se; } -struct symtabe * lookup_symbol(asmstate_t *as, char *sym, int context, int version) +struct symtabe * lookup_symbol(asmstate_t *as, line_t *cl, char *sym, int context, int version) { return NULL; }