changeset 79:d0ce3f5f6797

Checkpointing deployment of non-constant expression handling
author lost
date Sat, 10 Jan 2009 07:09:14 +0000
parents 121bf4a588ea
children 8929e1ee99cf
files src/lwasm.c src/pseudo.c src/symbol.c
diffstat 3 files changed, 111 insertions(+), 46 deletions(-) [+]
line wrap: on
line diff
--- a/src/lwasm.c	Sat Jan 10 05:00:42 2009 +0000
+++ b/src/lwasm.c	Sat Jan 10 07:09:14 2009 +0000
@@ -384,14 +384,15 @@
 */
 int lwasm_expr_result2(asmstate_t *as, lwasm_line_t *l, char **inp, int flag, int *val, int slot)
 {
-	lwasm_expr_stack_t *s;
+	lwasm_expr_stack_t *s = NULL;
 	const char *ep;
 	int rval;
 
-	if (as -> passnum == 1)
+	if (as -> passnum == 1 || slot < 0)
 	{		
 		s = lwasm_evaluate_expr(as, l, *inp, &ep);
-		l -> exprs[slot] = s;
+		if (slot >= 0)
+			l -> exprs[slot] = s;
 		if (!s)
 		{
 			register_error(as, l, 1, "Bad expression");
@@ -399,8 +400,11 @@
 			return -1;
 		}
 		*inp = (char *)ep;
-		l -> exprends[slot] = *inp;
-		l -> exprvals[slot] = lwasm_expr_get_value(s);
+		if (slot >= 0)
+		{
+			l -> exprends[slot] = *inp;
+			l -> exprvals[slot] = lwasm_expr_get_value(s);
+		}
 	}
 	else if (l -> exprs[slot])
 	{
@@ -417,21 +421,28 @@
 		s = NULL;
 	}
 
-	if (!s)
+	if (!s && slot >= 0)
 	{
 		*val = l -> exprvals[slot];
 		return 0;
 	}
+	else if (!s)
+	{
+		*val = 0;
+		return 0;
+	}
 
 	// was a constant result on pass 1 requested?
 	// that means we must have a constant on either pass
 	if (flag & EXPR_PASS1CONST)
 	{
 		*val = 0;
-		l -> exprvals[slot] = 0;
+		if (slot >= 0)
+			l -> exprvals[slot] = 0;
 		register_error(as, l, 1, "Illegal forward, external, or inter-section reference");
 		lwasm_expr_stack_free(s);
-		l -> exprs[slot] = NULL;
+		if (slot >= 0)
+			l -> exprs[slot] = NULL;
 		return -1;
 	}
 	
--- a/src/pseudo.c	Sat Jan 10 05:00:42 2009 +0000
+++ b/src/pseudo.c	Sat Jan 10 07:09:14 2009 +0000
@@ -288,12 +288,14 @@
 	l -> symaddr = v & 0xFFFF;
 	l -> addrset = 2;
 	
+	// note: we need to do this because the symbol might have resolved
+	// to a constant!
 	lwasm_register_symbol(as, l, l -> sym, v, (r > 0 ? SYMBOL_COMPLEX: SYMBOL_NORM) | SYMBOL_FORCE);
 }
 
 OPFUNC(pseudo_set)
 {
-	int rval;
+	int r, v;
 
 	// set MUST run on both passes as the symbol value changes!
 
@@ -303,27 +305,41 @@
 		return;
 	}
 
-	if (lwasm_expr_result(as, l, p, EXPR_PASS1CONST | EXPR_PASS2CONST, &rval) < 0)
-		rval = 0;
+	r = lwasm_expr_result2(as, l, p, EXPR_PASS1CONST, &v, 0);
+	if (r < 0)
+		v = 0;
 
-	l -> symaddr = rval & 0xFFFF;
+	l -> symaddr = v & 0xFFFF;
 	l -> addrset = 2;
 	
-	lwasm_register_symbol(as, l, l -> sym, rval, SYMBOL_SET);
+	lwasm_register_symbol(as, l, l -> sym, v, (r > 0 ? SYMBOL_COMPLEX: SYMBOL_NORM) | SYMBOL_SET);
 }
 
 OPFUNC(pseudo_setdp)
 {
-	int rval;
+	int r, v;
 
-	// setdp is needed on both passes	
-	if (lwasm_expr_result(as, l, p, EXPR_PASS1CONST | EXPR_PASS2CONST | EXPR_BYTE, &rval) < 0)
-		rval = 0;
+	if (as -> outformat == OUTPUT_OBJ)
+	{
+		register_error(as, l, 1, "SETDP not permitted with OBJ target");
+		return;
+	}
+	
+	// setdp is needed on both passes; must resolve to a constant on pass 1
+	r = lwasm_expr_result2(as, l, p, EXPR_PASS1CONST, &v, 0);
+	if (r != 0)
+		return;
 
-	l -> symaddr = rval & 0xFF;
+	if (v < -127 || v > 255)
+	{
+		register_error(as, l, 1, "Byte overflow");
+		return;
+	}
+	
+	l -> symaddr = v & 0xFF;
 	l -> addrset = 2;
 	
-	as -> dpval = rval & 0xFF;
+	as -> dpval = v & 0xFF;
 }
 
 OPFUNC(pseudo_fcc)
@@ -391,15 +407,28 @@
 	lwasm_emit(as, l, 0);
 }
 
+// FIXME: handle external, etc., references in a useful manner
 OPFUNC(pseudo_fcb)
 {
-	int v1;
+	int r, v;
 	
 fcb_again:
-	if (lwasm_expr_result(as, l, p, EXPR_PASS2CONST | EXPR_BYTE, &v1) < 0)
+	r = lwasm_expr_result2(as, l, p, 0, &v, -1);
+	if (r < 0)
 		return;
+
+	if (r > 0)
+	{
+		register_error(as, l, 2, "Illegal external or inter-segment reference");
+		v = 0;
+	}
+
+	if (v < -127 || v > 255)
+	{
+		register_error(as, l, 1, "Byte overflow");
+	}
 	
-	lwasm_emit(as, l, v1);
+	lwasm_emit(as, l, v);
 	if (**p == ',')
 	{
 		(*p)++;
@@ -407,16 +436,24 @@
 	}
 }
 
+// FIXME: handle external references in an intelligent way
 OPFUNC(pseudo_fdb)
 {			
-	int v1;
+	int r, v;
 	
 fdb_again:
-	if (lwasm_expr_result(as, l, p, EXPR_PASS2CONST, &v1) < 0)
+	r = lwasm_expr_result2(as, l, p, 0, &v, -1);
+	if (r < 0)
 		return;
-	
-	lwasm_emit(as, l, v1 >> 8);
-	lwasm_emit(as, l, v1 & 0xff);
+
+	if (r > 0)
+	{
+		register_error(as, l, 2, "Illegal external or inter-segment reference");
+		v = 0;
+	}
+
+	lwasm_emit(as, l, v >> 8);
+	lwasm_emit(as, l, v & 0xff);
 	if (**p == ',')
 	{
 		(*p)++;
@@ -424,18 +461,26 @@
 	}
 }
 
+// FIXME: handle external references in a sensible way
 OPFUNC(pseudo_fqb)
 {	
-	int v1;
+	int r, v;
 	
 fqb_again:
-	if (lwasm_expr_result(as, l, p, EXPR_PASS2CONST, &v1) < 0)
+	r = lwasm_expr_result2(as, l, p, 0, &v, -1);
+	if (r < 0)
 		return;
-	
-	lwasm_emit(as, l, v1 >> 24);
-	lwasm_emit(as, l, v1 >> 16);
-	lwasm_emit(as, l, v1 >> 8);
-	lwasm_emit(as, l, v1 & 0xff);
+
+	if (r > 0)
+	{
+		register_error(as, l, 2, "Illegal external or inter-segment reference");
+		v = 0;
+	}
+
+	lwasm_emit(as, l, v >> 24);
+	lwasm_emit(as, l, v >> 16);
+	lwasm_emit(as, l, v >> 8);
+	lwasm_emit(as, l, v & 0xff);
 	if (**p == ',')
 	{
 		(*p)++;
@@ -488,8 +533,8 @@
 		return;
 	}
 
-	rval = lwasm_expr_result(as, l, p, EXPR_PASS1CONST, &v1);
-	if (rval < 0)
+	rval = lwasm_expr_result2(as, l, p, EXPR_PASS1CONST, &v1, 0);
+	if (rval != 0)
 		return;
 	if (!v1)
 	{
@@ -509,8 +554,8 @@
 		return;
 	}
 
-	rval = lwasm_expr_result(as, l, p, EXPR_PASS1CONST, &v1);
-	if (rval < 0)
+	rval = lwasm_expr_result2(as, l, p, EXPR_PASS1CONST, &v1, 0);
+	if (rval != 0)
 		return;
 	if (v1)
 	{
@@ -530,8 +575,8 @@
 		return;
 	}
 
-	rval = lwasm_expr_result(as, l, p, EXPR_PASS1CONST, &v1);
-	if (rval < 0)
+	rval = lwasm_expr_result2(as, l, p, EXPR_PASS1CONST, &v1, 0);
+	if (rval != 0)
 		return;
 	if (v1 >= 0)
 	{
@@ -551,8 +596,8 @@
 		return;
 	}
 
-	rval = lwasm_expr_result(as, l, p, EXPR_PASS1CONST, &v1);
-	if (rval < 0)
+	rval = lwasm_expr_result2(as, l, p, EXPR_PASS1CONST, &v1, 0);
+	if (rval != 0)
 		return;
 	if (v1 > 0)
 	{
@@ -572,8 +617,8 @@
 		return;
 	}
 
-	rval = lwasm_expr_result(as, l, p, EXPR_PASS1CONST, &v1);
-	if (rval < 0)
+	rval = lwasm_expr_result2(as, l, p, EXPR_PASS1CONST, &v1, 0);
+	if (rval != 0)
 		return;
 	if (v1 <= 0)
 	{
@@ -593,8 +638,8 @@
 		return;
 	}
 
-	rval = lwasm_expr_result(as, l, p, EXPR_PASS1CONST, &v1);
-	if (rval < 0)
+	rval = lwasm_expr_result2(as, l, p, EXPR_PASS1CONST, &v1, 0);
+	if (rval != 0)
 		return;
 	if (v1 < 0)
 	{
--- a/src/symbol.c	Sat Jan 10 05:00:42 2009 +0000
+++ b/src/symbol.c	Sat Jan 10 07:09:14 2009 +0000
@@ -92,6 +92,11 @@
 	se = lwasm_find_symbol(as, sym, scontext);
 	if (se)
 	{
+		if (flags & SYMBOL_FORCE && as -> passnum != 2)
+		{
+			register_error(as, l, 1, "Multiply 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);
@@ -105,6 +110,10 @@
 		{
 			se -> expr = l -> exprs[0];
 		}
+		else
+		{
+			se -> expr = NULL;
+		}
 		return;
 	}