2 * Copyright (C) 1991,1992 Erik Schoenfelder (schoenfr@ibr.cs.tu-bs.de)
4 * This file is part of NASE A60.
6 * NASE A60 is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
11 * NASE A60 is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with NASE A60; see the file COPYING. If not, write to the Free
18 * Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
22 * Erik Schoenfelder (schoenfr@ibr.cs.tu-bs.de)
32 char *sym_tag_name[] = {
42 new_symbol (name, type, tag)
47 SYMTAB *new = TALLOC (SYMTAB);
56 new->source = infname;
64 * return a new data record; next-ptr (last activation) is appended
71 DATA *new = TALLOC (DATA);
79 sym_all_type (s, type, own)
93 find_in_symtab (symtab, name)
97 for ( ; symtab && strcmp (symtab->name, name);
105 append_symtab (s1, s2)
116 examine_and_append_symtab (s1, s2)
125 for (s=s2; s; s=s->next) {
127 if (find_in_symtab (*s1, s->name)) {
128 a60_error (infname, lineno,
129 "duplicate symbol name `%s'\n", s->name);
134 append_symtab (s1, s2);
143 cleanup_identifier (str)
146 char *from_ptr = str, *to_ptr = str;
149 if (*from_ptr != ' ')
150 *to_ptr++ = *from_ptr;
170 print_expr (b->high);
173 print_bounds (b->next);
178 print_indent_proc (s, n)
184 if (s->type == ty_proc)
188 type_tag_name[TPROC_BASE(s->type)]);
189 printf("PROC [nparms: %d] pblock: (0x%lx; up 0x%lx; ext_ref %d)\n",
190 s->u.pproc->nparm, (long) s->u.pproc->block,
191 (long) s->u.pproc->block->up,
192 (int) s->u.pproc->block->ext_ref);
195 print_indent_symtab (s->u.pproc->block->symtab, n+4);
197 if(! s->u.pproc->block->stmt) {
199 printf ("<external reference>\n");
202 print_indent_tree (s->u.pproc->block->stmt, 0, n+4);
207 print_indent_switch_decl (s, n)
213 for (expr = s->u.dexpr; expr; expr = expr->next) {
214 if (expr != s->u.dexpr)
226 print_indent_symbol (s, n)
234 printf ("%s %s (%s)",
235 type_tag_name[s->type],
237 sym_tag_name[s->tag]);
239 if (TIS_ARR(s->type)) {
241 a60_error ("INTERNAL", 0, "INTERNAL: arr in nil\n");
243 printf (" dim %d; ", s->u.arr->dim);
244 print_bounds (s->u.arr->bound);
248 printf (" (sym 0x%lx;%s idx %d; block 0x%lx)\n",
249 (long) s, (s->own) ? " OWN" : "",
250 s->actidx, (long) s->block);
252 if (s->tag != s_byname && TIS_PROC(s->type))
253 print_indent_proc (s, n+2);
255 if (s->tag != s_byname && s->type == ty_switch) {
258 print_indent_switch_decl (s, n+8);
264 print_indent_symtab (s, n)
269 print_indent_symbol (s, n);
270 print_indent_symtab (s->next, n);
276 * scope management; on parsetime the scope list is handled like
277 * a stack; a new scope is instered at the beginning on a block
278 * entry and removed on exit.
281 SCOPE *current_scope = 0;
282 static SCOPE *sroot = 0;
287 SCOPE *new = TALLOC (SCOPE);
290 new->block = TALLOC (BLOCK);
292 new->block->up = current_scope->block;
295 new->symtab = & new->block->symtab;
299 current_scope = sroot;
303 close_current_scope ()
306 xabort("close_current_scope: nil ???");
308 if (current_scope->marked)
311 current_scope = sroot = current_scope->next;
316 * add a new symbol to the marked list for `symbol not found'...
320 add_marked_sym (lhelm)
323 MARK *new =TALLOC (MARK);
326 new->next = current_scope->marked;
327 current_scope->marked = new;
334 MARK *mark = current_scope->marked;
345 if (osym->tag != s_undef)
346 xabort ("INTERNAL: examine_marked: still defd");
348 sym = find_symbol_anywhere (name, current_scope->block,
352 a60_error (osym->source, osym->lineno,
353 "undeclared symbol `%s'\n", name);
357 xfree ((char *) osym);
359 lhelm->nscop = nscop;
368 * climb through the scopes looking for the given symbol.
372 find_symbol_anywhere (name, block, nscop)
380 if (! block || ! name)
383 s = find_in_symtab (block->symtab, name);
390 * extra check for extern reference:
391 * (allow recursion and check for func-var on lefthand)
393 if (block->up && (s = find_in_symtab (block->up->symtab, name)))
396 s = find_symbol_anywhere (name, block->up, nscop);
399 if (! s || ! up_ref || ! TIS_PROC(s->type)) {
400 /* inc extern reference: */
409 * return number of bounds.
418 for (n=0; b; n++, b=b->next)
427 * return number of symbols in symtab.
436 for (n=0; s; n++, s=s->next)
444 * set all syms in symtab to call_by_value;
445 * the syms are freed.
449 set_by_value (symtab, syms)
450 SYMTAB *symtab, *syms;
457 fnd = find_in_symtab (symtab, sym->name);
459 if (fnd->type == ty_unknown) {
460 a60_error (sym->source, sym->lineno,
461 "no specification present for `%s'\n", sym->name);
464 fnd->tag = s_byvalue;
467 a60_error (sym->source, sym->lineno,
468 "not in parameter list `%s'\n", sym->name);
472 xfree ((char *) sym);
478 * replace the type from syms in symtab;
483 replace_type (symtab, syms)
484 SYMTAB *symtab, *syms;
491 fnd = find_in_symtab (symtab, sym->name);
493 if (fnd->type != ty_unknown)
494 a60_error ("INTERNAL", 0,
495 "INTERNAL: replace_type: still defd\n");
496 fnd->type = sym->type;
499 a60_error (sym->source, sym->lineno,
500 "not in parameter list `%s'\n", sym->name);
504 xfree ((char *) sym);
518 return set_idx (symtab->next, n+1);
525 return set_idx (symtab, 0);
530 * find the reference for an identifier.
534 make_var_ref (name, mark)
544 sym = find_symbol_anywhere (name, current_scope->block,
553 a60_error (infname, lineno,
554 "undeclared symbol `%s'\n", name);
559 sym = new_symbol (name, ty_unknown, s_undef);
564 new = new_lhelm (sym);
567 if (not_found && mark)
568 add_marked_sym (new);
573 /* end of symtab.c */