diff src/lwasm.c @ 76:2fe5fd7d65a3

Checkpointing object target implementation
author lost
date Thu, 08 Jan 2009 02:57:24 +0000
parents c8c772ef5df9
children a338d496350e
line wrap: on
line diff
--- a/src/lwasm.c	Thu Jan 08 01:32:49 2009 +0000
+++ b/src/lwasm.c	Thu Jan 08 02:57:24 2009 +0000
@@ -175,10 +175,15 @@
 	lwasm_line_t *l;
 };	
 
-int lwasm_expr_lookup_symbol(char *sym, void *state, int *val)
+lwasm_expr_stack_t *lwasm_expr_lookup_symbol(char *sym, void *state)
 {
 	lwasm_symbol_ent_t *se;
 	struct symstateinfo *st;
+	lwasm_expr_stack_t *rs;
+	lwasm_expr_term_t *t;
+	lwasm_expr_stack_node_t *n;
+	
+	int val;
 	
 	st = state;
 	debug_message(3, "lwasm_expr_lookup_symbol(): find '%s' (context=%d)", sym, st -> as -> context);	
@@ -191,8 +196,8 @@
 		// current line address
 		case '*':
 		case '.':
-			*val = st -> l -> codeaddr;
-			return 0;
+			val = st -> l -> codeaddr;
+			goto retconst;
 		
 		case '<':
 			// previous branch point
@@ -211,9 +216,34 @@
 		se = lwasm_find_symbol(st -> as, sym, -1);
 	debug_message(3, "lwasm_expr_lookup_symbol(): got '%p'", se);
 	if (!se)
-		return -1;
-	*val = se -> value;
-	return 0;
+		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
+		val = se -> value;
+		goto retconst;
+	}
+	// an intersegment reference will return as NULL (to be resolved at output/link time)
+	// if se -> expr is NULL, it has to be an intersegment reference here
+	if (se -> expr == NULL)
+	{
+		return NULL;
+	}
+	
+	// duplicate the expression for return
+	rs = lwasm_expr_stack_create();
+	for (n = se -> expr -> head; n; n = n -> next)
+	{
+		lwasm_expr_stack_push(rs, n -> term);
+	}
+	return rs;
+
+retconst:
+	rs = lwasm_expr_stack_create();
+	t = lwasm_expr_term_create_int(val);
+	lwasm_expr_stack_push(rs, t);
+	lwasm_expr_term_free(t);
+	return rs;
 }
 
 lwasm_expr_stack_t *lwasm_evaluate_expr(asmstate_t *as, lwasm_line_t *l, const char *inp, const char **outp)
@@ -228,6 +258,38 @@
 	return(lwasm_expr_eval(inp, outp, 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)
+{
+	lwasm_expr_stack_node_t *n;
+	lwasm_symbol_ent_t *se;
+	
+	for (n = s -> head; n; n = n -> next)
+	{
+		if (n -> term -> term_type == LWASM_TERM_SYM)
+		{
+			se = lwasm_find_symbol(as, n -> term -> symbol, as -> context);
+			if (!se)
+				se = lwasm_find_symbol(as, n -> term -> symbol, -1);
+			if (!se)
+				return 0;
+		}
+	}
+	return 1;
+}
+
+/*
+Evaluate an expression according to the flag value. Return 0 if a constant result was
+obtained, 1 if an incomplete result was obtained, and -1 if an error was flagged.
+
+Symbol resolution will be modified for the object target as follows:
+- a symbol which is not defined within a section will evaluate as a constant
+- a symbol which is defined within the same section will evaluate as a constant
+- a symbol defined in another section will remain unresolved
+- external references will also remain unresolved
+
+*/
 int lwasm_expr_result(asmstate_t *as, lwasm_line_t *l, char **inp, int flag, int *val)
 {
 	lwasm_expr_stack_t *s;