[gforth] / gforth / Attic / main.c  

gforth: gforth/Attic/main.c


1 : anton 1.1 /*
2 : pazsan 1.12 $Id: main.c,v 1.11 1994/09/08 17:20:09 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 :     extern int getopt (argc, argv, optstring);
21 :    
22 :     extern char *optarg;
23 :     extern int optind, opterr;
24 :     #endif
25 : pazsan 1.2
26 : anton 1.10 #ifndef DEFAULTPATH
27 :     # define DEFAULTPATH "/usr/local/lib/gforth:."
28 :     #endif
29 :    
30 : anton 1.1 #ifdef DIRECT_THREADED
31 : pazsan 1.2 # define CA(n) (symbols[(n)])
32 : anton 1.1 #else
33 : pazsan 1.2 # 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 : anton 1.1 * 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 : pazsan 1.2 * 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 : anton 1.1 */
64 :    
65 : anton 1.10 void relocate(Cell *image, char *bitstring, int size, Label symbols[])
66 : anton 1.1 {
67 : pazsan 1.5 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 : anton 1.9 case CF(DOUSER) :
82 : pazsan 1.13 case CF(DODEFER) : MAKE_CF(image+i,symbols[CF(image[i])]); break;
83 : pazsan 1.5 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 : pazsan 1.2
91 : pazsan 1.5 CACHE_FLUSH(image,size);
92 : anton 1.1 }
93 :    
94 : anton 1.10 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 : anton 1.1 image[0]=header[0];
123 :     image[1]=header[1];
124 : anton 1.10 image[2]=header[2];
125 : anton 1.1
126 : anton 1.10 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 : anton 1.1 imagefile);
129 :     fclose(imagefile);
130 :    
131 : anton 1.10 relocate(image,(char *)image+header[1],header[1],engine(0,0,0,0,0));
132 : anton 1.1
133 :     return(image);
134 :     }
135 :    
136 : anton 1.10 int go_forth(Cell *image, int stack, Cell *entries)
137 : anton 1.1 {
138 : anton 1.10 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 : pazsan 1.8 int throw_code;
144 : anton 1.10
145 : anton 1.1 for(;stack>0;stack--)
146 :     *--sp=entries[stack-1];
147 :    
148 :     install_signal_handlers(); /* right place? */
149 : pazsan 1.8
150 :     if ((throw_code=setjmp(throw_jmp_buf))) {
151 :     static Cell signal_data_stack[8];
152 :     static Cell signal_return_stack[8];
153 : pazsan 1.13 static Float signal_fp_stack[1];
154 : pazsan 1.8
155 :     signal_data_stack[7]=throw_code;
156 :    
157 : anton 1.10 return((int)engine((Xt *)image[4],signal_data_stack+7,
158 : pazsan 1.13 signal_return_stack+8,signal_fp_stack,0));
159 : pazsan 1.8 }
160 : anton 1.1
161 : anton 1.4 return((int)engine(ip,sp,rp,fp,lp));
162 : anton 1.1 }
163 :    
164 : anton 1.10 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 : anton 1.1 int main(int argc, char **argv, char **env)
190 :     {
191 : anton 1.10 char *path, *path1;
192 :     char *imagename="gforth.fi";
193 :     FILE *image_file;
194 : pazsan 1.12 int c, retvalue;
195 : anton 1.10
196 : anton 1.6 #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 : pazsan 1.2
202 : anton 1.10 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 : pazsan 1.12 #ifdef USE_GETOPT
209 : anton 1.10 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 : pazsan 1.12 #else
223 :     c = getopt(argc, argv, "imdrflp");
224 :     #endif
225 :    
226 : anton 1.10 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 : pazsan 1.2 }
242 : anton 1.10 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 : anton 1.1
263 :     {
264 : anton 1.10 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 : pazsan 1.12 retvalue=go_forth(loader(image_file),3,environ);
271 :     deprep_terminal();
272 :     exit(retvalue);
273 : anton 1.1 }
274 :     }

CVS Admin

Powered by ViewCVS 1.0-dev
(Powered by ViewCVS)

ViewCVS and CVS Help