/******************************************************************************

			UNSW Prolog (version 4)

			Written by Claude Sammut
		     Department of Computer Science
		     University of New South Wales
		   (and St. Joseph's U., Philadelphia)

		   Copyright (c)  1983 - Claude Sammut

******************************************************************************/





#include <setjmp.h>
#include <stdio.h>
#include <signal.h>
#include "g.h"

#define MIN_SIZE 1000

jmp_buf	start_env;
char	interpret, *cur_file;
char	*temp_file = "/tmp/plXXXXXX";
char	*EDITOR = 0;
FILE	*input,
	*output,
	*prog_file;
int	library;

extern FILE *piport, *poport;
extern int linen;

static
ferr(fname)
char *fname;
{
	printf("\nCannot open %s\n", fname);
	exit();
}


static
p_panic()
{
	fprintf(stderr, "\nPANIC!! - Internal Prolog error!\n");
	exit();
}


static
interrupt()
{
	extern char run; extern argn, p_read_on, readatom;
	extern short sp, tp, parent, env;
	extern atom *prompt_string, *init_prompt;

	signal(SIGINT, interrupt);
	putchar(07); putchar('\n');
	argn = run = sp = tp = 0;
	readatom = p_read_on = FALSE;
	parent = env = -1;
	input = stdin; output = stdout;
	prompt_string = init_prompt;
	interpret = isatty(fileno(input));
	longjmp(start_env, 1);
}


fatal(msg)
char *msg;
{
	extern char run; extern argn, p_read_on, readatom;
	extern short sp, tp, parent, env;
	extern atom *prompt_string, *init_prompt;

	printf("\n%s\n", msg);
	argn = run = sp = tp = 0;
	readatom = p_read_on = FALSE;
	parent = env = -1;
	input = stdin; output = stdout;
	prompt_string = init_prompt;
	interpret = isatty(fileno(input));
	longjmp(start_env, 1);
}

static
say_hello()
{
	register char c;
	FILE *news;

	fprintf(stderr, "\nUNSW - PROLOG\n");
	if ((news = fopen(NEWS, "r")) == NULL)
		return;
	while ((c = getc(news)) != EOF) putc(c, stderr);
	fclose(news);
}


add_file(name, proc_list)
atom *name;
pval proc_list;
{
	extern clause *create();
	extern atom *_file;
	register clause *p;
	register pval q;

	p = create(0, 0);
	p -> rest = VAL(_file);
	VAL(_file) = p;
	p -> goal[0] = q = (pval) record(2);
	p -> goal[1] = 0;
	q -> c.term[0] = (pval) _file;
	q -> c.term[1] = (pval) name;
	q -> c.term[2] = proc_list;
}




static
get_file(name, lib)
char *name;
int lib;
{
	extern pval intern();
	extern pval proc_list;
	extern atom *nil;

	proc_list = (pval) nil;
	if ((input = fopen(name, "r")) == NULL)
		ferr(name);
	library = lib;
	linen = 1;
	cur_file = name;
	prog_file = input;
	if (! setjmp(start_env)) evloop();
	else {
		fprintf(stderr, "Fatal error while loading %s\n", name);
		fprintf(stderr, "Prolog execution aborted\n");
		exit();
	}
	fclose(input);
	if (! library)
		add_file(intern(atype(name), name, strlen(name)+1, FALSE), proc_list);
}


main(argc, argv)
register argc;
register char **argv;
{
	extern char *getenv();
	register i;
	int stack_size = MIN_SIZE;

#ifndef DEBUG
	signal(SIGSEGV, p_panic);
	signal(SIGBUS, p_panic);
	signal(SIGILL, p_panic);
#endif

	hash_init();
	setup();
	set_files();
	output = poport = stdout;
	mktemp(temp_file);	/* temporary file name for editor */

		/* read in command line */

	for (i = 1; i < argc; i++)
	{
		if (argv[i][0] == '-' && argv[i][1] == 's')
		{
			stack_size = atoi(&(argv[i][2]));
			if (stack_size < MIN_SIZE)
			{
				printf("\nStack too small\n");
				exit();
			}
		}
	}

	set_stacks(stack_size);
/*  For this statement to work, the logical name PROLOG$LIB must be defined */
/*  This should point to a file of Prolog library predicates.               */
	get_file(LIB, 1);

	for (i = 1; i < argc; i++)
		if (argv[i][0] != '-')
			get_file(argv[i], 0);

		/* start interactive interpreter loop */

	prog_file = input = piport = stdin;
	library = FALSE;
	if (interpret = isatty(fileno(input)))
	{
		say_hello();
		EDITOR = getenv("EDITOR");
		if (! EDITOR) EDITOR = DEFAULT_ED;
	}
	else cur_file = "input file";
	if (signal(SIGINT, interrupt) == SIG_IGN)
		signal(SIGINT, SIG_IGN);
L1:	if (! setjmp(start_env)) evloop();
	else goto L1;
}
