[gforth] / gforth / Attic / main.c  

gforth: gforth/Attic/main.c


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

CVS Admin

Powered by ViewCVS 1.0-dev
(Powered by ViewCVS)

ViewCVS and CVS Help