Logo Search packages:      
Sourcecode: nase-a60 version File versions

tree.c

/*
 * Copyright (C) 1991,1999 Erik Schoenfelder (schoenfr@ibr.cs.tu-bs.de)
 *
 * This file is part of NASE A60.
 * 
 * NASE A60 is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * NASE A60 is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with NASE A60; see the file COPYING.  If not, write to the Free
 * Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * tree.c:                          aug '90
 *
 * Erik Schoenfelder (schoenfr@ibr.cs.tu-bs.de)
 */

#include "comm.h"
#include "a60.h"
#include "util.h"
#include "tree.h"
#include "run.h"

/*
 * indent for code and for symtab.
 */
#define INDENT          4
#define SINDENT         6



char *
tree_tag_name[] = {
      "block",
      "label",
      "dummy stmt",
      "goto stmt",
      "assign stmt",
      "if stmt",
      "proc stmt",
      "for stmt",
      "last tree tag name"
};


/*
 * return a new tree element; lineno and source is set.
 */

TREE *
new_tree (tag)
ENUM tree_tag tag;
{
      TREE *new = TALLOC (TREE);
      new->source = infname;
      new->lineno = lineno;
      new->tag = tag;
      new->runme = run_dummy;
      new->next = (TREE *) 0;

      return new;
}


MINDEX *
new_mindex (e)
EXPR *e;
{
      MINDEX *new = TALLOC (MINDEX);

      new->expr = e;
      new->next = 0;

      return new;
}


LHELM *
new_lhelm (s)
SYMTAB *s;
{
      LHELM *new = TALLOC (LHELM);

      new->sym = s;
      new->mindex = 0;
      new->next = 0;

      new->source = infname;
      new->lineno = lineno;

      return new;
}


/*
 * make a new funcall struct.
 */

FUNCALL *
new_funcall (sym, parm)
SYMTAB *sym;
EXPR *parm;
{
      FUNCALL *new = TALLOC (FUNCALL);
      EXPR *ex;
      int n;

      for (n=0, ex=parm; ex; n++, ex=ex->next)
            continue;

      new->sym = sym;
      new->parm = parm;
      new->nparm = n;

      return new;
}


void
print_mindex (idx)
MINDEX *idx;
{
      printf ("[");
      for (; idx; idx=idx->next) {
            print_expr (idx->expr);
            if (idx->next)
                  printf (",");
      }
      printf ("]");
}


void
print_indent (n)
int n;
{
      while (n-- > 0)
            printf (" ");
}



static void
print_assign (t)
TREE *t;
{
      LHELM *l;

      printf ("assign");
      
      for (l=t->u.ass->lhelm; l; l=l->next) {
            printf (" %s (block 0x%lx) ", l->sym->name,
                  (long) (l->sym->block));
            if (l->mindex)
                  print_mindex (l->mindex);
            printf (" := ");
      }
      print_expr (t->u.ass->expr);
      printf ("\n");
}


static void
print_indent_ifstmt (t, n)
TREE *t;
int n;
{
      printf ("if");
      print_expr (t->u.ifstmt->cond);
      printf ("\n");
      print_indent (n+2);
      printf ("then\n");
      print_indent_tree (t->u.ifstmt->tthen, 1, n+4);
      if (t->u.ifstmt->telse) {
            print_indent (n+2);
            printf ("else\n");
            print_indent_tree (t->u.ifstmt->telse, 1, n+4);
      }
}


static void
print_indent_forstmt (t, n)
TREE *t;
int n;
{
      FORSTMT *fs = t->u.forstmt;
      FORELM *fe;

      printf ("for");
      printf (" %s (%s) := ", fs->lvar->sym->name,
            type_tag_name[fs->lvar->sym->type]);
      
      for (fe=fs->forelm; fe; fe=fe->next) {
            if (fe->tag == fe_expr) {
                  print_expr (fe->expr[0]);
            }
            else if (fe->tag == fe_until) {
                  print_expr (fe->expr[0]);
                  printf (" STEP ");
                  print_expr (fe->expr[1]);
                  printf (" UNTIL ");
                  print_expr (fe->expr[2]);
            }
            else if (fe->tag == fe_while) {
                  print_expr (fe->expr[0]);
                  printf (" WHILE ");
                  print_expr (fe->expr[1]);
            }
            else
                  xabort ("INTRNAL: bad tag in forelm");
            
            if (fe->next)
                  printf (", ");
      }
      
      printf (" DO\n");
      print_indent_tree (fs->stmt, 0, n+4);
}


static void
print_proc (t)
TREE *t;
{
      EXPR *ex;
      char *name = t->u.funcall->sym->name;

      if (! strcmp (name, "outstring"))
            name = "B_OUTSTR";
      else if (! strcmp (name, "outreal"))
            name = "B_OUTREAL";

      printf ("%s ( ", name);

      for (ex=t->u.funcall->parm; ex; ex=ex->next) {
            print_expr (ex);
            if (ex->next)
                  printf (", ");
      }
      printf (" )\n");
}

/*
 * now an goto may be an label or swich-target;
 */

static void
print_goto (t)
TREE *t;
{
      printf ("goto ");
      print_expr (t->u.dexpr);
      printf ("\n");
}


void
print_indent_tree (t, ret_if_cont, n)
TREE *t;
int ret_if_cont, n;
{
      print_indent (n);

      if (! t) {
            printf("<end of list>\n");
            return;
      }

      switch (t->tag) {
      case t_block:
            printf("block: (0x%lx; up 0x%lx; ext_ref %d)\n",
                   (long) t->u.block, (long) t->u.block->up,
                   (int) t->u.block->ext_ref);
            /* skip builtin symbols ... */
            if (t->u.block->symtab)
#ifdef DEBUG
                  if (do_debug || t->u.block->up)
                        print_indent_symtab (t->u.block->symtab,
                                         n+SINDENT);
#endif /* DEBUG */
            print_indent_tree (t->u.block->stmt, 0, n+INDENT);
            break;
      case t_dummy_stmt:
            printf ("dummy stmt\n");
            break;
      case t_goto_stmt:
            print_goto (t);
            break;
      case t_assign_stmt:
            print_assign (t);
            break;
      case t_if_stmt:
            print_indent_ifstmt (t, n);
            break;
      case t_label:
            printf ("%s:  (%s; sym 0x%lx; next 0x%lx)\n",
                  (t->u.symbol) ?
                  t->u.symbol->name : "!!unknown!!",
                  (t->u.symbol) ?
                  sym_tag_name[t->u.symbol->tag] : "???",
                  (long) t->u.symbol,
                  (long) t->next);
            break;
      case t_proc_stmt:
            print_proc (t);
            break;
      case t_for_stmt: 
            print_indent_forstmt (t, n);
            break;
      default:
            printf ("default: ??? (tag %d)\n", t->tag);
            break;
      }                 
      
      if (ret_if_cont && t->is_cont) {
            print_indent (n);
            printf("<end of list>\n");
            return;
      }

      print_indent_tree (t->next, 0, n);
}

void
print_tree (t)
TREE *t;
{
      print_indent_tree (t, 0, 0);
      printf ("\n");
}


Generated by  Doxygen 1.6.0   Back to index