File:  [gforth] / gforth / Attic / main.c
Revision 1.13: download - view: text, annotated - select for diffs
Mon Sep 26 20:31:14 1994 UTC (29 years, 6 months ago) by pazsan
Branches: MAIN
CVS tags: HEAD
Made DTC on HPPA run!
Changed -DDEBUG output to go to stderr

    1: /*
    2:   $Id: main.c,v 1.13 1994/09/26 20:31:14 pazsan Exp $
    3:   Copyright 1993 by the ANSI figForth Development Group
    4: */
    5: 
    6: #include <ctype.h>
    7: #include <stdio.h>
    8: #include <string.h>
    9: #include <math.h>
   10: #include <sys/types.h>
   11: #include <sys/stat.h>
   12: #include <fcntl.h>
   13: #include <assert.h>
   14: #include <stdlib.h>
   15: #include "forth.h"
   16: #include "io.h"
   17: #ifdef USE_GETOPT
   18: #  include "getopt.h"
   19: #else
   20:      extern int getopt (argc, argv, optstring);
   21: 
   22:      extern char *optarg;
   23:      extern int optind, opterr;
   24: #endif
   25: 
   26: #ifndef DEFAULTPATH
   27: #	define DEFAULTPATH "/usr/local/lib/gforth:."
   28: #endif
   29: 
   30: #ifdef DIRECT_THREADED
   31: #	define CA(n)	(symbols[(n)])
   32: #else
   33: #	define CA(n)	((int)(symbols+(n)))
   34: #endif
   35: 
   36: #define maxaligned(n)	((((Cell)n)+sizeof(Float)-1)&-sizeof(Float))
   37: 
   38: static int dictsize=0;
   39: static int dsize=0;
   40: static int rsize=0;
   41: static int fsize=0;
   42: static int lsize=0;
   43: char *progname;
   44: 
   45: 
   46: /* image file format:
   47:  *   size of image with stacks without tags (in bytes)
   48:  *   size of image without stacks and tags (in bytes)
   49:  *   size of data and FP stack (in bytes)
   50:  *   pointer to start of code
   51:  *   pointer into throw (for signal handling)
   52:  *   data (size in image[1])
   53:  *   tags (1 bit/data cell)
   54:  *
   55:  * tag==1 mean that the corresponding word is an address;
   56:  * If the word is >=0, the address is within the image;
   57:  * addresses within the image are given relative to the start of the image.
   58:  * If the word is =-1, the address is NIL,
   59:  * If the word is between -2 and -5, it's a CFA (:, Create, Constant, User)
   60:  * If the word is -6, it's a DOES> CFA
   61:  * If the word is -7, it's a DOES JUMP
   62:  * If the word is <-7, it's a primitive
   63:  */
   64: 
   65: void relocate(Cell *image, char *bitstring, int size, Label symbols[])
   66: {
   67:    int i=0, j, k, steps=(size/sizeof(Cell))/8;
   68:    char bits;
   69: /*   static char bits[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};*/
   70:    
   71:    for(k=0; k<=steps; k++)
   72:      for(j=0, bits=bitstring[k]; j<8; j++, i++, bits<<=1)
   73:        if(bits & 0x80)
   74:          if(image[i]<0)
   75:            switch(image[i])
   76:              {
   77: 		case CF_NIL      : image[i]=0; break;
   78: 		case CF(DOCOL)   :
   79: 		case CF(DOVAR)   :
   80: 		case CF(DOCON)   :
   81: 		case CF(DOUSER)  : 
   82: 		case CF(DODEFER) : MAKE_CF(image+i,symbols[CF(image[i])]); break;
   83: 		case CF(DODOES)  : MAKE_DOES_CF(image+i,image[i+1]+((int)image));
   84: 		                   break;
   85: 		case CF(DOESJUMP): MAKE_DOES_HANDLER(image+i); break;
   86: 		default          : image[i]=(Cell)CA(CF(image[i]));
   87: 	     }
   88:          else
   89:            image[i]+=(Cell)image;
   90: 
   91:    CACHE_FLUSH(image,size);
   92: }
   93: 
   94: Cell *loader(FILE *imagefile)
   95: {
   96: 	Cell header[3];
   97: 	Cell *image;
   98: 	int wholesize;
   99: 	int imagesize; /* everything needed by the image */
  100: 
  101: 	fread(header,1,3*sizeof(Cell),imagefile);
  102: 	if (dictsize==0)
  103: 	  dictsize = header[0];
  104: 	if (dsize==0)
  105: 	  dsize=header[2];
  106: 	if (rsize==0)
  107: 	  rsize=header[2];
  108: 	if (fsize==0)
  109: 	  fsize=header[2];
  110: 	if (lsize==0)
  111: 	  lsize=header[2];
  112: 	dictsize=maxaligned(dictsize);
  113: 	dsize=maxaligned(dsize);
  114: 	rsize=maxaligned(rsize);
  115: 	lsize=maxaligned(lsize);
  116: 	fsize=maxaligned(fsize);
  117: 
  118: 	wholesize = dictsize+dsize+rsize+fsize+lsize;
  119: 	imagesize = header[1]+((header[1]-1)/sizeof(Cell))/8+1;
  120: 	image=malloc(wholesize>imagesize?wholesize:imagesize);
  121: 	memset(image,0,wholesize); /* why? - anton */
  122: 	image[0]=header[0];
  123: 	image[1]=header[1];
  124: 	image[2]=header[2];
  125: 
  126: 	fread(image+3,1,header[1]-3*sizeof(Cell),imagefile);
  127: 	fread(((void *)image)+header[1],1,((header[1]-1)/sizeof(Cell))/8+1,
  128: 	      imagefile);
  129: 	fclose(imagefile);
  130: 
  131: 	relocate(image,(char *)image+header[1],header[1],engine(0,0,0,0,0));
  132: 
  133: 	return(image);
  134: }
  135: 
  136: int go_forth(Cell *image, int stack, Cell *entries)
  137: {
  138: 	Cell *sp=(Cell*)((void *)image+dictsize+dsize);
  139: 	Address lp=(Address)((void *)sp+lsize);
  140: 	Float *fp=(Float *)((void *)lp+fsize);
  141: 	Cell *rp=(Cell*)((void *)fp+rsize);
  142: 	Xt *ip=(Xt *)(image[3]);
  143: 	int throw_code;
  144: 
  145: 	for(;stack>0;stack--)
  146: 		*--sp=entries[stack-1];
  147: 
  148: 	install_signal_handlers(); /* right place? */
  149: 
  150: 	if ((throw_code=setjmp(throw_jmp_buf))) {
  151: 		static Cell signal_data_stack[8];
  152: 		static Cell signal_return_stack[8];
  153:       static Float signal_fp_stack[1];
  154: 
  155: 		signal_data_stack[7]=throw_code;
  156: 
  157: 		return((int)engine((Xt *)image[4],signal_data_stack+7,
  158: 				                  signal_return_stack+8,signal_fp_stack,0));
  159: 	}
  160: 
  161: 	return((int)engine(ip,sp,rp,fp,lp));
  162: }
  163: 
  164: int convsize(char *s, int elemsize)
  165: /* converts s of the format #+u (e.g. 25k) into the number of bytes.
  166:    the unit u can be one of bekM, where e stands for the element
  167:    size. default is e */
  168: {
  169:   char *endp;
  170:   int n,m;
  171: 
  172:   m = elemsize;
  173:   n = strtoul(s,&endp,0);
  174:   if (endp!=NULL) {
  175:     if (strcmp(endp,"b")==0)
  176:       m=1;
  177:     else if (strcmp(endp,"k")==0)
  178:       m=1024;
  179:     else if (strcmp(endp,"M")==0)
  180:       m=1024*1024;
  181:     else if (strcmp(endp,"e")!=0) {
  182:       fprintf(stderr,"%s: cannot grok size specification %s\n", progname, s);
  183:       exit(1);
  184:     }
  185:   }
  186:   return n*m;
  187: }
  188: 
  189: int main(int argc, char **argv, char **env)
  190: {
  191: 	char *path, *path1;
  192: 	char *imagename="gforth.fi";
  193: 	FILE *image_file;
  194: 	int c, retvalue;
  195: 	  
  196: #if defined(i386) && defined(ALIGNMENT_CHECK)
  197: 	/* turn on alignment checks on the 486.
  198: 	 * on the 386 this should have no effect. */
  199: 	__asm__("pushfl; popl %eax; orl $0x40000, %eax; pushl %eax; popfl;");
  200: #endif
  201: 
  202: 	progname = argv[0];
  203: 	if ((path=getenv("GFORTHPATH"))==NULL)
  204: 	  path = strcpy(malloc(strlen(DEFAULTPATH)+1),DEFAULTPATH);
  205: 	opterr=0;
  206: 	while (1) {
  207: 	  int option_index=0;
  208: #ifdef USE_GETOPT
  209: 	  static struct option opts[] = {
  210: 	    {"image-file", required_argument, NULL, 'i'},
  211: 	    {"dictionary-size", required_argument, NULL, 'm'},
  212: 	    {"data-stack-size", required_argument, NULL, 'd'},
  213: 	    {"return-stack-size", required_argument, NULL, 'r'},
  214: 	    {"fp-stack-size", required_argument, NULL, 'f'},
  215: 	    {"locals-stack-size", required_argument, NULL, 'l'},
  216: 	    {"path", required_argument, NULL, 'p'},
  217: 	    {0,0,0,0}
  218: 	    /* no-init-file, no-rc? */
  219: 	  };
  220: 
  221: 	  c = getopt_long(argc, argv, "+drfl", opts, &option_index);
  222: #else
  223: 	  c = getopt(argc, argv, "imdrflp");
  224: #endif
  225: 
  226: 	  if (c==EOF)
  227: 	    break;
  228: 	  if (c=='?') {
  229: 	    optind--;
  230: 	    break;
  231: 	  }
  232: 	  switch (c) {
  233: 	  case 'i': imagename = optarg; break;
  234: 	  case 'm': dictsize = convsize(optarg,sizeof(Cell)); break;
  235: 	  case 'd': dsize = convsize(optarg,sizeof(Cell)); break;
  236: 	  case 'r': rsize = convsize(optarg,sizeof(Cell)); break;
  237: 	  case 'f': fsize = convsize(optarg,sizeof(Float)); break;
  238: 	  case 'l': lsize = convsize(optarg,sizeof(Cell)); break;
  239: 	  case 'p': path = optarg; break;
  240: 	  }
  241: 	}
  242: 	path1=path;
  243: 	do {
  244: 	  char *pend=strchr(path, ':');
  245: 	  if (pend==NULL)
  246: 	    pend=path+strlen(path);
  247: 	  if (strlen(path)==0) {
  248: 	    fprintf(stderr,"%s: cannot open image file %s in path %s for reading\n", progname, imagename, path1);
  249: 	    exit(1);
  250: 	  }
  251: 	  {
  252: 	    int dirlen=pend-path;
  253: 	    char fullfilename[dirlen+strlen(imagename)+2];
  254: 	    memcpy(fullfilename, path, dirlen);
  255: 	    if (fullfilename[dirlen-1]!='/')
  256: 	      fullfilename[dirlen++]='/';
  257: 	    strcpy(fullfilename+dirlen,imagename);
  258: 	    image_file=fopen(fullfilename,"rb");
  259: 	  }
  260: 	  path=pend+(*pend==':');
  261: 	} while (image_file==NULL);
  262: 
  263: 	{
  264: 	  Cell environ[]= {(Cell)argc-(optind-1), (Cell)(argv+(optind-1)), (Cell)path1};
  265: 	  argv[optind-1] = progname;
  266: /*
  267: 	  for (i=0; i<environ[0]; i++)
  268: 	    printf("%s\n", ((char **)(environ[1]))[i]);
  269: */
  270:      retvalue=go_forth(loader(image_file),3,environ);
  271:      deprep_terminal();
  272:      exit(retvalue);
  273: 	}
  274: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>