|
|
1.1 root 1: /*
2: / OSINT.C - The Main Module of the Macro SPITBOL Compiler
3: */
4:
5: #include "osint.h"
6: #include "spitblks.h"
7:
8: extern char *sbrk();
9:
10: /*
11: / Global data areas needed by compiler.
12: */
13:
14: WORD gblargc; /* argc from command line */
15: char **gblargv; /* argv from command line */
16: char *uarg; /* -u argument from command line */
17:
18: /*
19: / Compiler flags (see compiler listing for more details):
20: /
21: / ERRORS send errors to terminal
22: / PRTICH terminal is standard output file
23: / NOLIST suppress compilation listing
24: / NOCMPS suppress compilation statistics
25: / NOEXCS suppress execution statistics
26: / LNGLST generate long listing (WITH page ejects)
27: / NOEXEC suppress program execution
28: / TRMNAL support terminal i/o association
29: / STDLST standard listing (intermediate)
30: / NOHDER suppress spitbol compiler header
31: /
32: / DFLT_FLAGS reasonable defaults for UN*X environment
33: */
34:
35: #define ERRORS 1
36: #define PRTICH 2
37: #define NOLIST 4
38: #define NOCMPS 8
39: #define NOEXCS 16
40: #define LNGLST 32
41: #define NOEXEC 64
42: #define TRMNAL 128
43: #define STDLST 256
44: #define NOHEDR 512
45:
46: #define DFLT_FLAGS (ERRORS+NOLIST+NOCMPS+NOEXCS+TRMNAL+NOHEDR)
47:
48: /*
49: / Information to be given to compiler
50: */
51:
52: WORD dfltcase = 1; /* case conversion: 0 - no / 1 - yes */
53: WORD lnsppage = 60; /* lines per page for listings */
54: WORD pagewdth = 120; /* width of output line for listings */
55: WORD spitflag = DFLT_FLAGS; /* flags to be given to compiler */
56:
57: /*
58: / Memory variables that control compiler's dynamic area and stack.
59: */
60: WORD meminc = 4096; /* # of words in memory chunk to allocate*/
61: WORD memincb = 4094*4; /* meminc converted to bytes */
62: WORD datawds = 262144; /* max size in words of data area */
63: char *basemem; /* base of dynamic memory */
64: char *topmem; /* current top of dynamic memory */
65: char *maxmem; /* maximum top of dynamic memory */
66: WORD maxsize = 8192; /* maximum size element in dyn. memory */
67:
68: WORD stacksiz = 2048; /* maximum size of stack in bytes */
69: char *initsp; /* initial sp value */
70: char *lowsp; /* lowest legal sp value */
71:
72: /*
73: /
74: */
75: WORD inpcnt; /* number of input files */
76: char **inpptr; /* pointer to input file in argv array */
77: char *outptr; /* pointer to output listing file */
78:
79: /*
80: / lmodstk is set when creating a load module. On the subsequent
81: / execution of a load module, the presence of a non-zero value in
82: / lmodstk determines that the execution is indeed of a load module.
83: */
84: char *lmodstk;
85:
86: main( argc, argv )
87:
88: int argc;
89: char *argv[];
90:
91: {
92: int ch, i;
93: char *cp, *optnum();
94:
95:
96: /*
97: / If this is a restart of this program from a load module, skip the
98: / option processing and handle things.
99: */
100: /* if ( lmodstk )
101: rstart();
102: */
103:
104: /*
105: / Here we are for a normal startup of the compiler. Process all
106: / command line options. Notice that certain options modify the value
107: / of the loop control variable i.
108: */
109: for( i = 1 ; i < argc ; i++ )
110: {
111: cp = argv[i];
112: if ( *cp != '-' )
113: {
114: if ( inpptr )
115: {
116: write( 2, "Hmmm\n", 5 );
117: exit();
118: }
119: inpptr = argv + i;
120: inpcnt = argc - i;
121: break;
122: }
123:
124: ++cp;
125: while( *cp )
126: switch( ch = *cp++ )
127: {
128: /*
129: / -a turn on listing options except header
130: */
131: case 'a':
132: spitflag &= ~(NOLIST | NOCMPS | NOEXCS);
133: break;
134:
135: /*
136: / -c turn on compilation statistics
137: */
138: case 'c':
139: spitflag &= ~NOCMPS;
140: break;
141:
142: /*
143: / -dnnn set maximum size of dynamic area in words
144: */
145: case 'd':
146: cp = optnum( cp, &datawds );
147: break;
148:
149: /*
150: / -e don't send errors to terminal
151: */
152: case 'e':
153: spitflag &= ~ERRORS;
154: break;
155:
156: /*
157: / -f don't fold lower case to upper case
158: */
159: case 'f':
160: dfltcase = 0;
161: break;
162:
163: /*
164: / -h print header listing
165: */
166: case 'h':
167: spitflag &= ~NOHEDR;
168: break;
169:
170: /*
171: / -iddd set memory expansion increment
172: */
173: case 'i':
174: cp = optnum( cp, &meminc );
175: memincb = meminc * sizeof( WORD );
176: break;
177:
178: /*
179: / -l turn on compilation listing
180: */
181: case 'l':
182: spitflag &= ~NOLIST;
183: break;
184:
185: /*
186: / -mddd set maximum size of object in dynamic area
187: */
188: case 'm':
189: cp = optnum( cp, &maxsize );
190: break;
191:
192: /*
193: / -n suppress program execution
194: */
195: case 'n':
196: spitflag |= NOEXEC;
197: break;
198:
199: /*
200: / -o fff set output file to fff
201: */
202: case 'o':
203: outptr = argv[++i];
204: if ( i == argc || *outptr == '-' )
205: abort();
206: break;
207:
208: /*
209: / -p turn on long listing format
210: */
211: case 'p':
212: spitflag |= LNGLST;
213: break;
214:
215: /*
216: / -s set stack size in bytes
217: */
218: case 's':
219: cp = optnum( cp, &stacksiz );
220: stacksiz *= sizeof( WORD );
221: break;
222:
223: /*
224: / -u aaa set user argument accessible via host()
225: */
226: case 'u':
227: uarg = argv[++i];
228: if ( i == argc )
229: abort();
230: break;
231:
232: /*
233: / -x print execution statistics
234: */
235: case 'x':
236: spitflag &= ~NOEXCS;
237: break;
238:
239: /*
240: / -z turn on standard listing options
241: */
242: case 'z':
243: spitflag |= STDLST;
244: break;
245:
246: /*
247: / anything else is an error
248: */
249: default:
250: write( 2, "Illegal option -", 17 );
251: write( 2, cp - 1, 1 );
252: write( 2, "?\n", 2 );
253: }
254: }
255:
256: /*
257: / Switch to proper input file.
258: */
259: swcinp( inpptr, inpcnt );
260:
261: /*
262: / Switch to proper output file.
263: */
264: swcoup( outptr );
265:
266: /*
267: / Determine if standard output is a tty or not.
268: */
269: if ( testty() )
270: {
271: lnsppage = 0;
272: spitflag |= PRTICH;
273: }
274:
275: /*
276: / Set signals for execution.
277: */
278: setsigs();
279:
280: /*
281: / Allocate dynamic memory.
282: */
283: basemem = sbrk( memincb );
284: topmem = basemem + memincb;
285: maxmem = basemem + (datawds * sizeof( WORD ) );
286: for( cp = basemem ; cp < topmem ; cp += sizeof( WORD ) )
287: *( (WORD *) cp ) = 0;
288:
289: /*
290: / All compiler registers are initially zero, except for XL and XR.
291: */
292: SET_RA( 0 );
293: SET_CP( 0 );
294: SET_IA( 0 );
295: SET_WA( 0 );
296: SET_WB( 0 );
297: SET_WC( 0 );
298: SET_XR( basemem );
299: SET_XL( topmem - 4 );
300:
301: /*
302: / Startup compiler.
303: */
304: startup();
305: }
306:
307:
308: /*
309: / getnum() converts an ASCII string to an integer AND returns a pointer
310: / to the character following the last valid digit.
311: /
312: / Parameters:
313: / cp pointer to character string
314: / ip pointer to WORD receiving converted result
315: / Returns:
316: / Pointer to character following last valid digit in input string
317: / Side Effects:
318: / Modifies contents of integer pointed to by ip.
319: */
320:
321: char *getnum( cp, ip )
322:
323: char *cp;
324: WORD *ip;
325:
326: {
327: WORD result = 0;
328:
329: while( *cp >= '0' && *cp <= '9' )
330: result = result * 10 + *cp++ - '0';
331:
332: *ip = result;
333: return cp;
334: }
335:
336:
337: /*
338: / optnum() converts an ASCII string to an integer AND returns a pointer
339: / to the character following the last valid digit. optnum() is similar
340: / to getnum() excpet that optnum accepts a trailing 'k' to indicate that
341: / the value should be scaled in units of 1024.
342: /
343: / Parameters:
344: / cp pointer to character string
345: / ip pointer to WORD receiving converted result
346: / Returns:
347: / Pointer to character following last valid digit in input string,
348: / including a trailing k.
349: / Side Effects:
350: / Modifies contents of integer pointed to by ip.
351: */
352:
353: char *optnum( cp, ip )
354:
355: char *cp;
356: WORD *ip;
357:
358: {
359: cp = getnum( cp, ip );
360:
361: if ( *cp == 'k' )
362: {
363: ++cp;
364: *ip <<= 10;
365: }
366:
367: return cp;
368: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.