changeset 17:df0c4a46af8f

Started adding expression handling infrastructure
author lost
date Thu, 01 Jan 2009 02:26:26 +0000
parents 4f14eae64d38
children 218aabbc3b1a
files src/Makefile.am src/expr.c src/expr.h src/util.c src/util.h
diffstat 5 files changed, 288 insertions(+), 71 deletions(-) [+]
line wrap: on
line diff
--- a/src/Makefile.am	Thu Oct 23 03:39:29 2008 +0000
+++ b/src/Makefile.am	Thu Jan 01 02:26:26 2009 +0000
@@ -1,4 +1,4 @@
 bin_PROGRAMS = lwasm
-lwasm_SOURCES = main.c expr.c lwval.c pass1.c pass2.c
-EXTRA_DIST = instab.h lwasm.h expr.h lwval.h
+lwasm_SOURCES = main.c expr.c lwval.c pass1.c pass2.c util.c
+EXTRA_DIST = instab.h lwasm.h expr.h lwval.h util.h
 
--- a/src/expr.c	Thu Oct 23 03:39:29 2008 +0000
+++ b/src/expr.c	Thu Jan 01 02:26:26 2009 +0000
@@ -25,82 +25,140 @@
 
 #define __expr_c_seen__
 
-#include <ctype.h>
+#include <stdio.h>
 #include <stdlib.h>
 
 #include "expr.h"
-#include "lwval.h"
+#include "util.h"
+
+lwasm_expr_stack_t *lwasm_expr_stack_create(void)
+{
+	lwasm_expr_stack_t *s;
+	
+	s = lwasm_alloc(sizeof(lwasm_expr_stack_t));
+	s -> head = NULL;
+	s -> tail = NULL;
+	return s;
+}
 
-// parse a single term out of the expression; return NULL if
-// end of expression; return LWVAL_TYPE_ERR if error
-/*
-The following is handled by lwasm_parse_term:
+void lwasm_expr_stack_free(lwasm_expr_stack_t *s)
+{
+	while (s -> head)
+	{
+		s -> tail = s -> head;
+		s -> head = s -> head -> next;
+		lwasm_expr_term_free(s -> tail -> term);
+		lwasm_free(s -> tail);
+	}
+	lwasm_free(s);
+}
 
-- constants
-- parsing a symbol
-- unary -
-- unary +
-- ()
+void lwasm_expr_term_free(lwasm_expr_term_t *t)
+{
+	if (t)
+	{
+		if (t -> symbol)
+			lwasm_free(t -> symbol);
+		lwasm_free(t);
+	}
+}
+
+lwasm_expr_term_t *lwasm_expr_term_create_oper(int oper)
+{
+	lwasm_expr_term_t *t;
+	
+	t = lwasm_alloc(sizeof(lwasm_expr_term_t));
+	t -> term_type = LWASM_TERM_OPER;
+	t -> value = oper;
+	return t;
+}
 
-*/
-LWVAL *lwasm_parse_term(char **ptr)
+lwasm_expr_term_t *lwasm_expr_term_create_int(int val)
 {
-	int sign = 1;
-	int s = 0;
-	LWVAL *rval;
+	lwasm_expr_term_t *t;
+	
+	t = lwasm_alloc(sizeof(lwasm_expr_term_t));
+	t -> term_type = LWASM_TERM_INT;
+	t -> value = val;
+	return t;
+}
+
+lwasm_expr_term_t *lwasm_expr_term_create_sym(char *sym)
+{
+	lwasm_expr_term_t *t;
 	
-start_term:
-	if (!**ptr || isspace(**ptr) || **ptr == ')')
-		return s ? lwval_construct_err(1) : NULL;
+	t = lwasm_alloc(sizeof(lwasm_expr_term_t));
+	t -> term_type = LWASM_TERM_SYM;
+	t -> symbol = lwasm_strdup(sym);
+	return t;
+}
 
-	s = 1;	
-	// unary + - NOOP
-	if (**ptr == '+')
+lwasm_expr_term_t *lwasm_expr_term_dup(lwasm_expr_term_t *t)
+{
+	switch (t -> term_type)
 	{
-		(*ptr)++;
-		goto start_term;
+	case LWASM_TERM_INT:
+		return lwasm_expr_term_create_int(t -> value);
+		
+	case LWASM_TERM_OPER:
+		return lwasm_expr_term_create_oper(t -> value);
+		
+	case LWASM_TERM_SYM:
+		return lwasm_expr_term_create_sym(t -> symbol);
+		
+	default:
+		fprintf(stderr, "lwasm_expr_term_dup(): invalid term type %d\n", t -> term_type);
+		exit(1);
+	}
+// can't get here
+}
+
+void lwasm_expr_stack_push(lwasm_expr_stack_t *s, lwasm_expr_term_t *t)
+{
+	lwasm_expr_stack_node_t *n;
+
+	if (!s)
+	{
+		fprintf(stderr, "lwasm_expr_stack_push(): invalid stack pointer\n");
+		exit(1);
 	}
 	
-	// unary - - applied once the rest of the term is worked out
-	if (**ptr == '-')
+	n = lwasm_alloc(sizeof(lwasm_expr_stack_node_t));
+	n -> next = NULL;
+	n -> prev = s -> tail;
+	n -> term = lwasm_expr_term_dup(t);
+	
+	if (s -> head)
+	{
+		s -> tail -> next = n;
+		s -> tail = n;
+	}
+	else
 	{
-		(*ptr)++;
-		sign = -sign;
-		goto start_term;
+		s -> head = n;
+		s -> tail = n;
+	}
+}
+
+lwasm_expr_term_t *lwasm_expr_stack_pop(lwasm_expr_stack_t *s)
+{
+	lwasm_expr_term_t *t;
+	lwasm_expr_stack_node_t *n;
+	
+	if (!(s -> tail))
+		return NULL;
+	
+	n = s -> tail;
+	s -> tail = n -> prev;
+	if (!(n -> prev))
+	{
+		s -> head = NULL;
 	}
 	
-	// parens
-	if (**ptr == '(')
-	{
-		LWVAL *v;
-		(*ptr)++;
-		rval = lwasm_parse_expr(ptr);
-		if (**ptr != ')')
-		{
-			lwval_destroy(rval);
-			return lwval_construct_err(1);
-		}
-		(*ptr)++;
-		goto ret;
-	}
-
-	// parse an actual term here; no more futzing with expressions
-
-ret:
-	// apply negation if appropriate
-	if (sign < 0)
-		lwval_neg(rval);
-	return rval;
+	t = n -> term;
+	n -> term = NULL;
+	
+	lwasm_free(n);
+	
+	return t;
 }
-
-// parse an expression
-LWVAL *lwasm_parse_expr(char **ptr)
-{
-}
-
-// attempt to evaluate/simplify expression
-int lwasm_eval_expr(LWVAL *expr)
-{
-}
-
-
--- a/src/expr.h	Thu Oct 23 03:39:29 2008 +0000
+++ b/src/expr.h	Thu Jan 01 02:26:26 2009 +0000
@@ -25,19 +25,69 @@
 #ifndef __expr_h_seen__
 #define __expr_h_seen__
 
-#include "lwval.h"
-
 #ifndef __expr_c_seen__
 #define __expr_E__ extern
 #else
 #define __expr_E__
 #endif
 
-// parse an expression
-__expr_E__ LWVAL *lwasm_parse_expr(char **ptr);
+// term types
+#define LWASM_TERM_NONE		0
+#define LWASM_TERM_OPER		1	// an operator
+#define LWASM_TERM_INT		2	// 32 bit signed integer
+#define LWASM_TERM_SYM		3	// symbol reference
+
+// operator types
+#define LWASM_OPER_NONE		0
+#define LWASM_OPER_PLUS		1	// +
+#define LWASM_OPER_MINUS	2	// -
+#define LWASM_OPER_TIMES	3	// *
+#define LWASM_OPER_DIVIDE	4	// /
+#define LWASM_OPER_MOD		5	// %
+#define LWASM_OPER_INTDIV	6	// \
+#define LWASM_OPER_BWAND	7	// bitwise AND
+#define LWASM_OPER_BWOR		8	// bitwise OR
+#define LWASM_OPER_BWXOR	9	// bitwise XOR
+#define LWASM_OPER_AND		10	// boolean AND
+#define LWASM_OPER_OR		11	// boolean OR
+#define LWASM_OPER_NEG		12	// unary negation (2's complement)
+#define LWASM_OPER_COM		13	// unary 1's complement
+
 
-// attempt to evaluate/simplify expression
-__expr_E__ int lwasm_eval_expr(LWVAL *expr);
+// term structure
+typedef struct lwasm_expr_term_s
+{
+	int term_type;		// type of term (see above)
+	char *symbol;		// name of a symbol
+	int value;			// value of the term (int) or operator number (OPER)
+} lwasm_expr_term_t;
+
+// type for an expression evaluation stack
+typedef struct lwasm_expr_stack_node_s lwasm_expr_stack_node_t;
+struct lwasm_expr_stack_node_s
+{
+	lwasm_expr_term_t		*term;
+	lwasm_expr_stack_node_t	*prev;
+	lwasm_expr_stack_node_t	*next;	
+};
+
+typedef struct lwasm_expr_stack_s
+{
+	lwasm_expr_stack_node_t *head;
+	lwasm_expr_stack_node_t *tail;
+} lwasm_expr_stack_t;
+
+__expr_E__ void lwasm_expr_term_free(lwasm_expr_term_t *t);
+__expr_E__ lwasm_expr_term_t *lwasm_expr_term_create_oper(int oper);
+__expr_E__ lwasm_expr_term_t *lwasm_expr_term_create_sym(char *sym);
+__expr_E__ lwasm_expr_term_t *lwasm_expr_term_create_int(int val);
+__expr_E__ lwasm_expr_term_t *lwasm_expr_term_dup(lwasm_expr_term_t *t);
+
+__expr_E__ void lwasm_expr_stack_free(lwasm_expr_stack_t *s);
+__expr_E__ lwasm_expr_stack_t *lwasm_expr_stack_create(void);
+
+__expr_E__ void lwasm_expr_stack_push(lwasm_expr_stack_t *s, lwasm_expr_term_t *t);
+__expr_E__ lwasm_expr_term_t *lwasm_expr_stack_pop(lwasm_expr_stack_t *s);
 
 #undef __expr_E__
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/util.c	Thu Jan 01 02:26:26 2009 +0000
@@ -0,0 +1,66 @@
+/*
+util.c
+Copyright © 2008 William Astle
+
+This file is part of LWASM.
+
+LWASM is free software: you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the Free Software
+Foundation, either version 3 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+more details.
+
+You should have received a copy of the GNU General Public License along with
+this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+Utility functions
+*/
+
+#define __util_c_seen__
+
+#include <malloc.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "util.h"
+
+void *lwasm_alloc(int size)
+{
+	void *ptr;
+	
+	ptr = malloc(size);
+	if (!ptr)
+	{
+		// bail out; memory allocation error
+		fprintf(stderr, "Memory allocation error\n");
+		exit(1);
+	}
+	return ptr;
+}
+
+void lwasm_free(void *ptr)
+{
+	if (ptr)
+		free(ptr);
+}
+
+char *lwasm_strdup(const char *s)
+{
+	char *d;
+	
+	d = strdup(s);
+	if (!d)
+	{
+		fprintf(stderr, "lwasm_strdup(): memory allocation error\n");
+		exit(1);
+	}
+	
+	return d;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/util.h	Thu Jan 01 02:26:26 2009 +0000
@@ -0,0 +1,43 @@
+/*
+expr.h
+Copyright © 2008 William Astle
+
+This file is part of LWASM.
+
+LWASM is free software: you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the Free Software
+Foundation, either version 3 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+more details.
+
+You should have received a copy of the GNU General Public License along with
+this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+Utility functions
+*/
+
+#ifndef __util_h_seen__
+#define __util_h_seen__
+
+#ifndef __util_c_seen__
+#define __util_E__ extern
+#else
+#define __util_E__
+#endif
+
+// allocate memory
+__util_E__ void *lwasm_alloc(int size);
+__util_E__ void lwasm_free(void *ptr);
+
+// string stuff
+__util_E__ char *lwasm_strdup(const char *s);
+
+#undef __util_E__
+
+#endif // __util_h_seen__