static SYM * curmac; // Macro currently being defined
static VALUE argno; // Formal argument count
-static LONG * firstrpt; // First .rept line
-static LONG * nextrpt; // Last .rept line
+static LLIST * firstrpt; // First .rept line
+static LLIST * nextrpt; // Last .rept line
static int rptlevel; // .rept nesting level
// Function prototypes
int ExitMacro(void)
{
WARNING(!!! Bad macro exiting !!!)
-
/*
This is a problem. Currently, the argument logic just keeps the current
arguments and doesn't save anything if a new macro is called in the middle
//
int defmac2(char * argname)
{
- SYM * arg;
-
if (lookup(argname, MACARG, (int)curmac->sattr) != NULL)
return error("multiple formal argument definition");
- arg = NewSymbol(argname, MACARG, (int)curmac->sattr);
+ SYM * arg = NewSymbol(argname, MACARG, (int)curmac->sattr);
arg->svalue = argno++;
return OK;
#else
if (curmac->lineList == NULL)
{
- curmac->lineList = malloc(sizeof(struct LineList));
+ curmac->lineList = malloc(sizeof(LLIST));
curmac->lineList->next = NULL;
curmac->lineList->line = strdup(ln);
curmac->last = curmac->lineList;
}
else
{
- curmac->last->next = malloc(sizeof(struct LineList));
+ curmac->last->next = malloc(sizeof(LLIST));
curmac->last->next->next = NULL;
curmac->last->next->line = strdup(ln);
curmac->last = curmac->last->next;
//
// Add lines to a .rept definition
//
-int defr1(char * ln, int kwno)
+int defr1(char * line, int kwno)
{
if (list_flag)
{
- listeol(); // Flush previous source line
- lstout('#'); // Mark this a 'rept' block
+ listeol(); // Flush previous source line
+ lstout('#'); // Mark this a 'rept' block
}
- switch (kwno)
+ if (kwno == 0) // .endr
{
- case 0: // .endr
if (--rptlevel == 0)
return 0;
-
- break;
- case 1: // .rept
- rptlevel++;
}
+ else if (kwno == 1) // .rept
+ rptlevel++;
+//DEBUG { printf(" defr1: line=\"%s\", kwno=%d, rptlevel=%d\n", line, kwno, rptlevel); }
+
+#if 0
//MORE stupidity here...
WARNING("!!! Casting (char *) as LONG !!!")
// Allocate length of line + 1('\0') + LONG
- LONG len = strlen(ln) + 1 + sizeof(LONG);
- LONG * p = (LONG *)malloc(len);
+ LONG * p = (LONG *)malloc(strlen(line) + 1 + sizeof(LONG));
*p = 0;
-
- strcpy((char *)(p + 1), ln);
+ strcpy((char *)(p + 1), line);
if (nextrpt == NULL)
- {
firstrpt = p; // First line of rept statement
- }
else
- {
*nextrpt = (LONG)p;
- }
nextrpt = p;
+#else
+ if (firstrpt == NULL)
+ {
+ firstrpt = malloc(sizeof(LLIST));
+ firstrpt->next = NULL;
+ firstrpt->line = strdup(line);
+ nextrpt = firstrpt;
+ }
+ else
+ {
+ nextrpt->next = malloc(sizeof(LLIST));
+ nextrpt->next->next = NULL;
+ nextrpt->next->line = strdup(line);
+ nextrpt = nextrpt->next;
+ }
+#endif
return rptlevel;
}
//
-// Define a .rept block, this gets hairy because they can be nested
+// Handle a .rept block; this gets hairy because they can be nested
//
-int DefineRept(void)
+int HandleRept(void)
{
VALUE eval;
rptlevel = 1;
LNCatch(defr1, "endr rept ");
+//DEBUG { printf("HandleRept: firstrpt=$%X\n", firstrpt); }
// Alloc and init input object
if (firstrpt)
{
//
// Hand off lines of text to the function 'lnfunc' until a line containing one
-// of the directives in 'dirlist' is encountered. Return the number of the
-// keywords encountered (0..n)
+// of the directives in 'dirlist' is encountered.
//
-// 'dirlist' contains null-seperated terminated keywords. A final null
-// terminates the list. Directives are compared to the keywords without regard
-// to case.
+// 'dirlist' contains space-separated terminated keywords. A final space
+// terminates the list. Directives are case-insensitively compared to the
+// keywords.
//
// If 'lnfunc' is NULL, then lines are simply skipped.
// If 'lnfunc' returns an error, processing is stopped.
//
static int LNCatch(int (* lnfunc)(), char * dirlist)
{
- char * p;
- int k;
-
if (lnfunc != NULL)
lnsave++; // Tell tokenizer to keep lines
- for(;;)
+ while (1)
{
if (TokenizeLine() == TKEOF)
{
// Test for end condition. Two cases to handle:
// <directive>
// symbol: <directive>
- p = NULL;
- k = -1;
+ char * p = NULL;
+ int k = -1;
if (*tok == SYMBOL)
{
+ // A string followed by a colon or double colon is a symbol and
+ // *not* a directive, see if we can find the directive after it
if ((tok[2] == ':' || tok[2] == DCOLON))
{
- if (tok[3] == SYMBOL) // label: symbol
+ if (tok[3] == SYMBOL)
p = string[tok[4]];
}
else
{
- p = string[tok[1]]; // Symbol
+ // Otherwise, just grab the directive
+ p = string[tok[1]];
}
}
if (p != NULL)
{
- if (*p == '.') // ignore leading '.'s
+ if (*p == '.') // Ignore leading periods
p++;
k = KWMatch(p, dirlist);
if (lnfunc != NULL)
k = (*lnfunc)(lnbuf, k);
- if (!k)
+ if (k == 0)
break;
}
//
-// See if the string `kw' matches one of the keywords in `kwlist'. If so,
-// return the number of the keyword matched. Return -1 if there was no match.
+// See if the string `kw' matches one of the keywords in `kwlist'. If so,
+// return the number of the keyword matched. Return -1 if there was no match.
// Strings are compared without regard for case.
//
static int KWMatch(char * kw, char * kwlist)