X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=blobdiff_plain;f=macro.c;h=17378dcde2f676a9546142eba0fc5f6a3c6d4365;hp=4d63f2fa5cc58d61c4e125660ff8ed3d772574f1;hb=HEAD;hpb=29fa5dcf504b966803063a1c2891f58f97126d04 diff --git a/macro.c b/macro.c index 4d63f2f..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-2019 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; } @@ -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++; } }