diff src/expr.c @ 37:538e15927776

Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
author lost
date Sat, 03 Jan 2009 04:20:49 +0000
parents ec0bf61a5502
children efa19ec69df9
line wrap: on
line diff
--- a/src/expr.c	Fri Jan 02 06:07:40 2009 +0000
+++ b/src/expr.c	Sat Jan 03 04:20:49 2009 +0000
@@ -67,6 +67,8 @@
 lwasm_expr_term_t *lwasm_expr_term_create_oper(int oper)
 {
 	lwasm_expr_term_t *t;
+
+fprintf(stderr, "Creating operator term: %d\n", oper);
 	
 	t = lwasm_alloc(sizeof(lwasm_expr_term_t));
 	t -> term_type = LWASM_TERM_OPER;
@@ -77,6 +79,7 @@
 lwasm_expr_term_t *lwasm_expr_term_create_int(int val)
 {
 	lwasm_expr_term_t *t;
+fprintf(stderr, "Creating integer term: %d\n", val);
 	
 	t = lwasm_alloc(sizeof(lwasm_expr_term_t));
 	t -> term_type = LWASM_TERM_INT;
@@ -88,6 +91,7 @@
 {
 	lwasm_expr_term_t *t;
 	
+fprintf(stderr, "Creating symbol term: %s\n", sym);
 	t = lwasm_alloc(sizeof(lwasm_expr_term_t));
 	t -> term_type = LWASM_TERM_SYM;
 	t -> symbol = lwasm_strdup(sym);
@@ -177,10 +181,11 @@
 int lwasm_expr_parse_term(lwasm_expr_stack_t *s, const char **p)
 {
 	lwasm_expr_term_t *t;
-
+fprintf(stderr, "Expression string %s\n", *p);
 eval_next:
 	if (**p == '(')
 	{
+	fprintf(stderr, "Starting paren\n");
 		(*p)++;
 		lwasm_expr_parse_expr(s, p, 0);
 		if (**p != ')')
@@ -191,6 +196,7 @@
 	
 	if (**p == '+')
 	{
+	fprintf(stderr, "Unary +\n");
 		(*p)++;
 		goto eval_next;
 	}
@@ -424,6 +430,7 @@
 				{
 					// otherwise we must be decimal (if we're still allowed one)
 					val = decval;
+					fprintf(stderr, "End of decimal value\n");
 					break;
 				}
 				else
@@ -492,7 +499,14 @@
 				dval -= '0';
 				if (dval > 9)
 					dval -= 7;
-				
+				fprintf(stderr, "Got digit: %d\n", dval);
+//				if (dval > 1)
+//					valtype &= 14;
+//				if (dval > 7)
+//					valtype &= 12;
+//				if (dval > 9)
+//					valtype &= 8;
+
 				if (valtype & 8)
 				{
 					hexval = hexval * 16 + dval;
@@ -520,11 +534,12 @@
 				}
 			}
 			// break out if we have a return value
-			if (valtype = -1)
+			if (valtype == -1)
 				break;
 			// return if no more valid possibilities!
 			if (valtype == 0)
 				return -1;
+			val = decval;	// in case we fall through
 		}
 		
 		// we get here when we have a value to return
@@ -560,12 +575,15 @@
 	lwasm_expr_term_t *operterm;
 	
 	// return if we are at the end of the expression or a subexpression
-	if (!**p || isspace(**p) || **p == ')')
+	if (!**p || isspace(**p) || **p == ')' || **p == ',')
 		return 0;
 	
-eval_next:
 	if (lwasm_expr_parse_term(s, p) < 0)
 		return -1;
+
+eval_next:
+	if (!**p || isspace(**p) || **p == ')' || **p == ',')
+		return 0;
 	
 	// expecting an operator here
 	for (opern = 0; operators[opern].opernum != LWASM_OPER_NONE; opern++)
@@ -625,15 +643,18 @@
 contain the pointer to the next character after the expression if and only
 if there is no error. In the case of an error, *outp is undefined.
 */
-lwasm_expr_stack_t *lwasm_expr_eval(const char *inp, const char **outp)
+lwasm_expr_stack_t *lwasm_expr_eval(const char *inp, const char **outp, int (*sfunc)(char *sym, void *state, int *val), void *state)
 {
 	lwasm_expr_stack_t *s;
 	const char *p;
-	
+	int rval;
+		
 	// actually parse the expression
 	p = inp;
 	s = lwasm_expr_stack_create();
-	if (lwasm_expr_parse_expr(s, &p, 0) < 0)
+	
+	rval = lwasm_expr_parse_expr(s, &p, 0);
+	if (rval < 0)
 		goto cleanup_error;
 	
 	// save end of expression
@@ -641,8 +662,11 @@
 		(*outp) = p;
 	
 	// return potentially partial expression
-	if (lwasm_expr_reval(s) < 0)
+	if (lwasm_expr_reval(s, sfunc, state) < 0)
 		goto cleanup_error;
+
+	if (lwasm_expr_is_constant(s))
+		fprintf(stderr, "Constant expression evaluates to: %d\n", lwasm_expr_get_value(s));
 	
 	return s;
 
@@ -668,9 +692,26 @@
 further operators or only a single term remains
 
 */
-int lwasm_expr_reval(lwasm_expr_stack_t *s)
+int lwasm_expr_reval(lwasm_expr_stack_t *s, int (*sfunc)(char *sym, void *state, int *val), void *state)
 {
 	lwasm_expr_stack_node_t *n;
+	int sval;
+	
+	// resolve symbols
+	// symbols that do not resolve to a constant are left alone
+	for (n = s -> head; n; n = n -> next)
+	{
+		if (n -> term -> term_type == LWASM_TERM_SYM)
+		{
+			if (sfunc(n -> term -> symbol, state, &sval) == 0)
+			{
+				n -> term -> term_type = LWASM_TERM_INT;
+				n -> term -> value = sval;
+				lwasm_free(n -> term -> symbol);
+				n -> term -> symbol = NULL;
+			}
+		}
+	}
 
 next_iter:	
 	// a single term