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