changeset 344:0215a0fbf61b

Added assembly error system and additional checks for symbol syntax
author lost@starbug
date Thu, 25 Mar 2010 22:06:50 -0600
parents b4157778d354
children 7416c3f9c321
files lwasm/lwasm.c lwasm/lwasm.h lwasm/pass1.c lwasm/symbol.c
diffstat 4 files changed, 91 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- 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 <http://www.gnu.org/licenses/>.
 */
 
+#define ___lwasm_c_seen___
+
 #include <config.h>
 
+#include <stdio.h>
+#include <stdarg.h>
+
 #include <lw_expr.h>
+#include <lw_alloc.h>
+#include <lw_string.h>
 
 #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);
+}
--- 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___ */
--- 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);
 			}
 		}
 		
--- 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;
 }