ftp.nice.ch/pub/next/developer/languages/ada/Adaed.1.11.s.tar.gz#/Adaed-1.11.0a/astread.c

This is astread.c in view mode; [Download] [Up]

/*
 * Copyright (C) 1985-1992  New York University
 * 
 * This file is part of the Ada/Ed-C system.  See the Ada/Ed README file for
 * warranty (none) and distribution info and also the GNU General Public
 * License for more details.

 */
#include "hdr.h"
#include "vars.h"
#include "attr.h"
#include "ifile.h"
#include "chapprots.h"
#include "libfprots.h"
#include "setprots.h"
#include "sspansprots.h"
#include "miscprots.h"
#include "smiscprots.h"
#include "astreadprots.h"
/* procedures to read the ast */
#define ZERO_NODE  9999

static Node astreadn(IFILE *);
static void attrnum(Node);

Node astreadu(IFILE *astfile)									/*;astreadu*/
{
	/* read next unit from file astfile. Build all necessary
	 * nodes and return the root node of the unit. This can be done in one
	 * pass since all sub-ast and list nodes appear before their "parents".
	 * The global tuple seq_node maps node sequence nubmers to their locations
	 * and is used to relocate pointers upon reading in nodes. 
	 * seq_node_n refers to the last node allocated.
	 */

	Node	node, comp_unit;

	for (;;) {
		node = astreadn(astfile); /* read next node */
		if (N_KIND(node) == as_astend) return node;
		if (N_KIND(node)== as_astnull) { /* if null node */
			comp_unit = (Node) seq_node[seq_node_n];
			return comp_unit;
		}
	}
}

static Node astreadn(IFILE *astfile)							/*;astreadn*/
{
	/* Return next node from ast file */
	/* Return node with kind 0 for null node, kind as_astend for EOF */

	int	c;
	int	n, astcount, listcount, val;
	int	iv, count;
	unsigned int kind;
	short	span0, span1;
	Tuple	list;
	Node	newn, nod;
	char	*newstr;

	count = getnum(astfile, "count");
	if (count == -1) {
		nod = node_new_noseq((unsigned) as_astend);
		return nod;
	}
	if (count == 0) {
		nod = node_new_noseq((unsigned) as_astnull);
		return nod;
	}

	/* Here at start of tuple */
	kind = (unsigned) getnum(astfile, "kind");
	/* allocate and initialize node */
	if (count <= seq_node_n) {
		/* copy of previously seen node, read in and ignore */
		newn = node_new_noseq(kind);
	}
	else if (count == seq_node_n + 1) {  /* next node in sequence */
		newn = node_new(kind);
	}
	else { /* unexpected node number */
		chaos("astreadn: node out of sequence");
	}
	if (newn == (Node) 0) {
		printf("astread cannot allocate node kind %d\n", kind);
		chaos("astread - bad kind");
	}
	if (is_terminal_node(kind)) {
		span0 = getnum(astfile, "span-line");
		span1 = getnum(astfile, "span-col");
	}
	if (kind != as_line_no) {
		/* as_line_no nodes do not have ast or list fields */
		astcount = getnum(astfile, "astcount");
		/* we need to distinguish the zero entered as initial value of AST
		 * field from the 0 used in input format to indicate OPT_NODE. Hence
		 * we mark nodes with ZERO_NODE, and then change values explicitly
		 * entered as zero to OPT_NODE
		 */
		N_AST1(newn) = (Node)ZERO_NODE;
		N_AST2(newn) = (Node)ZERO_NODE;
		N_AST3(newn) = (Node)ZERO_NODE;
		N_AST4(newn) = (Node)ZERO_NODE;
		/* Now read ast count*/
		for (n = 1; n <= astcount; n++) {
			c = getnum(astfile, "ast-count");
			if (c >= N_SEQ(newn))
				printf("astreadn: forward pointer in ast\n");
			switch (n) {
			case(1):	
				N_AST1(newn) = (Node) c; 
				break;
			case(2):	
				N_AST2(newn) = (Node) c; 
				break;
			case(3):	
				N_AST3(newn) = (Node) c; 
				break;
			case(4):	
				N_AST4(newn) = (Node) c; 
				break;
			default: 
				chaos("astreadn too many ast entries");
			};
		}
		if (N_AST1(newn) == (Node)0) N_AST1(newn) = OPT_NODE;
		else if (N_AST1(newn) != (Node)ZERO_NODE)
			N_AST1(newn) = (Node) seq_node[(int)N_AST1(newn)];
		else N_AST1(newn) = (Node)0;

		if (N_AST2(newn) == (Node)0) N_AST2(newn) = OPT_NODE;
		else if (N_AST2(newn) != (Node)ZERO_NODE)
			N_AST2(newn) = (Node) seq_node[(int)N_AST2(newn)];
		else N_AST2(newn) = (Node)0;

		if (N_AST3(newn) == (Node)0) N_AST3(newn) = OPT_NODE;
		else if (N_AST3(newn) != (Node)ZERO_NODE)
			N_AST3(newn) = (Node) seq_node[(int)N_AST3(newn)];
		else N_AST3(newn) = (Node)0;

		if (N_AST4(newn) == (Node) 0) N_AST4(newn) = OPT_NODE;
		else if (N_AST4(newn) != (Node)ZERO_NODE)
			N_AST4(newn) = (Node) seq_node[(int)N_AST4(newn)];
		else N_AST4(newn) = (Node)0;

		/* convert attribute string to internal code */
		if (N_KIND(newn) == as_attribute || N_KIND(newn) == as_range_attribute)
			attrnum(newn);
		/* now process list field */
		listcount = getnum(astfile, "if-list");
		if (listcount >= 0) {
			list = tup_new(listcount);
			for (n = 1; n <= listcount; n++) {
				val = getnum(astfile, "list-val");
				if (val >= N_SEQ(newn))
					printf("astreadn: forward pointer in ast\n");
				list[n] = (char *) seq_node[val];
			}
			N_LIST(newn) = list;
		}

		iv = getnum(astfile, "iv");
		if (iv == 0 ) goto set_span;

		newstr = getstr(astfile, "val");

		/* If mode, needing argument type conversion*/
		if (N_KIND(newn) == as_mode) {
			/* Input from tree has string. We convert to appropriate code
			 * according to the length of the string. This is sufficient, and
			 * avoids having to look at the characters in the string.
			 */
			n = strlen(newstr);
			switch(n) {
			case (0):	
				N_VAL(newn) = (char * ) 0; 
				break;
			case (2):	
				N_VAL(newn) = (char * ) na_in; 
				break;
			case (3):	
				N_VAL(newn) = (char * ) na_out; 
				break;
			case (5):	
				N_VAL(newn) = (char * ) na_inout; 
				break;
			default:	
				printf(" node type as_mode invalid argument type %s\n", newstr);
				/* how to indicate node error - TBSL */
			}
		}
		else {
			N_VAL(newn) = newstr;
		}
	} /* end of processing "non as_line_no" nodes */
	else {
		/* here, handle as_line_no which has just one integer field */
		c = getnum(astfile, "line-no");
		N_VAL(newn) = (char *) c;
	}
set_span:
	if (is_terminal_node(kind)) {
		N_SPAN0(newn) = span0;
		N_SPAN1(newn) = span1;
	}
	return newn;
}

static void attrnum(Node node)										/*;attrnum*/
{
	/* convert attribute string to internal attribute code */
	int		i;
	char	*s, *name;
	static char *attrnames[] = {
		"ADDRESS",
		"AFT",
		"BASE",
		"CALLABLE",
		"CONSTRAINED",
		"O_CONSTRAINED",
		"T_CONSTRAINED",
		"COUNT",
		"DELTA",
		"DIGITS",
		"EMAX",
		"EPSILON",
		"FIRST",
		"O_FIRST",
		"T_FIRST",
		"FIRST_BIT",
		"FORE",
		"IMAGE",
		"LARGE",
		"LAST",
		"O_LAST",
		"T_LAST",
		"LAST_BIT",
		"LENGTH",
		"O_LENGTH",
		"T_LENGTH",
		"MACHINE_EMAX",
		"MACHINE_EMIN",
		"MACHINE_MANTISSA",
		"MACHINE_OVERFLOWS",
		"MACHINE_RADIX",
		"MACHINE_ROUNDS",
		"MANTISSA",
		"POS",
		"POSITION",
		"PRED",
		"RANGE",
		"O_RANGE",
		"T_RANGE",
		"SAFE_EMAX",
		"SAFE_LARGE",
		"SAFE_SMALL",
		"SIZE",
		"O_SIZE",
		"T_SIZE",
		"SMALL",
		"STORAGE_SIZE",
		"SUCC",
		"TERMINATED",
		"VAL",
		"VALUE",
		"WIDTH",
		0	};

	s = N_VAL(N_AST1(node));
	for (i = 0;; i++) {
		name = attrnames[i];
		if (name == (char *)0) break;
		if (streq(name, s)) {
			/* on match, change ast1 node to hold number, not str*/
			N_KIND(N_AST1(node)) = as_number;
			N_VAL(N_AST1(node)) = (char *) i;
			break;
		}
	}
#ifdef IGNORE
	printf("attribute %s\n", s);
	chaos("unable to match attribute name");
#endif
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.