|
|
1.1 root 1: /*
2: Copyright (C) 1996-1997 Id Software, Inc.
3:
4: This program is free software; you can redistribute it and/or
5: modify it under the terms of the GNU General Public License
6: as published by the Free Software Foundation; either version 2
7: of the License, or (at your option) any later version.
8:
9: This program is distributed in the hope that it will be useful,
10: but WITHOUT ANY WARRANTY; without even the implied warranty of
11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12:
13: See the GNU General Public License for more details.
14:
15: You should have received a copy of the GNU General Public License
16: along with this program; if not, write to the Free Software
17: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18:
19: */
20: //
21: // gas to MASM source code converter
22: //
23:
24: #include <stdio.h>
25: #include <stdlib.h>
26: #include <string.h>
27:
28: #define MAX_TOKENS 100
29: #define MAX_TOKEN_LENGTH 1024
30: #define LF 0x0A
31:
32: typedef enum {NOT_WHITESPACE, WHITESPACE, TOKEN_AVAILABLE, LINE_DONE, FILE_DONE, PARSED_OKAY} tokenstat;
33: typedef enum {NOSEG, DATASEG, TEXTSEG} segtype;
34:
35: int tokennum;
36: int inline, outline;
37:
38: char *token;
39: char tokens[MAX_TOKENS][MAX_TOKEN_LENGTH+1];
40:
41: segtype currentseg = NOSEG;
42:
43: typedef struct {
44: char *text;
45: char *emit;
46: int numtokens;
47: void (*parsefunc) (void);
48: } parsefield;
49:
50:
51: void errorexit (void);
52:
53:
54: //==============================================
55:
56: typedef struct {
57: char *text;
58: char *emit;
59: int len;
60: } regdesc;
61:
62: regdesc reglist[] = {
63: {"%eax", "eax", 4},
64: {"%ebx", "ebx", 4},
65: {"%ecx", "ecx", 4},
66: {"%edx", "edx", 4},
67: {"%esi", "esi", 4},
68: {"%edi", "edi", 4},
69: {"%ebp", "ebp", 4},
70: {"%esp", "esp", 4},
71: {"%ax", "ax", 3},
72: {"%bx", "bx", 3},
73: {"%cx", "cx", 3},
74: {"%dx", "dx", 3},
75: {"%si", "si", 3},
76: {"%di", "di", 3},
77: {"%bp", "bp", 3},
78: {"%sp", "sp", 3},
79: {"%al", "al", 3},
80: {"%bl", "bl", 3},
81: {"%cl", "cl", 3},
82: {"%dl", "dl", 3},
83: {"%ah", "ah", 3},
84: {"%bh", "bh", 3},
85: {"%ch", "ch", 3},
86: {"%dh", "dh", 3},
87: {"%st(0)", "st(0)", 6},
88: {"%st(1)", "st(1)", 6},
89: {"%st(2)", "st(2)", 6},
90: {"%st(3)", "st(3)", 6},
91: {"%st(4)", "st(4)", 6},
92: {"%st(5)", "st(5)", 6},
93: {"%st(6)", "st(6)", 6},
94: {"%st(7)", "st(7)", 6},
95: };
96:
97: int numregs = sizeof (reglist) / sizeof (reglist[0]);
98:
99: //==============================================
100:
101:
102: void emitanoperand (int tnum, char *type, int notdata)
103: {
104: int i, index, something_outside_parens, regfound;
105: int parencount;
106: char *pt;
107: char temp[MAX_TOKEN_LENGTH+1];
108:
109: pt = tokens[tnum];
110:
111: if (pt[0] == '%')
112: {
113: // register
114: for (i=0 ; i<numregs ; i++)
115: {
116: if (!strcmpi (pt, reglist[i].text))
117: {
118: printf ("%s", reglist[i].emit);
119: return;
120: }
121: }
122:
123: fprintf (stderr, "Error: bad register %s\n", pt);
124: errorexit ();
125: }
126: else if (pt[0] == '$')
127: {
128: // constant
129: if (pt[1] == '(')
130: {
131: if ((pt[2] > '9') || (pt[2] < '0'))
132: {
133: i = 2;
134: printf ("offset ");
135:
136: parencount = 1;
137:
138: while ((pt[i] != ')') || (parencount > 1))
139: {
140: if (!pt[i])
141: {
142: fprintf (stderr, "mismatched parens");
143: errorexit ();
144: }
145:
146: if (pt[i] == ')')
147: parencount--;
148: else if (pt[i] == '(')
149: parencount++;
150:
151: printf ("%c", pt[i]);
152: i++;
153: }
154: }
155: else
156: {
157: pt++;
158:
159: parencount = 1;
160:
161: for (i=1 ; (pt[i] != ')') || (parencount > 1) ; i++)
162: {
163: if (!pt[i])
164: {
165: fprintf (stderr, "mismatched parens");
166: errorexit ();
167: }
168:
169: if (pt[i] == ')')
170: parencount--;
171: else if (pt[i] == '(')
172: parencount++;
173: }
174:
175: pt[i] = 0;
176:
177: if ((pt[1] == '0') && ((pt[2] == 'x') || (pt[2] == 'X')))
178: {
179: printf ("0%sh", &pt[3]);
180: }
181: else
182: {
183: printf ("%s", &pt[1]);
184: }
185: }
186: }
187: else if ((pt[1] == '0') && ((pt[2] == 'x') || (pt[2] == 'X')))
188: {
189: printf ("0%sh", &pt[3]);
190: }
191: else if ((pt[1] >= '0') && (pt[1] <= '9'))
192: {
193: printf ("%s", &pt[1]);
194: }
195: else
196: {
197: printf ("offset %s", &pt[1]);
198: }
199: }
200: else if (!notdata && ((pt[0] >= '0') && (pt[0] <= '9')))
201: {
202: pt--;
203:
204: if ((pt[1] == '0') && ((pt[2] == 'x') || (pt[2] == 'X')))
205: {
206: printf ("0%sh", &pt[3]);
207: }
208: else
209: {
210: printf ("%s", &pt[1]);
211: }
212: }
213: else
214: {
215: // must be a memory location
216: strcpy (temp, type);
217: index = strlen (temp);
218:
219: if (notdata)
220: temp[index++] = '[';
221:
222: something_outside_parens = 0;
223:
224: while (*pt)
225: {
226: if (index > (MAX_TOKEN_LENGTH - 10))
227: {
228: fprintf (stderr, "Error: operand too long %s\n",
229: tokens[tnum]);
230: errorexit ();
231: }
232:
233: if (*pt != ')')
234: {
235: if (*pt == '(')
236: {
237: if (something_outside_parens)
238: temp[index++] = '+';
239: }
240: else if (*pt == '%')
241: {
242: regfound = 0;
243:
244: for (i=0 ; i<numregs ; i++)
245: {
246: if (!strnicmp (pt, reglist[i].text,
247: reglist[i].len))
248: {
249: strcpy (&temp[index], reglist[i].emit);
250: index += strlen (reglist[i].emit);
251: pt += strlen (reglist[i].text) - 1;
252: regfound = 1;
253: break;
254: }
255: }
256:
257: if (!regfound)
258: {
259: fprintf (stderr, "Error: bad register %s\n", pt);
260: errorexit ();
261: }
262: }
263: else if (*pt == ',')
264: {
265: pt++;
266:
267: if ((*pt >= '1') && (*pt <= '8'))
268: {
269: temp[index++] = '*';
270: temp[index++] = *pt;
271: }
272: else if (*pt != ')')
273: {
274: if (temp[index-1] != '+')
275: temp[index++] = '+';
276: }
277: }
278: else
279: {
280: something_outside_parens = 1;
281:
282: // handle hexadecimal constants in addresses
283: if ((*pt == '0') &&
284: ((*(pt+1) == 'x') || (*(pt+1) == 'X')))
285: {
286: pt += 2;
287:
288: do
289: {
290: temp[index++] = *pt++;
291: } while (((*pt >= '0') && (*pt <= '9')) ||
292: ((*pt >= 'a') && (*pt <= 'f')) ||
293: ((*pt >= 'A') && (*pt <= 'F')));
294:
295: pt--;
296: temp[index++] = 'h';
297: }
298: else
299: {
300: temp[index++] = *pt;
301: }
302: }
303: }
304:
305: pt++;
306: }
307:
308: if (notdata)
309: temp[index++] = ']';
310:
311: temp[index] = 0;
312: printf ("%s", temp);
313: }
314: }
315:
316:
317: void datasegstart (void)
318: {
319: if (currentseg == DATASEG)
320: return;
321:
322: if (currentseg == TEXTSEG)
323: printf ("_TEXT ENDS\n");
324:
325: printf ("_DATA SEGMENT");
326:
327: currentseg = DATASEG;
328: }
329:
330:
331: void textsegstart (void)
332: {
333: if (currentseg == TEXTSEG)
334: return;
335:
336: if (currentseg == DATASEG)
337: printf ("_DATA ENDS\n");
338:
339: printf ("_TEXT SEGMENT");
340:
341: currentseg = TEXTSEG;
342: }
343:
344:
345: void emitdata (void)
346: {
347: int i;
348:
349: for (i=1 ; i<(tokennum-1) ; i++)
350: printf (" %s,", tokens[i]);
351:
352: printf (" %s", tokens[tokennum-1]);
353: }
354:
355:
356: void emitonedata (void)
357: {
358:
359: printf (" %s", tokens[1]);
360: }
361:
362:
363: void emitonecalldata (void)
364: {
365: int i, isaddr, len;
366:
367: if (tokens[1][0] == '*')
368: {
369: printf (" dword ptr[%s]", &tokens[1][1]);
370: }
371: else
372: {
373: isaddr = 0;
374: len = strlen(tokens[1]);
375:
376: for (i=0 ; i<len ; i++)
377: {
378: if (tokens[1][i] == '(')
379: {
380: isaddr = 1;
381: break;
382: }
383: }
384:
385: if (!isaddr)
386: {
387: printf (" near ptr %s", tokens[1]);
388: }
389: else
390: {
391: emitanoperand (1, " dword ptr", 1);
392: }
393: }
394: }
395:
396:
397: void emitonejumpdata (void)
398: {
399: int i, isaddr, len;
400:
401: if (tokens[1][0] == '*')
402: {
403: printf (" dword ptr[%s]", &tokens[1][1]);
404: }
405: else
406: {
407: isaddr = 0;
408: len = strlen(tokens[1]);
409:
410: for (i=0 ; i<len ; i++)
411: {
412: if (tokens[1][i] == '(')
413: {
414: isaddr = 1;
415: break;
416: }
417: }
418:
419: if (!isaddr)
420: {
421: printf (" %s", tokens[1]);
422: }
423: else
424: {
425: emitanoperand (1, " dword ptr", 1);
426: }
427: }
428: }
429:
430:
431: void emitexterndef (void)
432: {
433:
434: printf (" %s:dword", tokens[1]);
435: }
436:
437:
438: void nooperands (void)
439: {
440:
441: }
442:
443:
444: void emitoneoperandl (void)
445: {
446:
447: printf (" ");
448: emitanoperand (1, "ds:dword ptr", 1);
449: }
450:
451:
452: void emitoneoperandb (void)
453: {
454:
455: printf (" ");
456: emitanoperand (1, "ds:byte ptr", 1);
457: }
458:
459:
460: void emitoneoperandw (void)
461: {
462:
463: printf (" ");
464: emitanoperand (1, "ds:word ptr", 1);
465: }
466:
467:
468: void emittwooperandsl (void)
469: {
470:
471: printf (" ");
472: emitanoperand (2, "ds:dword ptr", 1);
473: printf (",");
474: emitanoperand (1, "ds:dword ptr", 1);
475: }
476:
477:
478: void emittwooperandsb (void)
479: {
480:
481: printf (" ");
482: emitanoperand (2, "ds:byte ptr", 1);
483: printf (",");
484: emitanoperand (1, "ds:byte ptr", 1);
485: }
486:
487:
488: void emittwooperandsw (void)
489: {
490:
491: printf (" ");
492: emitanoperand (2, "ds:word ptr", 1);
493: printf (",");
494: emitanoperand (1, "ds:word ptr", 1);
495: }
496:
497:
498: void emit_0_or_1_operandsl (void)
499: {
500:
501: if (tokennum == 2)
502: {
503: printf (" ");
504: emitanoperand (1, "ds:dword ptr", 1);
505: }
506: }
507:
508:
509: void emit_1_or_2_operandsl (void)
510: {
511: int j;
512:
513: if (tokennum == 2)
514: {
515: printf (" ");
516: emitanoperand (1, "ds:dword ptr", 1);
517: }
518: else if (tokennum == 3)
519: {
520: printf (" ");
521: emitanoperand (2, "ds:dword ptr", 1);
522: printf (",");
523: emitanoperand (1, "ds:dword ptr", 1);
524: }
525: else
526: {
527:
528: fprintf (stderr, "Error: too many operands\n");
529:
530: for (j=0 ; j<tokennum ; j++)
531: fprintf (stderr, "%s\n", tokens[j]);
532:
533: fprintf (stderr, "\n");
534: errorexit ();
535: }
536: }
537:
538:
539: void emit_1_or_2_operandsl_vartext (char *str0, char *str1)
540: {
541: int j;
542:
543: if (tokennum == 2)
544: {
545: printf (" %s ", str0);
546: emitanoperand (1, "ds:dword ptr", 1);
547: }
548: else if (tokennum == 3)
549: {
550: if (!strcmpi (tokens[2], "%st(0)"))
551: printf (" %s ", str0);
552: else
553: printf (" %s ", str1);
554:
555: emitanoperand (2, "ds:dword ptr", 1);
556: printf (",");
557: emitanoperand (1, "ds:dword ptr", 1);
558: }
559: else
560: {
561:
562: fprintf (stderr, "Error: too many operands\n");
563:
564: for (j=0 ; j<tokennum ; j++)
565: fprintf (stderr, "%s\n", tokens[j]);
566:
567: fprintf (stderr, "\n");
568: errorexit ();
569: }
570: }
571:
572:
573: void special_fdivl (void)
574: {
575:
576: emit_1_or_2_operandsl_vartext ("fdiv", "fdivr");
577: }
578:
579:
580: void special_fdivpl (void)
581: {
582:
583: emit_1_or_2_operandsl_vartext ("fdivp", "fdivrp");
584: }
585:
586:
587: void special_fdivrl (void)
588: {
589:
590: emit_1_or_2_operandsl_vartext ("fdivr", "fdiv");
591: }
592:
593:
594: void special_fdivrpl (void)
595: {
596:
597: emit_1_or_2_operandsl_vartext ("fdivrp", "fdivp");
598: }
599:
600:
601: void special_fsubl (void)
602: {
603:
604: emit_1_or_2_operandsl_vartext ("fsub", "fsubr");
605: }
606:
607:
608: void special_fsubpl (void)
609: {
610:
611: emit_1_or_2_operandsl_vartext ("fsubp", "fsubrp");
612: }
613:
614:
615: void special_fsubrl (void)
616: {
617:
618: emit_1_or_2_operandsl_vartext ("fsubr", "fsub");
619: }
620:
621:
622: void special_fsubrpl (void)
623: {
624:
625: emit_1_or_2_operandsl_vartext ("fsubrp", "fsubp");
626: }
627:
628:
629: void emit_multiple_data (void)
630: {
631: int i;
632:
633: printf (" ");
634:
635: for (i=1 ; i<(tokennum-1) ; i++)
636: {
637: emitanoperand (i, "", 0);
638: printf (", ");
639: }
640:
641: emitanoperand (i, "", 0);
642: }
643:
644:
645: //==============================================
646:
647: parsefield parsedata[] = {
648: {".align", " align", 2, emitonedata},
649: {".byte", " db", -2, emit_multiple_data},
650: {".data", "", 1, datasegstart},
651: {".extern"," externdef", 2, emitexterndef},
652: {".globl", " public", -2, emit_multiple_data},
653: {".long", " dd", -2, emit_multiple_data},
654: {".single"," dd", -2, emit_multiple_data},
655: {".text", "", 1, textsegstart},
656: {"adcl", " adc", 3, emittwooperandsl},
657: {"addb", " add", 3, emittwooperandsb},
658: {"addl", " add", 3, emittwooperandsl},
659: {"andb", " and", 3, emittwooperandsb},
660: {"andl", " and", 3, emittwooperandsl},
661: {"call", " call", 2, emitonecalldata},
662: {"cmpb", " cmp", 3, emittwooperandsb},
663: {"cmpl", " cmp", 3, emittwooperandsl},
664: {"cmpw", " cmp", 3, emittwooperandsw},
665: {"decl", " dec", 2, emitoneoperandl},
666: {"decw", " dec", 2, emitoneoperandw},
667: {"divl", " div", 2, emitoneoperandl},
668: {"fadd", " fadd", -2, emit_1_or_2_operandsl},
669: {"faddp", " faddp", -2, emit_1_or_2_operandsl},
670: {"faddps", " faddp", -2, emit_1_or_2_operandsl},
671: {"fadds", " fadd", -2, emit_1_or_2_operandsl},
672: {"fcom", " fcom", 2, emitoneoperandl},
673: {"fcoms", " fcom", 2, emitoneoperandl},
674: {"fcomp", " fcomp", 2, emitoneoperandl},
675: {"fcomps", " fcomp", 2, emitoneoperandl},
676: {"fdiv", "", -2, special_fdivl},
677: {"fdivp", "", -2, special_fdivpl},
678: {"fdivr", "", -2, special_fdivrl},
679: {"fdivrp", "", -2, special_fdivrpl},
680: {"fdivrs", "", -2, special_fdivrl},
681: {"fildl", " fild", 2, emitoneoperandl},
682: {"fistl", " fist", 2, emitoneoperandl},
683: {"fistpl", " fistp", 2, emitoneoperandl},
684: {"fld", " fld", 2, emitoneoperandl},
685: {"fldcw", " fldcw", 2, emitoneoperandw},
686: {"fldenv", " fldenv", 2, emitoneoperandl},
687: {"flds", " fld", 2, emitoneoperandl},
688: {"fmul", " fmul", -2, emit_1_or_2_operandsl},
689: {"fmulp", " fmulp", -2, emit_1_or_2_operandsl},
690: {"fmulps", " fmulp", -2, emit_1_or_2_operandsl},
691: {"fmuls", " fmul", -2, emit_1_or_2_operandsl},
692: {"fnstcw", " fnstcw", 2, emitoneoperandw},
693: {"fnstenv"," fnstenv", 2, emitoneoperandl},
694: {"fnstsw", " fnstsw", 2, emitoneoperandw},
695: {"fstp", " fstp", 2, emitoneoperandl},
696: {"fstps", " fstp", 2, emitoneoperandl},
697: {"fsts", " fst", 2, emitoneoperandl},
698: {"fsubr", "", -2, special_fsubrl},
699: {"fsubrp", "", -2, special_fsubrpl},
700: {"fsubrs", "", -2, special_fsubrl},
701: {"fsub", "", -2, special_fsubl},
702: {"fsubp", "", -2, special_fsubpl},
703: {"fsubps", "", -2, special_fsubpl},
704: {"fsubs", "", -2, special_fsubl},
705: {"fxch", " fxch", 2, emitoneoperandl},
706: {"imull", " imul", -2, emit_1_or_2_operandsl},
707: {"incl", " inc", 2, emitoneoperandl},
708: {"ja", " ja", 2, emitonedata},
709: {"jae", " jae", 2, emitonedata},
710: {"jb", " jb", 2, emitonedata},
711: {"jbe", " jbe", 2, emitonedata},
712: {"jc", " jc", 2, emitonedata},
713: {"je", " je", 2, emitonedata},
714: {"jg", " jg", 2, emitonedata},
715: {"jge", " jge", 2, emitonedata},
716: {"jl", " jl", 2, emitonedata},
717: {"jle", " jle", 2, emitonedata},
718: {"jmp", " jmp", 2, emitonejumpdata},
719: {"jna", " jna", 2, emitonedata},
720: {"jnae", " jnae", 2, emitonedata},
721: {"jnb", " jnb", 2, emitonedata},
722: {"jnbe", " jnbe", 2, emitonedata},
723: {"jnc", " jnc", 2, emitonedata},
724: {"jne", " jne", 2, emitonedata},
725: {"jng", " jng", 2, emitonedata},
726: {"jnge", " jnge", 2, emitonedata},
727: {"jnl", " jnl", 2, emitonedata},
728: {"jnle", " jnle", 2, emitonedata},
729: {"jns", " jns", 2, emitonedata},
730: {"jnz", " jnz", 2, emitonedata},
731: {"js", " js", 2, emitonedata},
732: {"jz", " jz", 2, emitonedata},
733: {"leal", " lea", 3, emittwooperandsl},
734: {"movb", " mov", 3, emittwooperandsb},
735: {"movl", " mov", 3, emittwooperandsl},
736: {"movw", " mov", 3, emittwooperandsw},
737: {"negl", " neg", 2, emitoneoperandl},
738: {"orb", " or", 3, emittwooperandsb},
739: {"orl", " or", 3, emittwooperandsl},
740: {"popl", " pop", 2, emitoneoperandl},
741: {"pushl", " push", 2, emitoneoperandl},
742: {"ret", " ret", -1, emit_0_or_1_operandsl},
743: {"rorl", " ror", 3, emittwooperandsl},
744: {"sarl", " sar", 3, emittwooperandsl},
745: {"sbbl", " sbb", 3, emittwooperandsl},
746: {"shll", " shl", 3, emittwooperandsl},
747: {"shrl", " shr", 3, emittwooperandsl},
748: {"subl", " sub", 3, emittwooperandsl},
749: {"testb", " test", 3, emittwooperandsb},
750: {"testl", " test", 3, emittwooperandsl},
751: {"xorb", " xor", 3, emittwooperandsb},
752: {"xorl", " xor", 3, emittwooperandsl},
753: };
754:
755: int numparse = sizeof (parsedata) / sizeof (parsedata[0]);
756:
757: //==============================================
758:
759: void errorexit (void)
760: {
761: fprintf (stderr, "In line: %d, out line: %d\n", inline, outline);
762: exit (1);
763: }
764:
765:
766: tokenstat whitespace (char c)
767: {
768: if (c == '\n')
769: return LINE_DONE;
770:
771: if ((c <= ' ') ||
772: (c > 127) ||
773: (c == ','))
774: {
775: return WHITESPACE;
776: }
777:
778: return NOT_WHITESPACE;
779: }
780:
781:
782: int gettoken (void)
783: {
784: char c;
785: int count, parencount;
786: tokenstat stat;
787:
788: do
789: {
790: if ((c = getchar ()) == EOF)
791: return FILE_DONE;
792:
793: if ((stat = whitespace (c)) == LINE_DONE)
794: return LINE_DONE;
795: } while (stat == WHITESPACE);
796:
797: token[0] = c;
798: count = 1;
799:
800: if (c == '~')
801: {
802: count--;
803: token[count++] = 'n';
804: token[count++] = 'o';
805: token[count++] = 't';
806: token[count++] = ' ';
807: }
808:
809: if (c == '(')
810: {
811: do
812: {
813: if ((c = getchar ()) == EOF)
814: {
815: fprintf (stderr, "EOF in middle of parentheses\n");
816: errorexit ();
817: }
818:
819: token[count++] = c;
820:
821: } while (c != ')');
822: }
823:
824: for ( ;; )
825: {
826: if ((c = getchar ()) == EOF)
827: {
828: token[count] = 0;
829: return TOKEN_AVAILABLE;
830: }
831:
832: if (whitespace (c) == LINE_DONE)
833: {
834: if (ungetc (c, stdin) == EOF)
835: {
836: fprintf (stderr, "Couldn't unget character\n");
837: errorexit ();
838: }
839:
840: token[count] = 0;
841: return TOKEN_AVAILABLE;
842: }
843:
844: if (whitespace (c) == WHITESPACE)
845: {
846: token[count] = 0;
847: return TOKEN_AVAILABLE;
848: }
849:
850: if (count >= MAX_TOKEN_LENGTH)
851: {
852: fprintf (stderr, "Error: token too long\n");
853: errorexit ();
854: }
855:
856: token[count++] = c;
857:
858: if (c == '~')
859: {
860: count--;
861: token[count++] = 'n';
862: token[count++] = 'o';
863: token[count++] = 't';
864: token[count++] = ' ';
865: }
866: else if (c == '(')
867: {
868: parencount = 1;
869:
870: do
871: {
872: if ((c = getchar ()) == EOF)
873: {
874: fprintf (stderr, "EOF in middle of parentheses\n");
875: errorexit ();
876: }
877:
878: if (c == '(')
879: parencount++;
880: else if (c == ')')
881: parencount--;
882:
883: if (c == '~')
884: {
885: token[count++] = 'n';
886: token[count++] = 'o';
887: token[count++] = 't';
888: token[count++] = ' ';
889: }
890: else
891: {
892: token[count++] = c;
893: }
894:
895: } while ((c != ')') || (parencount > 0));
896: }
897: }
898: }
899:
900:
901: tokenstat parseline (void)
902: {
903: tokenstat stat;
904: int i, j, firsttoken, labelfound;
905: int mnemfound;
906:
907: firsttoken = 1;
908: tokennum = 0;
909: labelfound = 0;
910:
911: for ( ;; )
912: {
913: token = tokens[tokennum];
914: stat = gettoken ();
915:
916: switch (stat)
917: {
918: case FILE_DONE:
919: return FILE_DONE;
920:
921: case LINE_DONE:
922: if (!firsttoken && tokennum)
923: {
924: mnemfound = 0;
925:
926: for (i=0 ; i<numparse; i++)
927: {
928: if (!strcmpi (tokens[0], parsedata[i].text))
929: {
930: if (((parsedata[i].numtokens > 0) &&
931: (parsedata[i].numtokens != tokennum)) ||
932: ((parsedata[i].numtokens < 0) &&
933: (tokennum < -parsedata[i].numtokens)))
934: {
935: fprintf (stderr, "mismatched number of tokens\n");
936:
937: for (j=0 ; j<tokennum ; j++)
938: fprintf (stderr, "%s\n", tokens[j]);
939:
940: fprintf (stderr, "\n");
941: errorexit ();
942: }
943:
944: printf ("%s", parsedata[i].emit);
945: (*parsedata[i].parsefunc) ();
946:
947: mnemfound = 1;
948: break;
949: }
950: }
951:
952: if (!mnemfound)
953: {
954: fprintf (stderr, "Error: unknown mnemonic\n");
955:
956: for (j=0 ; j<tokennum ; j++)
957: fprintf (stderr, "%s\n", tokens[j]);
958:
959: fprintf (stderr, "\n");
960: errorexit ();
961: }
962: }
963:
964: if (!firsttoken)
965: {
966: if ((currentseg == DATASEG) && labelfound && !tokennum)
967: printf (":\n");
968: else
969: printf ("\n");
970:
971: outline++;
972: }
973: return PARSED_OKAY;
974:
975: case TOKEN_AVAILABLE:
976: if (firsttoken)
977: {
978: if (token[strlen(token) - 1] == ':')
979: {
980: labelfound = 1;
981:
982: if (currentseg == DATASEG)
983: {
984: token[strlen(token) - 1] = 0;
985: printf ("%s", token);
986: }
987: else if (currentseg == TEXTSEG)
988: {
989: printf ("%s", token);
990: }
991: else
992: {
993: fprintf (stderr, "Error: not in segment block\n");
994: errorexit ();
995: }
996:
997: firsttoken = 0;
998: break;
999: }
1000: }
1001:
1002: firsttoken = 0;
1003:
1004: if (tokennum >= MAX_TOKENS)
1005: {
1006: fprintf (stderr, "Error: too many tokens\n");
1007: exit (0);
1008: }
1009:
1010: tokennum++;
1011:
1012: break;
1013:
1014: default:
1015: fprintf (stderr, "Error: unknown tokenstat %d\n", stat);
1016: exit (0);
1017: }
1018: }
1019: }
1020:
1021:
1022: void main (int argc, char **argv)
1023: {
1024: tokenstat stat;
1025:
1026: printf (" .386P\n"
1027: " .model FLAT\n");
1028: inline = 1;
1029: outline = 3;
1030:
1031: for ( ;; )
1032: {
1033: stat = parseline ();
1034: inline++;
1035:
1036: switch (stat)
1037: {
1038: case FILE_DONE:
1039: if (currentseg == TEXTSEG)
1040: printf ("_TEXT ENDS\n");
1041: else if (currentseg == DATASEG)
1042: printf ("_DATA ENDS\n");
1043:
1044: printf (" END\n");
1045: exit (0);
1046:
1047: case PARSED_OKAY:
1048: break;
1049:
1050: default:
1051: fprintf (stderr, "Error: unknown tokenstat %d\n", stat);
1052: exit (0);
1053: }
1054: }
1055: }
1056:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.