diff lwasm/parse.c @ 254:c7a41b4c89b3 2.x

Added struct support to LWASM
author lost
date Sat, 19 Dec 2009 06:38:43 +0000
parents c537a3a723fc
children 6363b9ebf825
line wrap: on
line diff
--- a/lwasm/parse.c	Wed Dec 09 03:59:26 2009 +0000
+++ b/lwasm/parse.c	Sat Dec 19 06:38:43 2009 +0000
@@ -188,6 +188,62 @@
 	if (as -> skipcond && instab[opnum].iscond == 0)
 		goto done_line;
 
+	if (as -> instruct && as -> passnum == 1)
+	{
+		structtab_t *s = NULL;
+		struct struct_sym_e *e, *e2;
+
+		// look for a structure if not an acceptable opcode
+		if (!instab[opnum].opcode)
+		{
+			for (s = as -> structs; s; s = s -> next)
+			{
+				if (s == as -> cstruct)
+					continue;
+				if (!strcmp(opc, s -> name))
+					goto isok;
+			}
+		}
+		// check for a "reservation opcode"
+		if (instab[opnum].opcode && instab[opnum].isreserve)
+		{
+			(instab[opnum].fn)(as, l, &p2, opnum);
+			
+			// if we didn't end on a "space" character or EOL, throw error
+			if (p2 && *p2 && !isspace(*p2) && !(l -> err) && as -> passnum == 1)
+				register_error(as, l, 1, "Bad operand: %s (%d)", p2, as -> passnum);
+			
+			if (as -> instruct == 0)
+				goto done_line;
+			
+			goto isok;
+		}
+		// carp if not valid
+		register_error(as, l, 1, "Only other structs and rmb allowed in struct");
+		l -> badop = 1;
+		goto done_line;
+		
+	isok:
+		for (e2 = as -> cstruct -> fields; e2 && e2 -> next; e2 = e2 -> next)
+			/* do nothing */ ;
+		e = lwasm_alloc(sizeof(struct struct_sym_e));
+		e -> next = NULL;
+		e -> substruct = s;
+		if (sym)
+			e -> name = lwasm_strdup(sym);
+		else
+			e -> name = NULL;
+		if (s)
+			e -> size = s -> size;
+		else
+			e -> size = l -> nocodelen;
+		if (e2)
+			e2 -> next = e;
+		else
+			as -> cstruct -> fields = e;
+		as -> cstruct -> size += e -> size;
+	}
+
 	// we've registered the symbol as needed
 	// now we need to check for a macro call IFF we don't collide with
 	// an operation code; otherwise, call the operation function
@@ -215,6 +271,9 @@
 		if (expand_macro(as, l, &p2, opc) == 0)
 			goto done_line;
 
+		if (expand_struct(as, l, &p2, opc) == 0)
+			goto done_line;
+
 		// carp about an unknown operation code and note that fact for
 		// pass 2 in case a macro appears later with the same name!
 		register_error(as, l, 1, "Uknown operation code: %s", opc);
@@ -225,7 +284,7 @@
 	if (!(as -> skipcond || as -> inmacro))
 	{
 		// register symbol if the operation didn't
-		if (sym && instab[opnum].setsym == 0)
+		if (sym && instab[opnum].setsym == 0 && as -> instruct == 0)
 		{
 			if (as -> passnum == 1)
 			{