char lntag; // Line tag
char * curfname; // Current filename
char tolowertab[128]; // Uppercase ==> lowercase
-char hextab[128]; // Table of hex values
+int8_t hextab[128]; // Table of hex values
char dotxtab[128]; // Table for ".b", ".s", etc.
char irbuf[LNSIZ]; // Text for .rept block line
char lnbuf[LNSIZ]; // Text of current line
if (dst >= edst)
goto overflow;
+ // Skip comments in case a loose @ or \ is in there
+ // In that case the tokeniser was trying to expand it.
+ if (*s == '*' || *s == ';' || ((*s == '/') && (*(s + 1) == '/')))
+ goto skipcomments;
+
*dst++ = *s++;
}
// Do macro expansion
}
}
+skipcomments:
+
*dst = EOS;
DEBUG { printf("ExM: dst=\"%s\"\n", dest); }
return OK;
{
// Pop IFENT levels until we reach the conditional assembly context we
// were at when the input object was entered.
+ int numUnmatched = 0;
+
while (ifent != inobj->in_ifent)
{
- if (d_endif() != 0) // Something bad happened during endif parsing?
- return -1; // If yes, bail instead of getting stuck in a loop
+ if (d_endif() != 0) // Something bad happened during endif parsing?
+ return -1; // If yes, bail instead of getting stuck in a loop
+
+ numUnmatched++;
}
- tok = inobj->in_otok; // Restore tok and otok
+ // Give a warning to the user that we had to wipe their bum for them
+ if (numUnmatched > 0)
+ warni("missing %d .endif(s)", numUnmatched);
+
+ tok = inobj->in_otok; // Restore tok and otok
etok = inobj->in_etok;
switch (inobj->in_type)
{
- case SRC_IFILE: // Pop and release an IFILE
+ case SRC_IFILE: // Pop and release an IFILE
if (debug)
printf("[Leaving: %s]\n", curfname);
if ((ln = GetNextLine()) == NULL)
{
if (debug) printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n");
- if (fpop()==0) // Pop input level
+ if (fpop() == 0) // Pop input level
goto retry; // Try for more lines
else
{
v = 0; // Assume no DOT attrib follows symbol
stuffnull = 1;
+
+ // In some cases, we need to check for a DOTx at the *beginning*
+ // of a symbol, as the "start" of the line we're currently looking
+ // at could be somewhere in the middle of that line!
+ if (*ln == '.')
+ {
+ // Make sure that it's *only* a .[bwsl] following, and not the
+ // start of a local symbol:
+ if ((chrtab[*(ln + 1)] & DOT)
+ && (dotxtab[*(ln + 1)] != 0)
+ && !(chrtab[*(ln + 2)] & CTSYM))
+ {
+ // We found a legitimate DOTx construct, so add it to the
+ // token stream:
+ ln++;
+ stuffnull = 0;
+ *tk++ = (TOKEN)dotxtab[*ln++];
+ continue;
+ }
+ }
+
p = nullspot = ln++; // Nullspot -> start of this symbol
// Find end of symbol (and compute its length)
// the chararacter after THAT one must not have a start-symbol
// attribute (to prevent symbols that look like, for example,
// "zingo.barf", which might be a good idea anyway....)
- if ((((int)chrtab[*ln] & DOT) == 0) || ((int)dotxtab[*ln] <= 0))
- return error("[bwsl] must follow `.' in symbol");
+ if (((chrtab[*ln] & DOT) == 0) || (dotxtab[*ln] == 0))
+ return error("[bwsl] must follow '.' in symbol");
v = (VALUE)dotxtab[*ln++];
- if ((int)chrtab[*ln] & CTSYM)
- return error("misuse of `.', not allowed in symbols");
+ if (chrtab[*ln] & CTSYM)
+ return error("misuse of '.', not allowed in symbols");
}
// If the symbol is small, check to see if it's really the name of
}
// If not tokenized keyword OR token was not found
- if (j < 0 || state < 0)
+ if ((j < 0) || (state < 0))
{
*tk++ = SYMBOL;
//#warning
// auto-optimise? I think it's ok for now...
if (*ln == '.')
{
- if (obj_format == ALCYON)
- {
- if ((*(ln + 1) == 'b') || (*(ln + 1) == 'B') || (*(ln + 1) == 'w') || (*(ln + 1) == 'W') || (*(ln + 1) == 'l') || (*(ln + 1) == 'L'))
- {
- ln += 2;
- }
- }
- else
+ if (obj_format == BSD)
{
if ((*(ln + 1) & 0xDF) == 'B')
{
*tk++ = CONST;
*tk++ = v;
+
+ if (obj_format == ALCYON)
+ {
+ if ((*(ln + 1) == 'w') || (*(ln + 1) == 'W'))
+ {
+ *tk++ = DOTW;
+ ln += 2;
+ }
+ else if ((*(ln + 1) == 'l') || (*(ln + 1) == 'L'))
+ {
+ *tk++ = DOTL;
+ ln += 2;
+ }
+ }
}
else
*tk++ = '$';