changeset 64:aaddd47219b4

Added the 'set' directive
author lost
date Mon, 05 Jan 2009 01:27:08 +0000
parents d85ba47b1e8f
children 31d8e85706e7
files src/lwasm.h src/parse.c src/pseudo.c src/symbol.c
diffstat 4 files changed, 34 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- a/src/lwasm.h	Mon Jan 05 01:17:23 2009 +0000
+++ b/src/lwasm.h	Mon Jan 05 01:27:08 2009 +0000
@@ -160,7 +160,7 @@
 #define __lwasm_E__
 #endif
 
-__lwasm_E__ int lwasm_register_symbol(asmstate_t *as, lwasm_line_t *l, char *sym, int val);
+__lwasm_E__ int lwasm_register_symbol(asmstate_t *as, lwasm_line_t *l, char *sym, int val, int flags);
 __lwasm_E__ lwasm_symbol_ent_t *lwasm_find_symbol(asmstate_t *as, char *sym, int scontext);
 __lwasm_E__ int lwasm_set_symbol(asmstate_t *as, char *sym, int scontext, int val);
 __lwasm_E__ void lwasm_list_symbols(asmstate_t *as, FILE *f);
--- a/src/parse.c	Mon Jan 05 01:17:23 2009 +0000
+++ b/src/parse.c	Mon Jan 05 01:27:08 2009 +0000
@@ -132,7 +132,7 @@
 			// have a symbol; now determine if it is valid and register it
 			// at the current address of the line
 			debug_message(1, "Registering symbol '%s' at %04X", sym, as -> addr);
-			if (lwasm_register_symbol(as, l, sym, as -> addr) < 0)
+			if (lwasm_register_symbol(as, l, sym, as -> addr, SYMBOL_NORM) < 0)
 				l -> sym = NULL;
 		}
 	}
--- a/src/pseudo.c	Mon Jan 05 01:17:23 2009 +0000
+++ b/src/pseudo.c	Mon Jan 05 01:27:08 2009 +0000
@@ -372,45 +372,31 @@
 	l -> symaddr = rval & 0xFFFF;
 	l -> addrset = 2;
 	
-	lwasm_register_symbol(as, l, l -> sym, rval);
+	lwasm_register_symbol(as, l, l -> sym, rval, SYMBOL_NORM);
 }
 
 OPFUNC(pseudo_set)
 {
+	int rval;
+
+	// set MUST run on both passes as the symbol value changes!
+
+	if (l -> sym == NULL)
+	{
+		register_error(as, l, 1, "No symbol specified");
+		return;
+	}
+
+	if (lwasm_expr_result(as, l, p, EXPR_PASS1CONST | EXPR_PASS2CONST, &rval) < 0)
+		rval = 0;
+
+	l -> symaddr = rval & 0xFFFF;
+	l -> addrset = 2;
+	
+	lwasm_register_symbol(as, l, l -> sym, rval, SYMBOL_SET);
 }
 
 /*
-void pseudo_set(asmstate_t *as, sourceline_t *cl, char **optr)
-{
-	int rval, v1;
-	
-	if (cl -> hassym == 0)
-	{
-		errorp1(ERR_NOSYM);
-		return;
-	}
-	rval = eval_expr(as, cl, optr, &v1);
-	// eval_expr returns -1 if there was a forward ref
-	// or -2 if the expr was invalid
-	if (rval == -2)
-	{
-		// carp
-		errorp1(ERR_FORWARD);
-	}
-	if (rval < 0)
-	{
-		// remove symbol ref
-		cl -> hassym = 0;
-		// mark as a "comment" so it isn't processed next time
-		cl -> opcode = -1;
-		return;
-	}
-	cl -> code_symloc = v1;
-	cl -> isset = 1;
-	cl -> isequ = 1;
-	cl -> symaddr = v1 & 0xFFFF;
-}
-
 void pseudo_setdp(asmstate_t *as, sourceline_t *cl, char **optr)
 {
 	int rval, v1;
--- a/src/symbol.c	Mon Jan 05 01:17:23 2009 +0000
+++ b/src/symbol.c	Mon Jan 05 01:27:08 2009 +0000
@@ -34,7 +34,7 @@
 recognize because the expression evaluator must avoid all ambiguity in order
 to achieve predictable results. The checks here are simply a fuzz check.
 */
-int lwasm_register_symbol(asmstate_t *as, lwasm_line_t *l, char *sym, int val)
+int lwasm_register_symbol(asmstate_t *as, lwasm_line_t *l, char *sym, int val, int flags)
 {
 	lwasm_symbol_ent_t *se, *se2;
 	char *p;
@@ -70,16 +70,24 @@
 			scontext = as -> context;
 	}
 	
-	debug_message(3, "lwasm_register_symbol(): registering '%s' (%d) at %04X", sym, scontext, val);
+	debug_message(3, "lwasm_register_symbol(): registering '%s' (%d) at %04X; flags=%d", sym, scontext, val, flags);
 	
 	// now look it for to see if it is a duplicate
 	se = lwasm_find_symbol(as, sym, scontext);
 	if (se)
 	{
-		register_error(as, l, 1, "Mulitply defined symbol: %s", sym);
-		return -1;
+		if (!(flags & SYMBOL_SET) || (flags & SYMBOL_SET && !(se -> flags & SYMBOL_SET)))
+		{
+			register_error(as, l, 1, "Mulitply defined symbol: %s", sym);
+			return -1;
+		}
 	}
-		
+	if (se)
+	{
+		se -> value = val;
+		return;
+	}
+
 	// if not a duplicate, register it with the value
 	se = lwasm_alloc(sizeof(lwasm_symbol_ent_t));
 	if (as -> symhead)
@@ -99,6 +107,7 @@
 	se -> value = val;
 	se -> sym = lwasm_strdup(sym);
 	se -> context = scontext;
+	se -> flags = flags;
 
 	return 0;
 }