/* * Top level of the RSL parser/type checker. */ #include #include #include "list.h" #include "std-macros.h" #include "parse-tree.h" #include "sym.h" #include "options.h" #include "parser.h" #include "tokens.h" #include "translator.h" #include "type-preds.h" #include "utilities.h" #include "sym-aux.h" #include "universe.h" #include "token-mapping.h" #ifdef COBRA #define int32_t int #endif #include #define ungetchar(c) ungetc(c, yyin) #ifdef YYDEBUG extern int yydebug; #endif int ANY_PARSE_ERROR; int DEBUGGING; /* set true for system-level debugging */ int ly; extern FILE *yyin; extern int yylineno; extern int yycharno; extern int yycharpos; extern char* yyfilename; /* extern langType parse_language; */ #ifndef BROWSER int main(int argc, char *argv[]) #else int translator(int argc, char *argv[]) #endif { FILE *fp; char option; bool doBatchSpec(int argc, char *argv[]); void doConverseSpec(int argc, char *argv[]); int rtn; OptionsStatus optstat; if( argc < 2 ) { PrintUsage(); #ifndef BROWSER exit(0); #else return -1; #endif } interactive = false; InitOptions(); switch (ProcessCommandLineOptions(argc, argv)) { case OPTIONS_OK: break; case OPTIONS_FAILED: #ifndef BROWSER exit(0); #else return -1; #endif break; case OPTIONS_START_INTERACTIVE: interactive = true; doConverseSpec(argc, argv); break; } if (! interactive) { rtn = doBatchSpec(argc, argv); #ifdef BROWSER if (not rtn) return -1; else return 1; /* if (ANY_PARSE_ERROR) return -1; else return rtn; */ #endif exit(EXIT_SUCCESS); } } bool doBatchSpec(int argc, char *argv[]) { nodep ptree = null; char c; bool FoundFile; void pp(nodep t); void DumpSymtab(Symtab *Tab, int Level); bool chk; TypeStruct t; #ifdef YYDEBUG ly = 0; yydebug = ly; #endif DEBUGGING = 0; InitLex(); /*InitParser();*/ InitSymtab(); InitSymtabAux(); InitTypechk(); InitErrors(); InitMainChkList(); InitUniverse(); ANY_PARSE_ERROR = false; /* * Here's the checking strategy: * (a) Parse each module and hang its full parse tree off its symtab. * (b) Parse each loose top-level entity decl, and hang parse tree on * top-level check list (these are entity_spec_lists). * (c) After all parsing is done, check each module and the top-level * check list. * We wait till all parsing is done before doing any checking so that we * don't impose a strict declare-before use regime on decls. Note that all * loose entity decls are put in the default level 1 main symtab. In this * way, all spec checking is done uniformly starting at the module level. */ FoundFile = GetFirstInFile(argc, argv); while (FoundFile) { while ((c = getc(yyin)) != EOF) { /* * Consume extra newline chars at the beginning or end of a file. */ if (c == '\n') { yylineno++; yycharno = 1; yycharpos += 1; continue; } ungetchar(c); ptree = parser(); if (PARSE_ERROR) ANY_PARSE_ERROR = true; if (ptree) { if (DEBUGGING) { pp(ptree); printf("\n"); } if (not isTopLevelExpr(ptree)) { AddSpec(ptree); } } else { if (DEBUGGING) printf("EMPTY OR ERRONEOUS PARSE TREE.\n"); } if (DEBUGGING) printf("\n"); MoveToSymtab(MainSymtab); } FoundFile = GetNextInFile(argc, argv); ForceEOF(); } if (! ANY_PARSE_ERROR) { FixMainList(); } if (DEBUGGING) { printf("\n"); DumpSymtab(Level0Symtab, 0); } if (! ANY_PARSE_ERROR) { chk = chkSpec(); } /* * Execute if all checking succeeds. */ if ((not ANY_PARSE_ERROR) and chk) { runSpec(); } if (DEBUGGING) { printf("\n"); DumpSymtab(Level0Symtab, 0); } return ((not ANY_PARSE_ERROR) and chk); } void doConverseSpec(int argc, char *argv[]) { nodep ptree; char c; bool FoundFile; void pp(nodep t); void DumpSymtab(Symtab *Tab, int Level); #ifdef YYDEBUG ly = 0; yydebug = ly; #endif DEBUGGING = 1; InitLex(); /*InitParser();*/ InitSymtab(); InitSymtabAux(); InitTypechk(); InitErrors(); InitMainChkList(); ANY_PARSE_ERROR = false; /* * Here's the checking strategy: * (a) Parse each module and hang its full parse tree off its symtab. * (b) Parse each loose top-level entity decl, and hang parse tree on * top-level check list. * (c) After all parsing is done, check each module and the top-level * check list. * We wait till all parsing is done before doing any checking so that * we don't impose a strict declare-before use regime on decls. */ /* FoundFile = GetFirstInFile(argc, argv); */ while (GetLine(yyin)) { /* while ((c = getc(yyin)) != EOF) { ungetchar(c); */ Parsing = true; /* switch (parse_language) { case SPEC: */ ptree = parser(); /* break; case MOD: break; } */ Parsing = false; if (PARSE_ERROR) ANY_PARSE_ERROR = true; if (ptree) { /* if (ptree->header.name != YLANGUAGE) { */ if (DEBUGGING) { pp(ptree); printf("\n"); } AddSpec(ptree); } else { if (DEBUGGING) printf("EMPTY OR ERRONEOUS PARSE TREE.\n"); } if (DEBUGGING) printf("\n"); MoveToSymtab(MainSymtab); /* } */ /* FoundFile = GetNextInFile(argc, argv); */ } if (! ANY_PARSE_ERROR) { FixMainList(); } if (DEBUGGING) { printf("\n"); DumpSymtab(Level0Symtab, 0); } if (! ANY_PARSE_ERROR) { ChkSpec(); } if (DEBUGGING) { printf("\n"); DumpSymtab(Level0Symtab, 0); } /* if (! ANY_PARSE_ERROR) { TypeChkSpec(); } */ } void pp(nodep t) { void pp1(nodep t, int level); printf("PARSE TREE:\n"); pp1(t,0); fflush(stdout); } void pp1(nodep t, int level) { int i; nodep t1; char *name; if (t == null) return; for (i=2*level; i>0; printf(" "), i--); switch (t->header.kind) { case MODULE_NODE: name = (LookupString(t->components.module.name-> components.atom.val.text))->Symbol; switch (t->header.name) { case YOBJ: /* this is the only case at present */ printf("SPEC_MODULE %s:\n", name); break; } pp1(t->components.module.parms,level+1); pp1(t->components.module.priority,level+1); pp1(t->components.module.imports,level+1); pp1(t->components.module.exports,level+1); pp1(t->components.module.body,level+1); break; case SPEC_NODE: printf("SPEC_NODE:\n"); pp1(t->components.spec.entities,level+1); break; case BLOCK_NODE: printf("BLOCK_NODE:\n"); pp1(t->components.block.decls,level+1); pp1(t->components.block.stmts,level+1); break; case DECL_NODE: switch (t->header.name) { case YOBJ: if (t->components.decl.kind.obj.flags & isClass) printf("CLASS "); printf("OBJ_DECL_NODE:\n"); pp1(t->components.decl.kind.obj.name,level+1); if (t->components.decl.kind.obj.inheritsfrom) { for (i=2*level+1; i>0; printf(" "), i--); printf("instance of:\n"); pp1(t->components.decl.kind.obj.inheritsfrom,level+1); } pp1(t->components.decl.kind.obj.parts,level+1); pp1(t->components.decl.kind.obj.ops,level+1); pp1(t->components.decl.kind.obj.eqns,level+1); pp1(t->components.decl.kind.obj.attrs,level+1); break; case YOP: if (t->components.decl.kind.obj.flags & isClass) printf("CLASS "); printf("OP_DECL_NODE:\n"); pp1(t->components.decl.kind.op.name,level+1); if (t->components.decl.kind.op.inheritsfrom) { for (i=2*level+1; i>0; printf(" "), i--); printf("instance of:\n"); pp1(t->components.decl.kind.op.inheritsfrom,level+1); } pp1(t->components.decl.kind.op.parts,level+1); pp1(t->components.decl.kind.op.ins,level+1); pp1(t->components.decl.kind.op.outs,level+1); pp1(t->components.decl.kind.op.precond,level+1); pp1(t->components.decl.kind.op.postcond,level+1); pp1(t->components.decl.kind.op.attrs,level+1); break; case ':': /* an attr/value pair */ printf("NAME/VALUE_PAIR_NODE:\n"); for (i=2*level+1; i>0; printf(" "), i--); printf("name:\n"); pp1(t->components.decl.kind.attr.name,level+1); for (i=2*level+1; i>0; printf(" "), i--); printf("value:\n"); if (t->components.decl.kind.attr.colon) { for (i=2*level+1; i>0; printf(" "), i--); printf(" "); printf("\n"); } pp1(t->components.decl.kind.attr.value,level+1); break; case 'f': /* built record field */ printf("RECORD_FIELD_NODE:\n"); for (i=2*level+1; i>0; printf(" "), i--); printf("vars:\n"); pp1(t->components.decl.kind.field.vars,level+1); for (i=2*level+1; i>0; printf(" "), i--); printf("type:\n"); pp1(t->components.decl.kind.field.type,level+1); break; case '=': /* where clause */ printf("WHERE_NODE:\n"); pp1(t->components.decl.kind.eq.left_operand,level+1); pp1(t->components.decl.kind.eq.right_operand,level+1); break; case YEQUATIONS: printf("EQUATION_DECL_NODE:\n"); for (i=2*level+1; i>0; printf(" "), i--); pp1(t->components.decl.kind.eqns.vars,level+1); pp1(t->components.decl.kind.eqns.eqns,level+1); break; case YEQEQ: printf("EQUATION_NODE:\n"); for (i=2*level+1; i>0; printf(" "), i--); pp1(t->components.decl.kind.eqn.lhs,level+1); pp1(t->components.decl.kind.eqn.rhs,level+1); break; case YVAR: printf("VAR_DECL_NODE:\n"); pp1(t->components.decl.kind.var.vars,level+1); pp1(t->components.decl.kind.var.type,level+1); pp1(t->components.decl.kind.var.next,level); break; case YAX: printf("AXIOM_DECL_NODE:\n"); for (i=2*level+1; i>0; printf(" "), i--); printf("NAME: %s\n", (t1 = t->components.decl.kind.formaldef.name) ? t1->components.atom.val.text : "none"); pp1(t->components.decl.kind.var.vars,level+1); pp1(t->components.decl.kind.formaldef.expr,level+1); break; case YTHM: printf("THM_DECL_NODE:\n"); for (i=2*level+1; i>0; printf(" "), i--); printf("NAME: %s\n", (t1 = t->components.decl.kind.formaldef.name) ? t1->components.atom.val.text : "none"); pp1(t->components.decl.kind.var.vars,level+1); pp1(t->components.decl.kind.formaldef.expr,level+1); break; case YASSMNT: printf("INIT_DECL_NODE:\n"); pp1(t->components.decl.kind.initdecl.decl,level+1); /* pp1(t->components.decl.kind.initdecl.init,level+1); */ break; case '(': if (t->components.decl.kind.parm.isvar) printf("VAR "); if (t->components.decl.kind.parm.isarray) printf("OPEN_ARRAY "); printf("PARM_DECL_NODE:\n"); pp1(t->components.decl.kind.parm.vars,level+1); pp1(t->components.decl.kind.parm.type,level+1); break; case YMODULE: printf("LOCAL_MODULE_DECL_NODE:\n"); pp1(t->components.decl.kind.module,level+1); break; case YIMPORT: printf("IMPORT_DECL_NODE:\n"); pp1(t->components.decl.kind.import.items,level+1); for (i=2*level+1; i>0; printf(" "), i--); printf("ISALL: %d\n", t->components.decl.kind.import.isall); if (t->components.decl.kind.import.except) { for (i=2*level+1; i>0; printf(" "), i--); printf("EXCEPT: "); pp1(t->components.decl.kind.import.except, level+1); } break; case YEXPORT: printf("EXPORT_DECL_NODE:\n"); pp1(t->components.decl.kind.export_.names, level+1); printf(" %d\n", t->components.decl.kind.export_.isall); pp1(t->components.decl.kind.export_.except, level+1); break; case YLET: printf("LET_DECL_NODE:\n"); pp1(t->components.decl.kind.let.names,level+1); pp1(t->components.decl.kind.let.expr,level+1); pp1(t->components.decl.kind.let.type,level+1); break; case YPRE: printf("PRECOND_DECL_NODE:\n"); pp1(t->components.decl.kind.pre.expr,level+1); break; case YPOST: printf("PRECOND_DECL_NODE:\n"); pp1(t->components.decl.kind.pre.expr,level+1); break; case YLIST: printf("EXPR_SEQ_NODE:\n"); pp1(t->components.decl.kind.expr,level+1); break; case YFORALL: case YEXISTS: printf("%s\n", (t->header.name == YFORALL) ? "YFORALL" : "YEXISTS"); pp1(t->components.decl.kind.quant.vars,level+1); for (i=2*level+1; i>0; printf(" "), i--); if (t->components.decl.kind.quant.in) { printf("%s:\n", t->components.decl.kind.quant.in-> header.name == YIN ? "IN" : "SUCH THAT:"); pp1(t->components.decl.kind.quant.in,level+1); } for (i=2*level+1; i>0; printf(" "), i--); printf("EXPR:\n"); pp1(t->components.decl.kind.quant.expr,level+1); break; } pp1(t->components.decl.next,level); break; case EXPR_LIST_NODE: printf("EXPR_LIST_NODE:\n"); for (t1=t; t; t=t->components.exprlist.next) pp1(t->components.exprlist.expr, level+1); break; case BINOP_NODE: printf("BINOP_NODE, OPERATOR: "); switch (t->header.name) { case YASSMNT: printf(":="); break; case '=': case '#': case '<': case '>': case '+': case '-': case '*': case '/': case '.': case '^': printf("%c", t->header.name); break; case '[': printf("[]"); break; case '(': printf("("); break; case YNEQ: printf("!="); break; case YLEQ: printf("<="); break; case YGEQ: printf(">="); break; case YIN: printf("in"); break; case YOR: printf("or"); break; case YAND: printf("and"); break; case YDIV: printf("div"); break; case YMOD: printf("mod"); break; case YIMPLIES: printf("implies"); break; case YEXISTS: printf("exists"); break; case YIFF: printf("iff"); break; } printf("\n"); for (i=2*level+1; i>0; printf(" "), i--); printf("LEFT_OPRND:\n"); pp1(t->components.binop.left_operand, level+1); for (i=2*level+1; i>0; printf(" "), i--); printf("RIGHT_OPRND:\n"); pp1(t->components.binop.right_operand, level+1); break; case UNOP_NODE: printf("UNOP_NODE, OPERATOR: "); switch (t->header.name) { case '+': case '-': case '#': case '[': case ']': printf("%c\n", t->header.name); break; case YNOT: printf("not\n"); break; case YUNYPLUS: printf("+\n"); break; case YUNYMINUS: printf("-\n"); break; case YLET: printf("let\n"); break; } for (i=2*level+1; i>0; printf(" "), i--); printf("OPRND:\n"); pp1(t->components.unop.operand, level+1); break; case TRINOP_NODE: printf("TRINOP_NODE, OPERATOR: "); switch (t->header.name) { case YIF: printf("if:\n"); pp1(t->components.trinop.left_operand,level+1); for (i=2*level+1; i>0; printf(" "), i--); printf("THEN_PART:\n"); pp1(t->components.trinop.middle_operand,level+1); if (t->components.trinop.right_operand) { for (i=2*level+1; i>0; printf(" "), i--); printf("ELSE_PART:\n"); pp1(t->components.trinop.right_operand,level+1); } break; case YFORALL: printf("YFORALL:\n"); pp1(t->components.trinop.left_operand,level+1); for (i=2*level+1; i>0; printf(" "), i--); printf("SUCH THAT:\n"); pp1(t->components.trinop.middle_operand,level+1); if (t->components.stmt.kind.ifstmt.elsepart) { for (i=2*level+1; i>0; printf(" "), i--); printf("CLAUSE\n"); pp1(t->components.stmt.kind.ifstmt.elsepart,level+1); } break; case YIN: /* shorthand "forall (s in S) ... " */ printf("YFORALL:\n"); pp1(t->components.trinop.left_operand,level+1); for (i=2*level+1; i>0; printf(" "), i--); printf("IN:\n"); pp1(t->components.trinop.middle_operand,level+1); if (t->components.stmt.kind.ifstmt.elsepart) { for (i=2*level+1; i>0; printf(" "), i--); printf("CLAUSE\n"); pp1(t->components.stmt.kind.ifstmt.elsepart,level+1); } break; case YAEQ: printf("~=\n"); for (i=2*level+1; i>0; printf(" "), i--); printf("LEFT_OPRND:\n"); pp1(t->components.trinop.left_operand, level+1); for (i=2*level+1; i>0; printf(" "), i--); printf("MIDDLE_OPRND:\n"); pp1(t->components.trinop.middle_operand, level+1); for (i=2*level+1; i>0; printf(" "), i--); printf("RIGHT_OPRND:\n"); pp1(t->components.trinop.right_operand, level+1); break; } break; case PROC_CALL_NODE: printf("PROC_CALL_NODE%s:\n", (t->header.name == YQRTARROW) ? ", VALIDATION" : ""); for (i=2*level+1; i>0; printf(" "), i--); printf("DESIGNATOR:\n"); pp1(t->components.proccall.desig,level+1); for (i=2*level+1; i>0; printf(" "), i--); printf("ACTUALS:\n"); pp1(t->components.proccall.actuals,level+1); if (t->header.name == YQRTARROW) { for (i=2*level+1; i>0; printf(" "), i--); printf("RETURNS:\n"); pp1(t->components.proccall.returns,level+1); } break; case TYPE_NODE: switch (t->header.name) { case Yident: printf("TYPE_IDENT_NODE:\n"); pp1(t->components.type.kind.ident.type,level+1); break; case ';': printf("OPAQUE_TYPE_NODE:\n"); break; case '(': printf("ENUM_TYPE_NODE:\n"); pp1(t->components.type.kind.enumtype.idents,level+1); break; case '[': printf("SUBRANGE_TYPE_NODE:\n"); pp1(t->components.type.kind.subrange.basetype,level+1); pp1(t->components.type.kind.subrange.lower,level+1); pp1(t->components.type.kind.subrange.upper,level+1); break; case YOR: printf("UNION_TYPE_NODE:\n"); pp1(t->components.type.kind.record.fields,level+1); break; case YRECORD: printf("RECORD_TYPE_NODE:\n"); pp1(t->components.type.kind.record.fields,level+1); break; case YARRAY: printf("LIST_TYPE_NODE:\n"); pp1(t->components.type.kind.arraytype.basetype, level+1); break; case YOP: printf("OP_TYPE_NODE:\n"); pp1(t->components.type.kind.op.ins, level+1); pp1(t->components.type.kind.op.outs, level+1); break; case '\'': printf("LITERAL_TYPE_NODE:\n"); pp1(t->components.type.kind.lit.type, level+1); pp1(t->components.type.kind.lit.value, level+1); break; } break; case ATOM_NODE: printf("ATOM_NODE: "); switch (t->header.name) { case Yident: for (t1=t; t1->components.atom.next; t1=t1->components.atom.next) { printf("%s.", t1->components.atom.val.text); } printf("%s", t1->components.atom.val.text); break; case Yreal: printf("%f ",t->components.atom.val.real); break; case Yinteger: printf("%d ",t->components.atom.val.integer); break; case Ystring: printf("%s ",t->components.atom.val.string); break; case YLIST: printf("[ \n"); pp1(t->components.atom.next,level); break; case ']': printf("] \n"); pp1(t->components.atom.next, level-1); break; default: printf("(default as string) %s ", t->components.atom.val.text); } printf("\n"); /* pp1(t->components.atom.next,level); */ } } /* Dump out the contents of the symbol table. */ void DumpSymtab(Symtab *Tab, int Level) { int i; SymtabEntry *e; nodep im = Tab->Imports; nodep ex = Tab->Exports; char *name; void DumpSymtabEntry(SymtabEntry *Entry, int Index, int Level); /* * Print Level 0 header message. */ if (Level == 0) printf("\nSYMTAB DUMP:\n"); for (i=Level*4; i>0; i--) printf(" "); /* * Print symtab name, level, and size. */ printf("%s's Symtab Contents, at Level %d, Size %d:\n", Tab->ParentEntry ? Tab->ParentEntry->Symbol : "No parent", Tab->Level, Tab->Size); /* * Print the entries (only the non-null ones). */ for (i=0; iSize; i++) for (e=Tab->Entries[i]; e; e=e->Next) DumpSymtabEntry(e, i, Level); } /* * Dump a symtab entry, including all elements on the hash overflow chain. */ void DumpSymtabEntry(SymtabEntry *Entry, int Index, int Level) { int i; SymtabEntry *e; nodep n; for (i=Level*4; i>0; i--) printf(" "); printf("Entry %d: Symbol: %s, Type: 0x%p, Class: %d\n", Index, Entry->Symbol, (void *) Entry->Type, Entry->Class); /* * Print entity parts list. */ if (Entry->Class == C_Obj) { for (i=Level*4+2; i>0; i--) printf(" "); printf("Parts List: "); /* for (n=Entry->Info.Obj.partslist; n; n=n->components.atom.next) { printf("%s", n->components.atom.val.text); if (n->components.atom.next) printf(", "); } */ printf("\n"); if (Entry->Flags & isClass) { for (i=Level*4+2; i>0; i--) printf(" "); printf("Specialization List: "); for (n=Entry->Info.Obj.speclreq; n; n=n->components.atom.next) { printf("%s", n->components.atom.val.text); if (n->components.atom.next) printf(", "); } } printf("\n"); for (i=Level*4+2; i>0; i--) printf(" "); printf("Type is %d\n",Entry->Type->header.name); if ((Entry->Type->header.name != Yident) && Entry->Type->components.type.kind.parts.parts) DumpSymtab(Entry->Type->components.type.kind.parts.parts, Entry->Type->components.type.kind.parts.parts->Level); } if (Entry->Class == C_Name) { for (i=Level*4+2; i>0; i--) printf(" "); printf("Type is %d\n",Entry->Type->header.name); printf("\n"); if (Entry->Type->header.name != Yident) DumpSymtab(Entry->Type->components.type.kind.parts.parts, Entry->Type->components.type.kind.parts.parts->Level); } /* * Print entity parts list. */ if (Entry->Class == C_Op) { for (i=Level*4+2; i>0; i--) printf(" "); printf("Parts List: "); /* for (n=Entry->Info.Op.partslist; n; n=n->components.atom.next) { printf("%s", n->components.atom.val.text); if (n->components.atom.next) printf(", "); } */ printf("\n"); if (Entry->Flags & isClass) { for (i=Level*4+2; i>0; i--) printf(" "); printf("Specialization List: "); for (n=Entry->Info.Obj.speclreq; n; n=n->components.atom.next) { printf("%s", n->components.atom.val.text); if (n->components.atom.next) printf(", "); } } printf("\n"); for (i=Level*4+2; i>0; i--) printf(" "); if (Entry->Info.Op.parts) { printf("Parts Type is %d\n",Entry->Info.Op.parts->header.name); } if (Entry->Type) { if ((Entry->Type->header.name != Yident) && Entry->Info.Op.parts) DumpSymtab(Entry->Info.Op.parts->components.type.kind.parts.parts, Entry->Info.Op.parts->components.type.kind.parts.parts->Level); for (i=Level*4+2; i>0; i--) printf(" "); printf("Inputs Type is %d\n",Entry->Type->header.name); } if (Entry->Info.Op.ins) { DumpSymtab(Entry->Info.Op.ins->components.type.kind.parts.parts, Entry->Info.Op.ins->components.type.kind.parts.parts->Level); for (i=Level*4+2; i>0; i--) printf(" "); printf("Outputs Type is %d\n",Entry->Type->header.name); DumpSymtab(Entry->Type->components.type.kind.parts.parts, Entry->Type->components.type.kind.parts.parts->Level); } } /* * Print proc parms and symtab. */ if (Entry->Class == C_Proc) { for (i=Level*4+2; i>0; i--) printf(" "); printf("Parm Chain: "); for (e=Entry->Info.Proc.Parms; e; e=e->Info.Parm.Link) { printf("%s", e->Symbol); if (e->Info.Parm.Link) printf(", "); } printf("\n"); DumpSymtab(Entry->Info.Proc.Symtab, Level + 1); } /* * Print module symtab. */ if (Entry->Class == C_Module) { DumpSymtab(Entry->Info.Module.Symtab, Level + 1); } } /* * Skip any top-level whitespace, including comments. */ void MoveOverWhitespace() { /* Dont need this afterall -- YEOF token in parser fixes things. */ } /* * Get the first input file form the command line. If the command agrlist is * empty, then use stdin. */ bool GetFirstInFile(int argc, char **argv) { argi = 1; if (argc == 1) return true; while (argi < argc) { /* * Ignore switch. */ if (*argv[argi] == '-') { argi++; continue; } /* * If not switch, assume file. */ CurFile = argv[argi++]; if (! (yyin = fopen(CurFile, "r"))) { error("File %s not found\n", CurFile); ANY_PARSE_ERROR = true; } else { yyfilename = (char *) stralloc(CurFile); return true; } } return false; } /* * Get the next input file from the commmand line list. */ bool GetNextInFile(int argc, char **argv) { yylineno = 1; while (argi < argc) { /* * Ignore switch. */ if (*argv[argi] == '-') { argi++; continue; } /* * Open the next file. */ CurFile = argv[argi++]; if (! (yyin = fopen(CurFile, "r"))) error("File %s not found\n", CurFile); else { yyfilename = (char *) stralloc(CurFile); return true; } } return false; } /* * Stub till things get cleaned up as called for in 8sep92 note in TODO. */ TopLevel() {} /* * An options function that should go in a clean options module. */ bool GrammarFlag() { return false; /* Do it right as soon as options module is * properly put together. */ } /* * Prints out all the known contents of the universe. How omniscient of us! */ void PrintUniverse() { int i; ValueStruct typeListValueStruct; printf("Value Universe contains: <\n"); for (i = 0; i < UniverseGetSize(); i++) { typeListValueStruct = UniverseGetValueStructAt(i); if (typeListValueStruct) { printf("%s: ", UniverseGetSymbolAt(i)); PpValue(typeListValueStruct, true); printf("\n"); } // if a type / value list here } // end for printf(">\n"); } /* * Pretty print a value structure by recursively descending it per its type. * This works like utilities.c:DumpVarVal, but on a value struct directly, * rather than a symtab entry. The quotes parm is true if string values should * be printed with enclosing double quotes, false if they should be printed * without quotes. The built-in print funtion calls with quotes = false. */ void PpValue(ValueStruct v, bool quotes) { int i; ListElemData* elemData; /* working elemData pointer for lists */ if (!v) { printf("nil"); return; } switch (v->tag) { case IntTag: { printf("%d", v->val.IntVal); break; } case RealTag: { printf("%g", v->val.RealVal); break; } case BoolTag: { printf("%s", v->val.BoolVal ? "true" : "false"); break; } case StringTag: { if (quotes) { printf("\"%s\"", ConstStringConvert(v->val.StringVal)); } else { printf("%s", ConstStringConvert(v->val.StringVal)); } break; } case NilTag: { printf("nil"); break; } case ListTag: { printf("[ "); for (i = 1; i <= ListLen(v->val.ListVal); i++) { elemData = GetListNth(v->val.ListVal, i); if (elemData != null) { PpValue((ValueStruct)elemData, true); } // end if elemData != null /* If we're not the last one, print out comma, else just space */ if (i != v->val.ListVal->size) { printf(", "); } else { printf(" "); } } // end for printf("]"); break; } // end case ListTag case StructTag: { printf("{ "); for (i = 1; i <= v->type->components.type.kind.record.numfields; i++) { elemData = GetListNth(v->val.StructVal, i); // if (elemData != null) { PpValue((ValueStruct)elemData, true); // } // end if elemData != null /* If we're not the last one, print out comma, else just space */ if (i != v->type->components.type.kind.record.numfields) { printf(", "); } else { printf(" "); } } printf("}"); break; } default: { printf("Sorry, but only ints, reals, bools, nil, and strings are printable at the moment (especially not [%s] with value: %d)\n", ValTagToString(v->tag), v->tag); if (v->type != null) { printf("Details:\n"); printf("LorR: %d: \n", v->LorR); printf("Size: %d: \n", v->size); } } /*** *** Everthing that follows is copied from DumpVarVal, and needs to be *** changed to act like the preceding IntTag case. *** case LIntTag: { long v; bcopy(&(StaticPool[Entry->Info.Var.Offset]), &v, sizeof(long)); printf(" var %s: longinteger = %d\n", Entry->Symbol, v); break; } case RealTag: { double v; bcopy(&(StaticPool[Entry->Info.Var.Offset]), &v, sizeof(double)); printf(" var %s: real = %g\n", Entry->Symbol, v); break; } case LRealTag: { double v; bcopy(&(StaticPool[Entry->Info.Var.Offset]), &v, sizeof(double)); printf(" var %s: longreal = %g\n", Entry->Symbol, v); break; } case CharTag: { char v; bcopy(&(StaticPool[Entry->Info.Var.Offset]), &v, sizeof(char)); printf(" var %s: char = '%c'\n", Entry->Symbol, v); break; } case BoolTag: { bool v; bcopy(&(StaticPool[Entry->Info.Var.Offset]), &v, sizeof(bool)); printf(" var %s: boolean = %s\n", Entry->Symbol, v ? "true" : "false"); break; } case StringTag: { char *v; bcopy(&(StaticPool[Entry->Info.Var.Offset]), &v, sizeof(char *)); printf(" var %s: string = %s\n", Entry->Symbol, v); break; } case SetTag: { char *v; bcopy(&(StaticPool[Entry->Info.Var.Offset]), &v, sizeof(char *)); printf(" var %s: set = %x\n", Entry->Symbol, v); break; } case PtrTag: { char *v; printf(" var %s: pointer = ", Entry->Symbol); bcopy(&(StaticPool[Entry->Info.Var.Offset]), &v, sizeof(char *)); if (not v) printf("nil\n"); else { printf ("\n"); HexMemDump(v, TypeSize( Entry->Type->components.type.kind.pointer.basetype)); } break; } case StructTag: { if (isArray(Entry->Type)) printf(" var %s: array = \n", Entry->Symbol); else printf(" var %s: record = \n", Entry->Symbol); HexMemDump(&(StaticPool[Entry->Info.Var.Offset]), TypeSize(Entry->Type)); break; } case ProcTag: { SymtabEntry *v; bcopy(&(StaticPool[Entry->Info.Var.Offset]), &v, sizeof(char *)); if (not v) printf(" var %s: procedure = nil\n", Entry->Symbol); else printf(" var %s: procedure = %s\n", Entry->Symbol, v->Symbol); break; } ***/ } } char* ValTagToString(ValTag vt) { switch(vt) { case NilTag: return ("NilTag"); break; case IntTag: return ("IntTag"); break; case LIntTag: return ("LIntTag"); break; case RealTag: return ("RealTag"); break; case LRealTag: return ("LRealTag"); break; case CharTag: return ("CharTag"); break; case BoolTag: return ("BoolTag"); break; case StringTag: return ("StringTag"); break; case SetTag: return ("SetTag"); break; case PtrTag: return ("PtrTag"); break; case StructTag: return ("StructTag"); break; case ListTag: return ("ListTag"); break; case ProcTag: return ("ProcTag"); break; case TypeTag: return ("TypeTag"); break; case SymLitTag: return ("SymLitTag"); break; default: return ("Error: Unknown Tag"); break; } } /* * Utility for printing lists, in particular from gdb. */ void PrintVList(Value* v) { int i; ListElemData* elemData; printf("[ "); for (i = 1; i <= ListLen(v->val.ListVal); i++) { elemData = GetListNth(v->val.ListVal, i); if (elemData != null) { PpValue((ValueStruct)elemData, true); } // end if elemData != null /* If we're not the last one, print out comma, else just space */ if (i != v->val.ListVal->size) { printf(", "); } else { printf(" "); } } // end for printf("]"); printf("\n"); } // end case ListTag /* * PpValue with a shorter name, and ending newline. */ void ppv(Value* v) { PpValue(v, true); printf("\n"); }