X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=blobdiff_plain;f=macro.c;h=17378dcde2f676a9546142eba0fc5f6a3c6d4365;hp=c92b2dbfa7b65708589ccc02162218017238f675;hb=HEAD;hpb=c2caacfdc844e2f8b5d05b0699fbacc04b4ce8ea diff --git a/macro.c b/macro.c index c92b2db..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; } @@ -172,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 @@ -406,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++; } }