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.