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.