This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
vsc e5f4633c39 This commit was generated by cvs2svn to compensate for changes in r4,
which included commits to RCS files with non-trunk default branches.


git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@5 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
2001-04-09 19:54:03 +00:00

466 lines
10 KiB
C

/*************************************************************************
* *
* Yap Prolog *
* *
* Yap Prolog Was Developed At Nccup - Universidade Do Porto *
* *
* Copyright L.Damas, V.S.Costa And Universidade Do Porto 1985-1997 *
* *
**************************************************************************
* *
* File: Yap.C *
* Last Rev: *
* Mods: *
* Comments: Yap's Main File *
* *
*************************************************************************/
/* static char SccsId[] = "X 4.3.3"; */
#include "config.h"
#include "c_interface.h"
#ifdef _MSC_VER /* Microsoft's Visual C++ Compiler */
#ifdef HAVE_UNISTD_H
#undef HAVE_UNISTD_H
#endif
#endif
#include <stdio.h>
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#if HAVE_FCNTL_H
#include <fcntl.h>
#endif
#if HAVE_STDARG_H
#include <stdarg.h>
#endif
#include <stdlib.h>
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#if HAVE_ERRNO_H
#include <errno.h>
#endif
#if HAVE_STRING_H
#include <string.h>
#endif
static int PROTO(mygetc, (void));
static void PROTO(do_bootfile, (char *));
static void PROTO(do_top_goal,(Term));
static void PROTO(exec_top_level,(int, char *));
#ifndef LIGHT
void PROTO (exit, (int));
#endif
#ifdef LIGHT
#include <unix.h>
int
_main (int, char **);
#else
int PROTO (main, (int, char **));
#endif
#ifdef DEBUG
static int output_msg;
#endif
static char BootFile[] = "boot.yap";
static char StartUpFile[] = "startup";
#ifdef lint
/* VARARGS1 */
#endif
#ifdef M_WILLIAMS
long _stksize = 32000;
#endif
static FILE *bootfile;
static int eof_found = FALSE;
static int yap_lineno = 0;
#ifdef DEBUG
static void myputc (int ch)
{
putc(ch,stderr);
}
#endif
static int
mygetc (void)
{
int ch;
if (eof_found)
return (EOF);
ch = getc (bootfile);
if (ch == EOF)
eof_found = TRUE;
if (ch == '\n') {
#ifdef MPW
ch = 10;
#endif
yap_lineno++;
}
return (ch);
}
static void
do_top_goal (Term Goal)
{
#ifdef DEBUG
if (output_msg)
fprintf(stderr,"Entering absmi\n");
#endif
/* PlPutc(0,'a'); PlPutc(0,'\n'); */
YapRunGoal(Goal);
}
/* do initial boot by consulting the file boot.yap */
static void
do_bootfile (char *bootfilename)
{
Term t;
Term term_nil = MkAtomTerm(YapLookupAtom("[]"));
Term term_end_of_file = MkAtomTerm(YapLookupAtom("end_of_file"));
Term term_true = MkAtomTerm(YapLookupAtom("true"));
Term functor_query = MkFunctor(YapLookupAtom("?-"),1);
/* consult boot.pl */
bootfile = fopen (bootfilename, "r");
if (bootfile == NULL)
{
fprintf(stderr, "[ FATAL ERROR: could not open bootfile %s ]\n", bootfilename);
exit(1);
}
/* the consult mode does not matter here, really */
/*
To be honest, YapInitConsult does not really do much,
it's here for the future. It also makes what we want to do clearer.
*/
YapInitConsult(YAP_CONSULT_MODE,bootfilename);
while (!eof_found)
{
t = YapRead(mygetc);
if (eof_found) {
break;
}
if (t == 0)
{
fprintf(stderr, "[ SYNTAX ERROR: while parsing bootfile %s at line %d ]\n", bootfilename, yap_lineno);
exit(1);
}
if (IsVarTerm (t) || t == term_nil)
{
continue;
}
else if (t == term_true)
{
YapExit(0);
}
else if (t == term_end_of_file)
{
break;
}
else if (IsPairTerm (t))
{
fprintf(stderr, "[ SYSTEM ERROR: consult not allowed in boot file ]\n");
fprintf(stderr, "error found at line %d and pos %d", yap_lineno, fseek(bootfile,0L,SEEK_CUR));
}
else if (IsApplTerm (t) && FunctorOfTerm (t) == functor_query)
{
do_top_goal(ArgOfTerm (1, t));
}
else
{
char *ErrorMessage = YapCompileClause(t);
if (ErrorMessage)
fprintf(stderr, ErrorMessage);
}
/* do backtrack */
YapReset();
}
YapEndConsult();
fclose (bootfile);
#ifdef DEBUG
if (output_msg)
fprintf(stderr,"Boot loaded\n");
#endif
}
static char *filename;
/*
* proccess command line arguments: valid switches are: -b boot -s
* stack area size (K) -h heap area size -a aux stack size -e
* emacs_mode -m reserved memory for alloc IF DEBUG -p if you
* want to check out startup IF MAC -mpw if we are using the mpw
* shell
*/
static int
parse_yap_arguments(int argc, char *argv[], yap_init_args *init_args)
{
char *p;
int BootMode = YAP_BOOT_FROM_SAVED_CODE;
int *ssize;
while (--argc > 0)
{
p = *++argv;
if (*p == '-')
switch (*++p)
{
case 'b':
BootMode = YAP_BOOT_FROM_PROLOG;
break;
case '?':
fprintf(stderr,"\n[ Valid switches for command line arguments: ]\n");
fprintf(stderr," -? Shows this screen\n");
fprintf(stderr," -b Boot file (%s)\n", StartUpFile);
fprintf(stderr," -l Prolog file\n");
fprintf(stderr," -h Heap area in Kbytes\n");
fprintf(stderr," -s Stack area in Kbytes\n");
fprintf(stderr," -t Trail area in Kbytes\n");
fprintf(stderr," -w YapOr option: Number of workers (default: %d)\n", init_args->NumberWorkers);
fprintf(stderr," -sl YapOr option: Loop scheduler executions before look for hiden shared work (default: %d)\n", init_args->SchedulerLoop);
fprintf(stderr," -d YapOr option: Value of delayed release of load (default: %d)\n", init_args->DelayedReleaseLoad);
fprintf(stderr,"\n");
exit(0);
case 'w':
ssize = &(init_args->NumberWorkers);
goto GetSize;
case 'd':
ssize = &(init_args->DelayedReleaseLoad);
goto GetSize;
#ifdef USE_SOCKET
case 'c': /* running as client */
{
char *host, *p1;
long port;
char *ptr;
host = *++argv;
argc--;
if (host != NULL && host[0] == '-')
YapError("sockets must receive host to connect to");
p1 = *++argv;
argc--;
if (p1[0] == '-')
YapError("sockets must receive port to connect to");
port = strtol(p1, &ptr, 10);
if (ptr == NULL || ptr[0] != '\0')
YapError("port argument to socket must be a number");
YapInitSocks(host,port);
}
break;
#endif
#ifdef EMACS
case 'e':
emacs_mode = TRUE;
{
File fd;
strcpy (emacs_tmp, ++p);
if ((fd = fopen (emacs_tmp, "w")) == NIL)
fprintf(stderr, "[ Warning: unable to communicate with emacs: failed to open %s ]\n", emacs_tmp);
fclose (fd);
unlink (emacs_tmp);
p = *++argv;
--argc;
strcpy (emacs_tmp2, p);
if ((fd = fopen (emacs_tmp2, "w")) == NIL)
fprintf(stderr, "Unable to communicate with emacs: failed to open %s\n", emacs_tmp2);
fclose (fd);
unlink (emacs_tmp2);
}
break;
#endif /* EMACS */
#ifdef MPWSHELL
case 'm':
if (*++p == 'p' && *++p == 'w' && *++p == '\0')
mpwshell = TRUE;
break;
#endif
case 's':
ssize = &(init_args->StackSize);
if (p[1] == 'l') {
p++;
ssize = &(init_args->SchedulerLoop);
}
goto GetSize;
case 'h':
ssize = &(init_args->HeapSize);
goto GetSize;
case 't':
ssize = &(init_args->TrailSize);
GetSize:
if (*++p == '\0')
{
if (argc > 1)
--argc, p = *++argv;
else
{
fprintf(stderr,"[ YAP unrecoverable error: missing size in flag %s ]", argv[-1]);
YapExit(1);
}
}
{
int i = 0, ch;
while ((ch = *p++) >= '0' && ch <= '9')
i = i * 10 + ch - '0';
if (ch)
{
fprintf(stderr,"[ YAP unrecoverable error: illegal size specification %s ]", argv[-1]);
YapExit(1);
}
*ssize = i;
}
break;
#ifdef DEBUG
case 'p':
YapSetOutputMessage();
output_msg = TRUE;
break;
#endif
case 'l':
case 'L':
if ((*argv)[0] == '\0')
init_args->YapPrologBootFile = *argv;
else {
argc--;
if (argc == 0) {
fprintf(stderr," [ YAP unrecoverable error: missing file name with option 'l' ]\n");
exit(1);
}
argv++;
init_args->YapPrologBootFile = *argv;
}
if (p[0] == 'L')
init_args->HaltAfterConsult = TRUE;
break;
case '-':
/* skip remaining arguments */
argc = 1;
break;
default:
{
fprintf(stderr,"[ YAP unrecoverable error: unknown switch -%c ]\n", *p);
exit(1);
}
}
else {
filename = p;
}
}
return(BootMode);
}
static int
init_standard_system(int argc, char *argv[])
{
int BootMode;
yap_init_args init_args;
init_args.SavedState = NULL;
init_args.HeapSize = 0;
init_args.StackSize = 0;
init_args.TrailSize = 0;
init_args.YapLibDir = NULL;
init_args.YapPrologBootFile = NULL;
init_args.HaltAfterConsult = FALSE;
init_args.NumberWorkers = 1;
init_args.SchedulerLoop = 10;
init_args.DelayedReleaseLoad = 3;
init_args.Argc = argc;
init_args.Argv = argv;
BootMode = parse_yap_arguments(argc,argv,&init_args);
/* init memory */
if (BootMode == YAP_BOOT_FROM_PROLOG)
{
YapInit(&init_args);
}
else
{
if (filename == NULL)
init_args.SavedState = StartUpFile;
else
init_args.SavedState = filename;
BootMode = YapInit(&init_args);
}
return(BootMode);
}
static void
exec_top_level(int BootMode, char *filename)
{
Term atomfalse;
Atom livegoal;
if (BootMode == YAP_BOOT_FROM_SAVED_STACKS)
{
/* continue executing from the frozen stacks */
YapContinueGoal();
}
else if (BootMode == YAP_BOOT_FROM_PROLOG)
{
Atom livegoal;
/* read the bootfile */
do_bootfile (filename ? filename : BootFile);
livegoal = FullLookupAtom("$live");
/* initialise the top-level */
YapPutValue(livegoal, MkAtomTerm (LookupAtom("true")));
}
/* the top-level is now ready */
/* read it before case someone, that is, Ashwin, hides
the atom false away ;-).
*/
livegoal = FullLookupAtom("$live");
atomfalse = MkAtomTerm (LookupAtom("false"));
while (YapGetValue (livegoal) != atomfalse) {
do_top_goal (MkAtomTerm (livegoal));
}
YapExit(0);
}
#ifdef LIGHT
int
_main (int argc, char **argv)
#else
int
main (int argc, char **argv)
#endif
{
int BootMode;
#ifdef SIMICS
fprintf(stdout,"Entering YAP\n");
#endif /* SIMICS */
BootMode = init_standard_system(argc, argv);
if (BootMode == YAP_BOOT_FROM_SAVED_ERROR) {
fprintf(stderr,"[ FATAL ERROR: could not find saved state ]\n");
exit(1);
}
#if defined(YAPOR) || defined(TABLING)
start_workers();
#endif /* YAPOR || TABLING */
exec_top_level(BootMode, filename);
return(0);
}