123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- /* macro.c - expand macros for assembler */
- #include "syshead.h"
- #include "const.h"
- #include "type.h"
- #include "globvar.h"
- #include "scan.h"
- #undef EXTERN
- #define EXTERN
- #include "macro.h"
- /*
- Enter macro: stack macro and get its parameters.
- Parameters form a linked list of null-terminated strings of form
- next:string. The first string is the macro number in 4 bytes.
- */
- PUBLIC void entermac(symptr)
- struct sym_s *symptr;
- {
- if (maclevel >= MAXMAC)
- error(MACOV);
- else if (macpar + 2 > macptop)
- error(PAROV); /* no room for 0th param */
- /* (2 structs to fit it!) */
- else
- {
- char ch;
- struct schain_s *param1;
- register char *reglineptr;
- register char *stringptr;
- ++maclevel;
- (--macstak)->text = (char *) symptr->value_reg_or_op.value;
- macstak->parameters = param1 = macpar;
- param1->next = NUL_PTR;
- *(stringptr = build_number(++macnum, 3, param1->string)) = 0;
- macpar = (struct schain_s *) (stringptr + 1);
- /* TODO: alignment */
- getsym();
- if (sym == EOLSYM)
- return; /* no other params */
- if (sym != LPAREN)
- reglineptr = symname;
- else
- reglineptr = lineptr;
- stringptr = macpar->string;
- while (TRUE)
- {
- if (stringptr >= (char *) macptop)
- {
- symname = reglineptr;
- error(PAROV);
- return;
- }
- ch = *reglineptr++;
- if (ch == '\\')
- /* escaped means no special meaning for slash, comma, paren */
- ch = *reglineptr++;
- else if (ch == ',' || ch == ')' || ch == '!' || ch == ';'
- || ch == '\n' || ch == 0)
- {
- if (stringptr >= (char *) macptop)
- {
- symname = reglineptr;
- error(PAROV); /* no room for null */
- return;
- }
- *stringptr = 0;
- param1->next = macpar; /* ptr from previous */
- (param1 = macpar)->next = NUL_PTR;
- /* this goes nowhere */
- macpar = (struct schain_s *) (stringptr + 1);
- /* but is finished OK - TODO align */
- stringptr = macpar->string;
- if (ch != ',')
- return;
- continue;
- }
- if ((*stringptr++ = ch) == 0)
- {
- symname = reglineptr;
- error(RPEXP);
- return;
- }
- }
- }
- }
- /* MACRO pseudo-op */
- PUBLIC void pmacro()
- {
- bool_t saving;
- bool_t savingc;
- struct sym_s *symptr=0;
- int maclen = 8;
- int macoff = 0;
- char * macbuf = asalloc(8);
- saving = /* prepare for bad macro */
- savingc = FALSE; /* normally don't save comments */
- macload = TRUE; /* show loading */
- if (label != NUL_PTR)
- error(ILLAB);
- else if (sym != IDENT)
- error(LABEXP);
- else
- {
- symptr = gsymptr;
- if (symptr->type & MNREGBIT)
- error(LABEXP);
- else if (symptr->type & LABIT || symptr->data & FORBIT)
- error(RELAB);
- else if (pass != last_pass || symptr->type & REDBIT)
- /* copy on pass 0, also pass 1 if redefined */
- {
- saving = TRUE;
- if (symptr->type & MACBIT)
- symptr->type |= REDBIT;
- else
- symptr->type |= MACBIT;
- symptr->data = UNDBIT; /* undefined till end */
- symptr->value_reg_or_op.value = (offset_t) macbuf;
- getsym_nolookup(); /* test for "C" */
- if (sym == IDENT && lineptr == symname + 1 && *symname == 'C')
- savingc = TRUE;
- }
- }
- while (TRUE)
- {
- skipline();
- listline();
- readline();
- if (!macload)
- break; /* macload cleared to show eof */
- getsym_nolookup();
- if (sym == IDENT)
- {
- if (lineptr == symname + 4 &&
- ( strncmp(symname, "MEND", 4) == 0 || strncmp(symname, "mend", 4) == 0) )
- {
- getsym();
- break;
- }
- }
- else if (sym != MACROARG)
- {
- if (!savingc)
- continue; /* don't save comment */
- }
- if (!saving)
- continue;
- {
- char * p = strchr(linebuf, EOLCHAR);
- int len = (p-linebuf+1);
- if ( macoff + len > maclen-4 )
- {
- maclen = maclen * 2 + len;
- macbuf = asrealloc(macbuf, maclen);
- }
- memcpy(macbuf+macoff, linebuf, len);
- macoff += len;
- }
- }
- macload = FALSE;
- if (saving)
- {
- macbuf[macoff] = ETB;
- symptr->value_reg_or_op.value = (offset_t) macbuf;
- symptr->data = 0;
- }
- }
|