changeset 13:05d4115b4860

Started work on new expression evaluator system and major code re-work for next release
author lost
date Wed, 22 Oct 2008 04:51:16 +0000
parents 287a6905a63c
children b28d7cb60779
files src/Makefile.am src/expr.c src/expr.h src/instab.h src/lwasm.c src/lwasm.h src/main.c src/pass1.c src/pass2.c
diffstat 9 files changed, 222 insertions(+), 318 deletions(-) [+]
line wrap: on
line diff
--- a/src/Makefile.am	Sat Oct 04 03:20:36 2008 +0000
+++ b/src/Makefile.am	Wed Oct 22 04:51:16 2008 +0000
@@ -1,3 +1,3 @@
 bin_PROGRAMS = lwasm
-lwasm_SOURCES = index.c instab.c macro.c pragma.c insn_gen.c list.c main.c pseudo.c insn_misc.c lwasm.c output.c symtab.c
-EXTRA_DIST = instab.h lwasm.h
+lwasm_SOURCES = main.c expr.c pass1.c pass2.c
+EXTRA_DIST = instab.h lwasm.h expr.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/expr.c	Wed Oct 22 04:51:16 2008 +0000
@@ -0,0 +1,25 @@
+/*
+expr.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/>.
+*/
+
+/*
+This file contains implementations associated with the expression evaluator
+used by LWASM.
+
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/expr.h	Wed Oct 22 04:51:16 2008 +0000
@@ -0,0 +1,75 @@
+/*
+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/>.
+*/
+
+/*
+This file contains definitions associated with the expression evaluator used
+by LWASM.
+
+The core of the entire expression handler is the opaque type LWVAL, pointers
+to which are passed around to keep track of values. A value may be a simple
+integer or it could be a more complex expression linked by operators or it
+could be a polynomial expression. Simple integers are merely a degenerate
+case of polynomials.
+
+The package understands the following operations:
+
+addition
+subtraction
+multiplication
+division
+modulus
+parentheses
+unary negation
+unary "positive"
+bitwise and
+bitwise or
+bitwise not (1's complement)
+bitwise exclusive or
+
+Infix operators can be expressed as LWVAL <op> LWVAL. Thus, the order of
+operations is only relevant when initially parsing the expression. The order
+of evaluation is determined by what appears on either side of the <op> as
+an LWVAL may be an expression.
+*/
+
+typedef union lwval LWVAL;
+
+struct lwval_int
+{
+	int	lwval_type;					// type of value
+	int lwval_int_value;			// integer value
+};
+
+union lwval
+{
+	struct lwval_int lwval_type_int;	// integer type
+};
+
+enum lwval_types
+{
+	LWVAL_TYPE_INT
+};
+
+#ifndef __expr_h_seen__
+#define __expr_h_seen__
+
+
+
+#endif //__expr_h_seen__
--- a/src/instab.h	Sat Oct 04 03:20:36 2008 +0000
+++ b/src/instab.h	Wed Oct 22 04:51:16 2008 +0000
@@ -21,53 +21,12 @@
 Contains definitions for the instruction table
 */
 
-#include "lwasm.h"
-
-#ifndef __instab_h_seen__
-#define __instab_h_seen__
-
-#define INSTYPE_INH			0	/* inherent addressing */
-#define INSTYPE_GEN			1	/* general addressing modes */
-#define INSTYPE_GEN8		2	/* general addressing, 8 bit immed */
-#define INSTYPE_GENNOIMM	3	/* no immediate addressing */
-#define INSTYPE_RTOR		4	/* register to register */
-#define INSTYPE_RLIST		5	/* register list */
-#define INSTYPE_REL8		6	/* relative addressing */
-#define INSTYPE_REL16		7	/* 16 bit relative addressing */
-#define INSTYPE_INDEX		8	/* indexed mode only */
-#define INSTYPE_IMM8		9	/* immediate only 8 bit (andcc, cwai) */
-#define INSTYPE_LOGICMEM	10	/* aim/oim/eim/tim */
-#define INSTYPE_BITBIT		11	/* bit to bit ops */
-#define INSTYPE_TFM			12	/* TFM ops */
-#define INSTYPE_GEN32		13	/* general addressing, 32 bit immed */
-#define INSTYPE_PSEUDO		14	/* special handling, pseudo op */
-
-#define SPECIAL_EQU		1	/* equ */
-#define	SPECIAL_ORG		2	/* org */
-#define SPECIAL_SETDP	3
-#define SPECIAL_FCB		4
-#define SPECIAL_FDB		5
-#define SPECIAL_FQB		6
-#define SPECIAL_FCC		7
-#define SPECIAL_FCS		8
-#define SPECIAL_FCN		9
-#define SPECIAL_RMB		10
-#define SPECIAL_ALIGN	11
-#define SPECIAL_END		12
-#define SPECIAL_INCLUDE	13
-#define SPECIAL_ENDM	14
-#define SPECIAL_ENDC	15
-#define SPECIAL_MACRO	16
-#define SPECIAL_COND	17
-#define SPECIAL_ELSE	18
-
 typedef struct
 {
 	char *opcode;				/* the mneumonic */
 	int ops[4];					/* opcode values for up to four addr modes */
-	int instype;				/* type of instruction (see above) */
-	int specialnum;				/* type of special instruction */
-	void (*opfn)(asmstate_t *as, sourceline_t *cl, char **optr);
+	void (*p1fn)(asmstate_t *as, sourceline_t *cl, char **optr);
+	void (*p2fn)(asmstate_t *as, sourceline_t *cl, char **optr);
 } instab_t;
 
 #ifndef __instab_c_seen__
--- a/src/lwasm.c	Sat Oct 04 03:20:36 2008 +0000
+++ b/src/lwasm.c	Wed Oct 22 04:51:16 2008 +0000
@@ -423,75 +423,6 @@
 	}
 }
 
-void lwasm_read_file(asmstate_t *as, char *fname)
-{
-	FILE *f;
-	int cline = 0;
-	sourceline_t *cl;
-	size_t bufflen;
-	char *buff = NULL;
-	int retval;
-	
-	as -> passnum = 1;
-	
-	f = fopen(fname, "r");
-	if (!f)
-	{
-		fprintf(stderr, "Cannot open input file %s: %s\n", fname, strerror(errno));
-		return;
-	}
-	
-	while (!feof(f))
-	{
-		retval = getline(&buff, &bufflen, f);
-		debug(" read line (%s:%d): %s\n", fname, cline, buff);
-		if (retval < 0)
-		{
-			if (feof(f))
-				break;
-			fprintf(stderr, "Error reading '%s': %s\n", fname, strerror(errno));
-			exit(1);
-		}
-		if (strchr(buff, '\n'))
-			*strchr(buff, '\n') = '\0';
-		if (strchr(buff, '\r'))
-			*strchr(buff, '\r') = '\0';
-		cl = calloc(sizeof(sourceline_t), 1);
-		if (!cl)
-		{
-			perror("Malloc");
-			exit(1);
-		}
-		
-		cl -> lineno = cline++;
-		cl -> sourcefile = fname;
-		cl -> opcode = -1;
-		cl -> addrmode = -1;
-		cl -> addr = as -> addr;
-		cl -> dpval = as -> dpval;
-		cl -> prev = as -> source_tail;
-		if (as -> source_tail)
-			as -> source_tail -> next = cl;
-		as -> source_tail = cl;
-		if (as -> source_head == NULL)
-			as -> source_head = cl;
-		cl -> line = strdup(buff);
-
-		resolve_insn(as, cl);
-
-		if (cl -> opcode >= 0 && instab[cl -> opcode].instype == INSTYPE_PSEUDO && instab[cl -> opcode].specialnum == SPECIAL_END)
-			break;
-		
-		*buff = '\0';
-
-	}
-	if (buff)
-		free(buff);
-
-	fclose(f);
-
-	return;
-}
 
 /*
 below this point is the expression evaluation package
--- a/src/lwasm.h	Sat Oct 04 03:20:36 2008 +0000
+++ b/src/lwasm.h	Wed Oct 22 04:51:16 2008 +0000
@@ -24,211 +24,33 @@
 #ifndef __lwasm_h_seen__
 #define __lwasm_h_seen__
 
-#define MAX_OP_LEN 32
-#define SYMCHAR_START "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
-#define SYMCHAR "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$."
-
-#define MACROCHAR_START "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
-#define MACROCHAR "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
-
-
-#define OPER_INH	0
-#define OPER_RTOR	1
-#define OPER_RLIST	2
-#define OPER_TFM	3
-#define OPER_IMM8	4
-#define OPER_IMM16	5
-#define OPER_IMM32	6
-#define OPER_DIR	7
-#define OPER_EXT	8
-#define OPER_INDEX	9	// indexed with no offset
-#define OPER_DIREXT	10	// used as a placeholder when direct/extended unknown
-#define OPER_BITBIT	11	// bit to bit direct page opers
-#define OPER_REL8	12
-#define OPER_REL16	13
-#define OPER_INDEX5	14	// 5 bit offset indexed
-#define OPER_INDEX8	15	// 8 bit offset indexed
-#define OPER_INDEX16 16	// 16 bit offset indexed
-#define OPER_INDEXV	17	// unknown size offset indexed
-#define OPER_EXTIND	18	// extended indirect
-#define OPER_LOGICD	19	// logic on mem, direct mode
-#define OPER_LOGICE 20	// logic on mem, extended mode
-#define OPER_LOGICEI 21	// logic on mem, extended indir mode
-#define OPER_LOGICI	22	// logic on mem, indexed no offset
-#define OPER_LOGICI5 23	// logic on mem, 5 bit indexed offset
-#define OPER_LOGICI8 24	// logic on mem, 8 bit indexed offset
-#define OPER_LOGICI16 25 // logic on mem, 16 bit indexed offset
-#define OPER_LOGICIV 26	// logic on mem, unknown size offset
-
 #define OUTPUT_DECB		0	// DECB multirecord format
 #define OUTPUT_RAW		1	// raw sequence of bytes
 #define OUTPUT_RAWREL	2	// raw but with ORG as a relative offset
-
-enum
-{
-	ERR_NONE,		// no error
-	ERR_BADOP,		// bad opcode
-	ERR_BADSYM,		// illegal symbol
-	ERR_DUPSYM,		// duplicate symbol definition
-	ERR_NOSYM,		// symbol required but not present
-	ERR_FORWARD,	// forward references not permitted here
-	ERR_OVERFLOW,	// byte overflow
-	ERR_PHASE,		// phasing error
-	ERR_BADOPER,	// bad operand
-	ERR_SYM,		// symbol present where not permitted
-	ERR_UNDEF,		// undefined symbol
-	ERR_OVERFLOW3,	// bit number out of range
-	ERR_BADEXPR,	// invalid expression
-	ERR_BADREG,		// invalid register
-	ERR_BADFN,		// bad file name
-	ERR_ENDM,		// end macro without macro
-	ERR_MACRO,		// redefined macro
-	ERR_NESTNAME,	// nested namespace
-	ERR_BADCOND,	// bad condition
-	ERR_USER,		// user error
-	ERR_PRAGMA,		// bad pragma
-	
-	ERR_MAXERR		// last error in the list
-};
-
-typedef struct sourceline_s sourceline_t;
-
-// structure to keep track of errors
-typedef struct errortab_s errortab_t;
-struct errortab_s {
-	int errnum;
-	sourceline_t *line;
-	errortab_t *next;
-};
-
-typedef struct macroline_s macroline_t;
-struct macroline_s
-{
-	char *linetext;
-	macroline_t *next;
-};
-
-typedef struct macrotab_s macrotab_t;
-struct macrotab_s
-{
-	char *name;				// name of the macro
-	macroline_t *linehead;	// start of the macro lines
-	macroline_t *linetail;	// last line of macro
-	macrotab_t *next;
-};
-
-
-// structure to keep track of each line of the source
-// this also keeps various bits of state about a line
-struct sourceline_s {
-	char *sourcefile;		// name of the source file
-	int lineno;				// line number in the source file
-	char *symstr;			// symbol on this line (if any)
-	int opcode;				// index to instab for this line
-	int opbytes;			// actual bytes of opcode
-	int postbyte;			// post byte for the instruction
-	int numcodebytes;		// how many code bytes for this line
-	unsigned char *codebytes; // actual code for this line
-	int codesize;			// size of codebytes
-// if minaddr and maxaddr are the same, we know exactly which address
-// we are at so there can be no possible phase error with symbols defined
-// here; these are *code* addresses
-	int len;				// length of this insn
-	int in_macro;			// set if it's a macro expansion line
-	int code_symloc;
-	int addrmode;			// addressing mode of this insn
-	int addr;				// the lowest possible address of this line
-	int dpval;				// dp value at this point in the code
-	int hassym;				// is there a symbol on this line
-	int addrset;			// is this insn a point where the address is *set* (org)
-	int isequ;				// does this insn set a symbol address (equ)?
-	int isset;				// is the address setting from a "set"?
-	int issetdp;			// this insn sets DP
-	int symaddr;			// address for the symbol (if we're setting one)
-							// also used for "setdp"
-	int undef;				// set if the symbol is undefined
-	int p1f16;				// if we forced 16 bit on pass 1 so we can force it on pass 2
-	int nocode;				// if set, there is no code to output (rmb)
-	int notinsn;			// if this is not a regular insn (used for formatting output)
-	char *line;				// the text of the line
-	char *opcstr;			// opcode string
-	char *operstr;			// operand string
-	char *remainder;		// remainder string (whole line if no opcode/operand
-	errortab_t *errors;		// errors on this line
-	sourceline_t *next;		// next line
-	sourceline_t *prev;		// previous line
-	macrotab_t *macro;		// pointer to macro table entry if this is a macro
-	int skipped;			// set if the line was skipped
-	char *user_error;		// user error message
-	int macrodef;			// set if it's a macro definition line
-};
-
-// structure to keep the symbol table
-typedef struct symtab_s symtab_t;
-struct symtab_s {
-	char *symbol; // symbol name
-	sourceline_t *line;			// pointer to the line where symbol is defined
-	int addr;					// address of symbol (-1 for unknown)
-	int flags;					// flags for symbol
-	symtab_t *next;				// next symbol
-};
-
+#define OUTPUT_OBJ		3	// proprietary object file format
 
 // keep track of current assembler state
 typedef struct {
-	int dpval;			// current dp value (setdp)
-	int addr;		// current address
-	symtab_t *symbol_table;
-	sourceline_t *source_head;
-	sourceline_t *source_tail;
-	int errorcount;		// error count
-	int passnum;		// which pass are we on?
-	const char *infile;	// input file
-	const char *outfile;// output file
-	const char *listfile;	// output listing file
-	int debug;			// debug mode
-	int outformat;		// output format type: 0 = decb, 1 = raw
-	int execaddr;		// execution address for the program (END ....)
-	macrotab_t *macros;	// pointer to macros
-	int inmacro;		// are we in a macro?
-	char *cur_namespace;	// current namespace prefix
-	int skipcond;		// are we skipping a condition?
-	int skipcount;		// number of endc we need before we stop skipping
-	int skipmacro;		// are we skipping a macro definition?
-	int noelse;			// skipped an else?
-	int pragmas;		// what pragmas are in effect?
+	int dpval;					// current dp value (setdp)
+	int addr;					// current address
+	int errorcount;				// error count
+	int passnum;				// which pass are we on?
+	const char *infile;			// input file
+	const char *outfile;		// output file
+	const char *listfile;		// output listing file
+	int debug;					// debug mode
+	int outformat;				// output format type
+	int execaddr;				// execution address for the program (END ....)
+	int pragmas;				// what pragmas are in effect?
 } asmstate_t;
 
 #define PRAGMA_NOINDEX0TONONE	1
 
-
-#ifndef __lwasm_c_seen__
-extern int eval_expr(asmstate_t *as, sourceline_t *cl, char **optr, int *val);
-extern void register_error(asmstate_t *as, sourceline_t *cl, int errcode);
-extern int lookupreg3(const char *rlist, char **str);
-extern int lookupreg(const char *reglist, char **str);
-extern void lwasm_read_file(asmstate_t *as, char *fname);
-extern void addcodebyte(asmstate_t *as, sourceline_t *cl, int cb);
-#endif
-
-#define SYMFLAG_NONE	0
-#define SYMFLAG_SET		1
-
 #ifndef __symtab_c_seen__
-#include <stdio.h>
-extern void register_symbol(asmstate_t *as, sourceline_t *cl, char *symstr, int val, int flags);
-extern int lookup_symbol(asmstate_t *as, char *symstr);
-extern void list_symbols(asmstate_t *as, FILE *f);
+//extern void register_symbol(asmstate_t *as, sourceline_t *cl, char *symstr, int val, int flags);
+//extern int lookup_symbol(asmstate_t *as, char *symstr);
+//extern void list_symbols(asmstate_t *as, FILE *f);
 #endif
 
 
-#ifndef __index_c_seen__
-extern int parse_index_expr(asmstate_t *as, sourceline_t *cl, char **optr, int *postbyte, int *opmode, int *v1);
-#endif
-
-#define emit(cb)	do { addcodebyte(as, cl, (cb)); } while (0)
-#define emitop(cb)	do { if ((cb) > 0xff) addcodebyte(as, cl, (cb)>>8); addcodebyte(as, cl, (cb) & 0xff); } while (0)
-#define errorp1(e)	do { if (as -> passnum == 1) register_error(as, cl, (e)); } while (0)
-#define errorp2(e)	do { if (as -> passnum == 2) register_error(as, cl, (e)); } while (0)
-
 #endif //__lwasm_h_seen__
--- a/src/main.c	Sat Oct 04 03:20:36 2008 +0000
+++ b/src/main.c	Wed Oct 22 04:51:16 2008 +0000
@@ -22,7 +22,9 @@
 
 */
 
+#ifdef HAVE_CONFIG_H
 #include "config.h"
+#endif
 
 #include <argp.h>
 #include <errno.h>
@@ -32,10 +34,8 @@
 #include "lwasm.h"
 
 // external declarations
-extern void resolve_phasing(asmstate_t *as);
-extern void generate_code(asmstate_t *as);
-extern void list_code(asmstate_t *as);
-extern void write_code(asmstate_t *as);
+extern void lwasm_pass1(asmstate_t *as);
+extern void lwasm_pass2(asmstate_t *as);
 
 
 // command line option handling
@@ -78,7 +78,11 @@
 		// raw binary output
 		as -> outformat = OUTPUT_RAW;
 		break;
-		
+	
+	case 0x100:
+		// proprietary object format
+		as -> outformat = OUTPUT_OBJ;
+	
 	case ARGP_KEY_END:
 		// done; sanity check
 		if (!as -> outfile)
@@ -112,6 +116,8 @@
 				"Generate raw binary format output"},
 	{ "rawrel",		0,		0,		0,
 				"Generate raw binary respecing ORG statements as offsets from the start of the file"},
+	{ "obj",		0,		0,		0,
+				"Generate proprietary object file format for later linking" },
 	{ 0 }
 };
 
@@ -133,23 +139,21 @@
 	argp_parse(&argp, argc, argv, 0, 0, &asmstate);
 	if (!asmstate.listfile)
 		asmstate.listfile = "-";
-	
-//	printf("Assembling %s to %s; list to %s\n", asmstate.infile, asmstate.outfile, asmstate.listfile);
 
 	/* pass 1 - collect the symbols and assign addresses where possible */
 	/* pass 1 also resolves included files, etc. */
 	/* that means files are read exactly once unless included multiple times */
-	lwasm_read_file(&asmstate, (char *)(asmstate.infile));
+	lwasm_pass1(&asmstate);
 	
 	// pass 2: actually generate the code; if any phasing errors appear
 	// at this stage, we have a bug
-	generate_code(&asmstate);
+	lwasm_pass2(&asmstate);
 
 	// now make a pretty listing
-	list_code(&asmstate);
+//	lwasm_list(&asmstate);
 
 	// now write the code out to the output file
-	write_code(&asmstate);
+//	lwasm_output(&asmstate);
 
 	if (asmstate.errorcount > 0)
 		exit(1);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pass1.c	Wed Oct 22 04:51:16 2008 +0000
@@ -0,0 +1,50 @@
+/*
+pass1.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/>.
+
+
+Handles first pass of assembly
+
+First pass involves the following:
+
+1. read all lines from the main source file, following all "include"
+   directives as appropriate
+2. parse each line into a symbol, operation code, and operand as appropriate
+3. each operand is evaluated for syntax and futher for value if there are
+   multiple addressing sizes available; any undefined or not fully resolved
+   value will default to the largest addressing size available (16 bit)
+4. addresses are assigned to every symbol defined in the assembly
+5. macros are defined and expanded at this pass
+
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <argp.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "lwasm.h"
+
+void lwasm_pass1(asmstate_t *as)
+{
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pass2.c	Wed Oct 22 04:51:16 2008 +0000
@@ -0,0 +1,38 @@
+/*
+pass2.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/>.
+
+
+Handles second pass of assembly
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <argp.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "lwasm.h"
+
+void lwasm_pass2(asmstate_t *as)
+{
+}