changeset 340:1a6fc6ebb31c

Checkpoint
author lost
date Fri, 19 Mar 2010 02:54:43 +0000
parents eb230fa7d28e
children 4e1cff60c293
files lwasm/lwasm.h lwasm/pass1.c
diffstat 2 files changed, 121 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/lwasm/lwasm.h	Fri Mar 19 02:54:14 2010 +0000
+++ b/lwasm/lwasm.h	Fri Mar 19 02:54:43 2010 +0000
@@ -69,6 +69,7 @@
 	lw_expr_t addr;						// assembly address of the line
 	int len;							// the "size" this line occupies (address space wise) (-1 if unknown)
 	int insn;							// number of insn in insn table
+	char *sym;							// symbol, if any, on the line
 	line_t *prev;
 	line_t *next;
 };
--- a/lwasm/pass1.c	Fri Mar 19 02:54:14 2010 +0000
+++ b/lwasm/pass1.c	Fri Mar 19 02:54:43 2010 +0000
@@ -30,14 +30,30 @@
 
 /*
 pass 1: parse the lines
+
+line format:
+
+[<symbol>] <opcode> <operand>[ <comment>]
+
+If <symbol> is followed by a :, whitespace may precede the symbol
+
+A line may optionally start with a number which must not be preceded by
+white space and must be followed by a single whitespace character. After
+that whitespace character, the line is parsed as if it had no line number.
+
 */
 void do_pass1(asmstate_t *as)
 {
 	char *line;
 	line_t *cl;
-
+	char *p1;
+	int stpace;
+	char *tok, *sym;
+	int opnum;
+	
 	for (;;)
 	{
+		sym = NULL;
 		line = input_readline(as);
 		if (!line)
 			break;
@@ -64,10 +80,113 @@
 		}
 		as -> line_tail = cl;
 
+		// blank lines don't count for anything
+		if (!*line)
+		{
+			goto nextline;
+		}
+	
+		// skip comments
+		if (*line == '*' || *line == ';' || *line == '#')
+			goto nextline;
+
+		p1 = line;
+		if (isdigit(*p1))
+		{
+			// skip line number
+			while (*p1 && isdigit(*p1))
+				p1++;
+			if (!*p1 && !isspace(*p1))
+				p1 = line;
+			else if (*p1 && isspace(*p1))
+				p1++;
+		}
+
+		if (!*p1)
+			goto nextline;
+
+		if (*p1 == '*' || *p1 == ';' || *p1 == '#')
+			goto nextline;
+
+		if (isspace(*p1))
+		{
+			for (; *p1 && isspace(*p1); p1++)
+				/* do nothing */ ;
+			stspace = 1;
+		}
+		else
+			stspace = 0;
+
+		if (*p1 == '*' || *p1 == ';' || *p1 == '#' || !*p1)
+			goto nextline;
+
+		
+		for (tok = p1; *p1 && !isspace(*p1) && *p1 != ':'; p1++)
+			/* do nothing */ ;
+		
+		if (*p1 == ':' || stspace == 0)
+		{
+			// have a symbol here
+			sym = lw_strndup(tok, p1 - tok);
+			if (*p1 == ':')
+				p1++;
+			for (; *p1 && isspace(*p1); p1++)
+				/* do nothing */ ;
+			
+			for (tok = p1; *p1 && !isspace(*p1); p1++)
+				/* do nothing */ ;
+		}
+
+		cl -> sym = sym;
+		cl -> symset = 0;
+		
+		// tok points to the opcode for the line or NUL if none
+		if (*tok)
+		{
+			// look up operation code
+			sym = lw_strndup(tok, p1 - tok);
+			for (; *p1 && isspace(p1); p1++)
+				/* do nothing */ ;
+
+			for (opnum = 0; instab[opnum].opcode; opnum++)
+			{
+				if (!strcasecmp(instab[opnum].opcode, sym))
+					break;
+			}
+			lw_free(sym);
+			
+			// p1 points to the start of the operand
+			
+			if (instab[opnum].opcode == NULL)
+			{
+				cl -> insn = -1;
+				if (*tok != ';' && *tok != '*')
+				{
+					// bad opcode; check for macro here
+				}
+			}
+			else
+			{
+				cl -> insn = opnum;
+				// call parse function
+				
+				if (*p1 && !isspace(*p1))
+				{
+					// flag bad operand error
+				}
+			}
+		}
+		
+		if (cl -> sym && cl -> symset == 0)
+		{
+			// register symbol at line address
+		}
+		
 		lw_expr_print(cl -> addr);
 		printf("\n");
 		// now parse the line
 		
+	nextline:
 		lw_free(line);
 	}
 }