X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=blobdiff_plain;f=macro.c;h=22bd0d9f7c444d4824228cab8307e82c648c9f85;hp=54d34c43687b3cae932b9c7b5387e55b36a9ce99;hb=HEAD;hpb=eace4e1b294ccec54a5c476619f616f5da0bf8a9 diff --git a/macro.c b/macro.c index 54d34c4..8da9bcb 100644 --- a/macro.c +++ b/macro.c @@ -1,7 +1,7 @@ // -// RMAC - Reboot's Macro Assembler for all Atari computers +// RMAC - Renamed Macro Assembler for all Atari computers // MACRO.C - Macro Definition and Invocation -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2021 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // @@ -22,11 +22,12 @@ int macnum; // Unique number for macro definition static LONG macuniq; // Unique-per-macro number static SYM * curmac; // Macro currently being defined -static uint32_t argno; // Formal argument count +static uint32_t argno; // Formal argument count +LONG reptuniq; // Unique-per-rept number static LLIST * firstrpt; // First .rept line static LLIST * nextrpt; // Last .rept line -static int rptlevel; // .rept nesting level +int rptlevel; // .rept nesting level // Function prototypes static int KWMatch(char *, char *); @@ -40,6 +41,7 @@ void InitMacro(void) { macuniq = 0; macnum = 1; + reptuniq = 0; } @@ -117,6 +119,7 @@ int defmac1(char * ln, int notEndFlag) curmac->lineList = malloc(sizeof(LLIST)); curmac->lineList->next = NULL; curmac->lineList->line = strdup(ln); + curmac->lineList->lineno = curlineno; curmac->last = curmac->lineList; } else @@ -124,6 +127,7 @@ int defmac1(char * ln, int notEndFlag) curmac->last->next = malloc(sizeof(LLIST)); curmac->last->next->next = NULL; curmac->last->next->line = strdup(ln); + curmac->lineList->lineno = curlineno; curmac->last = curmac->last->next; } @@ -170,7 +174,7 @@ int DefineMacro(void) { argno = 0; symlist(defmac2); - at_eol(); + ErrorIfNotAtEOL(); } // Suck in the macro definition; we're looking for an ENDM symbol on a line @@ -224,6 +228,7 @@ WARNING("!!! Casting (char *) as LONG !!!") firstrpt = malloc(sizeof(LLIST)); firstrpt->next = NULL; firstrpt->line = strdup(line); + firstrpt->lineno = curlineno; nextrpt = firstrpt; } else @@ -231,6 +236,7 @@ WARNING("!!! Casting (char *) as LONG !!!") nextrpt->next = malloc(sizeof(LLIST)); nextrpt->next->next = NULL; nextrpt->next->line = strdup(line); + nextrpt->next->lineno = curlineno; nextrpt = nextrpt->next; } #endif @@ -402,41 +408,75 @@ int InvokeMacro(SYM * mac, WORD siz) // Parse out the arguments and set them up correctly TOKEN * p = imacro->argument[nargs].token; int stringNum = 0; + int numTokens = 0; while (*tok != EOL) { if (*tok == ACONST) { + // Sanity checking (it's numTokens + 1 because we need an EOL + // if we successfully parse this argument) + if ((numTokens + 3) >= TS_MAXTOKENS) + return error("Too many tokens in argument #%d in MACRO invocation", nargs + 1); + for(int i=0; i<3; i++) *p++ = *tok++; + + numTokens += 3; } else if (*tok == CONST) // Constants are 64-bits { + // Sanity checking (it's numTokens + 1 because we need an EOL + // if we successfully parse this argument) + if ((numTokens + 3) >= TS_MAXTOKENS) + return error("Too many tokens in argument #%d in MACRO invocation", nargs + 1); + *p++ = *tok++; // Token uint64_t *p64 = (uint64_t *)p; uint64_t *tok64 = (uint64_t *)tok; *p64++ = *tok64++; tok = (TOKEN *)tok64; p = (uint32_t *)p64; + numTokens += 3; } else if ((*tok == STRING) || (*tok == SYMBOL)) { + // Sanity checking (it's numTokens + 1 because we need an EOL + // if we successfully parse this argument) + if (stringNum >= TS_MAXSTRINGS) + return error("Too many strings in argument #%d in MACRO invocation", nargs + 1); + + if ((numTokens + 2) >= TS_MAXTOKENS) + return error("Too many tokens in argument #%d in MACRO invocation", nargs + 1); + *p++ = *tok++; imacro->argument[nargs].string[stringNum] = strdup(string[*tok++]); *p++ = stringNum++; + numTokens += 2; } else if (*tok == ',') { + // Sanity checking + if ((nargs + 1) >= TS_MAXARGS) + return error("Too many arguments in MACRO invocation"); + // Comma delimiter was found, so set up for next argument *p++ = EOL; tok++; stringNum = 0; + numTokens = 0; nargs++; p = imacro->argument[nargs].token; } else { + // Sanity checking (it's numTokens + 1 because we need an EOL + // if we successfully parse this argument) + if ((numTokens + 1) >= TS_MAXTOKENS) + return error("Too many tokens in argument #%d in MACRO invocation", nargs + 1); + *p++ = *tok++; + numTokens++; } }