1 /* macro.c - macro support for gas and gasp
2 Copyright (C) 1994, 1995 Free Software Foundation, Inc.
4 Written by Steve and Judy Chamberlain of Cygnus Support,
7 This file is part of GAS, the GNU Assembler.
9 GAS is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
14 GAS is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GAS; see the file COPYING. If not, write to the Free
21 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
31 #include "libiberty.h"
36 /* The routines in this file handle macro definition and expansion.
37 They are called by both gasp and gas. */
39 /* Structures used to store macros.
41 Each macro knows its name and included text. It gets built with a
42 list of formal arguments, and also keeps a hash table which points
43 into the list to speed up formal search. Each formal knows its
44 name and its default value. Each time the macro is expanded, the
45 formals get the actual values attatched to them. */
47 /* describe the formal arguments to a macro */
49 typedef struct formal_struct
51 struct formal_struct *next; /* next formal in list */
52 sb name; /* name of the formal */
53 sb def; /* the default value */
54 sb actual; /* the actual argument (changed on each expansion) */
55 int index; /* the index of the formal 0..formal_count-1 */
59 /* Other values found in the index field of a formal_entry. */
60 #define QUAL_INDEX (-1)
61 #define NARG_INDEX (-2)
62 #define LOCAL_INDEX (-3)
64 /* describe the macro. */
66 typedef struct macro_struct
68 sb sub; /* substitution text. */
69 int formal_count; /* number of formal args. */
70 formal_entry *formals; /* pointer to list of formal_structs */
71 struct hash_control *formal_hash; /* hash table of formals. */
75 /* Internal functions. */
77 static int get_token PARAMS ((int, sb *, sb *));
78 static int getstring PARAMS ((int, sb *, sb *));
79 static int get_any_string PARAMS ((int, sb *, sb *, int, int));
80 static int do_formals PARAMS ((macro_entry *, int, sb *));
81 static int get_apost_token PARAMS ((int, sb *, sb *, int));
83 PARAMS ((int, sb *, sb *, struct hash_control *, int, sb *, int));
84 static const char *macro_expand_body
85 PARAMS ((sb *, sb *, formal_entry *, struct hash_control *, int, int));
86 static const char *macro_expand PARAMS ((int, sb *, macro_entry *, sb *, int));
88 #define ISWHITE(x) ((x) == ' ' || (x) == '\t')
91 ((x) == ' ' || (x) == '\t' || (x) == ',' || (x) == '"' || (x) == ';' \
92 || (x) == '<' || (x) == '>' || (x) == ')' || (x) == '(')
95 ((x) == 'b' || (x) == 'B' \
96 || (x) == 'q' || (x) == 'Q' \
97 || (x) == 'h' || (x) == 'H' \
98 || (x) == 'd' || (x) == 'D')
100 /* The macro hash table. */
102 static struct hash_control *macro_hash;
104 /* Whether any macros have been defined. */
108 /* Whether we are in GASP alternate mode. */
110 static int macro_alternate;
112 /* Whether we are in MRI mode. */
114 static int macro_mri;
116 /* Whether we should strip '@' characters. */
118 static int macro_strip_at;
120 /* Function to use to parse an expression. */
122 static int (*macro_expr) PARAMS ((const char *, int, sb *, int *));
124 /* Number of macro expansions that have been done. */
126 static int macro_number;
128 /* Initialize macro processing. */
131 macro_init (alternate, mri, strip_at, expr)
135 int (*expr) PARAMS ((const char *, int, sb *, int *));
137 macro_hash = hash_new ();
139 macro_alternate = alternate;
141 macro_strip_at = strip_at;
145 /* Read input lines till we get to a TO string.
146 Increase nesting depth if we get a FROM string.
147 Put the results into sb at PTR.
148 Add a new input line to an sb using GET_LINE.
149 Return 1 on success, 0 on unexpected EOF. */
152 buffer_and_nest (from, to, ptr, get_line)
156 int (*get_line) PARAMS ((sb *));
158 int from_len = strlen (from);
159 int to_len = strlen (to);
161 int line_start = ptr->len;
163 int more = get_line (ptr);
167 /* Try and find the first pseudo op on the line */
170 if (! macro_alternate && ! macro_mri)
172 /* With normal syntax we can suck what we want till we get
173 to the dot. With the alternate, labels have to start in
174 the first column, since we cant tell what's a label and
177 /* Skip leading whitespace */
178 while (i < ptr->len && ISWHITE (ptr->ptr[i]))
181 /* Skip over a label */
183 && (isalnum ((unsigned char) ptr->ptr[i])
184 || ptr->ptr[i] == '_'
185 || ptr->ptr[i] == '$'))
190 && ptr->ptr[i] == ':')
194 /* Skip trailing whitespace */
195 while (i < ptr->len && ISWHITE (ptr->ptr[i]))
198 if (i < ptr->len && (ptr->ptr[i] == '.'
202 if (ptr->ptr[i] == '.')
204 if (strncasecmp (ptr->ptr + i, from, from_len) == 0)
206 if (strncasecmp (ptr->ptr + i, to, to_len) == 0)
211 /* Reset the string to not include the ending rune */
212 ptr->len = line_start;
218 /* Add a CR to the end and keep running */
219 sb_add_char (ptr, '\n');
220 line_start = ptr->len;
221 more = get_line (ptr);
224 /* Return 1 on success, 0 on unexpected EOF. */
228 /* Pick up a token. */
231 get_token (idx, in, name)
237 && (isalpha ((unsigned char) in->ptr[idx])
238 || in->ptr[idx] == '_'
239 || in->ptr[idx] == '$'))
241 sb_add_char (name, in->ptr[idx++]);
243 && (isalnum ((unsigned char) in->ptr[idx])
244 || in->ptr[idx] == '_'
245 || in->ptr[idx] == '$'))
247 sb_add_char (name, in->ptr[idx++]);
250 /* Ignore trailing & */
251 if (macro_alternate && idx < in->len && in->ptr[idx] == '&')
256 /* Pick up a string. */
259 getstring (idx, in, acc)
264 idx = sb_skip_white (idx, in);
267 && (in->ptr[idx] == '"'
268 || in->ptr[idx] == '<'
269 || (in->ptr[idx] == '\'' && macro_alternate)))
271 if (in->ptr[idx] == '<')
273 if (macro_alternate || macro_mri)
277 while ((in->ptr[idx] != '>' || nest)
280 if (in->ptr[idx] == '!')
283 sb_add_char (acc, in->ptr[idx++]);
287 if (in->ptr[idx] == '>')
289 if (in->ptr[idx] == '<')
291 sb_add_char (acc, in->ptr[idx++]);
301 ("character code in string must be absolute expression",
303 sb_add_char (acc, code);
306 if (in->ptr[idx] != '>')
307 ERROR ((stderr, "Missing > for character code.\n"));
312 else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
314 char tchar = in->ptr[idx];
316 while (idx < in->len)
318 if (macro_alternate && in->ptr[idx] == '!')
321 sb_add_char (acc, in->ptr[idx++]);
325 if (in->ptr[idx] == tchar)
328 if (idx >= in->len || in->ptr[idx] != tchar)
331 sb_add_char (acc, in->ptr[idx]);
341 /* Fetch string from the input stream,
343 'Bxyx<whitespace> -> return 'Bxyza
344 %<char> -> return string of decimal value of x
345 "<string>" -> return string
346 xyx<whitespace> -> return xyz
350 get_any_string (idx, in, out, expand, pretend_quoted)
358 idx = sb_skip_white (idx, in);
362 if (in->len > 2 && in->ptr[idx+1] == '\'' && ISBASE (in->ptr[idx]))
364 while (!ISSEP (in->ptr[idx]))
365 sb_add_char (out, in->ptr[idx++]);
367 else if (in->ptr[idx] == '%'
373 /* Turns the next expression into a string */
374 idx = (*macro_expr) ("% operator needs absolute expression",
378 sprintf(buf, "%d", val);
379 sb_add_string (out, buf);
381 else if (in->ptr[idx] == '"'
382 || in->ptr[idx] == '<'
383 || (macro_alternate && in->ptr[idx] == '\''))
385 if (macro_alternate && expand)
387 /* Keep the quotes */
388 sb_add_char (out, '\"');
390 idx = getstring (idx, in, out);
391 sb_add_char (out, '\"');
395 idx = getstring (idx, in, out);
401 && (in->ptr[idx] == '"'
402 || in->ptr[idx] == '\''
404 || (in->ptr[idx] != ' '
405 && in->ptr[idx] != '\t'
406 && in->ptr[idx] != ','
407 && in->ptr[idx] != '<')))
409 if (in->ptr[idx] == '"'
410 || in->ptr[idx] == '\'')
412 char tchar = in->ptr[idx];
413 sb_add_char (out, in->ptr[idx++]);
415 && in->ptr[idx] != tchar)
416 sb_add_char (out, in->ptr[idx++]);
420 sb_add_char (out, in->ptr[idx++]);
428 /* Pick up the formal parameters of a macro definition. */
431 do_formals (macro, idx, in)
436 formal_entry **p = ¯o->formals;
438 macro->formal_count = 0;
439 macro->formal_hash = hash_new ();
440 while (idx < in->len)
442 formal_entry *formal;
444 formal = (formal_entry *) xmalloc (sizeof (formal_entry));
446 sb_new (&formal->name);
447 sb_new (&formal->def);
448 sb_new (&formal->actual);
450 idx = sb_skip_white (idx, in);
451 idx = get_token (idx, in, &formal->name);
452 if (formal->name.len == 0)
454 idx = sb_skip_white (idx, in);
455 if (formal->name.len)
457 /* This is a formal */
458 if (idx < in->len && in->ptr[idx] == '=')
461 idx = get_any_string (idx + 1, in, &formal->def, 1, 0);
465 /* Add to macro's hash table */
466 hash_jam (macro->formal_hash, sb_terminate (&formal->name), formal);
468 formal->index = macro->formal_count;
469 idx = sb_skip_comma (idx, in);
470 macro->formal_count++;
478 formal_entry *formal;
481 /* Add a special NARG formal, which macro_expand will set to the
482 number of arguments. */
483 formal = (formal_entry *) xmalloc (sizeof (formal_entry));
485 sb_new (&formal->name);
486 sb_new (&formal->def);
487 sb_new (&formal->actual);
489 /* The same MRI assemblers which treat '@' characters also use
490 the name $NARG. At least until we find an exception. */
496 sb_add_string (&formal->name, name);
498 /* Add to macro's hash table */
499 hash_jam (macro->formal_hash, name, formal);
501 formal->index = NARG_INDEX;
509 /* Define a new macro. Returns NULL on success, otherwise returns an
513 define_macro (idx, in, label, get_line)
517 int (*get_line) PARAMS ((sb *));
522 macro = (macro_entry *) xmalloc (sizeof (macro_entry));
523 sb_new (¯o->sub);
526 macro->formal_count = 0;
529 idx = sb_skip_white (idx, in);
530 if (! buffer_and_nest ("MACRO", "ENDM", ¯o->sub, get_line))
531 return "unexpected end of file in macro definition";
532 if (label != NULL && label->len != 0)
534 sb_add_sb (&name, label);
535 if (in->ptr[idx] == '(')
537 /* It's the label: MACRO (formals,...) sort */
538 idx = do_formals (macro, idx + 1, in);
539 if (in->ptr[idx] != ')')
540 return "missing ) after formals";
544 /* It's the label: MACRO formals,... sort */
545 idx = do_formals (macro, idx, in);
550 idx = get_token (idx, in, &name);
551 idx = sb_skip_comma (idx, in);
552 idx = do_formals (macro, idx, in);
555 /* and stick it in the macro hash table */
556 for (idx = 0; idx < name.len; idx++)
557 if (isupper (name.ptr[idx]))
558 name.ptr[idx] = tolower (name.ptr[idx]);
559 hash_jam (macro_hash, sb_terminate (&name), (PTR) macro);
566 /* Scan a token, and then skip KIND. */
569 get_apost_token (idx, in, name, kind)
575 idx = get_token (idx, in, name);
576 if (idx < in->len && in->ptr[idx] == kind
577 && (! macro_mri || macro_strip_at))
582 /* Substitute the actual value for a formal parameter. */
585 sub_actual (src, in, t, formal_hash, kind, out, copyifnotthere)
589 struct hash_control *formal_hash;
596 src = get_apost_token (src, in, t, kind);
597 /* See if it's in the macro's hash table */
598 ptr = (formal_entry *) hash_find (formal_hash, sb_terminate (t));
603 sb_add_sb (out, &ptr->actual);
607 sb_add_sb (out, &ptr->def);
610 else if (copyifnotthere)
616 sb_add_char (out, '\\');
622 /* Expand the body of a macro. */
625 macro_expand_body (in, out, formals, formal_hash, comment_char, locals)
628 formal_entry *formals;
629 struct hash_control *formal_hash;
636 formal_entry *loclist = NULL;
640 while (src < in->len)
642 if (in->ptr[src] == '&')
645 if (macro_mri && src + 1 < in->len && in->ptr[src + 1] == '&')
647 src = sub_actual (src + 2, in, &t, formal_hash, '\'', out, 1);
651 src = sub_actual (src + 1, in, &t, formal_hash, '&', out, 0);
654 else if (in->ptr[src] == '\\')
657 if (in->ptr[src] == comment_char && comment_char != '\0')
659 /* This is a comment, just drop the rest of the line */
661 && in->ptr[src] != '\n')
664 else if (in->ptr[src] == '(')
666 /* Sub in till the next ')' literally */
668 while (src < in->len && in->ptr[src] != ')')
670 sb_add_char (out, in->ptr[src++]);
672 if (in->ptr[src] == ')')
675 return "missplaced )";
677 else if (in->ptr[src] == '@')
679 /* Sub in the macro invocation number */
683 sprintf (buffer, "%05d", macro_number);
684 sb_add_string (out, buffer);
686 else if (in->ptr[src] == '&')
688 /* This is a preprocessor variable name, we don't do them
690 sb_add_char (out, '\\');
691 sb_add_char (out, '&');
695 && isalnum ((unsigned char) in->ptr[src]))
700 if (isdigit ((unsigned char) in->ptr[src]))
701 ind = in->ptr[src] - '0';
702 else if (isupper ((unsigned char) in->ptr[src]))
703 ind = in->ptr[src] - 'A' + 10;
705 ind = in->ptr[src] - 'a' + 10;
707 for (f = formals; f != NULL; f = f->next)
709 if (f->index == ind - 1)
711 if (f->actual.len != 0)
712 sb_add_sb (out, &f->actual);
714 sb_add_sb (out, &f->def);
722 src = sub_actual (src, in, &t, formal_hash, '\'', out, 0);
725 else if ((macro_alternate || macro_mri)
726 && (isalpha ((unsigned char) in->ptr[src])
727 || in->ptr[src] == '_'
728 || in->ptr[src] == '$')
731 || (src > 0 && in->ptr[src - 1] == '@')))
734 || src + 5 >= in->len
735 || strncasecmp (in->ptr + src, "LOCAL", 5) != 0
736 || ! ISWHITE (in->ptr[src + 5]))
739 src = sub_actual (src, in, &t, formal_hash,
740 (macro_strip_at && inquote) ? '@' : '\'',
747 src = sb_skip_white (src + 5, in);
748 while (in->ptr[src] != '\n' && in->ptr[src] != comment_char)
754 f = (formal_entry *) xmalloc (sizeof (formal_entry));
758 f->index = LOCAL_INDEX;
762 src = get_token (src, in, &f->name);
764 sprintf (buf, "LL%04x", loccnt);
765 sb_add_string (&f->actual, buf);
767 err = hash_jam (formal_hash, sb_terminate (&f->name), f);
771 src = sb_skip_comma (src, in);
775 else if (comment_char != '\0'
776 && in->ptr[src] == comment_char
778 && in->ptr[src + 1] == comment_char
781 /* Two comment chars in a row cause the rest of the line to
783 while (src < in->len && in->ptr[src] != '\n')
786 else if (in->ptr[src] == '"'
787 || (macro_mri && in->ptr[src] == '\''))
790 sb_add_char (out, in->ptr[src++]);
792 else if (in->ptr[src] == '@' && macro_strip_at)
796 && in->ptr[src] == '@')
798 sb_add_char (out, '@');
803 && in->ptr[src] == '='
805 && in->ptr[src + 1] == '=')
810 src = get_token (src + 2, in, &t);
811 ptr = (formal_entry *) hash_find (formal_hash, sb_terminate (&t));
813 return "macro formal argument does not exist";
818 sb_add_string (out, "-1");
822 sb_add_char (out, '0');
828 sb_add_char (out, in->ptr[src++]);
834 while (loclist != NULL)
839 hash_delete (formal_hash, sb_terminate (&loclist->name));
840 sb_kill (&loclist->name);
841 sb_kill (&loclist->def);
842 sb_kill (&loclist->actual);
850 /* Assign values to the formal parameters of a macro, and expand the
854 macro_expand (idx, in, m, out, comment_char)
864 int is_positional = 0;
871 /* Reset any old value the actuals may have */
872 for (f = m->formals; f; f = f->next)
873 sb_reset (&f->actual);
875 while (f != NULL && f->index < 0)
880 /* The macro may be called with an optional qualifier, which may
881 be referred to in the macro body as \0. */
882 if (idx < in->len && in->ptr[idx] == '.')
886 n = (formal_entry *) xmalloc (sizeof (formal_entry));
890 n->index = QUAL_INDEX;
892 n->next = m->formals;
895 idx = get_any_string (idx + 1, in, &n->actual, 1, 0);
899 /* Peel off the actuals and store them away in the hash tables' actuals */
900 idx = sb_skip_white (idx, in);
901 while (idx < in->len && in->ptr[idx] != comment_char)
905 /* Look and see if it's a positional or keyword arg */
907 while (scan < in->len
908 && !ISSEP (in->ptr[scan])
909 && (!macro_alternate && in->ptr[scan] != '='))
911 if (scan < in->len && !macro_alternate && in->ptr[scan] == '=')
915 return "can't mix positional and keyword arguments";
917 /* This is a keyword arg, fetch the formal name and
918 then the actual stuff */
920 idx = get_token (idx, in, &t);
921 if (in->ptr[idx] != '=')
922 return "confusion in formal parameters";
924 /* Lookup the formal in the macro's list */
925 ptr = (formal_entry *) hash_find (m->formal_hash, sb_terminate (&t));
927 return "macro formal argument does not exist";
930 /* Insert this value into the right place */
931 sb_reset (&ptr->actual);
932 idx = get_any_string (idx + 1, in, &ptr->actual, 0, 0);
933 if (ptr->actual.len > 0)
939 /* This is a positional arg */
942 return "can't mix positional and keyword arguments";
950 return "too many positional arguments";
952 f = (formal_entry *) xmalloc (sizeof (formal_entry));
959 for (pf = &m->formals; *pf != NULL; pf = &(*pf)->next)
960 if ((*pf)->index >= c)
961 c = (*pf)->index + 1;
968 sb_reset (&f->actual);
969 idx = get_any_string (idx, in, &f->actual, 1, 0);
970 if (f->actual.len > 0)
976 while (f != NULL && f->index < 0);
980 idx = sb_skip_comma (idx, in);
983 if (in->ptr[idx] == ',')
985 if (ISWHITE (in->ptr[idx]))
995 sb_add_string (&t, macro_strip_at ? "$NARG" : "NARG");
996 ptr = (formal_entry *) hash_find (m->formal_hash, sb_terminate (&t));
997 sb_reset (&ptr->actual);
998 sprintf (buffer, "%d", narg);
999 sb_add_string (&ptr->actual, buffer);
1002 err = macro_expand_body (&m->sub, out, m->formals, m->formal_hash,
1007 /* Discard any unnamed formal arguments. */
1015 if ((*pf)->name.len != 0)
1019 sb_kill (&(*pf)->name);
1020 sb_kill (&(*pf)->def);
1021 sb_kill (&(*pf)->actual);
1035 /* Check for a macro. If one is found, put the expansion into
1036 *EXPAND. COMMENT_CHAR is the comment character--this is used by
1037 gasp. Return 1 if a macro is found, 0 otherwise. */
1040 check_macro (line, expand, comment_char, error)
1051 if (! isalpha ((unsigned char) *line)
1054 && (! macro_mri || *line != '.'))
1058 while (isalnum ((unsigned char) *s)
1063 copy = (char *) xmalloc (s - line + 1);
1064 memcpy (copy, line, s - line);
1065 copy[s - line] = '\0';
1066 for (cs = copy; *cs != '\0'; cs++)
1068 *cs = tolower (*cs);
1070 macro = (macro_entry *) hash_find (macro_hash, copy);
1075 /* Wrap the line up in an sb. */
1077 while (*s != '\0' && *s != '\n' && *s != '\r')
1078 sb_add_char (&line_sb, *s++);
1081 *error = macro_expand (0, &line_sb, macro, expand, comment_char);
1088 /* Delete a macro. */
1094 hash_delete (macro_hash, name);
1097 /* Handle the MRI IRP and IRPC pseudo-ops. These are handled as a
1098 combined macro definition and execution. This returns NULL on
1099 success, or an error message otherwise. */
1102 expand_irp (irpc, idx, in, out, get_line, comment_char)
1107 int (*get_line) PARAMS ((sb *));
1113 struct hash_control *h;
1121 idx = sb_skip_white (idx, in);
1124 if (! buffer_and_nest (mn, "ENDR", &sub, get_line))
1125 return "unexpected end of file in irp or irpc";
1131 idx = get_token (idx, in, &f.name);
1132 if (f.name.len == 0)
1133 return "missing model parameter";
1136 err = hash_jam (h, sb_terminate (&f.name), &f);
1145 idx = sb_skip_comma (idx, in);
1146 if (idx >= in->len || in->ptr[idx] == comment_char)
1148 /* Expand once with a null string. */
1149 err = macro_expand_body (&sub, out, &f, h, comment_char, 0);
1155 if (irpc && in->ptr[idx] == '"')
1157 while (idx < in->len && in->ptr[idx] != comment_char)
1160 idx = get_any_string (idx, in, &f.actual, 1, 0);
1163 if (in->ptr[idx] == '"')
1167 nxt = sb_skip_white (idx + 1, in);
1168 if (nxt >= in->len || in->ptr[nxt] == comment_char)
1174 sb_reset (&f.actual);
1175 sb_add_char (&f.actual, in->ptr[idx]);
1178 err = macro_expand_body (&sub, out, &f, h, comment_char, 0);
1182 idx = sb_skip_comma (idx, in);
1184 idx = sb_skip_white (idx, in);