ast.cpp 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023
  1. /*
  2. * File: ast.c
  3. * Purpose: Support module for abstract syntax trees.
  4. * Date: September 1993
  5. * (C) Cristina Cifuentes
  6. */
  7. #if __BORLAND__
  8. #include <alloc.h>
  9. #else
  10. #include <malloc.h> /* For free() */
  11. #endif
  12. #include <string.h>
  13. #include "dcc.h"
  14. /* Index registers **** temp solution */
  15. static char *idxReg[8] = {"bx+si", "bx+di", "bp+si", "bp+di",
  16. "si", "di", "bp", "bx" };
  17. /* Conditional operator symbols in C. Index by condOp enumeration type */
  18. static char *condOpSym[] = { " <= ", " < ", " == ", " != ", " > ", " >= ",
  19. " & ", " | ", " ^ ", " ~ ",
  20. " + ", " - ", " * ", " / ",
  21. " >> ", " << ", " % ", " && ", " || " };
  22. #define EXP_SIZE 200 /* Size of the expression buffer */
  23. /* Local expression stack */
  24. typedef struct _EXP_STK {
  25. COND_EXPR *exp;
  26. struct _EXP_STK *next;
  27. } EXP_STK;
  28. static EXP_STK *expStk = NULL; /* local expression stack */
  29. static char *hexStr (Int i)
  30. /* Returns the integer i in C hexadecimal format */
  31. { static char buf[10];
  32. i &= 0xFFFF;
  33. sprintf (buf, "%s%lX", (i > 9) ? "0x" : "", i);
  34. return (buf);
  35. }
  36. void setRegDU (PICODE pIcode, byte regi, operDu du)
  37. /* Sets the du record for registers according to the du flag */
  38. {
  39. switch (du) {
  40. case DEF: pIcode->du.def |= duReg[regi];
  41. pIcode->du1.numRegsDef++;
  42. break;
  43. case USE: pIcode->du.use |= duReg[regi];
  44. break;
  45. case USE_DEF: pIcode->du.def |= duReg[regi];
  46. pIcode->du1.numRegsDef++;
  47. pIcode->du.use |= duReg[regi];
  48. break;
  49. case NONE: /* do nothing */
  50. break;
  51. }
  52. }
  53. void copyDU (PICODE pIcode, PICODE duIcode, operDu du, operDu duDu)
  54. /* Copies the def, use, or def and use fields of duIcode into pIcode */
  55. {
  56. switch (du) {
  57. case DEF:
  58. if (duDu == DEF)
  59. memcpy (&pIcode->du.def, &duIcode->du.def, sizeof(dword));
  60. else
  61. memcpy (&pIcode->du.def, &duIcode->du.use, sizeof(dword));
  62. break;
  63. case USE:
  64. if (duDu == DEF)
  65. memcpy (&pIcode->du.use, &duIcode->du.def, sizeof(dword));
  66. else
  67. memcpy (&pIcode->du.use, &duIcode->du.use, sizeof(dword));
  68. break;
  69. case USE_DEF:
  70. memcpy (&pIcode->du, &duIcode->du, sizeof(DU_ICODE));
  71. break;
  72. }
  73. }
  74. static COND_EXPR *newCondExp (condNodeType t)
  75. /* Creates a newExp conditional expression node of type t and returns it */
  76. { COND_EXPR *newExp;
  77. newExp = allocStruc(COND_EXPR);
  78. memset(newExp, 0, sizeof(COND_EXPR));
  79. newExp->type = t;
  80. return (newExp);
  81. }
  82. COND_EXPR *boolCondExp (COND_EXPR *lhs, COND_EXPR *rhs, condOp op)
  83. /* Creates a conditional boolean expression and returns it */
  84. { COND_EXPR *newExp;
  85. newExp = newCondExp (BOOLEAN_OP);
  86. newExp->expr.boolExpr.op = op;
  87. newExp->expr.boolExpr.lhs = lhs;
  88. newExp->expr.boolExpr.rhs = rhs;
  89. return (newExp);
  90. }
  91. COND_EXPR *unaryCondExp (condNodeType t, COND_EXPR *exp)
  92. /* Returns a unary conditional expression node. This procedure should
  93. * only be used with the following conditional node types: NEGATION,
  94. * ADDRESSOF, DEREFERENCE, POST_INC, POST_DEC, PRE_INC, PRE_DEC */
  95. { COND_EXPR *newExp;
  96. newExp = newCondExp (t);
  97. newExp->expr.unaryExp = exp;
  98. return (newExp);
  99. }
  100. COND_EXPR *idCondExpGlob (int16 segValue, int16 off)
  101. /* Returns an identifier conditional expression node of type GLOB_VAR */
  102. { COND_EXPR *newExp;
  103. dword adr;
  104. Int i;
  105. newExp = newCondExp (IDENTIFIER);
  106. newExp->expr.ident.idType = GLOB_VAR;
  107. adr = opAdr(segValue, off);
  108. for (i = 0; i < symtab.csym; i++)
  109. if (symtab.sym[i].label == adr)
  110. break;
  111. if (i == symtab.csym)
  112. printf ("Error, glob var not found in symtab\n");
  113. newExp->expr.ident.idNode.globIdx = i;
  114. return (newExp);
  115. }
  116. COND_EXPR *idCondExpReg (byte regi, flags32 icodeFlg, LOCAL_ID *locsym)
  117. /* Returns an identifier conditional expression node of type REGISTER */
  118. { COND_EXPR *newExp;
  119. newExp = newCondExp (IDENTIFIER);
  120. newExp->expr.ident.idType = REGISTER;
  121. if ((icodeFlg & B) || (icodeFlg & SRC_B))
  122. {
  123. newExp->expr.ident.idNode.regiIdx = newByteWordRegId (locsym,
  124. TYPE_BYTE_SIGN, regi);
  125. newExp->expr.ident.regiType = BYTE_REG;
  126. }
  127. else /* word */
  128. {
  129. newExp->expr.ident.idNode.regiIdx = newByteWordRegId (locsym,
  130. TYPE_WORD_SIGN, regi);
  131. newExp->expr.ident.regiType = WORD_REG;
  132. }
  133. return (newExp);
  134. }
  135. COND_EXPR *idCondExpRegIdx (Int idx, regType type)
  136. /* Returns an identifier conditional expression node of type REGISTER */
  137. { COND_EXPR *newExp;
  138. newExp = newCondExp (IDENTIFIER);
  139. newExp->expr.ident.idType = REGISTER;
  140. newExp->expr.ident.regiType = type;
  141. newExp->expr.ident.idNode.regiIdx = idx;
  142. return (newExp);
  143. }
  144. COND_EXPR *idCondExpLoc (Int off, LOCAL_ID *localId)
  145. /* Returns an identifier conditional expression node of type LOCAL_VAR */
  146. { COND_EXPR *newExp;
  147. Int i;
  148. newExp = newCondExp (IDENTIFIER);
  149. newExp->expr.ident.idType = LOCAL_VAR;
  150. for (i = 0; i < localId->csym; i++)
  151. if ((localId->id[i].id.bwId.off == off) &&
  152. (localId->id[i].id.bwId.regOff == 0))
  153. break;
  154. if (i == localId->csym) printf ("Error, cannot find local var\n");
  155. newExp->expr.ident.idNode.localIdx = i;
  156. sprintf (localId->id[i].name, "loc%ld", i);
  157. return (newExp);
  158. }
  159. COND_EXPR *idCondExpParam (Int off, PSTKFRAME argSymtab)
  160. /* Returns an identifier conditional expression node of type PARAM */
  161. { COND_EXPR *newExp;
  162. Int i;
  163. newExp = newCondExp (IDENTIFIER);
  164. newExp->expr.ident.idType = PARAM;
  165. for (i = 0; i < argSymtab->csym; i++)
  166. if (argSymtab->sym[i].off == off)
  167. break;
  168. if (i == argSymtab->csym) printf ("Error, cannot find argument var\n");
  169. newExp->expr.ident.idNode.localIdx = i;
  170. return (newExp);
  171. }
  172. COND_EXPR *idCondExpIdxGlob (int16 segValue, int16 off, byte regi,
  173. LOCAL_ID *locSym)
  174. /* Returns an identifier conditional expression node of type GLOB_VAR_IDX.
  175. * This global variable is indexed by regi. */
  176. { COND_EXPR *newExp;
  177. Int i;
  178. newExp = newCondExp (IDENTIFIER);
  179. newExp->expr.ident.idType = GLOB_VAR_IDX;
  180. for (i = 0; i < locSym->csym; i++)
  181. if ((locSym->id[i].id.bwGlb.seg == segValue) &&
  182. (locSym->id[i].id.bwGlb.off == off) &&
  183. (locSym->id[i].id.bwGlb.regi == regi))
  184. break;
  185. if (i == locSym->csym)
  186. printf ("Error, indexed-glob var not found in local id table\n");
  187. newExp->expr.ident.idNode.idxGlbIdx = i;
  188. return (newExp);
  189. }
  190. COND_EXPR *idCondExpKte (dword kte, byte size)
  191. /* Returns an identifier conditional expression node of type CONSTANT */
  192. { COND_EXPR *newExp;
  193. newExp = newCondExp (IDENTIFIER);
  194. newExp->expr.ident.idType = CONSTANT;
  195. newExp->expr.ident.idNode.kte.kte = kte;
  196. newExp->expr.ident.idNode.kte.size = size;
  197. return (newExp);
  198. }
  199. COND_EXPR *idCondExpLongIdx (Int idx)
  200. /* Returns an identifier conditional expression node of type LONG_VAR,
  201. * that points to the given index idx. */
  202. { COND_EXPR *newExp;
  203. newExp = newCondExp (IDENTIFIER);
  204. newExp->expr.ident.idType = LONG_VAR;
  205. newExp->expr.ident.idNode.longIdx = idx;
  206. return (newExp);
  207. }
  208. COND_EXPR *idCondExpLong (LOCAL_ID *localId, opLoc sd, PICODE pIcode,
  209. hlFirst f, Int ix, operDu du, Int off)
  210. /* Returns an identifier conditional expression node of type LONG_VAR */
  211. { COND_EXPR *newExp;
  212. Int idx;
  213. newExp = newCondExp (IDENTIFIER);
  214. /* Check for long constant and save it as a constant expression */
  215. if ((sd == SRC) && ((pIcode->ic.ll.flg & I) == I)) /* constant */
  216. {
  217. newExp->expr.ident.idType = CONSTANT;
  218. if (f == HIGH_FIRST)
  219. newExp->expr.ident.idNode.kte.kte = (pIcode->ic.ll.immed.op << 16) +
  220. (pIcode+off)->ic.ll.immed.op;
  221. else /* LOW_FIRST */
  222. newExp->expr.ident.idNode.kte.kte =
  223. ((pIcode+off)->ic.ll.immed.op << 16)+ pIcode->ic.ll.immed.op;
  224. newExp->expr.ident.idNode.kte.size = 4;
  225. }
  226. /* Save it as a long expression (reg, stack or glob) */
  227. else
  228. {
  229. idx = newLongId (localId, sd, pIcode, f, ix, du, off);
  230. newExp->expr.ident.idType = LONG_VAR;
  231. newExp->expr.ident.idNode.longIdx = idx;
  232. }
  233. return (newExp);
  234. }
  235. COND_EXPR *idCondExpFunc (PPROC pproc, PSTKFRAME args)
  236. /* Returns an identifier conditional expression node of type FUNCTION */
  237. { COND_EXPR *newExp;
  238. newExp = newCondExp (IDENTIFIER);
  239. newExp->expr.ident.idType = FUNCTION;
  240. newExp->expr.ident.idNode.call.proc = pproc;
  241. newExp->expr.ident.idNode.call.args = args;
  242. return (newExp);
  243. }
  244. COND_EXPR *idCondExpOther (byte seg, byte regi, int16 off)
  245. /* Returns an identifier conditional expression node of type OTHER.
  246. * Temporary solution, should really be encoded as an indexed type (eg.
  247. * arrays). */
  248. { COND_EXPR *newExp;
  249. newExp = newCondExp (IDENTIFIER);
  250. newExp->expr.ident.idType = OTHER;
  251. newExp->expr.ident.idNode.other.seg = seg;
  252. newExp->expr.ident.idNode.other.regi = regi;
  253. newExp->expr.ident.idNode.other.off = off;
  254. return (newExp);
  255. }
  256. COND_EXPR *idCondExpID (ID *retVal, LOCAL_ID *locsym, Int ix)
  257. /* Returns an identifier conditional expression node of type TYPE_LONG or
  258. * TYPE_WORD_SIGN */
  259. { COND_EXPR *newExp;
  260. Int idx;
  261. newExp = newCondExp (IDENTIFIER);
  262. if (retVal->type == TYPE_LONG_SIGN)
  263. {
  264. idx = newLongRegId (locsym, TYPE_LONG_SIGN, retVal->id.longId.h,
  265. retVal->id.longId.l, ix);
  266. newExp->expr.ident.idType = LONG_VAR;
  267. newExp->expr.ident.idNode.longIdx = idx;
  268. }
  269. else if (retVal->type == TYPE_WORD_SIGN)
  270. {
  271. newExp->expr.ident.idType = REGISTER;
  272. newExp->expr.ident.idNode.regiIdx = newByteWordRegId (locsym,
  273. TYPE_WORD_SIGN, retVal->id.regi);
  274. newExp->expr.ident.regiType = WORD_REG;
  275. }
  276. return (newExp);
  277. }
  278. COND_EXPR *idCondExp (PICODE pIcode, opLoc sd, PPROC pProc, Int i,
  279. PICODE duIcode, operDu du)
  280. /* Returns an identifier conditional expression node, according to the given
  281. * type.
  282. * Arguments: i : index into the icode array, used for newLongRegId only.
  283. * duIcode: icode instruction that needs the du set.
  284. * du: operand is defined or used in current instruction. */
  285. { COND_EXPR *newExp;
  286. PMEM pm;
  287. Int idx; /* idx into pIcode->localId table */
  288. pm = (sd == SRC) ? &pIcode->ic.ll.src : &pIcode->ic.ll.dst;
  289. if (((sd == DST) && (pIcode->ic.ll.flg & IM_DST) == IM_DST) ||
  290. ((sd == SRC) && (pIcode->ic.ll.flg & IM_SRC)) ||
  291. (sd == LHS_OP)) /* for MUL lhs */
  292. { /* implicit dx:ax */
  293. idx = newLongRegId (&pProc->localId, TYPE_LONG_SIGN, rDX, rAX, i);
  294. newExp = idCondExpLongIdx (idx);
  295. setRegDU (duIcode, rDX, du);
  296. setRegDU (duIcode, rAX, du);
  297. }
  298. else if ((sd == DST) && (pIcode->ic.ll.flg & IM_TMP_DST) == IM_TMP_DST)
  299. { /* implicit tmp */
  300. newExp = idCondExpReg (rTMP, 0, &pProc->localId);
  301. setRegDU (duIcode, rTMP, (operDu)USE);
  302. }
  303. else if ((sd == SRC) && ((pIcode->ic.ll.flg & I) == I)) /* constant */
  304. newExp = idCondExpKte (pIcode->ic.ll.immed.op, 2);
  305. else if (pm->regi == 0) /* global variable */
  306. newExp = idCondExpGlob (pm->segValue, pm->off);
  307. else if (pm->regi < INDEXBASE) /* register */
  308. {
  309. newExp = idCondExpReg (pm->regi, (sd == SRC) ? pIcode->ic.ll.flg :
  310. pIcode->ic.ll.flg & NO_SRC_B, &pProc->localId);
  311. setRegDU (duIcode, pm->regi, du);
  312. }
  313. else if (pm->off) /* offset */
  314. {
  315. if ((pm->seg == rSS) && (pm->regi == INDEXBASE + 6)) /* idx on bp */
  316. {
  317. if (pm->off >= 0) /* argument */
  318. newExp = idCondExpParam (pm->off, &pProc->args);
  319. else /* local variable */
  320. newExp = idCondExpLoc (pm->off, &pProc->localId);
  321. }
  322. else if ((pm->seg == rDS) && (pm->regi == INDEXBASE + 7)) /* bx */
  323. {
  324. if (pm->off > 0) /* global variable */
  325. newExp = idCondExpIdxGlob (pm->segValue, pm->off, rBX,
  326. &pProc->localId);
  327. else
  328. newExp = idCondExpOther (pm->seg, pm->regi, pm->off);
  329. setRegDU (duIcode, rBX, (operDu)USE);
  330. }
  331. else /* idx <> bp, bx */
  332. newExp = idCondExpOther (pm->seg, pm->regi, pm->off);
  333. /**** check long ops, indexed global var *****/
  334. }
  335. else /* (pm->regi >= INDEXBASE && pm->off = 0) => indexed && no off */
  336. {
  337. if ((pm->seg == rDS) && (pm->regi > INDEXBASE + 3)) /* dereference */
  338. {
  339. switch (pm->regi) {
  340. case INDEXBASE + 4: newExp = idCondExpReg(rSI, 0, &pProc->localId);
  341. setRegDU (duIcode, rSI, du);
  342. break;
  343. case INDEXBASE + 5: newExp = idCondExpReg(rDI, 0, &pProc->localId);
  344. setRegDU (duIcode, rDI, du);
  345. break;
  346. case INDEXBASE + 6: newExp = idCondExpReg(rBP, 0, &pProc->localId);
  347. break;
  348. case INDEXBASE + 7: newExp = idCondExpReg(rBX, 0, &pProc->localId);
  349. setRegDU (duIcode, rBX, du);
  350. break;
  351. }
  352. newExp = unaryCondExp (DEREFERENCE, newExp);
  353. }
  354. else
  355. newExp = idCondExpOther (pm->seg, pm->regi, 0);
  356. }
  357. return (newExp);
  358. }
  359. condId idType (PICODE pIcode, opLoc sd)
  360. /* Returns the identifier type */
  361. { PMEM pm;
  362. pm = (sd == SRC) ? &pIcode->ic.ll.src : &pIcode->ic.ll.dst;
  363. if ((sd == SRC) && ((pIcode->ic.ll.flg & I) == I))
  364. return (CONSTANT);
  365. else if (pm->regi == 0)
  366. return (GLOB_VAR);
  367. else if (pm->regi < INDEXBASE)
  368. return (REGISTER);
  369. else if ((pm->seg == rSS) && (pm->regi == INDEXBASE))
  370. {
  371. if (pm->off >= 0)
  372. return (PARAM);
  373. else
  374. return (LOCAL_VAR);
  375. }
  376. else
  377. return (OTHER);
  378. }
  379. /* Size of hl types */
  380. Int hlSize[] = {2, 1, 1, 2, 2, 4, 4, 4, 2, 2, 1, 4, 4};
  381. Int hlTypeSize (COND_EXPR *exp, PPROC pproc)
  382. /* Returns the type of the expression */
  383. { Int first, second;
  384. if (exp == NULL)
  385. return (2); /* for TYPE_UNKNOWN */
  386. switch (exp->type) {
  387. case BOOLEAN_OP: first = hlTypeSize (exp->expr.boolExpr.lhs, pproc);
  388. second = hlTypeSize (exp->expr.boolExpr.rhs, pproc);
  389. if (first > second)
  390. return (first);
  391. else
  392. return (second);
  393. case NEGATION: case ADDRESSOF:
  394. case POST_INC: case POST_DEC:
  395. case PRE_INC: case PRE_DEC:
  396. case DEREFERENCE: return (hlTypeSize (exp->expr.unaryExp, pproc));
  397. case IDENTIFIER:
  398. switch (exp->expr.ident.idType) {
  399. case GLOB_VAR:
  400. return (symtab.sym[exp->expr.ident.idNode.globIdx].size);
  401. case REGISTER:
  402. if (exp->expr.ident.regiType == BYTE_REG)
  403. return (1);
  404. else
  405. return (2);
  406. case LOCAL_VAR:
  407. return (hlSize[pproc->localId.id[exp->expr.ident.idNode.localIdx].type]);
  408. case PARAM:
  409. return (hlSize[pproc->args.sym[exp->expr.ident.idNode.paramIdx].type]);
  410. case GLOB_VAR_IDX:
  411. return (hlSize[pproc->localId.id[exp->expr.ident.idNode.idxGlbIdx].type]);
  412. case CONSTANT:
  413. return (exp->expr.ident.idNode.kte.size);
  414. case STRING:
  415. return (2);
  416. case LONG_VAR:
  417. return (4);
  418. case FUNCTION:
  419. return (hlSize[exp->expr.ident.idNode.call.proc->retVal.type]);
  420. case OTHER:
  421. return (2);
  422. } /* eos */
  423. break;
  424. }
  425. return 2; // CC: is this correct?
  426. }
  427. hlType expType (COND_EXPR *exp, PPROC pproc)
  428. /* Returns the type of the expression */
  429. { hlType first, second;
  430. if (exp == NULL)
  431. return (TYPE_UNKNOWN);
  432. switch (exp->type) {
  433. case BOOLEAN_OP: first = expType (exp->expr.boolExpr.lhs, pproc);
  434. second = expType (exp->expr.boolExpr.rhs, pproc);
  435. if (first != second)
  436. {
  437. if (hlTypeSize (exp->expr.boolExpr.lhs, pproc) >
  438. hlTypeSize (exp->expr.boolExpr.rhs, pproc))
  439. return (first);
  440. else
  441. return (second);
  442. }
  443. else
  444. return (first);
  445. case POST_INC: case POST_DEC:
  446. case PRE_INC: case PRE_DEC:
  447. case NEGATION: return (expType (exp->expr.unaryExp, pproc));
  448. case ADDRESSOF: return (TYPE_PTR); /***????****/
  449. case DEREFERENCE: return (TYPE_PTR);
  450. case IDENTIFIER:
  451. switch (exp->expr.ident.idType) {
  452. case GLOB_VAR:
  453. return (symtab.sym[exp->expr.ident.idNode.globIdx].type);
  454. case REGISTER:
  455. if (exp->expr.ident.regiType == BYTE_REG)
  456. return (TYPE_BYTE_SIGN);
  457. else
  458. return (TYPE_WORD_SIGN);
  459. case LOCAL_VAR:
  460. return (pproc->localId.id[exp->expr.ident.idNode.localIdx].type);
  461. case PARAM:
  462. return (pproc->args.sym[exp->expr.ident.idNode.paramIdx].type);
  463. case GLOB_VAR_IDX:
  464. return (pproc->localId.id[exp->expr.ident.idNode.idxGlbIdx].type);
  465. case CONSTANT:
  466. return (TYPE_CONST);
  467. case STRING:
  468. return (TYPE_STR);
  469. case LONG_VAR:
  470. return (pproc->localId.id[exp->expr.ident.idNode.longIdx].type);
  471. case FUNCTION:
  472. return (exp->expr.ident.idNode.call.proc->retVal.type);
  473. case OTHER:
  474. return (TYPE_UNKNOWN);
  475. } /* eos */
  476. }
  477. return TYPE_UNKNOWN; // CC: Correct?
  478. }
  479. void removeRegFromLong (byte regi, LOCAL_ID *locId, COND_EXPR *tree)
  480. /* Removes the register from the tree. If the register was part of a long
  481. * register (eg. dx:ax), the node gets transformed into an integer register
  482. * node. */
  483. {
  484. IDENTTYPE* ident; /* ptr to an identifier */
  485. byte otherRegi; /* high or low part of long register */
  486. switch (tree->type) {
  487. case BOOLEAN_OP:
  488. break;
  489. case POST_INC: case POST_DEC:
  490. case PRE_INC: case PRE_DEC:
  491. case NEGATION: case ADDRESSOF:
  492. case DEREFERENCE:
  493. break;
  494. case IDENTIFIER:
  495. ident = &tree->expr.ident;
  496. if (ident->idType == LONG_VAR)
  497. {
  498. otherRegi = otherLongRegi (regi, ident->idNode.longIdx, locId);
  499. ident->idType = REGISTER;
  500. ident->regiType = WORD_REG;
  501. ident->idNode.regiIdx = newByteWordRegId (locId, TYPE_WORD_SIGN,
  502. otherRegi);
  503. }
  504. break;
  505. }
  506. }
  507. static char *getString (Int offset)
  508. /* Returns the string located in image, formatted in C format. */
  509. { char *o;
  510. Int strLen, i;
  511. strLen = strSize (&prog.Image[offset], '\0');
  512. o = (char *) allocMem((strLen*2+1) * sizeof(char));
  513. o[0] = '"';
  514. o[1] = '\0';
  515. for (i = 0; i < strLen; i++)
  516. strcat (o, cChar(prog.Image[offset+i]));
  517. strcat (o, "\"\0");
  518. return (o);
  519. }
  520. char *walkCondExpr (COND_EXPR* exp, PPROC pProc, Int* numLoc)
  521. /* Walks the conditional expression tree and returns the result on a string */
  522. { int16 off; /* temporal - for OTHER */
  523. ID* id; /* Pointer to local identifier table */
  524. char* o; /* Operand string pointer */
  525. boolT needBracket; /* Determine whether parenthesis is needed */
  526. BWGLB_TYPE* bwGlb; /* Ptr to BWGLB_TYPE (global indexed var) */
  527. PSTKSYM psym; /* Pointer to argument in the stack */
  528. char* condExp, *e; /* Return and intermediate expressions */
  529. condExp = (char*) allocMem (EXP_SIZE * sizeof(char));
  530. condExp[0] = '\0';
  531. if (exp == NULL)
  532. return (condExp);
  533. needBracket = TRUE;
  534. switch (exp->type)
  535. {
  536. case BOOLEAN_OP: strcat (condExp, "(");
  537. e = walkCondExpr(exp->expr.boolExpr.lhs, pProc, numLoc);
  538. strcat (condExp, e);
  539. strcat (condExp, condOpSym[exp->expr.boolExpr.op]);
  540. e = walkCondExpr(exp->expr.boolExpr.rhs, pProc, numLoc);
  541. strcat (condExp, e);
  542. strcat (condExp, ")");
  543. break;
  544. case NEGATION: if (exp->expr.unaryExp->type == IDENTIFIER)
  545. {
  546. needBracket = FALSE;
  547. strcat (condExp, "!");
  548. }
  549. else
  550. strcat (condExp, "! (");
  551. e = walkCondExpr (exp->expr.unaryExp, pProc, numLoc);
  552. strcat (condExp, e);
  553. if (needBracket == TRUE)
  554. strcat (condExp, ")");
  555. break;
  556. case ADDRESSOF: if (exp->expr.unaryExp->type == IDENTIFIER)
  557. {
  558. needBracket = FALSE;
  559. strcat (condExp, "&");
  560. }
  561. else
  562. strcat (condExp, "&(");
  563. e = walkCondExpr (exp->expr.unaryExp, pProc, numLoc);
  564. strcat (condExp, e);
  565. if (needBracket == TRUE)
  566. strcat (condExp, ")");
  567. break;
  568. case DEREFERENCE: if (exp->expr.unaryExp->type == IDENTIFIER)
  569. {
  570. needBracket = FALSE;
  571. strcat (condExp, "*");
  572. }
  573. else
  574. strcat (condExp, "*(");
  575. e = walkCondExpr (exp->expr.unaryExp, pProc, numLoc);
  576. strcat (condExp, e);
  577. if (needBracket == TRUE)
  578. strcat (condExp, ")");
  579. break;
  580. case POST_INC: e = walkCondExpr (exp->expr.unaryExp, pProc, numLoc);
  581. strcat (condExp, e);
  582. strcat (condExp, "++");
  583. break;
  584. case POST_DEC: e = walkCondExpr (exp->expr.unaryExp, pProc, numLoc);
  585. strcat (condExp, e);
  586. strcat (condExp, "--");
  587. break;
  588. case PRE_INC: strcat (condExp, "++");
  589. e = walkCondExpr (exp->expr.unaryExp, pProc, numLoc);
  590. strcat (condExp, e);
  591. break;
  592. case PRE_DEC: strcat (condExp, "--");
  593. e = walkCondExpr (exp->expr.unaryExp, pProc, numLoc);
  594. strcat (condExp, e);
  595. break;
  596. case IDENTIFIER:
  597. o = (char*) allocMem (operandSize);
  598. switch (exp->expr.ident.idType) {
  599. case GLOB_VAR: sprintf (o, "%s",
  600. symtab.sym[exp->expr.ident.idNode.globIdx].name);
  601. break;
  602. case REGISTER:
  603. id = &pProc->localId.id[exp->expr.ident.idNode.regiIdx];
  604. if (id->name[0] == '\0') /* no name */
  605. {
  606. sprintf (id->name, "loc%ld", ++(*numLoc));
  607. if (id->id.regi < rAL)
  608. appendStrTab (&cCode.decl,
  609. "%s %s; /* %s */\n",
  610. hlTypes[id->type], id->name,
  611. wordReg[id->id.regi - rAX]);
  612. else
  613. appendStrTab (&cCode.decl,
  614. "%s %s; /* %s */\n",
  615. hlTypes[id->type], id->name,
  616. byteReg[id->id.regi - rAL]);
  617. }
  618. if (id->hasMacro)
  619. sprintf (o, "%s(%s)", id->macro, id->name);
  620. else
  621. sprintf (o, "%s", id->name);
  622. break;
  623. case LOCAL_VAR:
  624. sprintf (o, "%s",
  625. pProc->localId.id[exp->expr.ident.idNode.localIdx].name);
  626. break;
  627. case PARAM:
  628. psym = &pProc->args.sym[exp->expr.ident.idNode.paramIdx];
  629. if (psym->hasMacro)
  630. sprintf (o, "%s(%s)", psym->macro, psym->name);
  631. else
  632. sprintf (o, "%s", psym->name);
  633. break;
  634. case GLOB_VAR_IDX:
  635. bwGlb = &pProc->localId.id[exp->expr.ident.idNode.idxGlbIdx].id.bwGlb;
  636. sprintf (o, "%d[%s]", (bwGlb->seg << 4) +
  637. bwGlb->off, wordReg[bwGlb->regi - rAX]);
  638. break;
  639. case CONSTANT:
  640. if (exp->expr.ident.idNode.kte.kte < 1000)
  641. sprintf (o,"%d",exp->expr.ident.idNode.kte.kte);
  642. else
  643. sprintf(o,"0x%X",exp->expr.ident.idNode.kte.kte);
  644. break;
  645. case STRING:
  646. o = getString (exp->expr.ident.idNode.strIdx);
  647. break;
  648. case LONG_VAR:
  649. id = &pProc->localId.id[exp->expr.ident.idNode.longIdx];
  650. if (id->name[0] != '\0') /* STK_FRAME & REG w/name*/
  651. sprintf (o, "%s", id->name);
  652. else if (id->loc == REG_FRAME)
  653. {
  654. sprintf (id->name, "loc%ld", ++(*numLoc));
  655. appendStrTab (&cCode.decl,
  656. "%s %s; /* %s:%s */\n",
  657. hlTypes[id->type], id->name,
  658. wordReg[id->id.longId.h - rAX],
  659. wordReg[id->id.longId.l - rAX]);
  660. sprintf (o, "%s", id->name);
  661. propLongId (&pProc->localId, id->id.longId.l,
  662. id->id.longId.h, id->name);
  663. }
  664. else /* GLB_FRAME */
  665. {
  666. if (id->id.longGlb.regi == 0) /* not indexed */
  667. sprintf (o, "[%ld]", (id->id.longGlb.seg<<4)
  668. + id->id.longGlb.offH);
  669. else if (id->id.longGlb.regi == rBX)
  670. sprintf (o, "[%ld][bx]",
  671. (id->id.longGlb.seg<<4) +
  672. id->id.longGlb.offH);
  673. }
  674. break;
  675. case FUNCTION:
  676. o = writeCall (exp->expr.ident.idNode.call.proc,
  677. exp->expr.ident.idNode.call.args,
  678. pProc, numLoc);
  679. break;
  680. case OTHER:
  681. off = exp->expr.ident.idNode.other.off;
  682. if (off == 0)
  683. sprintf (o, "%s[%s]",
  684. wordReg[exp->expr.ident.idNode.other.seg - rAX],
  685. idxReg[exp->expr.ident.idNode.other.regi - INDEXBASE]);
  686. else if (off < 0)
  687. sprintf (o, "%s[%s-%s]",
  688. wordReg[exp->expr.ident.idNode.other.seg - rAX],
  689. idxReg[exp->expr.ident.idNode.other.regi - INDEXBASE],
  690. hexStr (-off));
  691. else
  692. sprintf (o, "%s[%s+%s]",
  693. wordReg[exp->expr.ident.idNode.other.seg - rAX],
  694. idxReg[exp->expr.ident.idNode.other.regi - INDEXBASE],
  695. hexStr (off));
  696. } /* eos */
  697. strcat (condExp, o);
  698. break;
  699. }
  700. return (condExp);
  701. }
  702. COND_EXPR *copyCondExp (COND_EXPR *exp)
  703. /* Makes a copy of the given expression. Allocates newExp storage for each
  704. * node. Returns the copy. */
  705. {
  706. COND_EXPR* newExp; /* Expression node copy */
  707. switch (exp->type) {
  708. case BOOLEAN_OP:
  709. newExp = allocStruc(COND_EXPR);
  710. memcpy(newExp, exp, sizeof(COND_EXPR));
  711. newExp->expr.boolExpr.lhs = copyCondExp (exp->expr.boolExpr.lhs);
  712. newExp->expr.boolExpr.rhs = copyCondExp (exp->expr.boolExpr.rhs);
  713. break;
  714. case NEGATION:
  715. case ADDRESSOF:
  716. case DEREFERENCE:
  717. newExp = allocStruc(COND_EXPR);
  718. memcpy(newExp, exp, sizeof(COND_EXPR));
  719. newExp->expr.unaryExp = copyCondExp (exp->expr.unaryExp);
  720. break;
  721. case IDENTIFIER:
  722. newExp = allocStruc(COND_EXPR);
  723. memcpy(newExp, exp, sizeof(COND_EXPR));
  724. }
  725. return (newExp);
  726. }
  727. void changeBoolCondExpOp (COND_EXPR *exp, condOp newOp)
  728. /* Changes the boolean conditional operator at the root of this expression */
  729. {
  730. exp->expr.boolExpr.op = newOp;
  731. }
  732. boolT insertSubTreeReg (COND_EXPR *exp, COND_EXPR **tree, byte regi,
  733. LOCAL_ID *locsym)
  734. /* Inserts the expression exp into the tree at the location specified by the
  735. * register regi */
  736. { byte treeReg;
  737. if (*tree == NULL)
  738. return FALSE;
  739. switch ((*tree)->type) {
  740. case IDENTIFIER:
  741. if ((*tree)->expr.ident.idType == REGISTER)
  742. {
  743. treeReg = locsym->id[(*tree)->expr.ident.idNode.regiIdx].id.regi;
  744. if (treeReg == regi) /* word reg */
  745. {
  746. *tree = exp;
  747. return TRUE;
  748. }
  749. else if ((regi >= rAX) && (regi <= rBX)) /* word/byte reg */
  750. {
  751. if ((treeReg == (regi + rAL-1)) || (treeReg == (regi + rAH-1)))
  752. {
  753. *tree = exp;
  754. return TRUE;
  755. }
  756. }
  757. }
  758. return FALSE;
  759. case BOOLEAN_OP:
  760. if (insertSubTreeReg (exp, &(*tree)->expr.boolExpr.lhs, regi,
  761. locsym))
  762. return TRUE;
  763. if (insertSubTreeReg (exp, &(*tree)->expr.boolExpr.rhs, regi,
  764. locsym))
  765. return TRUE;
  766. return FALSE;
  767. case NEGATION:
  768. case ADDRESSOF:
  769. case DEREFERENCE:
  770. if (insertSubTreeReg(exp, &(*tree)->expr.unaryExp,regi, locsym))
  771. return TRUE;
  772. return FALSE;
  773. }
  774. return FALSE;
  775. }
  776. boolT insertSubTreeLongReg (COND_EXPR *exp, COND_EXPR **tree, Int longIdx)
  777. /* Inserts the expression exp into the tree at the location specified by the
  778. * long register index longIdx*/
  779. {
  780. switch ((*tree)->type) {
  781. case IDENTIFIER: if ((*tree)->expr.ident.idNode.longIdx == longIdx)
  782. {
  783. *tree = exp;
  784. return TRUE;
  785. }
  786. return FALSE;
  787. case BOOLEAN_OP: if (insertSubTreeLongReg (exp,
  788. &(*tree)->expr.boolExpr.lhs, longIdx))
  789. return TRUE;
  790. if (insertSubTreeLongReg (exp,
  791. &(*tree)->expr.boolExpr.rhs, longIdx))
  792. return TRUE;
  793. return FALSE;
  794. case NEGATION:
  795. case ADDRESSOF:
  796. case DEREFERENCE: if (insertSubTreeLongReg (exp,
  797. &(*tree)->expr.unaryExp, longIdx))
  798. return TRUE;
  799. return FALSE;
  800. }
  801. return FALSE;
  802. }
  803. void freeCondExpr (COND_EXPR *exp)
  804. /* Recursively deallocates the abstract syntax tree rooted at *exp */
  805. {
  806. switch (exp->type) {
  807. case BOOLEAN_OP: freeCondExpr (exp->expr.boolExpr.lhs);
  808. freeCondExpr (exp->expr.boolExpr.rhs);
  809. break;
  810. case NEGATION:
  811. case ADDRESSOF:
  812. case DEREFERENCE: freeCondExpr (exp->expr.unaryExp);
  813. break;
  814. }
  815. free (exp);
  816. }
  817. /***************************************************************************
  818. * Expression stack functions
  819. **************************************************************************/
  820. void initExpStk()
  821. /* Reinitalizes the expression stack (expStk) to NULL, by freeing all the
  822. * space allocated (if any). */
  823. { EXP_STK *top;
  824. while (expStk != NULL)
  825. {
  826. top = expStk;
  827. expStk = expStk->next;
  828. free (top);
  829. }
  830. }
  831. void pushExpStk (COND_EXPR *exp)
  832. /* Pushes the given expression onto the local stack (expStk). */
  833. { EXP_STK *newExp;
  834. newExp = allocStruc(EXP_STK);
  835. newExp->exp = exp;
  836. newExp->next = expStk;
  837. expStk = newExp;
  838. }
  839. COND_EXPR *popExpStk()
  840. /* Returns the element on the top of the local expression stack (expStk),
  841. * and deallocates the space allocated by this node.
  842. * If there are no elements on the stack, returns NULL. */
  843. { EXP_STK *top;
  844. COND_EXPR *topExp;
  845. if (expStk != NULL)
  846. {
  847. topExp = expStk->exp;
  848. top = expStk;
  849. expStk = expStk->next;
  850. free (top);
  851. return (topExp);
  852. }
  853. else
  854. return (NULL);
  855. }
  856. Int numElemExpStk()
  857. /* Returns the number of elements available in the expression stack */
  858. { EXP_STK *top;
  859. Int num;
  860. num = 0;
  861. top = expStk;
  862. while (top)
  863. {
  864. top = top->next;
  865. num++;
  866. }
  867. return (num);
  868. }
  869. boolT emptyExpStk()
  870. /* Returns whether the expression stack is empty or not */
  871. {
  872. if (expStk == NULL)
  873. return TRUE;
  874. return FALSE;
  875. }