/* xlisp - a small implementation of lisp with object-oriented programming */
/*        Copyright (c) 1985, by David Michael Betz
          All Rights Reserved
          Permission is granted for unrestricted non-commercial use   */

#include "flp1_xlisp_h"

/* define the banner line string */
#define BANNER1      "XLISP version 1.7, Copyright (c) 1986, by David Betz"
#define BANNER2      "angepasst fuer den Sinclair QL von Ralf Biedermann"

/* external variables */
extern NODE *s_stdin,*s_stdout;
extern NODE *s_evalhook,*s_applyhook;
extern int xldebug;
extern NODE *true;
extern FILE *tfp;

/* external routines */
extern FILE *fopen();

/* main - the main routine */
main(argc,argv)
  int argc; char *argv[];
{
    char *transcript;
    int verbose,i;
    CONTEXT cntxt;
    NODE *expr;

    /* setup default argument values */
    transcript = NULL;
    verbose = FALSE;

    /* parse the argument list switches */
#ifndef MEGAMAX
    for (i = 1; i < argc; ++i)
          if (argv[i][0] == '-')
              switch(argv[i][1]) {
              case 't':
              case 'T':
                    transcript = &argv[i][2];
                    break;
              case 'v':
              case 'V':
                    verbose = TRUE;
                    break;
              }
#endif

    /* initialize and print the banner line */
    osinit(BANNER1);
    osinit(BANNER2);

    /* open the transcript file */
    if (transcript && (tfp = fopen(transcript,"w")) == NULL)
          printf("can't open transcript file: %s\n",transcript);

    /* setup initialization error handler */
    xlbegin(&cntxt,CF_TOPLEVEL|CF_ERROR,(NODE *) 1);
    if (setjmp(cntxt.c_jmpbuf)) {
          printf("fatal initialization error\n");
          wrapup();
    }

    /* initialize xlisp */
    xlinit();
    xlend(&cntxt);

    /* reset the error handler */
    xlbegin(&cntxt,CF_TOPLEVEL|CF_ERROR,true);

    /* load "flp1_init_lsp" */
    if (setjmp(cntxt.c_jmpbuf) == 0)
          xlload("flp1_init",FALSE,FALSE);

    /* load any files mentioned on the command line */
#ifndef MEGAMAX
    if (setjmp(cntxt.c_jmpbuf) == 0)
          for (i = 1; i < argc; i++)
              if (argv[i][0] != '-' && !xlload(argv[i],TRUE,verbose))
                    xlfail("can't load file");
#endif

    /* create a new stack frame */
    xlsave1(expr);

    /* main command processing loop */
    while (TRUE) {

          /* setup the error return */
          if (i = setjmp(cntxt.c_jmpbuf)) {
              if (i == CF_TOPLEVEL)
                    stdputstr("[ back to the top level ]\n");
              setvalue(s_evalhook,NIL);
              setvalue(s_applyhook,NIL);
              xldebug = 0;
              xlflush();
          }

          /* read an expression */
          if (!xlread(getvalue(s_stdin),&expr,FALSE))
              break;

          /* evaluate the expression */
          expr = xleval(expr);

          /* print it */
          stdprint(expr);
    }
    xlend(&cntxt);

    /* clean up */
    wrapup();
}

/* stdprint - print to standard output */
stdprint(expr)
  NODE *expr;
{
    xlprint(getvalue(s_stdout),expr,TRUE);
    xlterpri(getvalue(s_stdout));
}

/* stdputstr - print a string to standard output */
stdputstr(str)
  char *str;
{
    xlputstr(getvalue(s_stdout),str);
}

/* wrapup - clean up and exit to the operating system */
wrapup()
{
    if (tfp)
          fclose(tfp);
    exit();
}
