X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=blobdiff_plain;f=macro.c;h=f0152cec8ac50306bdfd918e23d3e48fd5b6364a;hp=e136c5a10145f86b1da550203aca567031372bde;hb=03dd34951a331e0b8971195ccef1600fffaea2e6;hpb=daf2f61a3664329ae7f9609e1e14da2b8780fd10 diff --git a/macro.c b/macro.c index e136c5a..f0152ce 100644 --- a/macro.c +++ b/macro.c @@ -1,9 +1,9 @@ // -// RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System +// RMAC - Reboot's Macro Assembler for all Atari computers // MACRO.C - Macro Definition and Invocation -// Copyright (C) 199x Landon Dyer, 2011 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 -// Source Utilised with the Kind Permission of Landon Dyer +// Source utilised with the kind permission of Landon Dyer // #include "macro.h" @@ -17,46 +17,41 @@ #include "token.h" -static void SetupDefaultMacros(void); - -LONG curuniq; // Current macro's unique number -//TOKEN ** argp; // Free spot in argptrs[] -int macnum; // Unique number for macro definition -TOKEN * argPtrs[128]; // 128 arguments ought to be enough for anyone +LONG curuniq; // Current macro's unique number +int macnum; // Unique number for macro definition +TOKEN * argPtrs[128]; // 128 arguments ought to be enough for anyone static int argp; -static LONG macuniq; // Unique-per-macro number -static SYM * curmac; // Macro currently being defined -//static char ** curmln; // Previous macro line (or NULL) -static VALUE argno; // Formal argument count +static LONG macuniq; // Unique-per-macro number +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 int rptlevel; // .rept nesting level +static LONG * firstrpt; // First .rept line +static LONG * nextrpt; // Last .rept line +static int rptlevel; // .rept nesting level // -// Initialize Macro Processor +// Initialize macro processor // void InitMacro(void) { macuniq = 0; macnum = 1; -// argp = NULL; argp = 0; - SetupDefaultMacros(); } // -// Exit from a Macro; +// Exit from a macro; // -- pop any intervening include files and repeat blocks; // -- restore argument stack; // -- pop the macro. // int ExitMacro(void) { -#warning !!! Bad macro exiting !!! +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 @@ -83,14 +78,12 @@ of another (nested macros). Need to fix that somehow. argp -= imacro->im_nargs; DEBUG printf("%d (nargs = %d)\n", argp, imacro->im_nargs); - fpop(); - mjump_align = 0; - return 0; + return fpop(); } // -// Add a Formal Argument to a Macro Definition +// Add a formal argument to a macro definition // int defmac2(char * argname) { @@ -114,8 +107,8 @@ int defmac2(char * argname) // int defmac1(char * ln, int notEndFlag) { - PTR p; - LONG len; +// PTR p; +// LONG len; if (list_flag) { @@ -155,7 +148,7 @@ features of the language. Seems like we can do better here. *curmln = p.cp; curmln = (char **)p.cp; - return 1; // Keep looking + return 1; // Keep looking #else if (curmac->lineList == NULL) { @@ -244,15 +237,15 @@ int defr1(char * ln, int kwno) switch (kwno) { - case 0: // .endr + case 0: // .endr if (--rptlevel == 0) return(0); goto addln; - case 1: // .rept + case 1: // .rept rptlevel++; default: //MORE stupidity here... -#warning "!!! Casting (char *) as LONG !!!" +WARNING(!!! Casting (char *) as LONG !!!) addln: // Allocate length of line + 1('\0') + LONG len = strlen(ln) + 1 + sizeof(LONG); @@ -261,7 +254,7 @@ int defr1(char * ln, int kwno) *p = 0; strcpy((char *)(p + 1), ln); - + if (nextrpt == NULL) { firstrpt = p; // First line of rept statement @@ -315,14 +308,14 @@ int defrept(void) // 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 // keyword encountered (0..n) -// +// // `dirlist' contains null-seperated terminated keywords. A final null // terminates the list. Directives are compared to the keywords without regard // to case. -// +// // If `lnfunc' is NULL, then lines are simply skipped. // If `lnfunc' returns an error, processing is stopped. -// +// // `lnfunc' is called with an argument of -1 for every line but the last one, // when it is called with an argument of the keyword number that caused the // match. @@ -333,11 +326,11 @@ int lncatch(int (* lnfunc)(), char * dirlist) int k; if (lnfunc != NULL) - lnsave++; // Tell tokenizer to keep lines + lnsave++; // Tell tokenizer to keep lines for(;;) { - if (tokln() == TKEOF) + if (TokenizeLine() == TKEOF) { errors("encountered end-of-file looking for '%s'", dirlist); fatal("cannot continue"); @@ -354,25 +347,17 @@ int lncatch(int (* lnfunc)(), char * dirlist) if ((tok[2] == ':' || tok[2] == DCOLON)) { if (tok[3] == SYMBOL) // label: symbol -#if 0 - p = (char *)tok[4]; -#else p = string[tok[4]]; -#endif } else { -#if 0 - p = (char *)tok[1]; // symbol -#else p = string[tok[1]]; // Symbol -#endif } } if (p != NULL) { - if (*p == '.') // ignore leading '.'s + if (*p == '.') // ignore leading '.'s p++; k = kwmatch(p, dirlist); @@ -451,13 +436,7 @@ int InvokeMacro(SYM * mac, WORD siz) // argp = 0; DEBUG printf("InvokeMacro: argp: %d -> ", argp); - if ((!strcmp(mac->sname, "mjump") || !strcmp(mac->sname, "mpad")) && !in_main) - { - error("macro cannot be used outside of .gpumain"); - return ERROR; - } - - INOBJ * inobj = a_inobj(SRC_IMACRO); // Alloc and init IMACRO + INOBJ * inobj = a_inobj(SRC_IMACRO); // Alloc and init IMACRO IMACRO * imacro = inobj->inobj.imacro; imacro->im_siz = siz; WORD nargs = 0; @@ -466,7 +445,6 @@ int InvokeMacro(SYM * mac, WORD siz) TOKEN * dest; int stringNum = 0; int argumentNum = 0; - int i; for(dry_run=1; ; dry_run--) { @@ -476,7 +454,7 @@ int InvokeMacro(SYM * mac, WORD siz) nargs++; else { -#if 0 +#if 0 *argptr++ = p; #else argPtrs[argp++] = p; @@ -570,12 +548,13 @@ int InvokeMacro(SYM * mac, WORD siz) Shamus: This construct is meant to deal with nested macros, so the simple minded way we deal with them now won't work. :-/ Have to think about how to fix. -What we could do is simply move the argp with each call, and move it back by the -number of arguments in the macro that's ending. That would solve the problem nicely. +What we could do is simply move the argp with each call, and move it back by +the number of arguments in the macro that's ending. That would solve the +problem nicely. [Which we do now. But that uncovered another problem: the token strings are all -stale by the time a nested macro gets to the end. But they're supposed to be symbols, -which means if we put symbol references into the argument token streams, we can -alleviate this problem.] +stale by the time a nested macro gets to the end. But they're supposed to be +symbols, which means if we put symbol references into the argument token +streams, we can alleviate this problem.] */ #if 0 argptr = (TOKEN **)malloc((nargs + 1) * sizeof(LONG)); @@ -587,7 +566,7 @@ alleviate this problem.] // argp += nargs; #endif } - else + else break; } @@ -623,47 +602,3 @@ alleviate this problem.] return OK; } - -// -// Setup inbuilt macros (SubQMod) -// -static void SetupDefaultMacros(void) -{ - curmac = NewSymbol("mjump", MACRO, 0); - curmac->svalue = 0; - curmac->sattr = (WORD)(macnum++); - argno = 0; - defmac2("cc"); - defmac2("addr"); - defmac2("jreg"); -// curmln = NULL; - curmac->lineList = NULL; - defmac1(" nop", -1); - defmac1(" movei #\\addr,\\jreg", -1); - defmac1(" jump \\cc,(\\jreg)", -1); - defmac1(" nop", -1); - defmac1(" nop", -1); - - curmac = NewSymbol("mjr", MACRO, 0); - curmac->svalue = 0; - curmac->sattr = (WORD)(macnum++); - argno = 0; - defmac2("cc"); - defmac2("addr"); -// curmln = NULL; - curmac->lineList = NULL; - defmac1(" jr \\cc,\\addr", -1); - defmac1(" nop", -1); - defmac1(" nop", -1); - - curmac = NewSymbol("mpad", MACRO, 0); - curmac->svalue = 0; - curmac->sattr = (WORD)(macnum++); - argno = 0; - defmac2("size"); -// curmln = NULL; - curmac->lineList = NULL; - defmac1(" .rept (\\size/2)", -1); - defmac1(" nop", -1); - defmac1(" .endr", -1); -}