xref: /csrg-svn/usr.bin/pascal/pdx/tree/build.c (revision 62161)
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