home *** CD-ROM | disk | FTP | other *** search
- /* --------------------------------------------------------------------------
- * gofer.c: Copyright (c) Mark P Jones 1991-1993. All rights reserved.
- * See goferite.h for details and conditions of use etc...
- * Gofer version 2.28 January 1993
- *
- * Command interpreter
- * ------------------------------------------------------------------------*/
-
- #include "prelude.h"
- #include "storage.h"
- #include "command.h"
- #include "connect.h"
- #include "errors.h"
- #include <setjmp.h>
- #if MPW
- #include "mac_ctype.h" /* KH: I need to override the defaults for the Mac */
- #else
- #include <ctype.h>
- #endif
-
- /* --------------------------------------------------------------------------
- * Machine dependent code for Gofer interpreter:
- * ------------------------------------------------------------------------*/
-
- #define MACHDEP_GOFER 1
- #include "machdep.c"
-
-
- /* --------------------------------------------------------------------------
- * Shared parts of user interface:
- * ------------------------------------------------------------------------*/
-
- #include "commonui.c"
-
-
- #if MPW
- #pragma segment Gofer
- #endif
-
- /* --------------------------------------------------------------------------
- * Local function prototypes:
- * ------------------------------------------------------------------------*/
-
- #if !MAC
- static Void local initialise Args((Int,String []));
- static Void local interpreter Args((Int,String []));
- #else
- static Void local initialise Args((Void));
- Void interpreter Args((Void));
- Void printPrompt Args((Void));
- Void showType Args((String));
- #endif
- static Void local menu Args((Void));
- static Void local guidance Args((Void));
- static Void local forHelp Args((Void));
- static Void local set Args((Void));
- static Void local changeDir Args((Void));
- #if !MAC
- static Void local load Args((Void));
- static Void local project Args((Void));
- static Void local readScripts Args((Int));
- #else
- Void load Args((Void));
- Void project Args((Void));
- Void readScripts Args((Void));
- Void resetScript Args((Int));
- #endif
- Void ResetInterpreter Args((Void));
- static Void local whatFiles Args((Void));
- static Void local editor Args((Void));
- static Void local find Args((Void));
- static Void local runEditor Args((Void));
- static Void local evaluator Args((Void));
- static Void local stopAnyPrinting Args((Void));
- static Void local showtype Args((Void));
- static Void local info Args((Void));
- static Void local describe Args((Text));
- static Void local listNames Args((Void));
- static Void local show_banner Args((Void)); /* KH */
-
- /* --------------------------------------------------------------------------
- * Local data areas:
- * ------------------------------------------------------------------------*/
-
- #if !MAC
- static Time lastChange[NUM_MODULES]; /* Time of last change to file */
- #endif
- static Bool printing = FALSE; /* TRUE => currently printing value*/
- #if !MAC
- static Bool addType; /* TRUE => print type with value */
- static Bool showStats = TRUE; /* TRUE => print stats after eval */
- #else
- Bool addType = FALSE; /* TRUE => print type with value */
- Bool showStats = TRUE; /* TRUE => print stats after eval */
- #endif
- static Bool listFiles = TRUE; /* TRUE => list files after loading*/
-
- #if MAC
- int errorLine = 0; /* Line number for last error */
- int errorMod = 0; /* File name for last error */
-
- extern Boolean quit; /* To enable :q -- MS */
-
- extern Bool AutoLoad; /* Automatically reload scripts */
-
- Bool literateModule = FALSE; /* TRUE => the module is literate */
- Bool moduleCoerceNumLiterals = FALSE; /* TRUE => coerce numbers in this module */
-
- #endif /* MAC */
-
-
- /* --------------------------------------------------------------------------
- * Gofer entry point:
- * ------------------------------------------------------------------------*/
-
- #if !MAC
- Main main Args((Int, String [])); /* now every func has a prototype */
-
- Main main(argc,argv)
- int argc;
- char *argv[]; {
- CStackBase = &argc; /* Save stack base for use in gc */
-
- show_banner();
- #if DYNAMIC_STORAGE
- Dynamic_Storage_Init(); /* Initialise the Dynamic Storage */
- #endif
- interpreter(argc,argv);
- printf("[Leaving Gofer]\n");
- everybody(EXIT);
- exit(0);
- MainDone
- }
-
- #else /* !MAC */
-
- /*
- The main routine is split up like this because the interpreter is called
- from the interface, rather than vice-versa as on a text-based system.
-
- The routines correspond to initialisation, printing prompts and termination,
- respectively.
- */
-
- Void init_gofer Args((Void));
- Void terminate_gofer Args((Void));
-
- Void init_gofer()
- {
- show_banner();
- updatewindows();
- Dynamic_Storage_Init();
- updatewindows();
-
- /* One dummy argument for the Mac version */
- initialise(0);
-
- printPrompt();
- }
-
- /* Print the prompt string */
- Void printPrompt()
- {
- ResetCursor();
- if(prompt != NULL)
- printf("%s\n",prompt);
- }
-
-
- Void terminate_gofer()
- {
- printf("[Leaving Gofer]\n");
- everybody(EXIT);
- }
-
- #endif
-
-
- /* The startup banner now includes my name. Gofer is provided free of */
- /* charge. I ask however that you show your appreciation for the many */
- /* hours of work involved by retaining my name in the banner. Thanks! */
-
- static Void local show_banner()
- {
- printf("Gofer Version 2.28b Copyright (c) Mark P Jones 1991-1993\n");
- #if MAC
- printf("Macintosh Interface by Kevin Hammond, 12/1/92--16/2/93\n");
- printf("Configuring Gofer's Memory and loading Prelude -- Please be Patient…\n\n");
- #else
- fflush(stdout);
- #endif
- }
-
-
- /* --------------------------------------------------------------------------
- * Initialisation, interpret command line args and read prelude:
- * ------------------------------------------------------------------------*/
-
- #if !MAC
-
- static Void local initialise(argc,argv)/* interpreter initialisation */
- Int argc;
- String argv[]; {
- Module i;
- String proj = 0;
-
- setLastEdit((String)0,0);
- lastEdit = 0;
- scriptFile = 0;
- numScripts = 0;
- namesUpto = 1;
- scriptName[0] = strCopy(fromEnv("GOFER",STD_PRELUDE));
- prompt = strCopy(PROMPT);
- repeatStr = strCopy("$$");
-
- for (i=1; i<argc; ++i) /* process command line arguments */
- if (strcmp(argv[i],"+")==0 && i+1<argc)
- if (proj) {
- ERROR(0) "Multiple project filenames on command line"
- EEND;
- }
- else
- proj = argv[++i];
- else
- addScriptName(argv[i]);
-
- everybody(INSTALL);
- if (proj) {
- if (namesUpto>1)
- fprintf(stderr,
- "\nUsing project file, ignoring additional filenames\n");
- loadProject(strCopy(proj));
- }
- readScripts(0);
- }
- #else /* !MAC */
- static Void local initialise(dummy) /* interpreter initialisation */
- int dummy;
- {
- CStackBase = &dummy;
- scriptFile = 0;
- numScripts = 0;
- prompt = PROMPT;
-
- everybody(INSTALL);
- updatewindows();
- readScripts(0);
- numScripts = 1;
- everybody(RESET);
- }
- #endif
-
-
- /* --------------------------------------------------------------------------
- * Print Menu of list of commands:
- * ------------------------------------------------------------------------*/
-
- static struct cmd cmds[] = {
- {":?", HELP}, {":type", TYPEOF}, {":load", LOAD},
- {":also", ALSO}, {":reload", RELOAD}, {":project", PROJECT},
- {":edit", EDIT}, {":find", FIND}, {":names", NAMES},
- {":set", SET}, {":quit", QUIT}, {":cd", CHGDIR},
- {":!", SYSTEM}, {":info", INFO}, {"", EVAL},
- #if MAC
- {":unload", UNLOAD},
- #endif
- {0,0}
- };
-
- static Void local menu() {
- #if !MAC
- printf("LIST OF COMMANDS: Any command may be abbreviated to :c where\n");
- printf("c is the first character in the full name.\n\n");
- #else
- printf("GOFER COMMANDS:\n\nAny command may be shortened to two characters (e.g. :l for :load)\n");
- #endif
- printf(":load <filenames> load scripts from specified files\n");
- printf(":load clear all files except prelude\n");
- printf(":also <filenames> read additional script files\n");
- #if MAC
- printf(":reload reload scripts from files\n");
- printf(":unload <filenames> remove files from the current project\n");
- #else
- printf(":reload repeat last load command\n");
- #endif
- printf(":project <filename> use project file\n");
- printf(":edit <filename> edit file\n");
- printf(":edit edit last file\n");
- printf("<expr> evaluate expression\n");
- printf(":type <expr> print type of expression\n");
- printf(":? display this list of commands\n");
- #if !MAC
- printf(":set <options> set command line options\n");
- printf(":set help on command line options\n");
- #endif
- printf(":names [pat] list names currently in scope\n");
- printf(":info <names> describe named objects\n");
- printf(":find <name> edit file containing definition of name\n");
- #if !MAC
- printf(":!command shell escape\n");
- printf(":cd dir change directory\n");
- #endif
- printf(":quit exit Gofer interpreter\n");
- #if MAC
- printf("\nCMD-period interrupts MacGofer at any time\n");
- printf("\nUse CMD-enter for end-of-input during evaluation\n");
- #endif
- }
-
- static Void local guidance() {
- printf("Command not recognised. ");
- forHelp();
- }
-
- static Void local forHelp() {
- printf("Type :? for help\n");
- }
-
-
- /* --------------------------------------------------------------------------
- * Setting of command line options:
- * ------------------------------------------------------------------------*/
-
- #if !MAC
-
- struct options toggle[] = { /* List of command line toggles */
- {'s', "Print no. reductions/cells after eval", &showStats},
- {'t', "Print type after evaluation", &addType},
- {'d', "Show dictionary values in output exprs",&showDicts},
- {'f', "Terminate evaluation on first error", &failOnError},
- {'g', "Print no. cells recovered after gc", &gcMessages},
- {'c', "Test conformality for pattern bindings",&useConformality},
- {'l', "Literate scripts as default", &literateScripts},
- {'e', "Warn about errors in literate scripts", &literateErrors},
- {'i', "Apply fromInteger to integer literals", &coerceNumLiterals},
- {'o', "Optimise use of (&&) and (||)", &andorOptimise},
- {'u', "Catch ambiguously typed top-level vars",&catchAmbigs},
- {'.', "Print dots to show progress", &useDots},
- {'w', "Always show which files loaded", &listFiles},
- {'1', "Overload singleton list notation", &overSingleton},
- {'v', "Print each reduction step in full", &traceEval},
- #ifdef TECH_TOGGLES
- {'a', "Use any evidence, not nec. best", &anyEvidence},
- {'E', "Fail silently if evidence not found", &silentEvFail},
- #endif
- {'k', "Show kind errors in full", &kindExpert},
- {0, 0, 0}
- };
-
- struct options memopt[] = { /* List of memory settings -- KH */
- #if DYNAMIC_STORAGE
- {'a', "Number of Machine Addresses", &num_addrs},
- {'c', "Number of Classes", &num_classes},
- {'d', "Number of Dictionaries", &num_dicts},
- {'i', "Number of Instances", &num_insts},
- {'I', "Number of Indexes", &num_indexes},
- {'m', "Number of Modules", &num_modules},
- {'n', "Number of Identifiers (Names)", &num_name},
- {'o', "Number of Machine Offsets", &num_offsets},
- {'s', "Size of Machine Stack (words)", &num_stack},
- {'S', "Number of Selectors", &num_selects},
- {'t', "Number of Type Constructors", &num_tycon},
- {'T', "Number of Tuple Types", &num_tuples},
- {'v', "Number of Type Variables", &num_tyvars},
- {'x', "Size of Text Buffer for Identifiers", &num_text},
- {'y', "Number of Operators Allowed", &num_syntax},
- #endif
- {0, 0, 0}
- };
-
-
- static Void local set() { /* change command line options from*/
- String s; /* Gofer command line */
-
- if (s=readFilename()) {
- do {
- if (s[0]=='+' || s[0]=='-')
- processOption(s);
- else {
- ERROR(0) "Option string must begin with `+' or `-'"
- EEND;
- }
- } while (s=readFilename());
- }
- else
- optionInfo();
- }
-
- #endif
-
-
- /* --------------------------------------------------------------------------
- * Change directory command:
- * ------------------------------------------------------------------------*/
-
- static Void local changeDir() { /* change directory */
- #if MPW
- ERROR(0) ":cd not yet implemented"
- EEND;
- #else
- extern int chdir Args((String));
- String s = readFilename();
- if (s && chdir(s)) {
- ERROR(0) "Unable to change to directory \"%s\"", s
- EEND;
- }
- #endif
- }
-
-
- /* --------------------------------------------------------------------------
- * Loading and removal of script files:
- * ------------------------------------------------------------------------*/
-
- #if !MAC
-
- static Void local load() { /* read filenames from command line */
- String s; /* and add to list of files waiting */
- /* to be read */
- while (s=readFilename())
- addScriptName(s);
- readScripts(1);
- }
-
- static Void local project() { /* read list of file names from */
- String s; /* project file */
-
- if ((s=readFilename()) || currProject) {
- if (!s)
- s = strCopy(currProject);
- else if (readFilename()) {
- ERROR(0) "Too many project files"
- EEND;
- }
- else
- s = strCopy(s);
- }
- else {
- ERROR(0) "No project filename specified"
- EEND;
- }
- loadProject(s);
- readScripts(1);
- }
-
- static Void local readScripts(first) /* reread current list of scripts, */
- Int first; { /* loading everything after and */
- Module i; /* including the first script which*/
- Time timeStamp; /* has been either changed or added*/
- Long fileSize;
-
- for (i=first; i<namesUpto; ++i) {
- getFileInfo(scriptName[i], &timeStamp, &fileSize);
-
- if (i<numScripts && timeChanged(timeStamp,lastChange[i])) {
- dropModulesFrom(i-1); /* previously loaded file changed ?*/
- numScripts = i;
- }
-
- if (i>=numScripts) { /* new script file to be read ? */
- timeSet(lastChange[i],timeStamp);
- if (i>0) /* no new module for prelude */
- startNewModule();
- addScript(scriptName[i],fileSize);
- numScripts++;
- }
- }
-
- if (listFiles)
- whatFiles();
- if (numScripts<=1)
- setLastEdit((String)0, 0);
- }
-
- static Void local whatFiles() { /* list files in current session */
- int i;
- printf("\nGofer session for:");
- if (projectLoaded)
- printf(" (project: %s)",currProject);
- for (i=0; i<numScripts; ++i)
- printf("\n%s",scriptName[i]);
- putchar('\n');
- }
-
-
- #else /* !MAC */
-
- Void readScripts(first)
- Int first;
- {
- int mod = 0;
- Module i;
- char *fname;
-
- CStackBase = &i;
-
- for (i = first; mod >= 0; i++)
- {
- /* Get the module index for the load item, and add it if necessary */
- if((mod = getProjectItem(i)) >= 0)
- {
- if(haschanged(mod))
- resetScript(i);
-
- if (i >= numScripts)
- {
- startNewModule();
- addScript(mod,i);
- fname = scriptname( mod);
- setLastEdit( fname, 0 );
-
- numScripts++;
- }
- }
- }
- }
-
-
- /* Clear to a particular script */
- Void resetScript(n)
- {
- if(n < numScripts)
- {
- dropModulesFrom(n);
- numScripts = n;
- }
- }
-
-
-
- static Void local whatFiles() { /* list files in current session */
- int i;
- printf("\nGofer session for:");
- for (i=0; i<numScripts; ++i)
- printf("\n%s",scriptname(i));
- putchar('\n');
- }
-
- #endif
-
- /* Reset the interpreter following failed evaluation */
- Void ResetInterpreter()
- {
- dropModulesFrom(numScripts); /* remove partially loaded scripts */
- everybody(RESET);
- #if MAC
- moduleCoerceNumLiterals = literateModule = FALSE;
- #endif
- }
-
-
-
-
- /* --------------------------------------------------------------------------
- * Access to external editor:
- * ------------------------------------------------------------------------*/
-
- static Void local editor() { /* interpreter-editor interface */
- String newFile = readFilename();
- if (newFile) {
- setLastEdit(newFile,0);
- if (readFilename()) {
- ERROR(0) "Multiple filenames not permitted"
- EEND;
- }
- }
- runEditor();
- #if !MAC
- readScripts(1); /* try to reload scripts after edit */
-
- /*
- There is no need to do this in the Mac interface -- scripts will
- be reloaded automatically when an expression is typed,
- or when the user requests a reload.
-
- Incidentally, readScripts(1) should probably be readScripts(0).
- If the user has sufficient privilege to be able to edit the Prelude,
- there can be no reason to prevent them loading the changes now!!
- To do so is distinctly inconsistent!!
-
- KH
- */
- #endif
- }
-
- static Void local find() { /* edit file containing definition */
- String nm = readFilename(); /* of specified name */
- if (!nm) {
- ERROR(0) "No name specified"
- EEND;
- }
- else if (readFilename()) {
- ERROR(0) "Multiple names not permitted"
- EEND;
- }
- else {
- Name n; int m;
- startNewModule();
- if (isNull(n = findName(findText(nm)))) {
- ERROR(0) "No current definition for name \"%s\"", nm
- EEND;
- }
- #if MAC
- m=moduleThisName(n);
- errorMod = m == 0? 0: m-1;
- setLastEdit(scriptname(errorMod),name(n).line);
- findError();
- #else
- setLastEdit(scriptName[moduleThisName(n)],name(n).line);
- runEditor();
- readScripts(1);
- #endif
- }
- }
-
-
-
- #if MAC
-
- /*
- Get the line and module number for the definition called name.
- */
-
- getName(name,module,line)
- char *name;
- int *module, *line;
- {
- Name n;
- Module m = startNewModule();
- if (isNull(n = findName(findText(name))))
- {
- ERROR(0) "No current definition for name \"%s\"", name
- EEND;
- }
- *module = moduleThisName(n);
- *line = name(n).line;
- dropModulesFrom(m);
- if(*module == 0)
- *module = 1;
- }
- #endif
-
-
- #if !MAC
- static Void local runEditor() { /* run editor on file lastEdit at */
- static char editorCmd[100]; /* line editLine */
- String editor = fromEnv("EDITOR",DEF_EDITOR);
- String editline = fromEnv("EDITLINE",DEF_EDITLINE);
- Int l,f;
-
- if (lastEdit && editline && lastLine
- && (l=substr("%d",editline))>=0
- && (f=substr("%s",editline))>=0)
- if (l<f)
- sprintf(editorCmd,editline,lastLine,lastEdit);
- else
- sprintf(editorCmd,editline,lastEdit,lastLine);
- else if (editor)
- if (lastEdit)
- sprintf(editorCmd,"%s %s",editor,lastEdit);
- else
- sprintf(editorCmd,"%s",editor);
- else {
- ERROR(0) "No editor specified in environment variable EDITOR"
- EEND;
- }
-
- if (shellEsc(editorCmd)) {
- ERROR(0) "Editor terminated abnormally"
- EEND;
- }
- }
- #else
-
- static Void local runEditor() { /* run editor on file lastEdit at */
- /* line editLine */
- if(lastEdit)
- findFile(lastEdit,lastVol,lastDir,lastLine);
- else
- {
- ERROR(0) "No file to edit\n" EEND;
- }
- }
- #endif
-
- /* --------------------------------------------------------------------------
- * Read and evaluate an expression:
- * ------------------------------------------------------------------------*/
-
- static Void local evaluator() { /* evaluate expr and print value */
- Type type;
-
- #if MPW
- CStackBase = &type; /* Set stack base for evaluation */
- #endif
-
- scriptFile = 0;
- startNewModule(); /* Enables recovery of storage */
- /* allocated during evaluation */
- parseExp();
- checkExp();
- type = typeCheckExp();
- if (whatIs(isPolyType(type) ? monoTypeOf(type) : type)==QUAL) {
- ERROR(0) "Unresolved overloading" ETHEN
- ERRTEXT "\n*** type : " ETHEN ERRTYPE(type);
- ERRTEXT "\n*** translation : " ETHEN ERREXPR(inputExpr);
- ERRTEXT "\n"
- EEND;
- }
- compileExp();
- numCells = 0;
- numReductions = 0;
- numberGcs = 0;
- printing = TRUE;
- if (typeMatches(type,typeString))
- outputString(stdout,graphForExp(),TRUE);
- else if (typeMatches(type,typeDialogue))
- dialogue(graphForExp());
- #ifdef LAMBDAVAR
- else if (typeMatches(type,typeProg))
- lvExecute(graphForExp());
- #endif
- #ifdef LAMBDANU
- else if (typeInstOf(type,typeLnProg))
- lnExecute(graphForExp());
- #endif
- else {
- outputString(stdout,ap(ap(ap(namePrint,
- mkInt(MIN_PREC)),
- graphForExp()),
- nameNil),TRUE);
- if (addType) {
- printf(" :: ");
- printType(stdout,type);
- }
- }
- stopAnyPrinting();
- }
-
- static Void local stopAnyPrinting() { /* terminate printing of expression,*/
- if (printing) { /* after successful termination or */
- printing = FALSE; /* runtime error (e.g. interrupt) */
- #if MAC
- ResetCursor(); /* Reset the cursor to an arrow */
- #endif
- putchar('\n');
- if (showStats) {
- #define plural(v) v, (v==1?"":"s")
- printf("(%lu reduction%s, ",plural(numReductions));
- printf("%lu cell%s",plural(numCells));
- if (numberGcs>0)
- printf(", %u garbage collection%s",plural(numberGcs));
- printf(")\n");
- #undef plural
- }
- fflush(stdout);
- }
- }
-
- /* --------------------------------------------------------------------------
- * Print type of input expression:
- * ------------------------------------------------------------------------*/
-
- static Void local showtype() { /* print type of expression (if any)*/
- Cell type;
-
- startNewModule(); /* Enables recovery of storage */
- /* allocated during evaluation */
- parseExp();
- checkExp();
- type = typeCheckExp();
- printExp(stdout,inputExpr);
- printf(" :: ");
- printType(stdout,type);
- putchar('\n');
- }
-
- #if MAC
-
- /*
- This is the graphical interface version of the above. KH
- */
-
- Void showType(defn)
- char *defn;
- {
- Name n;
- Module m = startNewModule();
- if (isNull(n = findName(findText(defn))))
- {
- ERROR(0) "No current definition for name \"%s\"", defn
- EEND;
- }
- printf("%s :: ",defn);
- printType(stdout,name(n).type);
- putchar('\n');
- dropModulesFrom(m);
- }
- #endif
-
-
- /* --------------------------------------------------------------------------
- * Enhanced help system: print current list of scripts or give information
- * about an object.
- * ------------------------------------------------------------------------*/
-
- static Void local info() { /* describe objects */
- Int count = 0; /* or give menu of commands */
- String s;
-
- startNewModule(); /* for recovery of storage */
- for (; s=readFilename(); count++)
- describe(findText(s));
- if (count == 0)
- whatFiles();
- }
-
- static Void local describe(t) /* describe an object */
- Text t; {
- Tycon tc = findTycon(t);
- Class cl = findClass(t);
- Name nm = findName(t);
-
- if (nonNull(tc)) { /* as a type constructor */
- Type t = tc;
- Int i;
- for (i=0; i<tycon(tc).arity; ++i)
- t = ap(t,mkOffset(i));
- printf("-- type constructor");
- if (kindExpert) {
- printf(" with kind ");
- printKind(stdout,tycon(tc).kind);
- }
- putchar('\n');
- switch (tycon(tc).what) {
- case SYNONYM : printf("type ");
- printType(stdout,t);
- printf(" = ");
- printType(stdout,tycon(tc).defn);
- break;
-
- case DATATYPE : { List cs = tycon(tc).defn;
- printf("data ");
- printType(stdout,t);
- if (nonNull(cs))
- printf("\n\n-- constructors:");
- for (; nonNull(cs); cs=tl(cs)) {
- putchar('\n');
- printExp(stdout,hd(cs));
- printf(" :: ");
- printType(stdout,name(hd(cs)).type);
- }
- }
- break;
-
- case RESTRICTSYN : printf("type ");
- printType(stdout,t);
- printf(" = <restricted>");
- break;
- }
- printf("\n\n");
- }
-
- if (nonNull(cl)) { /* as a class */
- List ins = class(cl).instances;
- if (isPair(class(cl).sig) && fst(class(cl).sig)==STAR
- && isNull(snd(class(cl).sig)))
- printf("-- type class");
- else {
- printf("-- constructor class");
- if (kindExpert) {
- printf(" with arity ");
- printSig(stdout,class(cl).sig);
- }
- }
- printf("\nclass ");
- if (nonNull(class(cl).supers)) {
- printContext(stdout,class(cl).supers);
- printf(" => ");
- }
- printPred(stdout,class(cl).head);
- if (nonNull(class(cl).members)) {
- List ms = class(cl).members;
- printf(" where");
- do {
- printf("\n ");
- printExp(stdout,hd(ms));
- printf(" :: ");
- printType(stdout,name(hd(ms)).type);
- ms = tl(ms);
- } while (nonNull(ms));
- }
- putchar('\n');
- if (nonNull(ins))
- printf("\n-- instances:\n");
- for (; nonNull(ins); ins=tl(ins)) {
- printf("instance ");
- if (nonNull(inst(hd(ins)).specifics)) {
- printContext(stdout,inst(hd(ins)).specifics);
- printf(" => ");
- }
- printPred(stdout,inst(hd(ins)).head);
- putchar('\n');
- }
- putchar('\n');
- }
-
- if (nonNull(nm)) { /* as a function/name */
- printExp(stdout,nm);
- printf(" :: ");
- if (nonNull(name(nm).type))
- printType(stdout,name(nm).type);
- else
- printf("<unknown type>");
- switch (name(nm).defn) {
- case MFUN : printf(" -- class member");
- break;
- case CFUN : printf(" -- data constructor");
- break;
- }
- if (name(nm).primDef)
- printf(" -- primitive");
- printf("\n\n");
- }
-
- if (isNull(tc) && isNull(cl) && isNull(nm)) {
- printf("Unknown reference `%s'\n",textToStr(t));
- }
- }
-
- /* --------------------------------------------------------------------------
- * List all names currently in scope:
- * ------------------------------------------------------------------------*/
-
- static Void local listNames() { /* list names matching optional pat*/
- String pat = readFilename();
- List names = NIL;
- Int width = getTerminalWidth() - 1;
- Int count = 0;
- Int termPos;
-
- if (pat) /* First gather names to list */
- do
- names = addNamesMatching(pat,names);
- while (pat=readFilename());
- else
- names = addNamesMatching((String)0,names);
-
- if (isNull(names)) { /* Then print them out */
- ERROR(0) "No names selected"
- EEND;
- }
- for (termPos=0; nonNull(names); names=tl(names)) {
- String s = textToStr(name(hd(names)).text);
- Int l = strlen(s);
- if (termPos+1+l>width) {
- putchar('\n');
- termPos = 0;
- }
- else if (termPos>0) {
- putchar(' ');
- termPos++;
- }
- printf("%s",s);
- termPos += l;
- count++;
- }
- printf("\n(%d names listed)\n", count);
- }
-
- /* --------------------------------------------------------------------------
- * main read-eval-print loop, with error trapping:
- * ------------------------------------------------------------------------*/
-
- jmp_buf catch_error; /* jump buffer for error trapping -- no longer static -- KH */
-
- #if !MAC
-
- static Void local interpreter(argc,argv)/* main interpreter loop */
- Int argc;
- String argv[]; {
- Int errorNumber = setjmp(catch_error);
-
- breakOn(TRUE); /* enable break trapping */
- if (numScripts==0) { /* only succeeds on first time, */
- if (errorNumber) /* before prelude has been loaded */
- fatal("Unable to load prelude");
- initialise(argc,argv);
- forHelp();
- }
-
- for (;;) {
- ResetInterpreter();
-
- everybody(RESET); /* reset to sensible initial state */
- dropModulesFrom(numScripts-1); /* remove partially loaded scripts */
- /* not counting prelude as a module*/
- consoleInput(prompt);
- switch (readCommand(cmds, (Char)':', (Char)'!')) {
- #if !MPW
- case EDIT : editor();
- break;
- #endif
- case FIND : find();
- break;
- case LOAD : clearProject();
- forgetScriptsFrom(1);
- load();
- break;
- case ALSO : clearProject();
- forgetScriptsFrom(numScripts);
- load();
- break;
- case RELOAD : readScripts(1);
- break;
- case PROJECT: project();
- break;
- case EVAL : evaluator();
- break;
- case TYPEOF : showtype();
- break;
- case NAMES : listNames();
- break;
- case HELP : menu();
- break;
- case BADCMD : guidance();
- break;
- case SET : set();
- break;
- #if !MPW
- /* This wouldn't work under the MPW shell */
- case SYSTEM : shellEsc(readLine());
- break;
- #endif
- case CHGDIR : changeDir();
- break;
- case INFO : info();
- break;
- case QUIT : return;
- case NOCMD : break;
- }
- }
- }
- #else /* !MAC */
- Void interpreter(dummy)
- int dummy;
- {
- int cmd;
- CStackBase = &dummy;
-
- breakOn(TRUE); /* enable break trapping */
-
- CStackBase = &dummy; /* Reset C stack base for console input */
- consoleInput();
-
- cmd = readCommand(cmds, (Char)':', (Char)'!');
-
- if(cmd==EVAL)
- {
- if(AutoLoad)
- {
- saveConsoleState();
- readScripts(0);
- restoreConsoleState();
- }
-
- evaluator();
- ResetInterpreter();
- }
-
- else
- {
- switch (cmd)
- {
- case EDIT:
- editor();
- break;
- case LOAD:
- clearProject();
- load();
- return;
- case FIND:
- find();
- break;
- case ALSO:
- load();
- return;
- case RELOAD:
- readScripts(0);
- break;
- case UNLOAD:
- unload();
- return;
- case PROJECT:
- project();
- return;
- case TYPEOF:
- showtype();
- break;
- case HELP:
- menu();
- break;
- case NAMES:
- listNames();
- break;
- case CHGDIR:
- changeDir();
- break;
- case INFO:
- info();
- break;
- case QUIT:
- quit = TRUE;
- printf("[Leaving Gofer]\n");
- return;
- case NOCMD:
- if(AutoLoad)
- readScripts(0);
- break;
- case BADCMD:
- default:
- guidance();
- break;
-
- }
- }
- printPrompt(); /* print prompt string */
- }
- #endif
-
-
- Void errHead(l) /* print start of error message */
- Int l; {
- failed(); /* failed to reach target ... */
- stopAnyPrinting();
- fprintf(errorStream,"ERROR");
-
- if (scriptFile) {
- fprintf(errorStream," \"%s\"", scriptFile);
- setLastEdit(scriptFile,l);
- if (l) fprintf(errorStream," (line %d)",l);
- scriptFile = 0;
- }
- fprintf(errorStream,": ");
- fflush(errorStream);
- }
-
- Void errFail() { /* terminate error message and */
- putc('\n',errorStream); /* produce exception to return to */
- fflush(errorStream); /* main command loop */
- longjmp(catch_error,1);
- }
-
- Void errAbort() { /* altern. form of error handling */
- failed(); /* used when suitable error message*/
- stopAnyPrinting(); /* has already been printed */
- errFail();
- }
-
- Void internal(msg) /* handle internal error */
- String msg; {
- failed();
- stopAnyPrinting();
- fprintf(errorStream,"INTERNAL ERROR: %s\n",msg);
- fflush(errorStream);
- longjmp(catch_error,1);
- }
-
- Void fatal(msg) /* handle fatal error */
- String msg; {
- fflush(stdout);
- printf("\nFATAL ERROR: %s\n",msg);
- everybody(EXIT);
- exit(1);
- }
-
- sigHandler(breakHandler) { /* respond to break interrupt */
- breakOn(TRUE);
- printf("{Interrupted!}\n");
- everybody(BREAK);
- failed();
- stopAnyPrinting();
- fflush(stdout);
- longjmp(catch_error,1);
- sigResume;/*NOTREACHED*/
- }
-
- /*-------------------------------------------------------------------------*/
-