changeset 342:7b4123dce741

Added basic symbol registration
author lost@starbug
date Wed, 24 Mar 2010 21:30:31 -0600
parents 4e1cff60c293
children b4157778d354
files lwasm/Makefile.am lwasm/instab.c lwasm/lwasm.h lwasm/main.c lwasm/pass1.c lwasm/symbol.c lwlib/lw_expr.c lwlib/lw_expr.h
diffstat 8 files changed, 154 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/lwasm/Makefile.am	Fri Mar 19 10:03:56 2010 +0000
+++ b/lwasm/Makefile.am	Wed Mar 24 21:30:31 2010 -0600
@@ -1,5 +1,5 @@
 AM_CPPFLAGS = -I$(top_builddir)/lib -I$(top_srcdir)/lib -I$(top_builddir)/lwlib -I$(top_srcdir)/lwlib
 bin_PROGRAMS = lwasm
-lwasm_SOURCES = main.c pragma.c input.c pass1.c lwasm.c
+lwasm_SOURCES = main.c pragma.c input.c pass1.c lwasm.c instab.c symbol.c
 lwasm_LDADD = -L$(top_builddir)/lib -L$(top_srcdir)/lib -L$(top_builddir)/lwlib -L$(top_srcdir)/lwlib -lgnu -llw
-EXTRA_DIST =  lwasm.h input.h
+EXTRA_DIST =  lwasm.h input.h instab.h
--- a/lwasm/instab.c	Fri Mar 19 10:03:56 2010 +0000
+++ b/lwasm/instab.c	Wed Mar 24 21:30:31 2010 -0600
@@ -151,6 +151,7 @@
 
 instab_t instab[] =
 {
+/*
 	{ "abx",		{	0x3a,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
 	{ "adca",		{	0x99,	0xa9,	0xb9,	0x89},	insn_parse_gen8,		insn_resolve_gen8,				lwasm_insn_normal},
 	{ "adcb",		{	0xd9,	0xe9,	0xf9,	0xc9},	insn_parse_gen8,		insn_resolve_gen8,				lwasm_insn_normal},
@@ -479,7 +480,8 @@
 	{ "mod",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_mod,		pseudo_resolve_mod,				lwasm_insn_normal},
 	{ "emod",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_emod,		pseudo_resolve_emod,			lwasm_insn_normal},
 
-	/* for compatibility with gcc6809 output... */
+	// for compatibility with gcc6809 output...
+
 	{ ".area",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_section,	pseudo_resolve_section,			lwasm_insn_normal},
 	{ ".globl",		{	-1, 	-1, 	-1, 	-1}, 	pseudo_parse_export,	pseudo_resolve_export,			lwasm_insn_normal},
 	{ ".module",	{	-1, 	-1, 	-1, 	-1},	pseudo_parse_noop,		pseudo_resolve_noop,			lwasm_insn_normal},
@@ -518,6 +520,7 @@
 	{ "pag",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_noop,		pseudo_resolve_noop,			lwasm_insn_normal},
 	{ "ttl",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_noop,		pseudo_resolve_noop,			lwasm_insn_normal},
 
-	/* flag end of table */	
-	{ NULL,			{	-1, 	-1, 	-1, 	-1 },	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal}
+	// flag end of table
+*/
+	{ NULL,			{	-1, 	-1, 	-1, 	-1 },	NULL,					NULL,							lwasm_insn_normal}
 };
--- a/lwasm/lwasm.h	Fri Mar 19 10:03:56 2010 +0000
+++ b/lwasm/lwasm.h	Wed Mar 24 21:30:31 2010 -0600
@@ -69,11 +69,33 @@
 	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
+	int symset;							// set if the line symbol was consumed by the instruction
 	char *sym;							// symbol, if any, on the line
 	line_t *prev;
 	line_t *next;
 };
 
+enum
+{
+	symbol_flag_set = 1,				// symbol was used with "set"
+	symbol_flag_none = 0				// no flags
+};
+
+struct symtabe
+{
+	char *symbol;						// the name of the symbol
+	int context;						// symbol context (-1 for global)
+	int version;						// version of the symbol (for "set")
+	int flags;							// flags for the symbol
+	lw_expr_t value;					// symbol value
+	struct symtabe *next;				// next symbol in the table
+};
+
+typedef struct
+{
+	struct symtabe *head;				// start of symbol table
+} symtab_t;
+
 typedef struct
 {
 	int output_format;					// output format
@@ -84,6 +106,10 @@
 
 	line_t *line_head;					// start of lines list
 	line_t *line_tail;					// tail of lines list
+	
+	int context;						// the current "context"
+
+	symtab_t symtab;					// meta data for the symbol table
 
 	char *list_file;					// name of file to list to
 	char *output_file;					// output file name	
@@ -93,4 +119,11 @@
 	lw_stack_t file_dir;				// stack of the "current file" dir
 } asmstate_t;
 
+#ifndef ___symbol_c_seen___
+
+extern struct symtabe *register_symbol(asmstate_t *as, char *sym, lw_expr_t value, int flags);
+extern struct symtabe *lookup_symbol(asmstate_t *as, char *sym, int context, int version);
+
+#endif
+
 #endif /* ___lwasm_h_seen___ */
--- a/lwasm/main.c	Fri Mar 19 10:03:56 2010 +0000
+++ b/lwasm/main.c	Wed Mar 24 21:30:31 2010 -0600
@@ -165,8 +165,8 @@
 assembler on the first file
 */
 extern void do_pass1(asmstate_t *as);
-extern void lwasm_evaluate_special(int t, void *ptr);
-extern void lwasm_evaluate_var(char *var);
+extern lw_expr_t lwasm_evaluate_special(int t, void *ptr);
+extern lw_expr_t lwasm_evaluate_var(char *var);
 
 int main(int argc, char **argv)
 {
--- a/lwasm/pass1.c	Fri Mar 19 10:03:56 2010 +0000
+++ b/lwasm/pass1.c	Wed Mar 24 21:30:31 2010 -0600
@@ -24,8 +24,10 @@
 #include <stdio.h>
 
 #include <lw_alloc.h>
+#include <lw_string.h>
 
 #include "lwasm.h"
+#include "instab.h"
 #include "input.h"
 
 /*
@@ -47,7 +49,7 @@
 	char *line;
 	line_t *cl;
 	char *p1;
-	int stpace;
+	int stspace;
 	char *tok, *sym;
 	int opnum;
 	
@@ -120,7 +122,7 @@
 		if (*p1 == '*' || *p1 == ';' || *p1 == '#' || !*p1)
 			goto nextline;
 
-		
+		// find the end of the first token
 		for (tok = p1; *p1 && !isspace(*p1) && *p1 != ':'; p1++)
 			/* do nothing */ ;
 		
@@ -179,7 +181,15 @@
 		
 		if (cl -> sym && cl -> symset == 0)
 		{
+			printf("Register symbol %s:", sym);
+			lw_expr_print(cl -> addr);
+			printf("\n");
+
 			// register symbol at line address
+			if (!register_symbol(as, cl -> sym, cl -> addr, symbol_flag_none))
+			{
+				// symbol error
+			}
 		}
 		
 		lw_expr_print(cl -> addr);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lwasm/symbol.c	Wed Mar 24 21:30:31 2010 -0600
@@ -0,0 +1,87 @@
+/*
+symbol.c
+
+Copyright © 2010 William Astle
+
+This file is part of LWTOOLS.
+
+LWTOOLS 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/>.
+*/
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <lw_alloc.h>
+#include <lw_expr.h>
+
+#include "lwasm.h"
+
+struct symtabe *register_symbol(asmstate_t *as, char *sym, lw_expr_t val, int flags)
+{
+	struct symtabe *se;
+	int islocal = 0;
+	int context = -1;
+	int version = -1;
+
+	if (strchr(sym, '@') || strchr(sym, '?'))
+		islocal = 1;
+	if (!(as -> pragmas & PRAGMA_DOLLARNOTLOCAL) && strchr(sym, '$'))
+		islocal = 1;
+
+	if (islocal)
+		context = as -> context;
+	
+	// first, look up symbol to see if it is already defined
+	for (se = as -> symtab.head; se; se = se -> next)
+	{
+		if (!strcmp(sym, se -> symbol))
+		{
+			if (se -> context != context)
+				continue;
+			if ((flags & symbol_flag_set) && (se -> flags & symbol_flag_set))
+			{
+				if (version < se -> version)
+					version = se -> version;
+					continue;
+			}
+			break;
+		}
+	}
+	if (se)
+	{
+		// multiply defined symbol
+		return NULL;
+	}
+
+	if (flags & symbol_flag_set)
+	{
+		version++;
+	}
+	
+	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);
+	return se;
+}
+
+struct symtabe * lookup_symbol(asmstate_t *as, char *sym, int context, int version)
+{
+	return NULL;
+}
--- a/lwlib/lw_expr.c	Fri Mar 19 10:03:56 2010 +0000
+++ b/lwlib/lw_expr.c	Wed Mar 24 21:30:31 2010 -0600
@@ -31,15 +31,15 @@
 #include "lw_error.h"
 #include "lw_string.h"
 
-static lw_expr_t (*evaluate_special)(int t, void *ptr) = NULL;
-static lw_expr_t (*evaluate_var)(char *var) = NULL;
+static lw_expr_fn_t *evaluate_special = NULL;
+static lw_expr_fn2_t *evaluate_var = NULL;
 
-void lw_expr_set_special_handler(lw_expr_t (*fn)(int t, void *ptr))
+void lw_expr_set_special_handler(lw_expr_fn_t *fn)
 {
 	evaluate_special = fn;
 }
 
-void lw_expr_set_var_handler(lw_expr_t (*fn)(char *var))
+void lw_expr_set_var_handler(lw_expr_fn2_t *fn)
 {
 	evaluate_var = fn;
 }
--- a/lwlib/lw_expr.h	Fri Mar 19 10:03:56 2010 +0000
+++ b/lwlib/lw_expr.h	Wed Mar 24 21:30:31 2010 -0600
@@ -66,6 +66,9 @@
 	struct lw_expr_opers *operands;		// ptr to list of operands (for operators)
 };
 
+typedef lw_expr_t lw_expr_fn_t(int t, void *ptr);
+typedef lw_expr_t lw_expr_fn2_t(char *var);
+
 
 #else /* def ___lw_expr_c_seen___ */
 
@@ -80,8 +83,11 @@
 extern int lw_expr_compare(lw_expr_t E1, lw_expr_t E2);
 extern void lw_expr_simplify(lw_expr_t E);
 
-extern void lw_expr_set_special_handler(lw_expr_t (*fn)(int t, void *ptr));
-extern void lw_expr_set_var_handler(lw_expr_t (*fn)(char *var));
+typedef lw_expr_t lw_expr_fn_t(int t, void *ptr);
+typedef lw_expr_t lw_expr_fn2_t(char *var);
+
+extern void lw_expr_set_special_handler(lw_expr_fn_t *fn);
+extern void lw_expr_set_var_handler(lw_expr_fn2_t *fn);
 
 #endif /* def ___lw_expr_c_seen___ */