gas2masm.c 19 KB

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