changeset 399:6153cb49403c

Initial commit of pragma newsource pragma newsource enables a source code variant as follows: 1. no line numbers 2. no implied comments at the end of lines 3. all comments must be introduced by a comment character 4. spaces are allowed in operands (4) is not quite complete. This commit handles "operandless" instructions (anything where the parser calls skip_operand()) and expression parsing.
author William Astle <lost@l-w.ca>
date Tue, 13 Oct 2015 23:38:02 -0600
parents 4cf907aa634c
children bbe5401a9bf3
files lwasm/lwasm.c lwasm/lwasm.h lwasm/pass1.c lwasm/pragma.c lwlib/lw_expr.c lwlib/lw_expr.h
diffstat 6 files changed, 89 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/lwasm/lwasm.c	Sun Oct 11 09:31:06 2015 -0600
+++ b/lwasm/lwasm.c	Tue Oct 13 23:38:02 2015 -0600
@@ -32,6 +32,15 @@
 #include "lwasm.h"
 #include "instab.h"
 
+void lwasm_skip_to_next_token(line_t *cl, char **p)
+{
+	if (CURPRAGMA(cl, PRAGMA_NEWSOURCE))
+	{
+		for (; **p && isspace(**p); (*p)++)
+			/* do nothing */ ;
+	}
+}
+
 int lwasm_expr_exportable(asmstate_t *as, lw_expr_t expr)
 {
 	return 0;
@@ -869,13 +878,20 @@
 	if (as->exprwidth != 16)	
 	{
 		lw_expr_setwidth(as->exprwidth);
-		e = lw_expr_parse(p, as);
+		if (CURPRAGMA(as -> cl, PRAGMA_NEWSOURCE))
+			e = lw_expr_parse(p, as);
+		else
+			e = lw_expr_parse_compact(p, as);
 		lw_expr_setwidth(0);
 	}
 	else
 	{
-		e = lw_expr_parse(p, as);
+		if (CURPRAGMA(as -> cl, PRAGMA_NEWSOURCE))
+			e = lw_expr_parse(p, as);
+		else
+			e = lw_expr_parse_compact(p, as);
 	}
+	lwasm_skip_to_next_token(as -> cl, p);
 	return e;
 }
 
@@ -921,8 +937,10 @@
 	return NULL;
 }
 
-void skip_operand(char **p)
+void skip_operand_real(line_t *cl, char **p)
 {
+	if (CURPRAGMA(cl, PRAGMA_NEWSOURCE))
+		return;
 	for (; **p && !isspace(**p); (*p)++)
 		/* do nothing */ ;
 }
--- a/lwasm/lwasm.h	Sun Oct 11 09:31:06 2015 -0600
+++ b/lwasm/lwasm.h	Tue Oct 13 23:38:02 2015 -0600
@@ -102,6 +102,7 @@
 	PRAGMA_M80EXT				= 1 << 21,	// enable Macro-80C assembler extensions
 	PRAGMA_6809CONV				= 1 << 22,	// enable 6809 convenience ops
 	PRAGMA_6309CONV				= 1 << 23,	// enable 6309 convenience ops
+	PRAGMA_NEWSOURCE			= 1 << 24,	// don't use compatibility source format
 	PRAGMA_CLEARBIT				= 1 << 31	// reserved to indicate negated pragma flag status
 };
 
@@ -444,7 +445,9 @@
 lw_expr_t lwasm_parse_expr(asmstate_t *as, char **p);
 int lwasm_emitexpr(line_t *cl, lw_expr_t expr, int s);
 
-void skip_operand(char **p);
+void skip_operand_real(line_t *l, char **p);
+/* this macro can only be used where "l" is the current line pointer */
+#define skip_operand(p) skip_operand_real(l, p)
 
 int lwasm_lookupreg2(const char *rlist, char **p);
 int lwasm_lookupreg3(const char *rlist, char **p);
@@ -472,4 +475,8 @@
 #define OPLEN(op) (((op)>0xFF)?2:1)
 #define CURPRAGMA(l,p)	(((l) && ((l)->pragmas & (p))) ? 1 : 0)
 
+/* some functions for parsing */
+/* skip to the start of the next token if the current parsing mode allows it */
+void lwasm_skip_to_next_token(line_t *cl, char **p);
+
 #endif /* ___lwasm_h_seen___ */
--- a/lwasm/pass1.c	Sun Oct 11 09:31:06 2015 -0600
+++ b/lwasm/pass1.c	Tue Oct 13 23:38:02 2015 -0600
@@ -38,7 +38,7 @@
 /*
 pass 1: parse the lines
 
-line format:
+line format if PRAGMA_NEWSOURCE is not in force:
 
 [<symbol>] <opcode> <operand>[ <comment>]
 
@@ -48,6 +48,14 @@
 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.
 
+Also, no spaces are permitted within <operand>.
+
+With PRAGMA_NEWSOURCE in effect, line numbers are not allowed and there
+is no automatic comment at the end of each line. All comments must be
+introduced with the comment character. This allows the parser to handle
+spaces in operands unambiguously so in this mode, spaces are permitted
+within operands.
+
 */
 void do_pass1(asmstate_t *as)
 {
@@ -174,12 +182,12 @@
 		}
 	
 		// skip comments
-		// commends do not create a context break
+		// comments do not create a context break
 		if (*line == '*' || *line == ';' || *line == '#')
 			goto nextline;
 
 		p1 = line;
-		if (isdigit(*p1))
+		if (isdigit(*p1) && !CURPRAGMA(cl, PRAGMA_NEWSOURCE))
 		{
 			// skip line number
 			while (*p1 && isdigit(*p1))
@@ -212,8 +220,6 @@
 		else
 			stspace = 0;
 
-//		if (*p1 == '*' || *p1 == ';' || *p1 == '#')
-//			goto nextline;
 		if (!*p1)
 		{
 			// nothing but whitespace - context break
@@ -235,7 +241,7 @@
 				p1++;
 			for (; *p1 && isspace(*p1); p1++)
 				/* do nothing */ ;
-			
+		
 			if (*p1 == '=')
 			{
 				tok = p1++;
@@ -263,12 +269,12 @@
 		}
 		if (*tok)
 		{
-			if (CURPRAGMA(cl, PRAGMA_TESTMODE))
-			{
-				/* in test mode, terminate the line here so we don't affect the parsers */
-				/* (cl -> ltext retains the full, unmodified string) */
-				char *t = strstr(p1, ";.");
-				if (t) *t = 0;
+			if (CURPRAGMA(cl, PRAGMA_TESTMODE))
+			{
+				/* in test mode, terminate the line here so we don't affect the parsers */
+				/* (cl -> ltext retains the full, unmodified string) */
+				char *t = strstr(p1, ";.");
+				if (t) *t = 0;
 			}
 
 			// look up operation code
@@ -371,10 +377,23 @@
 							else
 								cl -> dlen = cl -> len;
 						}
-						if (*p1 && !isspace(*p1) && !(cl -> err))
+						if (!CURPRAGMA(cl, PRAGMA_NEWSOURCE))
 						{
-							// flag bad operand error
-							lwasm_register_error2(as, cl, E_OPERAND_BAD, "(%s)", p1);
+							if (*p1 && !isspace(*p1) && !(cl -> err))
+							{
+								// flag bad operand error
+								lwasm_register_error2(as, cl, E_OPERAND_BAD, "(%s)", p1);
+							}
+						}
+						else
+						{
+							lwasm_skip_to_next_token(cl, &p1);
+							/* if we did not hit the end of the line and we aren't at a comment character, error out */
+							if (*p1 && *p1 != ';' && *p1 != '#' && *p1 != ';')
+							{
+								// flag bad operand error
+								lwasm_register_error2(as, cl, E_OPERAND_BAD, "%s", p1);
+							}
 						}
 						
 						/* do a reduction on the line expressions to avoid carrying excessive expression baggage if not needed */
--- a/lwasm/pragma.c	Sun Oct 11 09:31:06 2015 -0600
+++ b/lwasm/pragma.c	Tue Oct 13 23:38:02 2015 -0600
@@ -72,6 +72,8 @@
 	{ "m80ext", "nom80ext", PRAGMA_M80EXT },
 	{ "6809conv", "no6809conv", PRAGMA_6809CONV },
 	{ "6309conv", "no6309conv", PRAGMA_6309CONV },
+	{ "newsource", "nonewsource", PRAGMA_NEWSOURCE },
+	{ "nooldsource", "oldsource", PRAGMA_NEWSOURCE },
 	{ 0, 0, 0 }
 };
 
--- a/lwlib/lw_expr.c	Sun Oct 11 09:31:06 2015 -0600
+++ b/lwlib/lw_expr.c	Tue Oct 13 23:38:02 2015 -0600
@@ -36,6 +36,7 @@
 /* Q&D to break out of infinite recursion */
 static int level = 0;
 static int bailing = 0;
+static int parse_compact = 0;
 
 static void (*divzero)(void *priv) = NULL;
 
@@ -1141,7 +1142,7 @@
 following conditions:
 
 1. a NUL character
-2. a whitespace character
+2. a whitespace character (if parse mode is "COMPACT")
 3. a )
 4. a ,
 5. any character that is not recognized as a term
@@ -1155,19 +1156,29 @@
 
 lw_expr_t lw_expr_parse_expr(char **p, void *priv, int prec);
 
+static void lw_expr_parse_next_tok(char **p)
+{
+	if (parse_compact)
+		return;
+	for (; **p && isspace(**p); (*p)++)
+		/* do nothing */ ;
+}
+
 lw_expr_t lw_expr_parse_term(char **p, void *priv)
 {
 	lw_expr_t term, term2;
 	
 eval_next:
+	lw_expr_parse_next_tok(p);
+
 	if (!**p || isspace(**p) || **p == ')' || **p == ']')
 		return NULL;
-
 	// parentheses
 	if (**p == '(')
 	{
 		(*p)++;
 		term = lw_expr_parse_expr(p, priv, 0);
+		lw_expr_parse_next_tok(p);
 		if (**p != ')')
 		{
 			lw_expr_destroy(term);
@@ -1247,6 +1258,7 @@
 	int opern, i;
 	lw_expr_t term1, term2, term3;
 	
+	lw_expr_parse_next_tok(p);
 	if (!**p || isspace(**p) || **p == ')' || **p == ',' || **p == ']' || **p == ';')
 		return NULL;
 
@@ -1255,6 +1267,7 @@
 		return NULL;
 
 eval_next:
+	lw_expr_parse_next_tok(p);
 	if (!**p || isspace(**p) || **p == ')' || **p == ',' || **p == ']' || **p == ';')
 		return term1;
 	
@@ -1312,9 +1325,17 @@
 
 lw_expr_t lw_expr_parse(char **p, void *priv)
 {
+	parse_compact = 0;
 	return lw_expr_parse_expr(p, priv, 0);
 }
 
+lw_expr_t lw_expr_parse_compact(char **p, void *priv)
+{
+	parse_compact = 1;
+	return lw_expr_parse_expr(p, priv, 0);
+}
+	
+
 int lw_expr_testterms(lw_expr_t e, lw_expr_testfn_t *fn, void *priv)
 {
 	struct lw_expr_opers *o;
--- a/lwlib/lw_expr.h	Sun Oct 11 09:31:06 2015 -0600
+++ b/lwlib/lw_expr.h	Tue Oct 13 23:38:02 2015 -0600
@@ -90,6 +90,7 @@
 void lw_expr_set_term_parser(lw_expr_fn3_t *fn);
 
 lw_expr_t lw_expr_parse(char **p, void *priv);
+lw_expr_t lw_expr_parse_compact(char **p, void *priv);
 int lw_expr_istype(lw_expr_t e, int t);
 int lw_expr_intval(lw_expr_t e);
 int lw_expr_specint(lw_expr_t e);