changeset 108:9960e05cbe3a

Added *pragmapush and *pragmapop; still seems to be nonfunctional
author lost@l-w.ca
date Sun, 07 Aug 2011 00:58:00 -0600
parents b3557f8325f7
children 6a919c3ca0e9
files lwasm/input.c lwasm/input.h lwasm/instab.c lwasm/pragma.c
diffstat 4 files changed, 196 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/lwasm/input.c	Sat Aug 06 23:29:17 2011 -0600
+++ b/lwasm/input.c	Sun Aug 07 00:58:00 2011 -0600
@@ -35,6 +35,7 @@
 #include <lw_error.h>
 
 #include "lwasm.h"
+#include "input.h"
 
 /*
 Data type for storing input buffers
@@ -51,6 +52,12 @@
 	input_type_error			// invalid input type
 };
 
+struct input_stack_node
+{
+	input_stack_entry *entry;
+	struct input_stack_node *next;
+};
+
 struct input_stack
 {
 	struct input_stack *next;
@@ -58,6 +65,7 @@
 	void *data;
 	int data2;
 	char *filespec;
+	struct input_stack_node *stack;
 };
 
 static char *make_filename(char *p, char *f)
@@ -135,6 +143,7 @@
 	t -> data = lw_strdup(str);
 	t -> data2 = 0;
 	t -> next = IS;
+	t -> stack = NULL;
 	as -> input_data = t;
 //	t -> filespec = lw_strdup(s);
 }
@@ -170,6 +179,7 @@
 		lw_free(ts);
 	}
 	t -> next = as -> input_data;
+	t -> stack = NULL;
 	as -> input_data = t;
 	
 	switch (IS -> type)
@@ -434,3 +444,39 @@
 		return IS -> filespec;
 	return NULL;
 }
+
+void input_stack_push(asmstate_t *as, input_stack_entry *e)
+{
+	struct input_stack_node *n;
+
+	n = lw_alloc(sizeof(struct input_stack_node));	
+	n -> next = IS -> stack;
+	n -> entry = e;
+}
+
+input_stack_entry *input_stack_pop(asmstate_t *as, int magic, int (*fn)(input_stack_entry *e, void *data), void *data)
+{
+	struct input_stack_node *n, *n2;
+	input_stack_entry *e2;
+	
+	n2 = NULL;
+	for (n = IS -> stack; n; n = n -> next)
+	{
+		if (n -> entry -> magic == magic)
+		{
+			if ((*fn)(n -> entry, data))
+			{
+				/* we have a match */
+				e2 = n -> entry;
+				if (n2)
+					n2 -> next = n -> next;
+				else
+					IS -> stack = n -> next;
+				lw_free(n);
+				return e2;
+			}
+		}
+		n2 = n;
+	}
+	return NULL;
+}
--- a/lwasm/input.h	Sat Aug 06 23:29:17 2011 -0600
+++ b/lwasm/input.h	Sun Aug 07 00:58:00 2011 -0600
@@ -24,6 +24,14 @@
 
 #include "lwasm.h"
 
+typedef struct
+{
+  int magic;
+} input_stack_entry;
+
+extern void input_stack_push(asmstate_t *as, input_stack_entry *se);
+extern input_stack_entry *input_stack_pop(asmstate_t *as, int magic, int (*fn)(input_stack_entry *e, void *data), void *data);
+
 extern void input_init(asmstate_t *as);
 extern void input_openstring(asmstate_t *as, char *s, char *str);
 extern void input_open(asmstate_t *as, char *s);
--- a/lwasm/instab.c	Sat Aug 06 23:29:17 2011 -0600
+++ b/lwasm/instab.c	Sun Aug 07 00:58:00 2011 -0600
@@ -239,6 +239,14 @@
 #define pseudo_resolve_starpragma NULL
 #define pseudo_emit_starpragma NULL
 
+extern PARSEFUNC(pseudo_parse_starpragmapush);
+#define pseudo_resolve_starpragmapush NULL
+#define pseudo_emit_starpragmapush NULL
+
+extern PARSEFUNC(pseudo_parse_starpragmapop);
+#define pseudo_resolve_starpragmapop NULL
+#define pseudo_emit_starpragmapop NULL
+
 extern PARSEFUNC(pseudo_parse_section);
 #define pseudo_resolve_section NULL
 #define pseudo_emit_section NULL
@@ -634,6 +642,9 @@
 
 	{ "pragma",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_pragma,	pseudo_resolve_pragma,			pseudo_emit_pragma,			lwasm_insn_normal},
 	{ "*pragma",	{	-1, 	-1, 	-1, 	-1},	pseudo_parse_starpragma,pseudo_resolve_starpragma,		pseudo_emit_starpragma,		lwasm_insn_normal},
+	{ "*pragmapush",	{	-1,	-1, 	-1,	-1},	pseudo_parse_starpragmapush, pseudo_resolve_starpragmapush, pseudo_emit_starpragmapush,	lwasm_insn_normal},
+	{ "*pragmappop",	{	-1,	-1, 	-1,	-1},	pseudo_parse_starpragmapop, pseudo_resolve_starpragmapop, pseudo_emit_starpragmapop,	lwasm_insn_normal},
+	
 	
 	// for os9 target
 	{ "os9",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_os9,		pseudo_resolve_os9,				pseudo_emit_os9,			lwasm_insn_normal},
--- a/lwasm/pragma.c	Sat Aug 06 23:29:17 2011 -0600
+++ b/lwasm/pragma.c	Sun Aug 07 00:58:00 2011 -0600
@@ -27,37 +27,34 @@
 
 #include "lwasm.h"
 #include "instab.h"
+#include "input.h"
 
 struct pragma_list
 {
-	const char *str;
+	const char *setstr;
+	const char *resetstr;
 	int flag;
 };
 
+struct pragma_stack_entry
+{
+	int magic;	// must always be at the start of any input stack entry
+	int flag;	// the pragma flag bit
+	char str[1];	// magic number - this will be allocated bigger
+			// string will be what's needed to re-instate a pragma
+};
+
 static const struct pragma_list set_pragmas[] =
 {
-	{ "dollarnotlocal", PRAGMA_DOLLARNOTLOCAL },
-	{ "noindex0tonone", PRAGMA_NOINDEX0TONONE },
-	{ "undefextern", PRAGMA_UNDEFEXTERN },
-	{ "cescapes", PRAGMA_CESCAPES },
-	{ "importundefexport", PRAGMA_IMPORTUNDEFEXPORT },
-	{ "pcaspcr", PRAGMA_PCASPCR },
-	{ "shadow", PRAGMA_SHADOW },
-	{ "nolist", PRAGMA_NOLIST },
-	{ 0, 0 }
-};
-
-static const struct pragma_list reset_pragmas[] =
-{
-	{ "nodollarnotlocal", PRAGMA_DOLLARNOTLOCAL },
-	{ "index0tonone", PRAGMA_NOINDEX0TONONE },
-	{ "noundefextern", PRAGMA_UNDEFEXTERN },
-	{ "nocescapes", PRAGMA_CESCAPES },
-	{ "noimportundefexport", PRAGMA_IMPORTUNDEFEXPORT },
-	{ "nopcaspcr", PRAGMA_PCASPCR },
-	{ "noshadow", PRAGMA_SHADOW },
-	{ "list", PRAGMA_NOLIST },
-	{ 0, 0 }
+	{ "dollarnotlocal", "nodollarnotlocal", PRAGMA_DOLLARNOTLOCAL },
+	{ "noindex0tonone", "index0tonone", PRAGMA_NOINDEX0TONONE },
+	{ "undefextern", "noundefextern", PRAGMA_UNDEFEXTERN },
+	{ "cescapes", "nocescapes", PRAGMA_CESCAPES },
+	{ "importundefexport", "noimportundefexport", PRAGMA_IMPORTUNDEFEXPORT },
+	{ "pcaspcr", "nopcaspcr", PRAGMA_PCASPCR },
+	{ "shadow", "noshadow", PRAGMA_SHADOW },
+	{ "nolist", "list", PRAGMA_NOLIST },
+	{ 0, 0, 0}
 };
 
 int parse_pragma_string(asmstate_t *as, char *str, int ignoreerr)
@@ -70,19 +67,16 @@
 	while (np)
 	{
 		p = lw_token(np, ',', &np);
-		for (i = 0; set_pragmas[i].str; i++)
+		for (i = 0; set_pragmas[i].setstr; i++)
 		{
-			if (!strcasecmp(p, set_pragmas[i].str))
+			if (!strcasecmp(p, set_pragmas[i].setstr))
 			{
 				pragmas |= set_pragmas[i].flag;
 				goto out;
 			}
-		}
-		for (i = 0; reset_pragmas[i].str; i++)
-		{
-			if (!strcasecmp(p, reset_pragmas[i].str))
+			if (!strcasecmp(p, set_pragmas[i].resetstr))
 			{
-				pragmas &= ~(reset_pragmas[i].flag);
+				pragmas &= ~(set_pragmas[i].flag);
 				goto out;
 			}
 		}
@@ -138,3 +132,110 @@
 		l -> pragmas |= PRAGMA_NOLIST;
 	lw_free(ps);
 }
+
+static int pragma_stack_compare(input_stack_entry *e, void *d)
+{
+	int flag = *((int *)d);
+	struct pragma_stack_entry *pse = (struct pragma_stack_entry *)e;
+	
+	if (pse -> flag == flag)
+		return 1;
+	return 0;
+}
+
+PARSEFUNC(pseudo_parse_starpragmapop)
+{
+	char *ps, *t;
+	char *pp;
+	int i;
+	const char *np;
+	struct pragma_stack_entry *pse;
+	
+	for (t = *p; *t && !isspace(*t); t++)
+		/* do nothing */ ;
+	
+	ps = lw_strndup(*p, t - *p);
+	*p = t;
+	
+	l -> len = 0;
+	
+	// *pragma stuff must never throw an error
+	np = ps;
+
+	while (np)
+	{
+		pp = lw_token(np, ',', &np);
+		for (i = 0; set_pragmas[i].setstr; i++)
+		{
+			if (!strcasecmp(pp, set_pragmas[i].setstr) || !strcasecmp(pp, set_pragmas[i].resetstr))
+			{
+				pse = (struct pragma_stack_entry *)input_stack_pop(as, 0x42424242, pragma_stack_compare, (void *)&(set_pragmas[i].flag));
+				if (pse)
+				{
+					parse_pragma_string(as, (char *)&(pse->str), 1);
+					lw_free(pse);
+				}
+				if (set_pragmas[i].flag == PRAGMA_NOLIST)
+					l -> pragmas |= PRAGMA_NOLIST;
+			}
+		}
+		lw_free(pp);
+	}
+
+	lw_free(ps);
+}
+
+PARSEFUNC(pseudo_parse_starpragmapush)
+{
+	char *ps, *t;
+	char *pp;
+	int i;
+	const char *np;
+	struct pragma_stack_entry *pse;
+	
+	for (t = *p; *t && !isspace(*t); t++)
+		/* do nothing */ ;
+	
+	ps = lw_strndup(*p, t - *p);
+	*p = t;
+	
+	l -> len = 0;
+	
+	// *pragma stuff must never throw an error
+	np = ps;
+
+	while (np)
+	{
+		pp = lw_token(np, ',', &np);
+		for (i = 0; set_pragmas[i].setstr; i++)
+		{
+			if (!strcasecmp(pp, set_pragmas[i].setstr) || !strcasecmp(pp, set_pragmas[i].resetstr))
+			{
+				/* found set or reset pragma */
+				/* push pragma state */
+				if (as -> pragmas & (set_pragmas[i].flag))
+				{
+					/* use set string */
+					t = (char *)set_pragmas[i].setstr;
+				}
+				else
+				{
+					/* use reset string */
+					t = (char *)set_pragmas[i].resetstr;
+				}
+				pse = lw_alloc(sizeof(struct pragma_stack_entry) + strlen(t));
+				pse -> flag = set_pragmas[i].flag;
+				pse -> magic = 0x42424242;
+				strcpy((char *)&(pse -> str), t);
+				input_stack_push(as, (input_stack_entry *)pse);
+				
+				if (set_pragmas[i].flag == PRAGMA_NOLIST)
+					l -> pragmas |= PRAGMA_NOLIST;
+			}
+		}
+		lw_free(pp);
+	}
+
+	lw_free(ps);
+}
+