|
|
1.1 root 1:
2:
3: %{
4:
5: #define YYSTYPE char *
6:
7:
8:
9: #include "asmtrans.h"
10:
11: %}
12:
13:
14:
15: %token WORD
16:
17: %token WHITESP
18:
19: %token EOLN
20:
21: %token STRING
22:
23: %token DEFINECMD
24:
25: %token INCLUDECMD
26:
27: %token IFDEFCMD
28:
29: %token IFNDEFCMD
30:
31: %token ELSECMD
32:
33: %token ENDIFCMD
34:
35:
36:
37: /* Grammar follows */
38:
39: %%
40:
41: input:
42:
43: | input line
44:
45: ;
46:
47:
48:
49: line: EOLN { emit($1); }
50:
51: /* note that emit() will automatically free the memory,
52:
53: and will also check the hidecnt variable */
54:
55: | label EOLN { emit($1); emit($2); }
56:
57: | opline EOLN { emit($1); emit($2); }
58:
59: | label opline EOLN { emit($1); emit($2);
60:
61: emit($3); }
62:
63: | INCLUDECMD WHITESP STRING EOLN { if (!hidecnt) do_include($3); free($3); }
64:
65: | INCLUDECMD WHITESP WORD EOLN { if (!hidecnt) do_include($3); free($3); }
66:
67: | DEFINECMD WHITESP WORD WHITESP STRING EOLN {
68:
69: if (!hidecnt) do_define($3, $5); free($3); free($5); }
70:
71: | DEFINECMD WHITESP WORD WHITESP operand EOLN {
72:
73: if (!hidecnt) do_define($3, $5); free($3); free($5); }
74:
75: | IFDEFCMD WHITESP WORD EOLN { do_ifdef($3); free($3); }
76:
77: | IFNDEFCMD WHITESP WORD EOLN { do_ifndef($3); free($3); }
78:
79: | ELSECMD EOLN { do_else(); }
80:
81: | ENDIFCMD EOLN { do_endif(); }
82:
83: ;
84:
85:
86:
87: opline: WHITESP opcode { $$ = do_ops("", $2, "", ""); free($2); }
88:
89: | WHITESP opcode WHITESP ops
90:
91: { $$ = do_ops("", $2, $3, $4);
92:
93: free($2); free($3); free($4); }
94:
95: | WORD WHITESP opcode { $$ = do_ops($1, $3, "", ""); free($1); free($3); }
96:
97: | WORD WHITESP opcode WHITESP ops
98:
99: { $$ = do_ops($1, $3, $4, $5);
100:
101: free($1); free($3); free($4); free($5);}
102:
103: ;
104:
105:
106:
107: ops: operand { $$ = $1; }
108:
109: | operand ',' ops { $$ = concat3($1, ",", $3);
110:
111: free($1); free($3); }
112:
113: ;
114:
115:
116:
117: opcode: WORD { $$ = wordlookup($1); free($1); }
118:
119: ;
120:
121:
122:
123: label: WORD ':' { $$ = concat($1, ":"); free($1); }
124:
125:
126:
127: operand: basic {$$ = $1; }
128:
129: | '#' basic {$$ = immediate($2); free($2); }
130:
131: | '(' basic ')' {$$ = indirect($2); free($2); }
132:
133: | '(' basic ')' '+' {$$ = postinc($2); free($2); }
134:
135: | '-' '(' basic ')' {$$ = predec($3); free($3); }
136:
137: | basic '(' basic ')' {$$ = indexed($1, $3); free($1); free($3); }
138:
139: | '(' basic ')' WORD {$$ = sizedop($2, $4); free($2); free($4); }
140:
141: | basic '(' basic ',' basic ')' {$$ = twoindex($1, $3, $5);
142:
143: free($1); free($3); free($5); }
144:
145: | basic '{' basic ':' basic '}' {$$ = bitfield($1, $3, $5);
146:
147: free($1); free($3); free($5); }
148:
1.1.1.3 ! root 149: | '(' '[' basic ',' basic ']' ',' basic ',' basic ')'
! 150:
! 151: { $$=postindex($3,$5,$8,$10);
! 152:
! 153: free($3); free($5); free($8); free($10); }
! 154:
! 155: | '(' '[' basic ',' basic ',' basic ']' ',' basic ')'
! 156:
! 157: { $$=preindex($3,$5,$7,$10);
! 158:
! 159: free($3); free($5); free($7); free($10); }
! 160:
! 161: | '(' '[' basic ']' ')'
! 162:
! 163: { $$=postindex0($3);
! 164:
! 165: free($3); }
! 166:
! 167: | '(' '[' basic ']' ',' basic ')'
! 168:
! 169: { $$=postindex1($3,$6);
! 170:
! 171: free($3); free($6); }
! 172:
1.1 root 173: ;
174:
175:
176:
177: basic: basexpr { $$ = $1; }
178:
179: | basexpr op basic { $$ = concat3($1, $2, $3); free($1); free($2); free($3); }
180:
181: | '-' basic { $$ = concat("-", $2); free($2); }
182:
183:
184:
185: basexpr: WORD {$$ = wordlookup($1); free($1); }
186:
187: | '$' WORD {$$ = hexop($2); free($2);}
188:
189: ;
190:
191:
192:
193: op: '+' { $$ = strdup("+"); }
194:
195: | '-' { $$ = strdup("-"); }
196:
197: | '*' { $$ = strdup("*"); }
198:
199: | '/' { $$ = strdup("/"); }
200:
201: ;
202:
203: %%
204:
205: #include <setjmp.h>
206:
207:
208:
209: jmp_buf start;
210:
211:
212:
213: #ifdef NATIVEATARI
214:
1.1.1.2 root 215: #define STACK 32*1024L
1.1 root 216:
217: #ifdef LATTICE
218:
219: long _STACK = STACK;
220:
221: #endif
222:
223: #ifdef __GNUC__
224:
225: long _stksize = STACK;
226:
227: #endif
228:
229:
230:
231: static void
232:
233: hit_return()
234:
235: {
236:
237: printf("Hit return to continue\n");
238:
239: fflush(stdout);
240:
241: getchar();
242:
243: }
244:
245: #endif
246:
247:
248:
249: void usage()
250:
251: {
252:
253: fprintf(stderr, "Usage: asmtrans [-gas][-asm][-o outfile] infile\n");
254:
255: exit(2);
256:
257: }
258:
259:
260:
261: int errors = 0;
262:
263:
264:
265: void
266:
267: do_include(file)
268:
269: char *file;
270:
271: {
272:
273: jmp_buf save;
274:
275: FILE *oldin, *f;
276:
277:
278:
1.1.1.3 ! root 279: f = fopen(file, "rt");
1.1 root 280:
281: if (!f) {
282:
283: perror(file);
284:
285: return;
286:
287: }
288:
289: bcopy(start, save, sizeof(jmp_buf));
290:
291: oldin = infile;
292:
293: infile = f;
294:
295: setjmp(start);
296:
297: yyparse();
298:
299: fclose(f);
300:
301: infile = oldin;
302:
303: bcopy(save, start, sizeof(jmp_buf));
304:
305: longjmp(start,1);
306:
307: }
308:
309:
310:
311: /* set up initial definitions based on syntax type */
312:
313:
314:
315: void
316:
317: do_initial_defs()
318:
319: {
320:
321: if (syntax == GAS) {
322:
1.1.1.2 root 323: do_define("mmusr", "psr");
324:
1.1 root 325: do_define("fpiar", "fpi");
326:
327: do_define("XREF", ".globl");
328:
329: do_define("XDEF", ".globl");
330:
331: do_define("TEXT", ".text");
332:
333: do_define("DATA", ".data");
334:
335: /* gas doesn't have a .bss directive */
336:
337: do_define("BSS", ".data");
338:
339: do_define("END", "| END");
340:
341: do_define("dc.l", ".long");
342:
343: do_define("dc.w", ".word");
344:
345: do_define("dc.b", ".byte");
346:
347: } else if (syntax == ASM) {
348:
1.1.1.3 ! root 349: do_define("TEXT", "SECTION TEXT,CODE");
1.1 root 350:
1.1.1.3 ! root 351: do_define("DATA", "SECTION DATA,DATA");
1.1 root 352:
1.1.1.3 ! root 353: do_define("BSS", "SECTION BSS,BSS");
1.1 root 354:
355: }
356:
357: }
358:
359:
360:
361: int
362:
363: main (argc, argv)
364:
365: int argc; char **argv;
366:
367: {
368:
369: FILE *f;
370:
371: #ifdef NATIVEATARI
372:
373: if (!argv[0] || !argv[0][0]) /* run from desktop? */
374:
375: atexit(hit_return);
376:
377: #endif
378:
379: argv++;
380:
381: outfile = stdout;
382:
383:
384:
385: while (*argv) {
386:
387: if (!strcmp(*argv, "-o")) {
388:
389: argv++;
390:
391: if (*argv == 0) {
392:
393: fprintf(stderr, "missing argument to -o\n");
394:
395: usage();
396:
397: }
398:
1.1.1.3 ! root 399: f = fopen(*argv, "wt");
1.1 root 400:
401: if (!f)
402:
403: perror(*argv);
404:
405: else
406:
407: outfile = f;
408:
409: argv++;
410:
411: } else if (!strcmp(*argv, "-gas")) {
412:
413: argv++;
414:
415: syntax = GAS;
416:
417: } else if (!strcmp(*argv, "-asm")) {
418:
419: argv++;
420:
421: syntax = ASM;
422:
423: } else if (!strcmp(*argv, "-purec")) {
424:
425: argv++;
426:
427: syntax = PUREC;
428:
429: } else if (!strncmp(*argv, "-D", 2)) {
430:
431: char *word, *defn;
432:
433: word = *argv+2;
434:
435: defn = index(word,'=');
436:
437: if (defn)
438:
439: *defn++ = '\0';
440:
441: else
442:
443: defn = "1";
444:
445: if (*word) do_define(word,defn);
446:
447: argv++;
448:
449: } else if (!strcmp(*argv, "--")) {
450:
451: argv++;
452:
453: break;
454:
455: } else {
456:
457: if (**argv == '-') {
458:
459: fprintf(stderr, "unknown option: %s\n",
460:
461: *argv);
462:
463: usage();
464:
465: }
466:
467: break;
468:
469: }
470:
471: }
472:
473:
474:
475: do_initial_defs();
476:
477:
478:
479: if (*argv == 0) {
480:
481: setjmp(start);
482:
483: infile = stdin;
484:
485: yyparse();
486:
487: } else {
488:
489: while(*argv) {
490:
1.1.1.3 ! root 491: if (!(f = fopen(*argv, "rt")))
1.1 root 492:
493: perror(*argv);
494:
495: else {
496:
497: infile = f;
498:
499: setjmp(start);
500:
501: yyparse();
502:
503: fclose(f);
504:
505: }
506:
507: argv++;
508:
509: }
510:
511: }
512:
513:
514:
515: if (ifstkptr != 0) {
516:
517: fputs("%ifdef without matching %endif\n", stderr);
518:
519: errors++;
520:
521: }
522:
523: return errors;
524:
525: }
526:
527:
528:
529: void
530:
531: yyerror (s) /* Called by yyparse on error */
532:
533: char *s;
534:
535: {
536:
537: errors++;
538:
539: printf("%s\n", s);
540:
541: longjmp(start, 1);
542:
543: }
544:
545:
546:
547: void dbgmsg(s) char *s;
548:
549: {
550:
551: fprintf(stderr, "%s\n", s);
552:
553: }
554:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.