changeset 384:6ee9c67a0f8d

Add conditional for testing if a pragma is in effect An obvious addition that took someone else to notice... Thanks to Erik G <erik@6809.org> for the patch.
author William Astle <lost@l-w.ca>
date Mon, 13 Jul 2015 21:20:30 -0600
parents 04e11f6faead
children 4fd16faa4d93
files lwasm/instab.c lwasm/lwasm.h lwasm/pragma.c lwasm/pseudo.c
diffstat 4 files changed, 94 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/lwasm/instab.c	Mon Jul 13 21:19:38 2015 -0600
+++ b/lwasm/instab.c	Mon Jul 13 21:20:30 2015 -0600
@@ -244,6 +244,10 @@
 #define pseudo_resolve_ifndef NULL
 #define pseudo_emit_ifndef NULL
 
+PARSEFUNC(pseudo_parse_ifpragma);
+#define pseudo_resolve_ifpragma NULL
+#define pseudo_emit_ifpragma NULL
+
 PARSEFUNC(pseudo_parse_ifstr);
 #define pseudo_resolve_ifstr NULL
 #define pseudo_emit_ifstr NULL
@@ -657,6 +661,8 @@
 	{ "else",		{	-1, 	-1, 	-1, 	-1}, 	pseudo_parse_else,		pseudo_resolve_else,			pseudo_emit_else,			lwasm_insn_cond},
 	{ "ifdef",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_ifdef,		pseudo_resolve_ifdef,			pseudo_emit_ifdef,			lwasm_insn_cond},
 	{ "ifndef",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_ifndef,	pseudo_resolve_ifndef,			pseudo_emit_ifndef,			lwasm_insn_cond},
+	{ "ifpragma",	{	-1, 	-1, 	-1, 	-1}, 	pseudo_parse_ifpragma,	pseudo_resolve_ifpragma,		pseudo_emit_ifpragma,		lwasm_insn_cond},
+	{ "ifopt",		{	-1, 	-1, 	-1, 	-1}, 	pseudo_parse_ifpragma,	pseudo_resolve_ifpragma,		pseudo_emit_ifpragma,		lwasm_insn_cond},
 
 	// string operations, mostly useful in macros
 	{ "ifstr",		{	-1,		-1,		-1,		-1},	pseudo_parse_ifstr,		pseudo_resolve_ifstr,			pseudo_emit_ifstr,			lwasm_insn_cond},
--- a/lwasm/lwasm.h	Mon Jul 13 21:19:38 2015 -0600
+++ b/lwasm/lwasm.h	Mon Jul 13 21:20:30 2015 -0600
@@ -99,7 +99,8 @@
 	PRAGMA_CT					= 1 << 18,	// enable cycle count running total
 	PRAGMA_CC					= 1 << 19,	// clear cycle count running total
 	PRAGMA_QRTS					= 1 << 20,	// enable BRA ?RTS support
-	PRAGMA_M80EXT				= 1 << 21	// enable Macro-80C assembler extensions
+	PRAGMA_M80EXT				= 1 << 21,	// enable Macro-80C assembler extensions
+	PRAGMA_CLEARBIT				= 1 << 31	// reserved to indicate negated pragma flag status
 };
 
 enum
@@ -419,6 +420,8 @@
 struct symtabe *register_symbol(asmstate_t *as, line_t *cl, char *sym, lw_expr_t value, int flags);
 struct symtabe *lookup_symbol(asmstate_t *as, line_t *cl, char *sym);
 
+int parse_pragma_helper(char *p);
+
 int lwasm_cycle_calc_ind(line_t *cl);
 int lwasm_cycle_calc_rlist(line_t *cl);
 void lwasm_cycle_update_count(line_t *cl, int opc);
--- a/lwasm/pragma.c	Mon Jul 13 21:19:38 2015 -0600
+++ b/lwasm/pragma.c	Mon Jul 13 21:20:30 2015 -0600
@@ -73,40 +73,48 @@
 	{ 0, 0, 0 }
 };
 
+int parse_pragma_helper(char *p)
+{
+	int i;
+
+	for (i = 0; set_pragmas[i].setstr; i++)
+	{
+		if (!strcasecmp(p, set_pragmas[i].setstr))
+		{
+			return set_pragmas[i].flag;
+			return 1;
+		}
+		if (!strcasecmp(p, set_pragmas[i].resetstr))
+		{
+			return set_pragmas[i].flag | PRAGMA_CLEARBIT;
+			return 2;
+		}
+	}
+
+	return 0;
+}
+
 int parse_pragma_string(asmstate_t *as, char *str, int ignoreerr)
 {
 	char *p;
-	int i;
 	const char *np = str;
-	int pragmas = as -> pragmas;
+	int pragma;
 
 	while (np)
 	{
 		p = lw_token(np, ',', &np);
-		debug_message(as, 200, "Setting pragma %s", p);
-		for (i = 0; set_pragmas[i].setstr; i++)
-		{
-			if (!strcasecmp(p, set_pragmas[i].setstr))
-			{
-				pragmas |= set_pragmas[i].flag;
-				goto out;
-			}
-			if (!strcasecmp(p, set_pragmas[i].resetstr))
-			{
-				pragmas &= ~(set_pragmas[i].flag);
-				goto out;
-			}
-		}
-		/* unrecognized pragma here */
-		if (!ignoreerr)
-		{
-			lw_free(p);
+		debug_message(as, 200, "Setting/resetting pragma %s", p);
+		pragma = parse_pragma_helper(p);
+		lw_free(p);
+
+		if (pragma == 0 && !ignoreerr)
 			return 0;
-		}
-	out:	
-		lw_free(p);
+
+		if (pragma & PRAGMA_CLEARBIT)
+			as->pragmas &= ~pragma;
+		else
+			as->pragmas |= pragma;
 	}
-	as -> pragmas = pragmas;
 	return 1;
 }
 
--- a/lwasm/pseudo.c	Mon Jul 13 21:19:38 2015 -0600
+++ b/lwasm/pseudo.c	Mon Jul 13 21:20:30 2015 -0600
@@ -1369,6 +1369,58 @@
 	}
 }
 
+PARSEFUNC(pseudo_parse_ifpragma)
+{
+	char *pstr;
+	int i;
+	int pragma;
+	int compare;
+
+	l -> len = 0;
+	l -> hideline = 1;
+
+	if (as -> skipcond && !(as -> skipmacro))
+	{
+		as -> skipcount++;
+		skip_operand(p);
+		return;
+	}
+
+again:
+	for (i = 0; (*p)[i] && !isspace((*p)[i]) && (*p)[i] != '|' && (*p)[i] != '&'; i++)
+		/* do nothing */;
+
+	pstr = lw_strndup(*p, i);
+	(*p) += i;
+
+	pragma = parse_pragma_helper(pstr);
+	if (!pragma) lwasm_register_error(as, l, E_PRAGMA_UNRECOGNIZED);
+
+	lw_free(pstr);
+
+	if (pragma & PRAGMA_CLEARBIT)
+	{
+		pragma &= ~PRAGMA_CLEARBIT;			/* strip off flag bit */
+		compare = l -> pragmas & pragma ? 0 : 1;
+	}
+	else
+	{
+		compare = l -> pragmas & pragma;
+	}
+
+	if (!compare)
+	{
+		if (**p == '|')
+		{
+			(*p)++;
+			goto again;
+		}
+		as -> skipcond = 1;
+		as -> skipcount = 1;
+	}
+	skip_operand(p);
+}
+
 PARSEFUNC(pseudo_parse_error)
 {
 	lwasm_register_error2(as, l, E_USER_SPECIFIED, "%s", *p);