Annotation of gforth/main.c, revision 1.4
1.1 anton 1: /*
1.4 ! anton 2: $Id: main.c,v 1.3 1994/05/05 17:05:35 pazsan Exp $
1.1 anton 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:
1.2 pazsan 17: #ifndef DEFAULTBIN
18: # define DEFAULTBIN ""
19: #endif
20:
1.1 anton 21: #ifdef DIRECT_THREADED
1.2 pazsan 22: # define CA(n) (symbols[(n)])
1.1 anton 23: #else
1.2 pazsan 24: # define CA(n) ((int)(symbols+(n)))
1.1 anton 25: #endif
26:
27: /* image file format:
28: * size of image with stacks without tags (in bytes)
29: * size of image without stacks and tags (in bytes)
1.4 ! anton 30: * size of return, FP and locals stack (in bytes, just one entry)
! 31: * !! have a different number for each one!
1.1 anton 32: * pointer to start of code
33: * data (size in image[1])
34: * tags (1 bit/data cell)
35: *
36: * tag==1 mean that the corresponding word is an address;
37: * If the word is >=0, the address is within the image;
38: * addresses within the image are given relative to the start of the image.
39: * If the word is =-1, the address is NIL,
1.2 pazsan 40: * If the word is between -2 and -5, it's a CFA (:, Create, Constant, User)
41: * If the word is -6, it's a DOES> CFA
42: * If the word is -7, it's a DOES JUMP
43: * If the word is <-7, it's a primitive
1.1 anton 44: */
45:
46: void relocate(int *image, char *bitstring, int size, Label symbols[])
47: {
48: int i;
49: static char bits[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
1.2 pazsan 50:
51: #ifdef DEBUG
52: printf("Dodoes-Adresse: %08x\n",(int)symbols[DODOES]);
53: #endif
1.1 anton 54:
55: for(i=0;i<size/sizeof(Cell);i++)
56: if(bitstring[i >> 3] & bits[i & 7])
57: if(image[i]<0)
1.2 pazsan 58: switch(image[i])
1.1 anton 59: {
1.2 pazsan 60: case CF_NIL :
61: image[i]=0; break;
62: case CF(DOCOL) :
63: case CF(DOVAR) :
64: case CF(DOCON) :
65: case CF(DOUSER) :
66: MAKE_CF(image+i,symbols[CF(image[i])]); break;
67: case CF(DODOES) :
68: MAKE_DOES_CF(image+i,image[i+1]+((int)image));
69: i++; break; /* is this necessary? */
70: case CF(DOESJUMP):
71: MAKE_DOES_HANDLER(image+i);
72: break;
73: default:
74: image[i]=(Cell)CA(CF(image[i]));
1.1 anton 75: }
76: else
77: image[i]+=(Cell)image;
1.3 pazsan 78:
79: CACHE_FLUSH(image,size);
1.1 anton 80: }
81:
82: int* loader(const char* filename)
83: { int header[2];
84: FILE *imagefile;
85: int *image;
86:
87: if(!(int)(imagefile=fopen(filename,"rb")))
88: {
89: fprintf(stderr,"Can't open image file '%s'",filename);
90: exit(1);
91: }
92:
93: fread(header,1,2*sizeof(int),imagefile);
94:
95: image=malloc(header[0]+((header[0]-1)/sizeof(Cell))/8+1);
96:
97: memset(image,0,header[0]+((header[0]-1)/sizeof(Cell))/8+1);
98:
99: image[0]=header[0];
100: image[1]=header[1];
101:
102: fread(image+2,1,header[1]-2*sizeof(Cell),imagefile);
103: fread(((void *)image)+header[0],1,((header[1]-1)/sizeof(Cell))/8+1,
104: imagefile);
105: fclose(imagefile);
106:
1.4 ! anton 107: relocate(image,(char *)image+header[0],header[1],engine(0,0,0,0,0));
1.1 anton 108:
109: return(image);
110: }
111:
112: int go_forth(int *image, int stack, Cell *entries)
113: {
114: Cell* rp=(Cell*)((void *)image+image[0]);
115: double* fp=(double*)((void *)rp-image[2]);
1.4 ! anton 116: Address lp=(Address)((void *)fp-image[2]);
! 117: Cell* sp=(Cell*)((void *)lp-image[2]);
1.1 anton 118: Cell* ip=(Cell*)(image[3]);
119:
120: for(;stack>0;stack--)
121: *--sp=entries[stack-1];
122:
123: install_signal_handlers(); /* right place? */
124:
1.4 ! anton 125: return((int)engine(ip,sp,rp,fp,lp));
1.1 anton 126: }
127:
128: int main(int argc, char **argv, char **env)
129: {
130: char imagefile[256];
131: Cell environ[3] = {(Cell)argc, (Cell)argv, (Cell)env};
132: char* imagepath;
133:
134: if((int)(imagepath=getenv("FORTHBIN")))
135: {
136: strcpy(imagefile,imagepath);
137:
138: if(imagefile[strlen(imagefile)-1]!='/')
139: imagefile[strlen(imagefile)]='/';
140: }
141: else
1.2 pazsan 142: {
143: strcpy(imagefile,DEFAULTBIN);
144:
145: if(imagefile[0]!=0 && imagefile[strlen(imagefile)-1]!='/')
146: imagefile[strlen(imagefile)]='/';
147: }
1.1 anton 148:
149: if(argc>1 && argv[1][0]=='@')
150: {
151: if(argv[1][1]=='/')
152: strcpy(imagefile,argv[1]+1);
153: else
154: strcpy(imagefile+strlen(imagefile),argv[1]+1);
155:
156: environ[0]-=1;
157: environ[1]+=sizeof(argv);
158: argv[1]=argv[0];
159: }
160: else
161: strcpy(imagefile+strlen(imagefile),"kernal.fi");
162:
163: exit(go_forth(loader(imagefile),3,environ));
164: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>