diff src/lwasm.c @ 77:a338d496350e

Checkpointing conversion to allow object target
author lost
date Fri, 09 Jan 2009 04:23:00 +0000
parents 2fe5fd7d65a3
children 121bf4a588ea
line wrap: on
line diff
--- a/src/lwasm.c	Thu Jan 08 02:57:24 2009 +0000
+++ b/src/lwasm.c	Fri Jan 09 04:23:00 2009 +0000
@@ -216,7 +216,10 @@
 		se = lwasm_find_symbol(st -> as, sym, -1);
 	debug_message(3, "lwasm_expr_lookup_symbol(): got '%p'", se);
 	if (!se)
+	{
+		register_error(st -> as, st -> l, 2, "Undefined symbol '%s'", sym);
 		return NULL;
+	}
 	if (st -> as -> outformat != OUTPUT_OBJ || se -> sect == NULL || se -> sect == st -> as -> csect)
 	{
 		// global symbol, intrasegment reference, or not an object target
@@ -258,6 +261,17 @@
 	return(lwasm_expr_eval(inp, outp, lwasm_expr_lookup_symbol, &st));
 }
 
+
+int lwasm_reevaluate_expr(asmstate_t *as, lwasm_line_t *l, lwasm_expr_stack_t *s)
+{
+	struct symstateinfo st;
+	
+	st.as = as;
+	st.l = l;
+	
+	return(lwasm_expr_reval(s, lwasm_expr_lookup_symbol, &st));
+}
+
 // return 1 if no undefined symbols (externals and incompletes are okay)
 // return 0 if there are undefined symbols
 int lwasm_expr_result_ckconst(asmstate_t *as, lwasm_expr_stack_t *s)
@@ -265,6 +279,14 @@
 	lwasm_expr_stack_node_t *n;
 	lwasm_symbol_ent_t *se;
 	
+	if (as -> outformat != OUTPUT_OBJ)
+	{
+		if (lwasm_expr_is_constant(s))
+			return 1;
+		else
+			return 0;
+	}
+	
 	for (n = s -> head; n; n = n -> next)
 	{
 		if (n -> term -> term_type == LWASM_TERM_SYM)
@@ -289,7 +311,13 @@
 - a symbol defined in another section will remain unresolved
 - external references will also remain unresolved
 
+EXPR_PASS2PASS will cause the result from pass 1 along with the offset to
+the end of the expression to be stored in the line data. There can only be
+one such expression per source line. In this case, the expression is parsed
+and evaluated on pass 1 but the intermediate representation is re-evaluated
+on pass 2.
 */
+/*
 int lwasm_expr_result(asmstate_t *as, lwasm_line_t *l, char **inp, int flag, int *val)
 {
 	lwasm_expr_stack_t *s;
@@ -305,22 +333,40 @@
 	}
 	*inp = (char *)ep;
 	
-	if (flag & EXPR_PASS1CONST && as -> passnum == 1 && !lwasm_expr_is_constant(s))
+	if (flag & EXPR_PASS1CONST && as -> passnum == 1 && !lwasm_expr_result_ckconst(as, s))
 	{
-		register_error(as, l, 1, "Illegal incomplete reference (pass 1)");
+		register_error(as, l, 1, "Undefined reference (pass 1)");
+		*val = 0;
+		lwasm_expr_stack_free(s);
+		return -1;
+	}
+	if (flag & EXPR_PASS2CONST && as -> passnum == 2 && !lwasm_expr_result_ckconst(as, s))
+	{
+		register_error(as, l, 2, "Undefined reference (pass 2)");
 		*val = 0;
 		lwasm_expr_stack_free(s);
 		return -1;
 	}
-	if (flag & EXPR_PASS2CONST && as -> passnum == 2 && !lwasm_expr_is_constant(s))
+	if (flag & EXPR_NOINTERSECT && !lwasm_expr_is_constant(s))
 	{
-		register_error(as, l, 2, "Incomplete reference (pass 2)");
-		*val = 0;
-		lwasm_expr_stack_free(s);
-		return -1;
+		register_error(as, l, 2, "Invalid inter-section reference");
 	}
 	*val = lwasm_expr_get_value(s);
-	lwasm_expr_stack_free(s);
+	if (l -> expr)
+	{
+		lwasm_expr_stack_free(l -> expr);
+		l -> expr = NULL;
+	}
+	if (lwasm_is_constant(s))
+	{
+		// fully resolved value here
+		lwasm_expr_stack_free(s);
+	}
+	else
+	{
+		// incomplete reference here
+		l -> expr = s;
+	}
 
 	if (flag & EXPR_BYTE && as -> passnum == 2 && (*val < -128 || *val > 255))
 	{
@@ -335,6 +381,50 @@
 
 	return 0;
 }
+*/
+int lwasm_expr_result2(asmstate_t *as, lwasm_line_t *l, char **inp, int flag, int *val, int slot)
+{
+	lwasm_expr_stack_t *s;
+	const char *ep;
+	int rval;
+
+	if (as -> passnum == 1)
+	{		
+		s = lwasm_evaluate_expr(as, l, *inp, &ep);
+		l -> exprs[slot] = s;
+		if (!s)
+		{
+			register_error(as, l, 1, "Bad expression");
+			*val = 0;
+			return -1;
+		}
+		*inp = (char *)ep;
+		l -> exprends[slot] = *inp;
+		l -> exprvals[slot] = lwasm_expr_get_value(s);
+	}
+	else if (l -> exprs[slot])
+	{
+		s = l -> exprs[slot];
+		*inp = l -> exprends[slot];
+		lwasm_reevaluate_expr(as, l, s);
+		l -> exprvals[slot] = lwasm_expr_get_value(s);
+	}
+
+	if (s && lwasm_expr_is_constant(s))
+	{
+		lwasm_expr_stack_free(s);
+		l -> exprs[slot] = NULL;
+		s = NULL;
+	}
+
+	if (!s)
+	{
+		*val = l -> exprvals[slot];
+		return 0;
+	}
+	
+	return 1;
+}
 
 void debug_message(int level, const char *fmt, ...)
 {