X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=blobdiff_plain;f=macro.c;h=6c67bb628b6887bdc6f5381c38e96bec0cfabbb0;hp=8731fb87e43ad13b21109e440884ddf8dec6812c;hb=d16b8ea0ee65b2ad901ca6b0624c07e6e4930cc4;hpb=49cce96fba11282e4244187f15be418d5ae5bb8d diff --git a/macro.c b/macro.c index 8731fb8..6c67bb6 100644 --- a/macro.c +++ b/macro.c @@ -7,22 +7,24 @@ // #include "macro.h" -#include "token.h" +#include "debug.h" +#include "direct.h" #include "error.h" #include "expr.h" #include "listing.h" -#include "symbol.h" #include "procln.h" -#include "direct.h" -#include "debug.h" +#include "symbol.h" +#include "token.h" LONG curuniq; // Current macro's unique number -TOKEN ** argp; // Free spot in argptrs[] +//TOKEN ** argp; // Free spot in argptrs[] 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 char ** curmln; // Previous macro line (or NULL) static VALUE argno; // Formal argument count static LONG * firstrpt; // First .rept line @@ -37,22 +39,20 @@ void init_macro(void) { macuniq = 0; macnum = 1; - argp = NULL; +// argp = NULL; + argp = 0; ib_macro(); } // // Exit from a Macro; -// o pop any intervening include files and repeat blocks; -// o restore argument stack; -// o pop the macro. +// -- pop any intervening include files and repeat blocks; +// -- restore argument stack; +// -- pop the macro. // int exitmac(void) { - IMACRO * imacro; - TOKEN ** p; - // Pop intervening include files and .rept blocks while (cur_inobj != NULL && cur_inobj->in_type != SRC_IMACRO) fpop(); @@ -65,16 +65,14 @@ int exitmac(void) // o old unique number // ...and then pop the macro. - imacro = cur_inobj->inobj.imacro; + IMACRO * imacro = cur_inobj->inobj.imacro; curuniq = imacro->im_olduniq; - p = --argp; - argp = (TOKEN **)*argp; + /*TOKEN ** p = */argp--; +// argp = (TOKEN **)*argp; fpop(); - mjump_align = 0; - return 0; } @@ -87,8 +85,9 @@ int defmac2(char * argname) SYM * arg; if (lookup(argname, MACARG, (int)curmac->sattr) != NULL) - return(error("multiple formal argument definition")); - arg = newsym(argname, MACARG, (int)curmac->sattr); + return error("multiple formal argument definition"); + + arg = NewSymbol(argname, MACARG, (int)curmac->sattr); arg->svalue = argno++; return OK; @@ -98,39 +97,74 @@ int defmac2(char * argname) // // Add a line to a macro definition; also print lines to listing file (if // enabled). The last line of the macro (containing .endm) is not included in -// the macro. A label on that line will be lost. `endflg' is misleading here. -// It is -1 for all lines but the last one (.endm), when it is 0. +// the macro. A label on that line will be lost. +// notEndFlag is -1 for all lines but the last one (.endm), when it is 0. // -int defmac1(char * ln, int endflg) +int defmac1(char * ln, int notEndFlag) { PTR p; LONG len; if (list_flag) { - listeol(); // Flush previous source line - lstout('.'); // Mark macro definition with period + listeol(); // Flush previous source line + lstout('.'); // Mark macro definition with period } - if (endflg) + // This is just wrong, wrong, wrong. It makes up a weird kind of string with + // a pointer on front, and then uses a ** to manage them: This is a recipe + // for disaster. + // How to manage it then? + // Could use a linked list, like Landon uses everywhere else. +/* +How it works: +Allocate a space big enough for the string + NULL + pointer. +Set the pointer to NULL. +Copy the string to the space after the pointer. +If this is the 1st time through, set the SYM * "svalue" to the pointer. +If this is the 2nd time through, derefence the ** to point to the memory you just allocated. +Then, set the ** to the location of the memory you allocated for the next pass through. + +This is a really low level way to do a linked list, and by bypassing all the safety +features of the language. Seems like we can do better here. +*/ + if (notEndFlag) { +#if 0 len = strlen(ln) + 1 + sizeof(LONG); -// p.cp = amem(len); p.cp = malloc(len); *p.lp = 0; strcpy(p.cp + sizeof(LONG), ln); // Link line of text onto end of list if (curmln == NULL) - curmac->svalue = (VALUE)p.cp; + curmac->svalue = p.cp; else *curmln = p.cp; curmln = (char **)p.cp; - return 1; // Keep looking + return 1; // Keep looking +#else + if (curmac->lineList == NULL) + { + curmac->lineList = malloc(sizeof(struct LineList)); + curmac->lineList->next = NULL; + curmac->lineList->line = strdup(ln); + curmac->last = curmac->lineList; + } + else + { + curmac->last->next = malloc(sizeof(struct LineList)); + curmac->last->next->next = NULL; + curmac->last->next->line = strdup(ln); + curmac->last = curmac->last->next; + } + + return 1; // Keep looking +#endif } - else - return 0; // Stop looking at the end + + return 0; // Stop looking at the end } @@ -147,24 +181,22 @@ int defmac1(char * ln, int endflg) // `defmac1' adds lines of text to the macro definition // `defmac2' processes the formal arguments (and sticks them into the symbol table) // -int defmac(void) +int DefineMacro(void) { - char * p; - SYM * mac; - - // Setup entry in symbol table, make sure the macro isn't a duplicate entry, and that - // it doesn't override any processor mnemonic or assembler directive. + // Setup entry in symbol table, make sure the macro isn't a duplicate + // entry, and that it doesn't override any processor mnemonic or assembler + // directive. if (*tok++ != SYMBOL) return error("missing symbol"); - p = (char *)*tok++; + char * name = string[*tok++]; - if (lookup(p, MACRO, 0) != NULL) - return error("multiple macro definition"); + if (lookup(name, MACRO, 0) != NULL) + return error("duplicate macro definition"); - curmac = mac = newsym(p, MACRO, 0); - mac->svalue = 0; - mac->sattr = (WORD)(macnum++); + curmac = NewSymbol(name, MACRO, 0); + curmac->svalue = 0; + curmac->sattr = (WORD)(macnum++); // Parse and define formal arguments in symbol table if (*tok != EOL) @@ -176,7 +208,8 @@ int defmac(void) // Suck in the macro definition; we're looking for an ENDM symbol on a line // by itself to terminate the definition. - curmln = NULL; +// curmln = NULL; + curmac->lineList = NULL; lncatch(defmac1, "endm "); return 0; @@ -204,8 +237,10 @@ int defr1(char * ln, int kwno) return(0); goto addln; case 1: // .rept - ++rptlevel; + rptlevel++; default: +//MORE stupidity here... +#warning "!!! Casting (char *) as LONG !!!" addln: // Allocate length of line + 1('\0') + LONG len = strlen(ln) + 1 + sizeof(LONG); @@ -286,7 +321,7 @@ int lncatch(int (* lnfunc)(), char * dirlist) int k; if (lnfunc != NULL) - ++lnsave; // Tell tokenizer to keep lines + lnsave++; // Tell tokenizer to keep lines for(;;) { @@ -307,18 +342,26 @@ 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 - ++p; + p++; k = kwmatch(p, dirlist); } @@ -334,7 +377,7 @@ int lncatch(int (* lnfunc)(), char * dirlist) } if (lnfunc != NULL) - --lnsave; // Tell tokenizer to stop keeping lines + lnsave--; // Tell tokenizer to stop keeping lines return 0; } @@ -374,7 +417,7 @@ int kwmatch(char * kw, char * kwlist) ++kwlist; if (*kwlist== ' ') - ++kwlist; + kwlist++; } return -1; @@ -386,16 +429,14 @@ int kwmatch(char * kw, char * kwlist) // o parse, count and copy arguments // o push macro's string-stream // -int invokemac(SYM * mac, WORD siz) +int InvokeMacro(SYM * mac, WORD siz) { TOKEN * p = NULL; - IMACRO * imacro; - INOBJ * inobj; int dry_run; - WORD nargs; WORD arg_siz = 0; - TOKEN ** argptr = NULL; - TOKEN * beg_tok; +// TOKEN ** argptr = NULL; +//Doesn't need to be global! (or does it???) + argp = 0; if ((!strcmp(mac->sname, "mjump") || !strcmp(mac->sname, "mpad")) && !in_main) { @@ -403,20 +444,24 @@ int invokemac(SYM * mac, WORD siz) return ERROR; } - inobj = a_inobj(SRC_IMACRO); // Alloc and init IMACRO - imacro = inobj->inobj.imacro; + INOBJ * inobj = a_inobj(SRC_IMACRO); // Alloc and init IMACRO + IMACRO * imacro = inobj->inobj.imacro; imacro->im_siz = siz; - nargs = 0; - beg_tok = tok; // 'tok' comes from token.c + WORD nargs = 0; + TOKEN * beg_tok = tok; // 'tok' comes from token.c - for(dry_run=1;; --dry_run) + for(dry_run=1; ; dry_run--) { for(tok=beg_tok; *tok!=EOL;) { if (dry_run) nargs++; else +#if 0 *argptr++ = p; +#else + argPtrs[argp++] = p; +#endif // Keep going while tok isn't pointing at a comma or EOL while (*tok != ',' && *tok != EOL) @@ -468,12 +513,17 @@ int invokemac(SYM * mac, WORD siz) { if (nargs != 0) //Barfing here with memory corruption in glibc. TOKEN is defined as LONG, which is uint32_t -// p = (TOKEN *)malloc(arg_siz + 1); - p = (TOKEN *)malloc(arg_siz + sizeof(TOKEN)); + p = (TOKEN *)malloc(arg_siz); +// p = (TOKEN *)malloc(arg_siz + sizeof(TOKEN)); +// 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. +#if 0 argptr = (TOKEN **)malloc((nargs + 1) * sizeof(LONG)); *argptr++ = (TOKEN *)argp; argp = argptr; +#else +#endif } else break; @@ -487,18 +537,10 @@ int invokemac(SYM * mac, WORD siz) // o bump `macuniq' counter and set 'curuniq' to it; imacro->im_nargs = nargs; imacro->im_macro = mac; - imacro->im_nextln = (TOKEN *)mac->svalue; +// imacro->im_nextln = (TOKEN *)mac->svalue; + imacro->im_nextln = mac->lineList; imacro->im_olduniq = curuniq; curuniq = macuniq++; -/*IMACRO { - IMACRO * im_link; // Pointer to ancient IMACROs - LONG * im_nextln; // Next line to include - WORD im_nargs; // # of arguments supplied on invocation - WORD im_siz; // Size suffix supplied on invocation - LONG im_olduniq; // Old value of 'macuniq' - SYM * im_macro; // Pointer to macro we're in - char im_lnbuf[LNSIZ]; // Line buffer -};*/ DEBUG { @@ -507,7 +549,8 @@ int invokemac(SYM * mac, WORD siz) for(nargs=0; nargsim_nargs; ++nargs) { printf("arg%d=", nargs); - dumptok(argp[imacro->im_nargs - nargs - 1]); +// dumptok(argp[imacro->im_nargs - nargs - 1]); + dumptok(argPtrs[imacro->im_nargs - nargs - 1]); } } @@ -520,40 +563,41 @@ int invokemac(SYM * mac, WORD siz) // void ib_macro(void) { - SYM * mac; - - curmac = mac = newsym("mjump", MACRO, 0); - mac->svalue = 0; - mac->sattr = (WORD)(macnum++); + curmac = NewSymbol("mjump", MACRO, 0); + curmac->svalue = 0; + curmac->sattr = (WORD)(macnum++); argno = 0; defmac2("cc"); defmac2("addr"); defmac2("jreg"); - curmln = NULL; - defmac1(" nop", -1); - defmac1(" movei #\\addr,\\jreg", -1); - defmac1(" jump \\cc,(\\jreg)", -1); - defmac1(" nop", -1); - defmac1(" nop", -1); - - curmac = mac = newsym("mjr", MACRO, 0); - mac->svalue = 0; - mac->sattr = (WORD)(macnum++); +// 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; - defmac1(" jr \\cc,\\addr", -1); - defmac1(" nop", -1); - defmac1(" nop", -1); - - curmac = mac = newsym("mpad", MACRO, 0); - mac->svalue = 0; - mac->sattr = (WORD)(macnum++); +// 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; - defmac1(" .rept (\\size/2)", -1); - defmac1(" nop", -1); - defmac1(" .endr", -1); +// curmln = NULL; + curmac->lineList = NULL; + defmac1(" .rept (\\size/2)", -1); + defmac1(" nop", -1); + defmac1(" .endr", -1); }