changeset 406:502fbc37ff4e

Symbol table is now sorted in lwasm
author lost@l-w.ca
date Fri, 23 Jul 2010 19:23:17 -0600
parents 7bcc50e828ff
children b2e007c28b8f
files lwasm/symbol.c
diffstat 1 files changed, 62 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/lwasm/symbol.c	Fri Jul 23 18:58:20 2010 -0600
+++ b/lwasm/symbol.c	Fri Jul 23 19:23:17 2010 -0600
@@ -31,14 +31,61 @@
 
 #include "lwasm.h"
 
+struct symtabe *symbol_findprev(asmstate_t *as, struct symtabe *se)
+{
+	struct symtabe *se1, *se2;
+	int i;
+	
+	for (se2 = NULL, se1 = as -> symtab.head; se1; se1 = se1 -> next)
+	{
+		debug_message(as, 200, "Sorting; looking at symbol %s (%p) for %s", se1 -> symbol, se1, se -> symbol);
+		/* compare se with se1 */
+		i = strcasecmp(se -> symbol, se1 -> symbol);
+		
+		/* if the symbol sorts before se1, we just need to return */
+		if (i < 0)
+			return se2;
+		
+		if (i == 0)
+		{
+			/* symbol name matches; compare other things */
+			
+			/*if next version is greater than this one, return */
+			if (se -> version > se1 -> version)
+				return se2;
+			/* if next context is great than this one, return */ 
+			if (se -> context > se1 -> context)
+				return se2;
+			
+			/* if section name is greater, return */
+			/* if se has no section but se1 does, we go first */
+			if (se -> section == NULL && se1 -> section != NULL)
+				return se2;
+			if (se -> section != NULL && se -> section != NULL)
+			{
+				/* compare section names and if se < se1, return */
+				i = strcasecmp(se -> section -> name, se1 -> section -> name);
+				if (i < 0)
+					return se2;
+			}
+		}
+		
+		se2 = se1;
+	}
+	return se2;
+}
+
 struct symtabe *register_symbol(asmstate_t *as, line_t *cl, char *sym, lw_expr_t val, int flags)
 {
 	struct symtabe *se;
+	struct symtabe *sprev;
 	int islocal = 0;
 	int context = -1;
 	int version = -1;
 	char *cp;
 
+	debug_message(as, 200, "Register symbol %s (%02X), %s", sym, flags, lw_expr_print(val));
+
 	if (!(flags & symbol_flag_nocheck))
 	{
 		if (*sym < 0x80 && !strchr(SSYMCHARS, *sym))
@@ -75,6 +122,7 @@
 	// first, look up symbol to see if it is already defined
 	for (se = as -> symtab.head; se; se = se -> next)
 	{
+		debug_message(as, 300, "Symbol add lookup: %p, %p", se, se -> next);
 		if (!strcmp(sym, se -> symbol))
 		{
 			if (se -> context != context)
@@ -104,16 +152,27 @@
 	// symplify the symbol expression - replaces "SET" symbols with
 	// symbol table entries
 	lwasm_reduce_expr(as, val);
-	
+
 	se = lw_alloc(sizeof(struct symtabe));
-	se -> next = as -> symtab.head;
-	as -> symtab.head = se;
 	se -> context = context;
 	se -> version = version;
 	se -> flags = flags;
 	se -> value = lw_expr_copy(val);
 	se -> symbol = lw_strdup(sym);
 	se -> section = cl -> csect;
+	sprev = symbol_findprev(as, se);
+	if (!sprev)
+	{
+		debug_message(as, 200, "Adding symbol at head of symbol table");
+		se -> next = as -> symtab.head;
+		as -> symtab.head = se;
+	}
+	else
+	{
+		debug_message(as, 200, "Adding symbol in middle of symbol table");
+		se -> next = sprev -> next;
+		sprev -> next = se;
+	}
 	return se;
 }