148069Sbostic /*-
2*62161Sbostic * Copyright (c) 1980, 1993
3*62161Sbostic * The Regents of the University of California. All rights reserved.
448069Sbostic *
548069Sbostic * %sccs.include.redist.c%
622558Sdist */
75542Slinton
822558Sdist #ifndef lint
9*62161Sbostic static char sccsid[] = "@(#)build.c 8.1 (Berkeley) 06/06/93";
1048069Sbostic #endif /* not lint */
1148069Sbostic
125542Slinton /*
135542Slinton * parse tree building routines
145542Slinton *
155542Slinton * Semantics is not checked here, this is done by the "treetype" routine
165542Slinton * in the SYM directory which returns the type of the newly built tree.
175542Slinton */
185542Slinton
195542Slinton #include "defs.h"
205542Slinton #include "tree.h"
215542Slinton #include "sym.h"
225542Slinton #include "source.h"
235542Slinton #include "tree.rep"
245542Slinton
255542Slinton /*
265542Slinton * header for using routines with unknown number and types of arguments
275542Slinton * I didn't like the looks of the standard varargs.h.
285542Slinton */
295542Slinton
305542Slinton typedef char *ARGLIST;
315542Slinton
325542Slinton #define nextarg(arglist, type) ((type *) (arglist += sizeof(type)))[-1]
335542Slinton
345542Slinton /*
355542Slinton * build a tree
365542Slinton */
375542Slinton
385542Slinton /*VARARGS1*/
build(op,args)395542Slinton NODE *build(op, args)
405542Slinton OP op;
415542Slinton {
425542Slinton register NODE *p;
435542Slinton register ARGLIST ap;
445542Slinton
455542Slinton p = alloc(1, NODE);
465542Slinton p->op = op;
475542Slinton ap = (ARGLIST) &args;
485542Slinton switch(degree(op)) {
495542Slinton case BINARY:
5030852Smckusick p->left = nextarg(ap, NODE *);
5130852Smckusick p->right = nextarg(ap, NODE *);
525542Slinton break;
535542Slinton
545542Slinton case UNARY:
5530852Smckusick p->left = nextarg(ap, NODE *);
565542Slinton p->right = NIL;
575542Slinton break;
585542Slinton
595542Slinton }
605542Slinton switch(op) {
615542Slinton case O_NAME:
625542Slinton case O_WHICH:
635542Slinton p->nameval = nextarg(ap, SYM *);
645542Slinton break;
655542Slinton
665542Slinton case O_LCON:
675542Slinton p->lconval = nextarg(ap, long);
685542Slinton break;
695542Slinton
705542Slinton case O_FCON:
715542Slinton p->fconval = nextarg(ap, double);
725542Slinton break;
735542Slinton
745542Slinton case O_SCON:
755542Slinton p->sconval = nextarg(ap, char *);
765542Slinton break;
775542Slinton
785542Slinton case O_CALL:
795542Slinton p->left = nextarg(ap, NODE *);
805542Slinton p->right = nextarg(ap, NODE *);
815542Slinton break;
825542Slinton
835542Slinton case O_CHFILE:
845542Slinton p->sconval = nextarg(ap, char *);
855542Slinton break;
865542Slinton
875542Slinton case O_EDIT:
885542Slinton p->sconval = nextarg(ap, char *);
895542Slinton if (p->sconval == NIL) {
905542Slinton p->sconval = cursource;
915542Slinton }
925542Slinton break;
935542Slinton
945542Slinton case O_SOURCE:
955542Slinton p->sconval = nextarg(ap, char *);
965542Slinton break;
975542Slinton
985542Slinton case O_PRINT:
995542Slinton case O_WHATIS:
1005542Slinton case O_LIST:
1015542Slinton case O_XI:
1025542Slinton case O_XD:
1035542Slinton p->left = nextarg(ap, NODE *);
1045542Slinton break;
1055542Slinton
1065542Slinton case O_TRACE:
1075542Slinton case O_TRACEI:
1085542Slinton case O_STOP:
1095542Slinton case O_STOPI:
1105542Slinton p->what = nextarg(ap, NODE *);
1115542Slinton p->where = nextarg(ap, NODE *);
1125542Slinton p->cond = nextarg(ap, NODE *);
1135542Slinton break;
1145542Slinton
1155542Slinton case O_DELETE:
1165542Slinton p->left = build(O_LCON, nextarg(ap, long));
1175542Slinton break;
1185542Slinton
1195542Slinton case O_QLINE: {
1205542Slinton char *s;
1215542Slinton
1225542Slinton s = nextarg(ap, char *);
1235542Slinton p->left = alloc(1, NODE);
1245542Slinton p->left->op = O_SCON;
1255542Slinton if (s != cursource) {
1265542Slinton p->left->sconval = s;
1275542Slinton s[strlen(s) - 1] = '\0';
1285542Slinton } else {
1295542Slinton p->left->sconval = strdup(s);
1305542Slinton }
1315542Slinton p->right = nextarg(ap, NODE *);
1325542Slinton break;
1335542Slinton }
1345542Slinton
1355542Slinton case O_ALIAS:
1365542Slinton p->left = alloc(1, NODE);
1375542Slinton p->left->op = O_SCON;
1385542Slinton p->left->sconval = nextarg(ap, char *);
1395542Slinton p->right = alloc(1, NODE);
1405542Slinton p->right->op = O_SCON;
1415542Slinton p->right->sconval = nextarg(ap, char *);
1425542Slinton break;
1435542Slinton
1445542Slinton default:
1455542Slinton if (op < O_NOP || op > O_LASTOP) {
1465542Slinton panic("build: bad op %d", op);
1475542Slinton }
1485542Slinton break;
1495542Slinton }
1505542Slinton p->nodetype = treetype(p, (ARGLIST) &args);
1515542Slinton return(p);
1525542Slinton }
153