EXPR.C
上传用户:hlzzc88
上传日期:2007-01-06
资源大小:220k
文件大小:79k
源码类别:

编译器/解释器

开发平台:

Others

  1. /*
  2.  * 68K/386 32-bit C compiler.
  3.  *
  4.  * copyright (c) 1997, David Lindauer
  5.  * 
  6.  * This compiler is intended for educational use.  It may not be used
  7.  * for profit without the express written consent of the author.
  8.  *
  9.  * It may be freely redistributed, as long as this notice remains intact
  10.  * and either the original sources or derived sources 
  11.  * are distributed along with any executables derived from the originals.
  12.  *
  13.  * The author is not responsible for any damages that may arise from use
  14.  * of this software, either idirect or consequential.
  15.  *
  16.  * v1.35 March 1997
  17.  * David Lindauer, gclind01@starbase.spd.louisville.edu
  18.  *
  19.  * Credits to Mathew Brandt for original K&R C compiler
  20.  *
  21.  */
  22. /*
  23.  * Evaluate expressions very recursive descent.  MAke sure your STACK
  24.  * is large enough to parse the expressions you want to parse.  a 4K stack
  25.  * will handle all but the very extreme cases
  26.  */
  27. #include        <stdio.h>
  28. #include        "expr.h"
  29. #include        "c.h"
  30. #include        "errors.h"
  31. #include "list.h"
  32. extern int block_nesting;
  33. extern int global_flag;
  34. extern enum e_sym lastst;
  35. extern char lastid[],laststr[];
  36. extern TABLE gsyms,lsyms;
  37. extern long ival;
  38. extern long double rval;
  39. /* Default types */
  40. extern TYP stdint,stdlongdouble, stduns,stdstring;
  41. TYP             stdfloat = { bt_float, 0, UF_DEFINED | UF_USED,0, 0,-1, -1, 8, {0, 0}, 0, 0,0 };
  42. TYP             stddouble = { bt_double, 0, 0,0,0, -1, -1, 8, {0, 0}, 0, 0,0 };
  43. TYP             stdvoid = { bt_matchall, 0, 0 ,0, 0,-1, -1, 4, {0, 0}, 0, 0,0 };
  44. TYP             stdmatch = { bt_matchall, 0, UF_DEFINED | UF_USED,0, 0,-1, -1, 4, {0, 0}, &stdvoid, 0,0 };
  45. TYP             stdlong = {bt_long, 0, 0,0,0,-1, -1, 4, {0, 0}, 0, 0,0 };
  46. TYP             stdunsigned = {bt_unsigned, 0, 0,0,0,-1, -1, 4, {0, 0}, 0, 0,0 };
  47. TYP             stdchar = {bt_char, 0, 0,0,0,-1, -1, 1, {0, 0}, 0, 0,0 };
  48. TYP             stdfunc = {bt_func, 1, UF_DEFINED | UF_USED,0,0,-1, -1, 0, {0, 0}, &stdint, 0,0};
  49. extern TYP      *head;          /* shared with decl */
  50. extern TABLE    tagtable;
  51. extern char declid[100];
  52. extern int goodcode;
  53. extern int prm_cplusplus;
  54. extern int regdsize,regasize,regfsize,stackadd,stackmod;
  55. int skm_closepa[] = { closepa, comma, semicolon, end, 0 };
  56. int skm_closebr[] = { closebr, comma, openbr, semicolon, end, 0 };
  57. static SYM *lastsym;
  58. static int globaldref = 0;
  59. static char regname[] = "processor reg" ;
  60. static char *nm = 0;
  61. static TYP *asntyp = 0;
  62. static int dumpos;
  63. static SYM undef;
  64. void exprini(void)
  65. {
  66. globaldref = 0;
  67. asntyp = 0;
  68. dumpos = 0;
  69. undef.value.i = 0;
  70. undef.name = "UNDEFINED";
  71. }
  72. ENODE    *makenode(enum e_node nt, char *v1, char *v2)
  73. /*
  74.  *      build an expression node with a node type of nt and values
  75.  *      v1 and v2.
  76.  */
  77. {       ENODE    *ep;
  78.         ep = xalloc(sizeof(ENODE));
  79.         ep->nodetype = (char)nt;
  80. ep->cflags = 0;
  81.         ep->v.p[0] = v1;
  82.         ep->v.p[1] = v2;
  83.         return ep;
  84. }
  85. TYP *deref(ENODE **node, TYP *tp)
  86. /*
  87.  *      build the proper dereference operation for a node using the
  88.  *      type pointer tp.
  89.  */
  90. {
  91. ENODE *onode = *node;
  92. switch( tp->type ) {
  93. case bt_double:
  94.                         *node = makenode(en_doubleref,*node,0);
  95.                         break;
  96. case bt_longdouble:
  97.                         *node = makenode(en_longdoubleref,*node,0);
  98.                         break;
  99. case bt_float:
  100.                         *node = makenode(en_floatref,*node,0);
  101.                         break;
  102. case bt_unsignedchar:
  103.                         *node = makenode(en_ub_ref,*node,0);
  104.                         break;
  105. case bt_unsignedshort:
  106.                         *node = makenode(en_uw_ref,*node,0);
  107.                         break;
  108.                 case bt_char:
  109.                         *node = makenode(en_b_ref,*node,0);
  110.                         break;
  111.                 case bt_short:
  112.                 case bt_enum:
  113.                         *node = makenode(en_w_ref,*node,0);
  114.                         break;
  115.                 case bt_unsigned:
  116.                         *node = makenode(en_ul_ref,*node,0);
  117. break;
  118.                 case bt_long:
  119.                 case bt_matchall:
  120.                 case bt_pointer:
  121. case bt_ptrfunc:
  122. case bt_ref:
  123.                         *node = makenode(en_l_ref,*node,0);
  124.                         break;
  125.                 default:
  126.                         generror(ERR_DEREF,0,0);
  127.                         break;
  128.                 }
  129. (*node)->cflags = onode->cflags;
  130.         return tp;
  131. }
  132. ENODE *dummyvar(int size, TYP *type)
  133. {
  134. char nm[20];
  135. ENODE *newnode;
  136. SYM *sp = xalloc(sizeof(SYM));
  137. sprintf(nm,"**DUMMY%d",dumpos++);
  138. sp->name = litlate(nm);
  139. sp->defalt = 0;
  140.   sp->storage_class = sc_auto;
  141.   sp->tp = type;
  142. type->uflags |= UF_USED;
  143. sp->extflag = FALSE;
  144. sp->absflag = FALSE;
  145. sp->intflag = FALSE;
  146. sp->pascaldefn = FALSE;
  147. sp->init = 0;
  148. sp->indecltable = 0;
  149. sp->funcparm = 0;
  150. sp->inreg = 0;
  151. sp->staticlabel = FALSE;
  152. sp->value.i = block_nesting;
  153. insert(sp,&lsyms);
  154. newnode = makenode(en_autocon,sp,0);
  155. return newnode;
  156. }
  157. int isintconst(int type)
  158. {
  159. switch (type) {
  160. case en_icon:
  161. case en_lcon:
  162. case en_lucon:
  163. case en_iucon:
  164. case en_ccon:
  165. return 1;
  166. }
  167. return 0;
  168. }
  169. TYP     *nameref(ENODE **node)
  170. /*
  171.  * get an identifier.  If it is followed by parenthesis gather the
  172.  * function parms.  If it is an undefined function declare it as external
  173.  * for now.
  174.  */
  175. {       SYM             *sp;
  176.         TYP             *tp,*tp1;
  177. ENODE *pnode=0,*qnode = 0;
  178. int fn = FALSE;
  179. char buf[100];
  180. strcpy(buf,lastid);
  181. getsym();
  182. /* Get function args */
  183. if (lastst == openpa) {
  184. fn = TRUE;
  185. getsym();
  186. tp1 = gatherparms(&pnode);
  187. sp = funcovermatch(buf,tp1);
  188. if (sp)
  189. tp1->sname = nm = sp->name;
  190. else
  191. #ifdef CPLUSPLUS
  192. if (prm_cplusplus)
  193. tp1->sname = nm = cppmangle(buf,tp1);
  194. else
  195. #endif
  196. tp1->sname = nm = litlate(buf);
  197. }
  198. else {
  199. nm = litlate(buf);
  200. sp = gsearch(nm);
  201. }
  202.         if( sp == 0 ) {
  203. /* No such identifier */
  204.                 if (fn) {
  205. /* External function, put it in the symbol table */
  206. #ifdef CPLUSPLUS
  207. if (prm_cplusplus) 
  208. gensymerror(ERR_NOFUNCMATCH,nm);
  209. else
  210. #endif
  211. gensymerror(ERR_NOPROTO,nm);
  212.                         ++global_flag;
  213. sp = xalloc(sizeof(SYM));
  214.                  sp->name = litlate(nm);
  215. sp->tp = maketype(bt_func,0);
  216. *(sp->tp) = stdfunc;
  217.                         sp->storage_class = sc_externalfunc;
  218. sp->extflag = TRUE;
  219.                         insert(sp,&gsyms);
  220.                         --global_flag;
  221.                         *node = makenode(en_napccon,sp,0);
  222. parmlist(&pnode,tp1,0);
  223. *node = makenode(en_void,*node,pnode);
  224.                         tp = &stdint;
  225. qnode = makenode(en_icon,(char *)-4,0);
  226.                       *node = makenode(en_fcall,qnode,*node);
  227. goodcode |= GF_ASSIGN;
  228.                         }
  229.                 else    {
  230. /* External non-function.  These also get put in the symbol table so that
  231.  * we don't keep spitting errors out but also put an error out
  232.  */
  233. #ifdef CPLUSPLUS
  234. if (prm_cplusplus && asntyp && asntyp->type == bt_ptrfunc) {
  235. sp = funcovermatch(lastid,asntyp);
  236. if (sp)
  237. goto foundsp;
  238. }
  239. #endif
  240. sp = xalloc(sizeof(SYM));
  241.                  sp->name = nm;
  242.                         sp->tp = tp = &stdmatch;
  243. sp->storage_class = sc_external;
  244. insert(sp,&lsyms);
  245. *node = makenode(en_nacon,&undef,0);
  246. gensymerror(ERR_UNDEFINED,nm);
  247.                         tp = deref(node,tp);
  248.                         }
  249.                 }
  250.         else    {
  251. /* If we get here the symbol was already in the table
  252.  */
  253. foundsp:
  254. sp->tp->uflags |= UF_USED;
  255.                 if( (tp = sp->tp) == 0 ) {
  256. /* This lack of type info should never happen */
  257.                         tp = &stdmatch;
  258. *node = makenode(en_nacon,&undef,0);
  259. gensymerror(ERR_UNDEFINED,nm);
  260.                         tp = deref(node,tp);
  261.                         return tp;       /* guard against untyped entries */
  262.                         }
  263.                 switch( sp->storage_class ) {
  264.                         case sc_static:
  265.                         case sc_global:
  266.                         case sc_external:
  267.                         case sc_externalfunc:
  268. case sc_abs:
  269. sp->extflag = TRUE;
  270. if (fn) {
  271. /* make a function node */
  272. if (sp->tp->type == bt_ptrfunc)
  273.                                  *node = makenode(en_nacon,sp,0);
  274. else
  275.                                  *node = makenode(en_napccon,sp,0);
  276. isfunc:
  277. if (sp->tp->type != bt_ptrfunc && sp->tp->type != bt_func && sp->tp->type != bt_ifunc)
  278. generror(ERR_MISMATCH,0,0);
  279. if (sp->tp->type == bt_ptrfunc)
  280. tp = deref(node,tp);
  281. #ifdef CPLUSPLUS
  282. if (prm_cplusplus && !strcmp(buf,"main"))
  283. generror(ERR_NOMAIN,0,0);
  284. #endif
  285. parmlist(&pnode,tp1,sp->tp);
  286. *node = makenode(en_void,*node,pnode);
  287. qnode = makenode(en_icon,(char *)sp->tp->btp->size,0);
  288.                                   tp = tp->btp;
  289. if (sp->intflag)
  290.                                  *node = makenode(en_intcall,qnode,*node);
  291. else
  292. if (tp->type == bt_union || tp->type == bt_struct) {
  293. if (sp->pascaldefn)
  294.                                  *node = makenode(en_pfcallb,qnode,*node);
  295. else 
  296.                                  *node = makenode(en_fcallb,qnode,*node);
  297. (*node)->size = tp->size;
  298. }
  299. else
  300. if (sp->pascaldefn)
  301.                                *node = makenode(en_pfcall,qnode,*node);
  302. else
  303.                                *node = makenode(en_fcall,qnode,*node);
  304. if (tp)
  305. (*node)->cflags = tp->cflags;
  306. goodcode |= GF_ASSIGN;
  307. }
  308. else
  309. /* otherwise make a node for a regular variable */
  310. if (sp->absflag)
  311.                                  *node = makenode(en_absacon,sp,0);
  312. else
  313. if (sp->tp->type == bt_func || sp->tp->type == bt_ifunc) {
  314. fn = TRUE;
  315.                                  *node = makenode(en_napccon,sp,0);
  316. }
  317. else
  318. if (sp->staticlabel)
  319. *node = makenode(en_nalabcon,(char *)sp->value.i,0);
  320. else
  321.                                  *node = makenode(en_nacon,sp,0);
  322.                                 break;
  323.                         case sc_const:
  324. /* constants and enums */
  325.                                 *node = makenode(en_icon,(char *)sp->value.i,0);
  326. return &stdint;
  327.                         default:        /* auto and any errors */
  328.                                 if( sp->storage_class != sc_auto && sp->storage_class != sc_autoreg) {
  329.                                         gensymerror(ERR_ILLCLASS2,sp->name);
  330. tp = 0;
  331. }
  332. else {
  333. /* auto variables */
  334.   if (sp->storage_class == sc_auto)
  335.                                  *node = makenode(en_autocon,sp,0);
  336. else if (sp->storage_class == sc_autoreg)
  337.                                  *node = makenode(en_autoreg,sp,0);
  338. if (fn)
  339. goto isfunc;
  340. }
  341.                                 break;
  342.                         }
  343. /* dereference if it isn't an array or structure address */
  344. (*node)->cflags = tp->cflags;
  345. /* deref if not an array or if is function parm */
  346.               if(!fn && tp && (tp->val_flag == 0 || (sp->funcparm && tp->type == bt_pointer)))
  347.                         tp = deref(node,tp);
  348. /* and dereference again if it is a refernece variable */
  349. if (tp->type == bt_ref) {
  350. tp = tp->btp;
  351. tp = deref(node,tp);
  352. }
  353.                 }
  354. lastsym = sp;
  355.         return tp;
  356. }
  357. void promote_type(TYP *typ, ENODE **node)
  358. /*
  359.  * Type promotion for casts and function args 
  360.  */
  361. {
  362. switch (typ->type) {
  363. case bt_char:
  364. *node = makenode(en_cb,*node,0);
  365. break;
  366. case bt_unsignedchar:
  367. *node = makenode(en_cub,*node,0);
  368. break;
  369. case bt_enum:
  370. case bt_short:
  371.    *node = makenode(en_cw,*node,0);
  372.    break;
  373. case bt_unsignedshort:
  374.    *node = makenode(en_cuw,*node,0);
  375. break;
  376.    case bt_long:
  377.      *node = makenode(en_cl,*node,0);
  378. break;
  379. case bt_unsigned:
  380. *node = makenode(en_cul,*node,0);
  381.    break;
  382. case bt_float:
  383.    *node = makenode(en_cf,*node,0);
  384. break;
  385. case bt_double:
  386. *node = makenode(en_cd,*node,0);
  387. break;
  388. case bt_longdouble:
  389. *node = makenode(en_cld,*node,0);
  390. break;
  391. default:
  392. *node = makenode(en_cp,*node,0);
  393. break;
  394. }
  395. (*node)->cflags = typ->cflags;
  396. }
  397. TYP *gatherparms( ENODE **node)
  398. /*
  399.  * create a type tree and primary parameter list for a function
  400.  *
  401.  * At this point the parameter list is backwards from what codegen
  402.  * needs!
  403.  */
  404. {
  405. ENODE *ep1 = 0,*ep2=0,**ep3 = &ep1;
  406. TABLE tbl;
  407. SYM **t = &tbl.head,*newt;
  408. TYP *tp;
  409. int ogc = goodcode;
  410. tbl.tail = tbl.head = 0;
  411. goodcode |= DF_FUNCPARMS;
  412. if (lastst == closepa) {
  413. #ifdef CPLUSPLUS
  414. if (prm_cplusplus)
  415. tbl.head=tbl.tail=(SYM *)-1;
  416. else
  417. #endif
  418. tbl.head=tbl.tail = 0;
  419. }
  420. else if (lastst == kw_void)
  421. tbl.head = tbl.tail = (SYM *)-1;
  422. else
  423.   while (lastst != closepa) {
  424. tp = exprnc(&ep2);
  425. if (!tp) {
  426. generror(ERR_EXPREXPECT,0,0);
  427. break;
  428. }
  429. ep2->cflags = tp->cflags;
  430. newt = xalloc(sizeof(SYM));
  431. newt->tp = tp;
  432. newt->next = 0;
  433. newt->name = 0;
  434. *t = newt;
  435. t = &newt->next;
  436. tbl.tail = newt;
  437. *ep3 = makenode(en_void,ep2,0);
  438. ep3 = &(*ep3)->v.p[1];
  439. if (lastst == comma)
  440. getsym();
  441. }
  442. needpunc(closepa,skm_closepa);
  443. tp = maketype(bt_func,0);
  444. tp->btp = &stdint;
  445. tp->lst = tbl;
  446. tp->bits = -1;
  447. tp->startbit = -1;
  448. tp->uflags = UF_DEFINED | UF_USED;
  449. goodcode = ogc;
  450. *node = ep1;
  451. return tp;
  452. }
  453. void checkparmconst(TYP *tp, TYP *tpi)
  454. /*
  455.  * Check the CONST flags for parameters
  456.  */
  457. {
  458. if (tpi->type != bt_pointer && tpi->type != bt_ref)
  459. return;
  460. while ((tp->type == bt_pointer || tp->type == bt_ref)&& !tp->val_flag && (!tpi || tpi->type == bt_pointer || tpi->type == bt_ref)) {
  461. if ((tp->cflags & DF_CONST) && (!tpi || !(tpi->cflags & DF_CONST)))
  462. generror(ERR_MODCONS,0,0);
  463. tp = tp->btp;
  464. tpi = tpi->btp;
  465. }
  466. if ((tp->cflags & DF_CONST) && (!tpi || !(tpi->cflags & DF_CONST)))
  467. generror(ERR_MODCONS,0,0);
  468. }
  469. void parmlist(ENODE **node, TYP *tpi, TYP *tp)
  470. /*
  471.  * take the primary type and node trees, the function argument expectations,
  472.  * and check for type mismatch errors
  473.  *
  474.  * also reverse the primary node tree so the parms will be ready for
  475.  * code generation
  476.  */
  477. {       ENODE    *ep1=0,*ep2=0,*ep3=*node;
  478. SYM *spi=tpi->lst.head,*sp=0;
  479. TYP *tp2;
  480. int matching = FALSE;
  481. if (tp)
  482. sp=tp->lst.head;
  483. if (tp && !sp)
  484. gensymerror(ERR_NOPROTO,tpi->sname);
  485. if (!prm_cplusplus && sp && sp != (SYM *)-1 && sp->tp->type != bt_ellipse)
  486. matching = TRUE;
  487. while (TRUE) {
  488. if (!spi || spi == (SYM *)-1){
  489. if (sp == (SYM *) -1)
  490. break;
  491. if (sp && sp->tp->type != bt_ellipse) 
  492. if (!sp->defalt) 
  493. genfuncerror(ERR_CALLLENSHORT,tpi->sname,0);
  494. else
  495. while (sp && sp != (SYM *)-1) {
  496. if (sp->tp->val_flag && (sp->tp->type == bt_struct || sp->tp->type == bt_union)) {
  497. ep1 = makenode(en_stackblock,sp->defalt,ep1);
  498. sp->defalt->size = sp->tp->size;
  499. }
  500. else
  501.               ep1 = makenode(en_void,sp->defalt,ep1);
  502. sp = sp->next;
  503. }
  504. break;
  505. }
  506. else {
  507. ep2 = ep3->v.p[0];
  508. ep3 = ep3->v.p[1];
  509. if (matching) {
  510. if (!sp || sp == (SYM *)-1) {
  511. genfuncerror(ERR_CALLLENLONG,tpi->sname,0);
  512. break;
  513. }
  514. else {
  515. checkparmconst(spi->tp,sp->tp);
  516. if (!checktype(spi->tp,sp->tp))
  517.    if (isscalar(sp->tp) && isscalar(spi->tp))
  518. promote_type(sp->tp,&ep2);
  519. else
  520. if (sp->tp->type == bt_pointer) {
  521. if (isintconst(ep2->nodetype)) {
  522. if (ep2->v.i != 0)
  523. generror(ERR_NONPORT,0,0);
  524. }
  525. else if (spi->tp->type != bt_pointer)
  526. genfuncerror(ERR_CALLMISMATCH,tpi->sname,sp->name);
  527.   }
  528. else genfuncerror(ERR_CALLMISMATCH,tpi->sname,sp->name);
  529. }
  530. }
  531. }
  532. if (sp && sp->tp->type == bt_ref) {
  533. if (lvalue(ep2)) {
  534. while (castvalue(ep2))
  535. ep2 = ep2->v.p[0];
  536. ep2 = ep2->v.p[0];
  537. }
  538. else {
  539. ENODE *x;
  540. tp2 = sp->tp->btp;
  541. genfuncerror(ERR_TEMPUSED,tpi->sname,sp->name);
  542. ep2 = makenode(en_refassign,dummyvar(tp2->size,tp2),ep2);
  543. }
  544. }
  545. if (spi && spi != (SYM *) -1 && spi->tp->val_flag && (spi->tp->type == bt_struct || spi->tp->type == bt_union)) {
  546. ep1 = makenode(en_stackblock,ep2,ep1);
  547. ep2->size = sp->tp->size;
  548. }
  549. else
  550.              ep1 = makenode(en_void,ep2,ep1);
  551. spi = spi->next;
  552.   if (sp && sp != (SYM *)-1) {
  553. sp = sp->next;
  554.   if (sp && sp->tp->type == bt_ellipse)
  555. matching = FALSE;
  556. }
  557. }
  558. if (tp)
  559. promote_type(tp->btp,&ep1);
  560. else
  561. promote_type(tpi->btp,&ep1);
  562. *node = ep1;
  563. }
  564. int floatrecurse(ENODE *node)
  565. /*
  566.  * Go through a node and see if it will be promoted to type FLOAT
  567.  */
  568. {
  569. if (!node)
  570. return 0;
  571. switch (node->nodetype) {
  572. case en_rcon:
  573. case en_lrcon:
  574. case en_fcon:
  575. case en_doubleref:
  576. case en_longdoubleref:
  577. case en_floatref:
  578. case en_cld:
  579. case en_cd:
  580. case en_cf:
  581. return 1;
  582.                 case en_labcon: case en_trapcall: 
  583.                 case en_nacon:  case en_autocon:  case en_autoreg: case en_nalabcon:
  584.                 case en_l_ref:  case en_tempref: case en_napccon: case en_absacon:
  585. case en_cl: case en_regref:
  586.                 case en_ul_ref:
  587. case en_cul:
  588. case en_cp:
  589.                 case en_icon:
  590. case en_lcon: case en_iucon: case en_lucon: case en_ccon:
  591. case en_bits:
  592.                 case en_ub_ref:
  593. case en_cub:
  594.                 case en_b_ref:
  595. case en_cb:
  596.                 case en_uw_ref:
  597. case en_cuw:
  598.                 case en_cw:
  599.                 case en_w_ref:
  600.                 case en_eq:     case en_ne:
  601.                 case en_lt:     case en_le:
  602.                 case en_gt:     case en_ge:
  603. case en_ugt: case en_uge: case en_ult: case en_ule:
  604.                         return 0;
  605. case en_fcall: case en_pfcall:
  606. case en_fcallb: case en_pfcallb:
  607. case en_callblock:
  608. return(floatrecurse(node->v.p[1]));
  609.                 case en_not:    case en_compl:
  610.                 case en_uminus: 
  611.                 case en_ainc:   case en_adec:
  612. case en_moveblock: case en_stackblock:
  613.                         return floatrecurse(node->v.p[0]);
  614. case en_refassign: case en_assign:
  615.                 case en_add:    case en_sub:
  616. case en_umul: case en_udiv: case en_umod: case en_pmul:
  617.                 case en_mul:    case en_div:
  618.                 case en_mod:    case en_and:
  619.                 case en_or:     case en_xor:
  620. case en_asalsh: case en_asarsh: case en_alsh: case en_arsh:
  621.                 case en_lsh:    case en_rsh:
  622.                 case en_land:   case en_lor:
  623.                 case en_asadd:  case en_assub:
  624.                 case en_asmul:  case en_asdiv:
  625.                 case en_asmod:  case en_asand:
  626. case en_asumod: case en_asudiv: case en_asumul:
  627.                 case en_asor:   case en_aslsh: case en_asxor:
  628.                 case en_asrsh:
  629.                         return(floatrecurse(node->v.p[0]) || floatrecurse(node->v.p[1]));
  630.                 case en_void:   case en_cond:
  631.                         return floatrecurse(node->v.p[1]);
  632. }
  633. return(0);
  634. }
  635. void floatcheck(ENODE *node)
  636. /*
  637.  * Error if node will be promoted to type float
  638.  */
  639. {
  640. if (floatrecurse(node))
  641. generror(ERR_INVFLOAT,0,0);
  642. }
  643. int     castbegin(int st)
  644. /*
  645.  *      return 1 if st in set of [ kw_char, kw_short, kw_long, kw_int,
  646.  *      kw_float, kw_double, kw_struct, kw_union, kw_float, or is typedef ]
  647.  */
  648. {      
  649. SYM *sp;
  650. switch(st) {
  651. case kw_void:
  652. case kw_char: case kw_short: case kw_int: case kw_long:
  653. case kw_float: case kw_double:
  654. case kw_struct: case kw_union: case kw_signed:
  655. case kw_unsigned: case kw_volatile: case kw_const:
  656. return 1;
  657. default:
  658. if (st != id)
  659. return 0;
  660. nm = lastid;
  661. sp = gsearch(lastid);
  662. if (!sp)
  663. sp = search(lastid,&lsyms);
  664. if (sp && sp->storage_class == sc_type)
  665. return 1 ;
  666. return 0;
  667. }
  668. int tostring()
  669. {
  670. short string[2048];
  671. int st = lastst;
  672. string[0] = 0;
  673. while (lastst == st) {
  674. if (st == lsconst) {
  675. if (pstrlen(string) +pstrlen(laststr) > 2040)
  676. generror(ERR_STRINGTOOBIG,0,0);
  677. else
  678. pstrcat(string,laststr);
  679. }
  680. else {
  681. if (strlen(string) +strlen(laststr) > 4090)
  682. generror(ERR_STRINGTOOBIG,0,0);
  683. else
  684. strcat(string,laststr);
  685. }
  686. getsym();
  687. }
  688. return(stringlit(string,st == lsconst));
  689. }
  690. TYP     *primary(ENODE **node)
  691. /*
  692.  *      primary will parse a primary expression and set the node pointer
  693.  *      returning the type of the expression parsed. primary expressions
  694.  *      are any of:
  695.  *                      id
  696.  *                      constant
  697.  *                      string
  698.  *                      ( expression )
  699.  *                      primary++
  700.  *                      primary--
  701.  *                      primary[ expression ]
  702.  *                      primary.id
  703.  *                      primary->id
  704.  *                      primary( parameter list )
  705.  * (* expression)( parameter list )
  706.  *                      (typecast)primary
  707.  *                      (typecast)(unary)
  708.  */
  709. {       ENODE    *pnode, *qnode, *rnode;
  710.         SYM             *sp=0;
  711.         TYP             *tptr,*tp1,*tp2;
  712. int flag = 0;
  713. int gcode,gdf;
  714. int isstring = FALSE;
  715.         switch( lastst ) {
  716. /* This trap thing should be in stmt.c */
  717. case kw__trap:    
  718. getsym();
  719. if (needpunc(openpa,0)) {
  720. long num = intexpr(0);
  721. if (num > 15 || num < 0)
  722. generror(ERR_INVTRAP,0,0);
  723. if (lastst == comma) 
  724. getsym();
  725. tptr = gatherparms(&pnode);
  726. parmlist(&pnode,tptr,0);
  727. qnode = makenode(en_icon,0,0);
  728. pnode = makenode(en_void,makenode(en_icon,(char *)num,0),pnode);
  729. pnode = makenode(en_trapcall,qnode,pnode);
  730. }
  731. goodcode |= GF_ASSIGN;
  732. *node = pnode;
  733. return &stdint;
  734. case kw_D0:
  735. case kw_D1:
  736. case kw_D2:
  737. case kw_D3:
  738. case kw_D4:
  739. case kw_D5:
  740. case kw_D6:
  741. case kw_D7:
  742. case kw_D8:
  743. case kw_D9:
  744. case kw_DA:
  745. case kw_DB:
  746. case kw_DC:
  747. case kw_DD:
  748. case kw_DE:
  749. case kw_DF:
  750. tptr = xalloc(sizeof(TYP));
  751. *tptr = stduns;
  752. tptr->sname = regname;
  753. pnode = makenode(en_regref,(char *)(regdsize*256+lastst-kw_D0),0);
  754. pnode = makenode(en_ul_ref,pnode,0);
  755. *node = pnode;
  756. getsym();
  757. return tptr;
  758. case kw_A0:
  759. case kw_A1:
  760. case kw_A2:
  761. case kw_A3:
  762. case kw_A4:
  763. case kw_A5:
  764. case kw_A6:
  765. case kw_A7:
  766. case kw_A8:
  767. case kw_A9:
  768. case kw_AA:
  769. case kw_AB:
  770. case kw_AC:
  771. case kw_AD:
  772. case kw_AE:
  773. case kw_AF:
  774. tptr = xalloc(sizeof(TYP));
  775. *tptr = stduns;
  776. tptr->sname = regname;
  777. pnode = makenode(en_regref,(char *)(regasize*256+lastst-kw_D0),0);
  778. pnode = makenode(en_ul_ref,pnode,0);
  779. *node = pnode;
  780. getsym();
  781. return tptr;
  782. case kw_F0:
  783. case kw_F1:
  784. case kw_F2:
  785. case kw_F3:
  786. case kw_F4:
  787. case kw_F5:
  788. case kw_F6:
  789. case kw_F7:
  790. case kw_F8:
  791. case kw_F9:
  792. case kw_FA:
  793. case kw_FB:
  794. case kw_FC:
  795. case kw_FD:
  796. case kw_FE:
  797. case kw_FF:
  798. tptr = xalloc(sizeof(TYP));
  799. *tptr = stdlongdouble;
  800. tptr->sname = regname;
  801. pnode = makenode(en_regref,(char *)(regfsize *256+lastst-kw_D0),0);
  802. pnode = makenode(en_longdoubleref,pnode,0);
  803. *node = pnode;
  804. getsym();
  805. return tptr;
  806.             case id:  
  807.                         tptr = nameref(&pnode);
  808.                         break;
  809.                 case iconst:
  810.                         tptr = &stdint;
  811.                         pnode = makenode(en_icon,(char *)ival,0);
  812.                         getsym();
  813. *node = pnode;
  814. return tptr;
  815.                 case iuconst:
  816.                         tptr = &stduns;
  817.                         pnode = makenode(en_iucon,(char *)ival,0);
  818.                         getsym();
  819. *node = pnode;
  820. return tptr;
  821.                 case lconst:
  822.                         tptr = &stdlong;
  823.                         pnode = makenode(en_lcon,(char *)ival,0);
  824.                         getsym();
  825. *node = pnode;
  826. return tptr;
  827.                 case luconst:
  828.                         tptr = &stdunsigned;
  829.                         pnode = makenode(en_lucon,(char *)ival,0);
  830.                         getsym();
  831. *node = pnode;
  832. return tptr;
  833.                 case cconst:
  834.                         tptr = &stdchar;
  835.                         pnode = makenode(en_ccon,(char *)ival,0);
  836.                         getsym();
  837. *node = pnode;
  838. return tptr;
  839. case rconst:
  840. tptr = &stddouble;
  841.          pnode = xalloc(sizeof(ENODE));
  842.         pnode->nodetype = en_rcon;
  843. pnode->cflags = 0;
  844. pnode->v.f = rval;
  845. getsym();
  846. *node = pnode;
  847. return tptr;
  848. case lrconst:
  849. tptr = &stdlongdouble;
  850.          pnode = xalloc(sizeof(ENODE));
  851.         pnode->nodetype = en_lrcon;
  852. pnode->cflags = 0;
  853. pnode->v.f = rval;
  854. getsym();
  855. *node = pnode;
  856. return tptr;
  857. case fconst:
  858. tptr = &stdfloat;
  859.          pnode = xalloc(sizeof(ENODE));
  860.         pnode->nodetype = en_fcon;
  861. pnode->cflags = 0;
  862. pnode->v.f = rval;
  863. getsym();
  864. *node = pnode;
  865. return tptr;
  866.                 case sconst:
  867. isstring = TRUE;
  868.                         tptr = &stdstring;
  869.                         pnode = makenode(en_labcon,(char *)tostring(),0);
  870. *node = pnode;
  871. break;
  872.                 case lsconst:
  873. isstring = TRUE;
  874.                         tptr = &stdstring;
  875.                         pnode = makenode(en_labcon,(char *)tostring(),0);
  876. *node = pnode;
  877. break;
  878.                 case openpa:
  879.                         getsym();
  880. if (lastst == star) {
  881. /* function pointers */
  882. gcode = goodcode;
  883. goodcode &= ~(GF_AND | GF_SUPERAND);
  884.                                 getsym();
  885. gdf = globaldref;
  886. globaldref = 1;
  887. tptr = expression(&pnode);
  888. globaldref = gdf;
  889. if (needpunc(closepa, skm_closepa)) {
  890. if (tptr->type == bt_ptrfunc) {
  891. tptr = deref(&pnode,tptr);
  892. goodcode = gcode;
  893. if (needpunc(openpa,skm_closepa)) {
  894. goodcode |= GF_ASSIGN;
  895. tp1 = gatherparms(&qnode);
  896. tp1->sname = tptr->sname;
  897. parmlist(&qnode,tp1,tptr);
  898. rnode = makenode(en_icon,(char *)tptr->btp->size,0);
  899. pnode = makenode(en_void,pnode,qnode);
  900. if (tptr->cflags & DF_INT)
  901.                                pnode = makenode(en_intcall,rnode,pnode);
  902. else
  903. if (tptr->type == bt_union || tptr->type == bt_struct) {
  904. if (lastsym && lastsym->pascaldefn)
  905.                                pnode = makenode(en_pfcallb,rnode,pnode);
  906. else
  907.                                pnode = makenode(en_fcallb,rnode,pnode);
  908. pnode->size = tptr->size;
  909. }
  910. else
  911. if (lastsym && lastsym->pascaldefn)
  912.                                pnode = makenode(en_pfcall,rnode,pnode);
  913. else
  914.                                pnode = makenode(en_fcall,rnode,pnode);
  915. pnode->cflags = tptr->btp->cflags;
  916. tptr = tptr->btp;
  917. break;
  918. }
  919. }
  920. else {
  921. goodcode = gcode | (goodcode & GF_ASSIGN);
  922.                         break;
  923.   }
  924. }
  925. else
  926. goodcode = gcode | GF_ASSIGN;
  927. *node = pnode;
  928. return tptr;
  929. }
  930. else
  931. castcont:
  932.                           if( !castbegin(lastst) ) {
  933. /* an expression in parenthesis */
  934. gcode = goodcode;
  935. goodcode &= ~(GF_AND | GF_SUPERAND);
  936. gdf = globaldref;
  937. globaldref = 0;
  938. tptr = expression(&pnode);
  939. globaldref = gdf;
  940. goodcode = gcode | (goodcode & GF_ASSIGN);
  941.                                 needpuncexp(closepa,skm_closepa);
  942. goto contfor;
  943.                                 }
  944.                           else    {       /* cast operator */
  945. /* a cast */
  946. declid[0] = 0;
  947.                                 decl(0); /* do cast declaration */
  948.                                 decl1();
  949.                                 tptr = head;
  950.                                 if (needpunc(closepa, 0)) {
  951. gcode = goodcode;
  952. goodcode &= ~(GF_AND | GF_SUPERAND);
  953. gdf = globaldref;
  954. globaldref = 0;
  955.                                  if( (unary(&pnode)) == 0 ) {
  956.                                         generror(ERR_IDEXPECT,0,0);
  957.                                         tptr = 0;
  958.                                  }
  959. globaldref = gdf;
  960. goodcode = gcode | (goodcode & GF_ASSIGN);
  961. pnode->cflags = tptr->cflags;
  962. if (tptr) {
  963. promote_type(tptr, &pnode);
  964. }
  965. }
  966. else
  967. return(0);
  968. }
  969. *node = pnode;
  970. return tptr;
  971.                 default:
  972.                         return 0;
  973.                 }
  974. contfor:
  975. /* modifiers that can appear after an expression */
  976.         for(;;) {
  977. int i;
  978.                 switch( lastst ) {
  979.                         case autoinc:
  980. case autodec:
  981. if (isstring)
  982. generror(ERR_INVALIDSTRING,0,0);
  983.                                 if( tptr->type == bt_pointer )
  984.                                         i = tptr->btp->size;
  985.                                 else
  986.                                         i = 1;
  987. if (i == 0)
  988. generror(ERR_ZEROPTR,0,0);
  989.                                 if(! lvalue(pnode) ) 
  990.                                   generror(ERR_LVALUE,0,0);
  991. if (pnode->cflags & DF_CONST)
  992. generror(ERR_MODCONS,0,0);
  993.                                 pnode = makenode(lastst==autoinc ? en_ainc : en_adec,pnode,(char *)i);
  994. goodcode |= GF_ASSIGN;
  995.                                 getsym();
  996. break;
  997.                         case openbr:    /* build a subscript reference */
  998. flag = 1;
  999.                                 if( tptr->type != bt_pointer )
  1000.                                         generrorexp(ERR_NOPOINTER,0,skm_closebr);
  1001.                                 else
  1002.                                         tptr = tptr->btp;
  1003.                                 getsym();
  1004.                                 qnode = makenode(en_icon,(char *)tptr->size,0);
  1005. gcode = goodcode;
  1006. goodcode &= ~(GF_AND | GF_SUPERAND);
  1007. gdf = globaldref;
  1008. globaldref = 0;
  1009. tp2 = expression(&rnode);
  1010. globaldref = gdf;
  1011. goodcode = gcode & ~GF_ASSIGN;
  1012. if (!isscalar(tp2) || tp2->type == bt_float || tp2->type == bt_double || tp2->type == bt_longdouble)
  1013.                                   generror(ERR_ARRAYMISMATCH,0,0);
  1014.                                 qnode = makenode(en_pmul,qnode,rnode);
  1015.                                 pnode = makenode(en_add,pnode,qnode);
  1016. pnode->cflags = tptr->cflags;
  1017.                                 if( tptr->val_flag == 0 )
  1018.                                         tptr = deref(&pnode,tptr);
  1019.                                 needpuncexp(closebr,skm_closebr);
  1020.                              break;
  1021.                         case pointsto: /* pointer reference */
  1022.                                 if( tptr->type != bt_pointer ) {
  1023.                                         generror(ERR_NOPOINTER,0,0);
  1024. while (lastst == pointsto || lastst == dot) {
  1025. getsym();
  1026. getsym();
  1027. }
  1028. break;
  1029. }
  1030.                                 else
  1031.                                         tptr = tptr->btp;
  1032. pnode->cflags = tptr->cflags;
  1033.                                 if( tptr->val_flag == 0 ) {
  1034.                                         pnode = makenode(en_l_ref,pnode,0);
  1035. pnode->cflags = tptr->cflags;
  1036. }
  1037. /*
  1038.  *      fall through to dot operation
  1039.  */
  1040.                         case dot:
  1041. if (isstring)
  1042. generror(ERR_INVALIDSTRING,0,0);
  1043.                                 getsym();       /* past -> or . */
  1044.                                 if( lastst != id )
  1045.                                         generror(ERR_IDEXPECT,0,0);
  1046.                                 else    {
  1047.                                         sp = search(nm=litlate(lastid),&tptr->lst);
  1048.                                         if( sp == 0 ) {
  1049.                          tptr = &stdmatch;
  1050. pnode = makenode(en_nacon,&undef,0);
  1051.                                                 gensymerror(ERR_UNDEFINED,nm);
  1052. getsym();
  1053. while (lastst == pointsto || lastst == dot) {
  1054. getsym();
  1055. getsym();
  1056. }
  1057. }
  1058.                                         else    {
  1059.                                                 tp2 = sp->tp;
  1060. if (pnode->nodetype == en_fcallb || pnode->nodetype == en_pfcallb) {
  1061. if (pnode->nodetype == en_pfcallb) 
  1062. pnode = makenode(en_pcallblock,dummyvar(pnode->size,tp2),pnode);
  1063. else
  1064. pnode = makenode(en_callblock,dummyvar(pnode->size,tp2),pnode);
  1065. }
  1066.                                                 qnode = makenode(en_icon,(char *)sp->value.i,0);
  1067.                                                 pnode = makenode(en_add,pnode,qnode);
  1068. pnode->cflags = tptr->cflags | pnode->v.p[0]->cflags;
  1069. tp2->uflags |= tptr->uflags;
  1070. tptr = tp2; 
  1071.                                                 if( tptr->val_flag == 0 )
  1072.                                                     tptr = deref(&pnode,tptr);
  1073. if (tp2->bits != -1) {
  1074. qnode = pnode;
  1075. pnode = makenode(en_bits,qnode,0);
  1076. pnode->bits = tp2->bits;
  1077. pnode->startbit = tp2->startbit;
  1078. pnode->cflags = tptr->cflags | pnode->v.p[0]->cflags;
  1079. }
  1080.                                         }
  1081.                                         getsym();       /* past id */
  1082.                                 }
  1083.                                 break;
  1084.                         case openpa:    /* function reference */
  1085. /* this SHOULD have been handled in nameref rather than here.  However
  1086.  * there are some weird cases like putting function names in parenthesis
  1087.  * or in hook expressions, so this has to be here too.
  1088.  */
  1089. flag = 1;
  1090. if (isstring)
  1091. generror(ERR_INVALIDSTRING,0,0);
  1092.                                 if( tptr->type != bt_func &&
  1093.                                         tptr->type != bt_ifunc && tptr->type != bt_ptrfunc) {
  1094.                                         gensymerrorexp(ERR_NOFUNC,nm);
  1095. expskim(skm_closepa);
  1096. }
  1097.                                 else {
  1098. #ifdef CPLUSPLUS
  1099. if (prm_cplusplus && !strcmp(nm,"main"))
  1100. generror(ERR_NOMAIN,0,0);
  1101. #endif
  1102. if (!sp && tptr->sname)
  1103. sp=gsearch(tptr->sname);
  1104. if (tptr->type == bt_ptrfunc)
  1105. tptr = deref(&pnode,tptr);
  1106.                                  getsym();
  1107. tp1 =gatherparms(&qnode);
  1108. parmlist(&qnode,tp1,tptr);
  1109. rnode = makenode(en_icon,(char *)tptr->btp->size,0);
  1110. pnode = makenode(en_void,pnode,qnode);
  1111.                                         tptr = tptr->btp;
  1112. if (sp && sp->intflag)
  1113.                                  pnode = makenode(en_intcall,rnode,pnode);
  1114. else
  1115. if (tptr->type == bt_union || tptr->type == bt_struct) {
  1116. if (lastsym && lastsym->pascaldefn)
  1117.                                pnode = makenode(en_pfcallb,rnode,pnode);
  1118. else
  1119.                                pnode = makenode(en_fcallb,rnode,pnode);
  1120. pnode->size = tptr->size;
  1121. }
  1122. else
  1123. if (lastsym && lastsym->pascaldefn)
  1124.                                pnode = makenode(en_pfcall,rnode,pnode);
  1125. else
  1126.                                pnode = makenode(en_fcall,rnode,pnode);
  1127. if (tptr)
  1128. pnode->cflags = tptr->cflags;
  1129. }
  1130. goodcode |= GF_ASSIGN;
  1131.                                 break;
  1132.                         default:
  1133.                                 goto fini;
  1134.                         }
  1135.                 }
  1136. fini:   *node = pnode;
  1137. /* symbol level error checking */
  1138. if (!flag && !isstring && !(goodcode & GF_AND) && lastsym && tptr->type != bt_func && tptr->type != bt_ifunc
  1139. &&!tptr->val_flag && lastsym->storage_class != sc_type 
  1140. && lastsym->storage_class != sc_static && lastsym->storage_class != sc_global
  1141. && lastsym->storage_class != sc_external && lastsym->storage_class != sc_externalfunc) {
  1142. if (!(lastsym->tp->uflags & UF_DEFINED) && lastst != assign
  1143. &&lastst != asplus && lastst != asminus && lastst != astimes
  1144. && lastst!= asdivide && lastst != asmodop && lastst != asrshift
  1145. && lastst != aslshift && lastst != asor && lastst != asxor && lastst != asand) {
  1146. gensymerror(ERR_SYMUNDEF,lastsym->name);
  1147. lastsym->tp->uflags |= UF_DEFINED;
  1148. }
  1149. lastsym->tp->uflags &=  ~UF_ASSIGNED;
  1150. }
  1151.         return tptr;
  1152. }
  1153. int castvalue(ENODE *node)
  1154. /*
  1155.  * See if this is a cast operator */
  1156. {
  1157. switch(node->nodetype) {
  1158. case en_cb: case en_cub: case en_bits:
  1159. case en_cw: case en_cuw:
  1160. case en_cl: case en_cul:
  1161. case en_cf: case en_cd: case en_cp: case en_cld:
  1162.                         return 1;
  1163.                 }
  1164.         return 0;
  1165. }
  1166. int     lvalue(ENODE *node)
  1167. /* See if this is an lvalue; that is has it been dereferenced?
  1168.  */
  1169. {       
  1170. if (!prm_cplusplus) {
  1171. while (castvalue(node))
  1172. node = node->v.p[0];
  1173. }
  1174. switch( node->nodetype ) {
  1175.                 case en_b_ref:
  1176.                 case en_w_ref:
  1177.                 case en_l_ref:
  1178.                 case en_ub_ref:
  1179.                 case en_uw_ref:
  1180.                 case en_ul_ref:
  1181. case en_floatref:
  1182. case en_doubleref:
  1183. case en_longdoubleref:
  1184.                         return 1;
  1185. case en_bits:
  1186.                         return lvalue(node->v.p[0]);
  1187.                 }
  1188.         return 0;
  1189. }
  1190. TYP     *unary(ENODE **node)
  1191. /*
  1192.  *      unary evaluates unary expressions and returns the type of the
  1193.  *      expression evaluated. unary expressions are any of:
  1194.  *
  1195.  *                      primary
  1196.  *                      ++unary
  1197.  *                      --unary
  1198.  *                      !unary
  1199.  *                      ~unary
  1200.  *                      &unary
  1201.  *                      -unary
  1202.  *                      *unary
  1203.  *                      sizeof(typecast)
  1204.  *
  1205.  */
  1206. {       TYP             *tp,*tp1;
  1207.         ENODE    *ep1, *ep2;
  1208.         int             flag, i,gdf;
  1209.         flag = 0;
  1210.         switch( lastst ) {
  1211.                 case autodec:
  1212.                         flag = 1;
  1213.                 /* fall through to common increment */
  1214.                 case autoinc:
  1215.                         getsym();
  1216. gdf = globaldref;
  1217. globaldref = 0;
  1218.                         tp = unary(&ep1);
  1219. globaldref = gdf;
  1220.                         if( tp == 0 ) {
  1221.                                 generror(ERR_IDEXPECT,0,0);
  1222.                                 return 0;
  1223.                                 }
  1224. goodcode |= GF_ASSIGN;
  1225.                         if( lvalue(ep1)) {
  1226.                                 if( tp->type == bt_pointer ) {
  1227. if (tp->btp->size == 0)
  1228. generror(ERR_ZEROPTR,0,0);
  1229.                                         ep2 = makenode(en_icon,(char *)tp->btp->size,0);
  1230. }
  1231.                                 else
  1232.                                         ep2 = makenode(en_icon,(char *)1,0);
  1233. if (ep1->cflags & DF_CONST)
  1234. generror(ERR_MODCONS,0,0);
  1235.                                 ep1 = makenode(flag ? en_assub : en_asadd,ep1,ep2);
  1236.                                 }
  1237.                         else {
  1238.                                 generror(ERR_LVALUE,0,0);
  1239. return(0);
  1240. }
  1241.                         break;
  1242.                 case minus:
  1243. case plus: {
  1244. int stt = lastst;
  1245.                         getsym();
  1246. gdf = globaldref;
  1247. globaldref = 0;
  1248.                         tp = unary(&ep1);
  1249. globaldref = gdf;
  1250. goodcode &= ~GF_ASSIGN;
  1251.                         if( tp == 0 ) {
  1252.                                 generror(ERR_IDEXPECT,0,0);
  1253.                                 return 0;
  1254.                                 }
  1255. if (stt == minus) 
  1256.                          ep1 = makenode(en_uminus,ep1,0);
  1257. }
  1258.                         break;
  1259.                 case not:
  1260.                         getsym();
  1261. gdf = globaldref;
  1262. globaldref = 0;
  1263.                         tp = unary(&ep1);
  1264. globaldref = gdf;
  1265. goodcode &= ~GF_ASSIGN;
  1266.                         if( tp == 0 ) {
  1267.                                 generror(ERR_IDEXPECT,0,0);
  1268.                                 return 0;
  1269.                                 }
  1270.                         ep1 = makenode(en_not,ep1,0);
  1271.                         break;
  1272.                 case compl:
  1273.                         getsym();
  1274. gdf = globaldref;
  1275. globaldref = 0;
  1276.                         tp = unary(&ep1);
  1277. globaldref = gdf;
  1278. goodcode &= ~GF_ASSIGN;
  1279.                         if( tp == 0 ) {
  1280.                                 generror(ERR_IDEXPECT,0,0);
  1281.                                 return 0;
  1282.                                 }
  1283. floatcheck(ep1);
  1284.                         ep1 = makenode(en_compl,ep1,0);
  1285.                         break;
  1286.                 case star:
  1287.                         getsym();
  1288. gdf = globaldref;
  1289. globaldref = 0;
  1290.                         tp = unary(&ep1);
  1291. globaldref = gdf;
  1292. goodcode &= ~GF_ASSIGN;
  1293.                         if( tp == 0 ) {
  1294.                                 generror(ERR_IDEXPECT,0,0);
  1295.                                 return 0;
  1296.                                 }
  1297.                         if( tp->btp == 0 ) {
  1298.                                 generror(ERR_DEREF,0,0);
  1299. }
  1300.                         else
  1301. if (tp->btp->type != bt_void)
  1302.                                 tp = tp->btp;
  1303. ep1->cflags = tp->cflags;
  1304.                         if( tp->val_flag == 0 )
  1305.                                 tp = deref(&ep1,tp);
  1306.                         break;
  1307.                 case and:
  1308.                         getsym();
  1309. if (!(goodcode & GF_INFUNCPARMS))
  1310. goodcode |= GF_AND;
  1311. gdf = globaldref;
  1312. globaldref = 0;
  1313.                         tp = unary(&ep1);
  1314. globaldref = gdf;
  1315. goodcode &= ~GF_AND;
  1316. goodcode &= ~GF_ASSIGN;
  1317.                         if( tp == 0 ) {
  1318.                                 generror(ERR_IDEXPECT,0,0);
  1319.                                 return 0;
  1320.                                 }
  1321. else 
  1322. if (tp->startbit != -1) 
  1323. generror(ERR_BFADDR,0,0);
  1324. else if (tp->cflags & DF_AUTOREG)
  1325. gensymerror(ERR_NOANDREG,tp->sname);
  1326. else if (tp->type == bt_pointer && tp->val_flag && !(goodcode & GF_SUPERAND))
  1327. generror(ERR_SUPERAND,0,0);
  1328.                         if( lvalue(ep1)) {
  1329.                                 ep1 = ep1->v.p[0];
  1330.   if (ep1->nodetype == en_regref)
  1331. gensymerror(ERR_NOANDREG,tp->sname);
  1332. }
  1333.                         tp1 = xalloc(sizeof(TYP));
  1334.                         tp1->size = 4;
  1335.                         tp1->type = bt_pointer;
  1336.                         tp1->btp = tp;
  1337.                         tp1->val_flag = 0;
  1338.                         tp1->lst.head = 0;
  1339.                         tp1->sname = 0;
  1340. tp = tp1;
  1341. break;
  1342.                 case kw_sizeof:
  1343.                         getsym();
  1344.                         needpunc(openpa,0);
  1345. if (castbegin(lastst)) {
  1346. sizeof_cast:
  1347.                          decl(0);
  1348. decl1();
  1349. }
  1350. else if (lastst == id) {
  1351. SYM *sp = gsearch(lastid);
  1352. if (!sp)
  1353. sp = search(lastid,&lsyms);
  1354. if (sp) {
  1355. goto sizeof_primary;
  1356. }
  1357. if ((sp = search(nm,&tagtable)) != 0) {
  1358. head = sp->tp;
  1359. getsym();
  1360. }
  1361. else {
  1362. generror(ERR_SIZE,0,0);
  1363. head = 0;
  1364. }
  1365. }
  1366. else if (lastst == kw_enum) {
  1367. getsym();
  1368. if (lastst == id) {
  1369. SYM *sp;
  1370. if ((sp = search(nm,&tagtable)) != 0) {
  1371. head = sp->tp;
  1372. getsym();
  1373. }
  1374. else goto sizeof_primary;
  1375. }
  1376. }
  1377. else  {
  1378. ENODE *node = 0;
  1379. sizeof_primary:
  1380. head = unary(&node);
  1381. }
  1382.                         if( head != 0 ) {
  1383. if (head->size == 0)
  1384. generror(ERR_SIZE,0,0);
  1385.                                 ep1 = makenode(en_icon,(char *)head->size,0);
  1386. }
  1387.                         else    {
  1388.                                 generror(ERR_IDEXPECT,0,0);
  1389.                                 ep1 = makenode(en_icon,(char *)0,0);
  1390.                                 }
  1391. goodcode &= ~GF_ASSIGN;
  1392.                         tp = &stdint;
  1393.                         needpunc(closepa,0);
  1394.                         break;
  1395.                 default:
  1396.                         tp = primary(&ep1);
  1397.                         break;
  1398.                 }
  1399. /* Dereference if necessary */
  1400. if (globaldref) {
  1401. globaldref = 0;
  1402. if (tp->type != bt_ptrfunc) {
  1403.   if( tp == 0 ) {
  1404.                generror(ERR_IDEXPECT,0,0);
  1405.        return 0;
  1406.           }
  1407. if( tp->btp == 0 ) {
  1408.        generror(ERR_DEREF,0,0);
  1409. }
  1410. else
  1411. if (tp->btp->type != bt_void)
  1412.           tp = tp->btp;
  1413. ep1->cflags = tp->cflags;
  1414.           if( tp->val_flag == 0 )
  1415.              tp = deref(&ep1,tp);
  1416. }
  1417. }
  1418.         *node = ep1;
  1419.         return tp;
  1420. }
  1421. TYP *maxsize(TYP *tp1, TYP *tp2)
  1422. /*
  1423.  * return the type that has the maximum size
  1424.  */
  1425. {
  1426. if (tp1->type > tp2->type)
  1427. return tp1;
  1428. return tp2;
  1429. }
  1430. TYP     *forcefit(ENODE **node1,TYP *tp1,ENODE **node2,TYP *tp2, int max, int allowpointers)
  1431. /*
  1432.  * compare two types and determine if they are compatible for purposes
  1433.  * of the current operation.  Return an appropriate type.  Also checks for
  1434.  * dangerous pointer conversions...
  1435.  */
  1436. { int error = ERR_MISMATCH;
  1437. TYP *tp3;
  1438.         switch( tp1->type ) {
  1439. case bt_void:
  1440. if (tp2->type != bt_void && tp2->type != bt_matchall)
  1441. break;
  1442. return tp1;
  1443.                 case bt_long:
  1444. if (isintconst((*node2)->nodetype)) {
  1445. if (isscalar(tp2) || (!prm_cplusplus && (tp2->type == bt_pointer || tp2 ->type == bt_ptrfunc)))
  1446. return tp2;
  1447. if (tp2->type != bt_matchall)
  1448. break;
  1449. }
  1450.                 case bt_matchall:
  1451.                         if( tp2->type == bt_matchall)
  1452. return(&stdint);
  1453.                         else if( tp2->type == bt_pointer)
  1454.                           return tp2;
  1455. else if  (allowpointers && (tp2->type == bt_pointer || tp2->type == bt_ptrfunc))
  1456. return &stdint;
  1457. else if (isscalar(tp2))
  1458. if (max)
  1459. return(maxsize(tp1,tp2));
  1460. else
  1461. return(tp1);
  1462.                         break;
  1463.                 case bt_pointer:
  1464. if (!prm_cplusplus && !max && (tp2->type == bt_short || tp2->type == bt_unsignedshort
  1465. || tp2->type == bt_char || tp2->type == bt_unsignedchar)) {
  1466. error = ERR_SHORTPOINTER;
  1467. break;
  1468. }
  1469.                         if( tp2->type == bt_pointer ||tp2->type == bt_ptrfunc) {
  1470.    if  (allowpointers) {
  1471.    while (tp1->type == bt_pointer && tp2->type == bt_pointer) {
  1472. tp1 = tp1->btp;
  1473. tp2 = tp2->btp;
  1474. }
  1475. if (tp1->type != tp2 ->type || tp1->size != tp2->size)
  1476. if (tp1->type != bt_void && tp2->type != bt_void)
  1477. generror(ERR_SUSPICIOUS,0,0);
  1478.   return &stdint;
  1479. }
  1480. else
  1481.                             return tp1;
  1482. }
  1483. if (!prm_cplusplus && isscalar(tp2))
  1484. if (max)
  1485. return(maxsize(tp1,tp2));
  1486. else
  1487. return(tp1);
  1488.                         break;
  1489. case bt_enum:
  1490.                 case bt_unsignedshort:
  1491.                 case bt_short:
  1492. if (isintconst((*node2)->nodetype)) {
  1493. if (!max && ((*node2)->v.i < -65536L || ((*node2)->v.i > 65535L))) {
  1494. error = ERR_LOSTCONV;
  1495. break;
  1496. }
  1497. return tp1;
  1498. }
  1499. else
  1500.   if (!max && (tp2->type == bt_long || tp2->type == bt_unsigned || (!prm_cplusplus && (tp2->type == bt_pointer) || tp2->type == bt_ptrfunc))) {
  1501.   error = ERR_LOSTCONV;
  1502.     break;
  1503. }
  1504.   if  (allowpointers && tp2->type == bt_pointer)
  1505. return &stdint;
  1506. else if (isscalar(tp2))
  1507. if (max)
  1508. return(maxsize(tp1,tp2));
  1509. else
  1510. return(tp1);
  1511. break;
  1512.                 case bt_char:
  1513.                 case bt_unsignedchar:
  1514. if (isintconst((*node2)->nodetype)) {
  1515. if (!max && ((*node2)->v.i < -256 || ((*node2)->v.i > 255))) {
  1516. error = ERR_LOSTCONV;
  1517. break;
  1518. }
  1519. return tp1;
  1520. }
  1521. else
  1522.   if (!max && (tp2->type == bt_long || tp2->type == bt_unsigned || ( !prm_cplusplus && tp2->type == bt_pointer)
  1523.   || tp2->type == bt_short || tp2->type == bt_unsignedshort)) {
  1524.   error = ERR_LOSTCONV;
  1525.     break;
  1526. }
  1527.   if  (allowpointers && (tp2->type == bt_pointer || tp2->type == bt_ptrfunc))
  1528. return &stdint;
  1529. else if (isscalar(tp2))
  1530. if (max)
  1531. return(maxsize(tp1,tp2));
  1532. else
  1533. return(tp1);
  1534. break;
  1535. case bt_float:
  1536. case bt_double:
  1537. case bt_longdouble:
  1538. if (isscalar(tp2))
  1539. return(tp1);
  1540. break;
  1541.                 case bt_unsigned:
  1542. if (isintconst((*node1)->nodetype)) {
  1543. if (isscalar(tp2) || (!prm_cplusplus && tp2->type == bt_pointer))
  1544. return tp2;
  1545. break;
  1546. }
  1547.                         if( !prm_cplusplus && (tp2->type == bt_pointer  || tp2->type == bt_ptrfunc))
  1548.    if  (allowpointers)
  1549. return &stdint;
  1550. else
  1551. return tp2;
  1552.   if (isscalar(tp2))
  1553.                           return tp2;
  1554.                         break;
  1555. case bt_ptrfunc:
  1556. if (!prm_cplusplus && (tp2->type == bt_short || tp2->type == bt_unsignedshort
  1557. || tp2->type == bt_char || tp2->type == bt_unsignedchar)) {
  1558. error = ERR_SHORTPOINTER;
  1559. break;
  1560. }
  1561. if (tp2->type == bt_pointer)
  1562. tp3 = tp2->btp;
  1563. else
  1564. tp3 = tp2;
  1565. if (tp3->type == bt_func || tp3->type == bt_ifunc || tp3->type == bt_ptrfunc
  1566. || (!prm_cplusplus && tp2->type == bt_pointer))
  1567.    if  (allowpointers)
  1568.   return &stdint;
  1569. else
  1570.                             return tp1;
  1571. break;
  1572. case bt_func:
  1573. case bt_ifunc:
  1574. if (tp2->type == bt_func || tp2->type == bt_ifunc)
  1575. return tp1;
  1576. break;
  1577.                 }
  1578. #ifdef CPLUSPLUS
  1579. if (error == ERR_MISMATCH && prm_cplusplus)
  1580. genmismatcherror(tp2,tp1);
  1581. else
  1582. #endif
  1583.          generror( error,0,0 );
  1584.         return tp1;
  1585. }
  1586. int     isscalar(TYP *tp)
  1587. /*
  1588.  * this is misnamed... it checks for ANY basic numeric type
  1589.  */
  1590. {       return  tp->type == bt_char ||  tp->type == bt_unsignedchar ||
  1591.                 tp->type == bt_short || tp->type == bt_unsignedshort ||
  1592.                 tp->type == bt_long || tp->type == bt_unsigned || tp->type == bt_enum
  1593. || tp->type == bt_float || tp->type == bt_double || tp->type == bt_longdouble;
  1594. }
  1595. void checknp(TYP *tp1,TYP*tp2,ENODE *ep1, ENODE *ep2)
  1596. /*
  1597.  * look for non-portable pointer conversions
  1598.  */
  1599. {
  1600. #ifdef CPLUSPLUS
  1601. if (prm_cplusplus)
  1602. return;
  1603. #endif
  1604. if (tp1->type == bt_pointer || tp2->type == bt_pointer)
  1605. if (tp1->type != tp2->type) 
  1606. if ((!isintconst(ep1->nodetype) || ep1->v.i != 0) && (!isintconst(ep2->nodetype) || ep2->v.i != 0))
  1607. generror(ERR_NONPORT,0,0);
  1608. }
  1609. TYP     *multops(ENODE **node)
  1610. /*
  1611.  *      multops parses the multiply priority operators. the syntax of
  1612.  *      this group is:
  1613.  *
  1614.  *              unary
  1615.  *              multop * unary
  1616.  *              multop / unary
  1617.  *              multop % unary
  1618.  */
  1619. {       ENODE    *ep1, *ep2;
  1620.         TYP             *tp1, *tp2;
  1621.         int       oper;
  1622.         tp1 = unary(&ep1);
  1623.         if( tp1 == 0 )
  1624.                 return 0;
  1625.         while( lastst == star || lastst == divide || lastst == modop ) {
  1626.                 oper = lastst;
  1627.                 getsym();       /* move on to next unary op */
  1628.                 tp2 = unary(&ep2);
  1629. goodcode &= ~GF_ASSIGN;
  1630.                 if( tp2 == 0 ) {
  1631.                         generror(ERR_IDEXPECT,0,0);
  1632.                         *node = ep1;
  1633.                         return tp1;
  1634.                         }
  1635.                 tp1 = forcefit(&ep1,tp1,&ep2,tp2,TRUE,FALSE);
  1636.                 switch( oper ) {
  1637.                         case star:
  1638.                                 if( tp1->type == bt_unsigned ||tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
  1639.                                         ep1 = makenode(en_umul,ep1,ep2);
  1640.                                 else
  1641.                                         ep1 = makenode(en_mul,ep1,ep2);
  1642.                                 break;
  1643.                         case divide:
  1644.                                 if( tp1->type == bt_unsigned ||tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
  1645.                                         ep1 = makenode(en_udiv,ep1,ep2);
  1646.                                 else
  1647.                                         ep1 = makenode(en_div,ep1,ep2);
  1648.                                 break;
  1649.                         case modop:
  1650.                                 if( tp1->type == bt_unsigned ||tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
  1651.                                         ep1 = makenode(en_umod,ep1,ep2);
  1652.                                 else
  1653.                                         ep1 = makenode(en_mod,ep1,ep2);
  1654. floatcheck(ep1);
  1655.                                 break;
  1656.                         }
  1657.                 }
  1658.         *node = ep1;
  1659.         return tp1;
  1660. }
  1661. TYP     *addops(ENODE **node)
  1662. /*
  1663.  *      addops handles the addition and subtraction operators.
  1664.  */
  1665. {       ENODE    *ep1, *ep2, *ep3;
  1666.         TYP             *tp1, *tp2;
  1667.         int             oper;
  1668.         tp1 = multops(&ep1);
  1669.         if( tp1 == 0 )
  1670.                 return 0;
  1671.         while( lastst == plus || lastst == minus ) {
  1672.                 oper = (lastst == plus);
  1673.                 getsym();
  1674.                 tp2 = multops(&ep2);
  1675. goodcode &= ~GF_ASSIGN;
  1676.                 if( tp2 == 0 ) {
  1677.                         generror(ERR_IDEXPECT,0,0);
  1678.                         *node = ep1;
  1679.                         return tp1;
  1680.                         }
  1681.                 if( tp1->type == bt_pointer ) {
  1682. if (tp2->type == bt_pointer) {
  1683.                  forcefit(&ep1,tp1,&ep2,tp2,TRUE,FALSE);
  1684.                  ep1 = makenode( oper ? en_add : en_sub,ep1,ep2);
  1685. ep1->cflags = ep1->v.p[0]->cflags | ep2->cflags;
  1686. if (tp1->btp->size == 0)
  1687. generror(ERR_ZEROPTR,0,0);
  1688. else
  1689. if (tp1->btp->size > 1)
  1690. ep1 = makenode(en_pdiv,ep1,makenode(en_icon,(char *)tp1->btp->size,0));
  1691. ep1->cflags = ep1->v.p[0]->cflags;
  1692.     tp1 = &stdint;
  1693. continue;
  1694. }
  1695. else {
  1696.                         tp2 = forcefit(0,&stdint,&ep2,tp2,TRUE,FALSE);
  1697. if (tp1->btp->size == 0)
  1698. generror(ERR_ZEROPTR,0,0);
  1699.                         ep3 = makenode(en_icon,(char *)tp1->btp->size,0);
  1700.                         ep2 = makenode(en_pmul,ep3,ep2);
  1701. ep2->cflags = ep2->v.p[1]->cflags;
  1702.                         }
  1703. }
  1704.                 else if( tp2->type == bt_pointer ) {
  1705.                         tp1 = forcefit(0,&stdint,&ep1,tp1,TRUE,FALSE);
  1706. if (tp2->btp->size == 0)
  1707. generror(ERR_ZEROPTR,0,0);
  1708.                         ep3 = makenode(en_icon,(char *)tp2->btp->size,0);
  1709.                         ep1 = makenode(en_pmul,ep3,ep1);
  1710. ep1->cflags = ep1->v.p[1]->cflags;
  1711.                         }
  1712.                 tp1 = forcefit(&ep1,tp1,&ep2,tp2,TRUE,FALSE);
  1713.                 ep1 = makenode( oper ? en_add : en_sub,ep1,ep2);
  1714. ep1->cflags = ep1->v.p[1]->cflags | ep2->cflags;
  1715.                 }
  1716. exit:
  1717.         *node = ep1;
  1718.         return tp1;
  1719. }
  1720. TYP     *shiftop(ENODE **node)
  1721. /*
  1722.  *      shiftop handles the shift operators << and >>.
  1723.  */
  1724. {       ENODE    *ep1, *ep2;
  1725.         TYP             *tp1, *tp2;
  1726.         int             oper;
  1727.         tp1 = addops(&ep1);
  1728.         if( tp1 == 0)
  1729.                 return 0;
  1730.         while( lastst == lshift || lastst == rshift) {
  1731.                 oper = (lastst == lshift);
  1732.                 getsym();
  1733.                 tp2 = addops(&ep2);
  1734. goodcode &= ~GF_ASSIGN;
  1735.                 if( tp2 == 0 )
  1736.                         generror(ERR_IDEXPECT,0,0);
  1737.                 else    {
  1738.                         tp1 = forcefit(&ep1,tp1,&ep2,tp2,TRUE,FALSE);
  1739. if (tp1->type == bt_unsigned ||
  1740. tp1->type == bt_unsignedchar ||
  1741. tp1->type == bt_unsignedshort)
  1742.                          ep1 = makenode(oper ? en_lsh : en_rsh,ep1,ep2);
  1743. else
  1744.                          ep1 = makenode(oper ? en_alsh : en_arsh,ep1,ep2);
  1745.                         }
  1746. floatcheck(ep1);
  1747.                 }
  1748.         *node = ep1;
  1749.         return tp1;
  1750. }
  1751. TYP     *relation(ENODE **node)
  1752. /*
  1753.  *      relation handles the relational operators < <= > and >=.
  1754.  */
  1755. {       ENODE    *ep1, *ep2;
  1756.         TYP             *tp1, *tp2;
  1757.         int             nt;
  1758.         tp1 = shiftop(&ep1);
  1759.         if( tp1 == 0 )
  1760.                 return 0;
  1761.         for(;;) {
  1762.                 switch( lastst ) {
  1763.                         case lt:
  1764.                                 if( tp1->type == bt_unsigned || tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
  1765.                                         nt = en_ult;
  1766.                                 else
  1767.                                         nt = en_lt;
  1768.                                 break;
  1769.                         case gt:
  1770.                                 if( tp1->type == bt_unsigned || tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
  1771.                                         nt = en_ugt;
  1772.                                 else
  1773.                                         nt = en_gt;
  1774.                                 break;
  1775.                         case leq:
  1776.                                 if( tp1->type == bt_unsigned || tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
  1777.                                         nt = en_ule;
  1778.                                 else
  1779.                                         nt = en_le;
  1780.                                 break;
  1781.                         case geq:
  1782.                                 if( tp1->type == bt_unsigned || tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
  1783.                                         nt = en_uge;
  1784.                                 else
  1785.                                         nt = en_ge;
  1786.                                 break;
  1787.                         default:
  1788.                                 goto fini;
  1789.                         }
  1790.                 getsym();
  1791.                 tp2 = shiftop(&ep2);
  1792. goodcode &= ~GF_ASSIGN;
  1793.                 if( tp2 == 0 )
  1794.                         generror(ERR_IDEXPECT,0,0);
  1795.                 else    {
  1796. checknp(tp1,tp2,ep1,ep2);
  1797.                         tp1 = forcefit(&ep1,tp1,&ep2,tp2,TRUE,TRUE);
  1798.                         ep1 = makenode(nt,ep1,ep2);
  1799.                         }
  1800.                 }
  1801. fini:   *node = ep1;
  1802.         return tp1;
  1803. }
  1804. TYP     *equalops(ENODE **node)
  1805. /*
  1806.  *      equalops handles the equality and inequality operators.
  1807.  */
  1808. {       ENODE    *ep1, *ep2;
  1809.         TYP             *tp1, *tp2;
  1810.         int             oper;
  1811.         tp1 = relation(&ep1);
  1812.         if( tp1 == 0 )
  1813.                 return 0;
  1814.         while( lastst == eq || lastst == neq ) {
  1815.                 oper = (lastst == eq);
  1816.                 getsym();
  1817.                 tp2 = relation(&ep2);
  1818. goodcode &= ~GF_ASSIGN;
  1819. checknp(tp1,tp2,ep1,ep2);
  1820.                 if( tp2 == 0 )
  1821.                         generror(ERR_IDEXPECT,0,0);
  1822.                 else    {
  1823.                         tp1 = forcefit(&ep1,tp1,&ep2,tp2,TRUE,TRUE);
  1824.                         ep1 = makenode( oper ? en_eq : en_ne,ep1,ep2);
  1825.                         }
  1826.                 }
  1827.         *node = ep1;
  1828.         return tp1;
  1829. }
  1830. TYP     *binop(ENODE **node,TYP *(*xfunc)(),int nt,int sy)
  1831. /*
  1832.  *      binop is a common routine to handle all of the legwork and
  1833.  *      error checking for bitand, bitor, bitxor, andop, and orop.
  1834.  */
  1835. {       ENODE    *ep1, *ep2;
  1836.         TYP             *tp1, *tp2;
  1837.         tp1 = (*xfunc)(&ep1);
  1838.         if( tp1 == 0 )
  1839.                 return 0;
  1840.         while( lastst == sy ) {
  1841.                 getsym();
  1842.                 tp2 = (*xfunc)(&ep2);
  1843. goodcode &= ~GF_ASSIGN;
  1844.                 if( tp2 == 0 )
  1845.                         generror(ERR_IDEXPECT,0,0);
  1846.                 else    {
  1847.                         tp1 = forcefit(&ep1,tp1,&ep2,tp2,TRUE,sy == lor || sy == land);
  1848.                         ep1 = makenode(nt,ep1,ep2);
  1849.                         }
  1850. floatcheck(ep1);
  1851.                 }
  1852.         *node = ep1;
  1853.         return tp1;
  1854. }
  1855. TYP     *bitand(ENODE **node)
  1856. /*
  1857.  *      the bitwise and operator...
  1858.  */
  1859. {       return binop(node,equalops,en_and,and);
  1860. }
  1861. TYP     *bitxor(ENODE **node)
  1862. {       return binop(node,bitand,en_xor,uparrow);
  1863. }
  1864. TYP     *bitor(ENODE **node)
  1865. {       return binop(node,bitxor,en_or,or);
  1866. }
  1867. TYP     *andop(ENODE **node)
  1868. {       return binop(node,bitor,en_land,land);
  1869. }
  1870. TYP     *orop(ENODE **node)
  1871. {       return binop(node,andop,en_lor,lor);
  1872. }
  1873. TYP     *conditional(ENODE **node)
  1874. /*
  1875.  *      this routine processes the hook operator.
  1876.  */
  1877. {       TYP             *tp1, *tp2, *tp3;
  1878.         ENODE    *ep1, *ep2, *ep3;
  1879.         tp1 = orop(&ep1);       /* get condition */
  1880.         if( tp1 == 0 )
  1881.                 return 0;
  1882.         if( lastst == hook ) {
  1883. int gcode1,gcode2;
  1884. goodcode &=~GF_ASSIGN;
  1885.                 getsym();
  1886.                 if( (tp2 = conditional(&ep2)) == 0) {
  1887.                         generror(ERR_IDEXPECT,0,0);
  1888. goodcode &= ~GF_ASSIGN;
  1889.                         goto cexit;
  1890.                         }
  1891.                 needpunc(colon,0);
  1892. gcode2 = goodcode;
  1893. goodcode &=~GF_ASSIGN;
  1894.                 if( (tp3 = conditional(&ep3)) == 0) {
  1895.                         generror(ERR_IDEXPECT,0,0);
  1896. goodcode &= ~GF_ASSIGN;
  1897.                         goto cexit;
  1898.                         }
  1899. gcode1 = gcode2 & goodcode;
  1900. goodcode = (goodcode &~GF_ASSIGN) | gcode1;
  1901.                 tp1 = forcefit(&ep2,tp2,&ep3,tp3,TRUE,FALSE);
  1902.                 ep2 = makenode(en_void,ep2,ep3);
  1903.                 ep1 = makenode(en_cond,ep1,ep2);
  1904.                 }
  1905. cexit:
  1906.   *node = ep1;
  1907.         return tp1;
  1908. }
  1909. TYP *autoasnop(ENODE **node, SYM *sp)
  1910. /*
  1911.  *  Handle assignment operators during auto init of local vars
  1912.  */
  1913. {       ENODE    *ep1, *ep2;
  1914.         TYP             *tp1, *tp2;
  1915.         if( (tp1 = sp->tp) == 0 ) {
  1916. tp1 = &stdmatch;
  1917. *node = makenode(en_nacon,&undef,0);
  1918. gensymerror(ERR_UNDEFINED,nm);
  1919.           tp1 = deref(&ep1,tp1);
  1920.           return tp1;       /* guard against untyped entries */
  1921.         }
  1922.         if( sp->storage_class != sc_auto && sp->storage_class != sc_autoreg)
  1923.           gensymerror(ERR_ILLCLASS2,sp->name);
  1924. if (sp->storage_class == sc_auto)
  1925.          ep1 = makenode(en_autocon,sp,0);
  1926. else if (sp->storage_class == sc_autoreg)
  1927.          ep1 = makenode(en_autoreg,sp,0);
  1928. if (tp1) {
  1929. tp1->uflags |= UF_DEFINED | UF_USED;
  1930. }
  1931. if ((tp1->uflags & UF_CANASSIGN) && !(goodcode & GF_INLOOP))
  1932. tp1->uflags |=  UF_ASSIGNED;
  1933.         if( tp1->val_flag == 0)
  1934.           tp1 = deref(&ep1,tp1);
  1935.         if( tp1 == 0 )
  1936.                 return 0;
  1937.         tp2 = asnop(&ep2,tp1);
  1938.         if( tp2 == 0) {
  1939.           generror(ERR_LVALUE,0,0);
  1940. *node = makenode(en_nacon,&undef,0);
  1941. }
  1942.         else    {
  1943. if (tp1->type == bt_struct || tp1->type == bt_union) {
  1944. if (!checktypeassign(tp1,tp2)) {
  1945.               generror(ERR_LVALUE,0,0);
  1946. *node = makenode(en_nacon,&undef,0);
  1947. }
  1948. else {
  1949. checknp(tp1,tp2,ep1,ep2);
  1950. if (ep2->nodetype == en_fcallb || ep2->nodetype == en_pfcallb)
  1951. if (ep2->nodetype == en_pfcallb) 
  1952. ep1 = makenode(en_pcallblock,ep1,ep2);
  1953. else
  1954. ep1 = makenode(en_callblock,ep1,ep2);
  1955. else
  1956. ep1 = makenode(en_moveblock,ep1,ep2);
  1957. ep1->size = tp1->size;
  1958. *node = ep1;
  1959. }
  1960. }
  1961.           else    {
  1962. if (tp1->type == bt_ref) {
  1963. if (lvalue(ep2)) {
  1964.   while (castvalue(ep2))
  1965.   ep2 = ep2->v.p[0];
  1966. ep2 = ep2->v.p[0];
  1967. tp1 = tp1->btp;
  1968. }
  1969. else {
  1970. tp1 = tp1->btp;
  1971. gensymerror(ERR_TEMPINIT,sp->name);
  1972. ep2 = makenode(en_refassign,dummyvar(tp1->size,tp1),ep2);
  1973. }
  1974. }
  1975. else if (tp1->val_flag) {
  1976. generror(ERR_LVALUE,0,0);
  1977. *node = makenode(en_nacon,&undef,0);
  1978. return tp1;
  1979. }
  1980. checknp(tp1,tp2,ep1,ep2);
  1981.            tp1 = forcefit(&ep1,tp1,&ep2,tp2,FALSE,FALSE);
  1982.            *node = makenode(en_assign,ep1,ep2);
  1983. }
  1984.         }
  1985. return(tp1);
  1986. }
  1987. void asncombine(ENODE **node)
  1988. /*
  1989.  * a simple optimization which turns an equate into a functional equate
  1990.  * if possible.  Code gen proceeds a little more cleanly if this info
  1991.  * is known.
  1992.  */
  1993. {
  1994. ENODE *var = (*node)->v.p[0];
  1995. ENODE *exp = (*node)->v.p[1];
  1996.   ENODE *var2 = exp->v.p[0];
  1997. int op = 0;
  1998. switch(exp->nodetype) {
  1999. case en_add:
  2000. if (equalnode(var,var2)) {
  2001. op = en_asadd;
  2002. break;
  2003. } else return;
  2004. case en_sub:
  2005. if (equalnode(var,var2)) {
  2006. op = en_assub;
  2007. break;
  2008. } else return;
  2009. case en_mul:
  2010. if (equalnode(var,var2)) {
  2011. op = en_asmul;
  2012. break;
  2013. } else return;
  2014. case en_umul:
  2015. if (equalnode(var,var2)) {
  2016. op = en_asumul;
  2017. break;
  2018. } else return;
  2019. case en_div:
  2020. if (equalnode(var,var2)) {
  2021. op = en_asdiv;
  2022. break;
  2023. } else return;
  2024. case en_udiv:
  2025. if (equalnode(var,var2)) {
  2026. op = en_asudiv;
  2027. break;
  2028. } else return;
  2029. case en_mod:
  2030. if (equalnode(var,var2)) {
  2031. op = en_asmod;
  2032. break;
  2033. } else return;
  2034. case en_umod:
  2035. if (equalnode(var,var2)) {
  2036. op = en_asumod;
  2037. break;
  2038. } else return;
  2039. case en_lsh:
  2040. if (equalnode(var,var2)) {
  2041. op = en_aslsh;
  2042. break;
  2043. } else return;
  2044. case en_alsh:
  2045. if (equalnode(var,var2)) {
  2046. op = en_asalsh;
  2047. break;
  2048. } else return;
  2049. case en_rsh:
  2050. if (equalnode(var,var2)) {
  2051. op = en_asrsh;
  2052. break;
  2053. } else return;
  2054. case en_arsh:
  2055. if (equalnode(var,var2)) {
  2056. op = en_asarsh;
  2057. break;
  2058. } else return;
  2059. case en_and:
  2060. if (equalnode(var,var2)) {
  2061. op = en_asand;
  2062. break;
  2063. } else return;
  2064. case en_or:
  2065. if (equalnode(var,var2)) {
  2066. op = en_asor;
  2067. break;
  2068. } else return;
  2069. case en_xor:
  2070. if (equalnode(var,var2)) {
  2071. op = en_asxor;
  2072. break;
  2073. } else return;
  2074. default:
  2075. return;
  2076. }
  2077. exp->nodetype = op;
  2078. (*node) = exp;
  2079. }
  2080. TYP     *asnop(ENODE **node,TYP *tptr)
  2081. /*
  2082.  *      asnop handles the assignment operators.
  2083.  */
  2084. {       ENODE    *ep1, *ep2, *ep3;
  2085.         TYP             *tp1, *tp2,*oldastyp;
  2086.         int             op;
  2087. oldastyp = asntyp;
  2088. if (tptr) 
  2089. asntyp = tptr;
  2090. else
  2091. asntyp = 0;
  2092.         tp1 = conditional(&ep1);
  2093. lastsym = 0;
  2094. if (!tptr)
  2095. asntyp = tp1;
  2096.         if( tp1 == 0 )
  2097.                 return 0;
  2098.         for(;;) {
  2099.                 switch( lastst ) {
  2100.                         case assign:
  2101.                                 op = en_assign;
  2102. ascomm:                         getsym();
  2103.                                 tp2 = asnop(&ep2,asntyp);
  2104. ascomm2:                        ep3 = ep1;
  2105. if (tp1) {
  2106. tp1->uflags |= UF_DEFINED;
  2107. }
  2108. goodcode |= GF_ASSIGN;
  2109. if ((tp1->uflags & UF_CANASSIGN) && !(goodcode & GF_INLOOP))
  2110. tp1->uflags |=  UF_ASSIGNED;
  2111. if( tp2 == 0 || tp1 == 0)
  2112.                                         generror(ERR_LVALUE,0,0);
  2113. else {
  2114. if (tp1->type == bt_struct || tp1->type == bt_union) {
  2115. if (!checktypeassign(tp1,tp2)) {
  2116.                                          generror(ERR_LVALUE,0,0);
  2117. }
  2118. else {
  2119. if (op != en_asadd && op != en_assub)
  2120. checknp(tp1,tp2,ep1,ep2);
  2121. if (ep2->nodetype == en_fcallb || ep2->nodetype == en_pfcallb)
  2122. if (ep2->nodetype == en_pfcallb) 
  2123. ep1 = makenode(en_pcallblock,ep1,ep2);
  2124. else
  2125. ep1 = makenode(en_callblock,ep1,ep2);
  2126. else
  2127. ep1 = makenode(en_moveblock,ep1,ep2);
  2128. ep1->size = tp1->size;
  2129. }
  2130. }
  2131.                                   else    {
  2132. if (!lvalue(ep1)) 
  2133.            generror(ERR_LVALUE,0,0);
  2134. if (op != en_asadd && op != en_assub)
  2135. checknp(tp1,tp2,ep1,ep2);
  2136.                                         tp1 = forcefit(&ep1,tp1,&ep2,tp2,FALSE,FALSE);
  2137.                                         ep1 = makenode(op,ep1,ep2);
  2138.                                         }
  2139. }
  2140.   if (ep3->cflags & DF_CONST)
  2141.   generror(ERR_MODCONS,0,0);
  2142.    if (op == en_assign) {
  2143.    asncombine(&ep1);
  2144. op = ep1->nodetype;
  2145. }
  2146.    if (op == en_asmod || op == en_asumod ||
  2147.    op ==en_aslsh || op== en_asrsh ||
  2148.    op == en_asalsh || op== en_asarsh ||
  2149.    op == en_asand || op== en_asor || op == en_asxor)
  2150.    floatcheck(ep1);
  2151.                                 break;
  2152.                         case asplus:
  2153.                                 op = en_asadd;
  2154. ascomm3: getsym();
  2155. tp2 = asnop(&ep2,asntyp);
  2156.                                 if( tp1->type == bt_pointer ) {
  2157. if (tp1->btp->size == 0)
  2158. generror(ERR_ZEROPTR,0,0);
  2159.                                         ep3 = makenode(en_icon,(char *)tp1->btp->size,0);
  2160.                                         ep2 = makenode(en_pmul,ep2,ep3);
  2161. tp2 = tp1;
  2162.                                         }
  2163.                                 goto ascomm2;
  2164.                         case asminus:
  2165.                                 op = en_assub;
  2166.                                 goto ascomm3;
  2167.                         case astimes:
  2168.                                 if( tp1->type == bt_unsigned ||tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
  2169.                                         op = en_asumul;
  2170.                                 else
  2171.                                         op =en_asmul;
  2172.                                 goto ascomm;
  2173.                         case asdivide:
  2174.                                 if( tp1->type == bt_unsigned ||tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
  2175.                                         op = en_asudiv;
  2176.                                 else
  2177.                                         op =en_asdiv;
  2178.                                 goto ascomm;
  2179.                         case asmodop:
  2180.                                 if( tp1->type == bt_unsigned ||tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
  2181.                                         op = en_asumod;
  2182.                                 else
  2183.                                         op =en_asmod;
  2184.                                 goto ascomm;
  2185.                         case aslshift:
  2186. if (tp1->type == bt_unsigned ||
  2187. tp1->type == bt_unsignedchar ||
  2188. tp1->type == bt_unsignedshort)
  2189. op = en_aslsh;
  2190. else
  2191.                               op = en_asalsh;
  2192.                                 goto ascomm;
  2193.                         case asrshift:
  2194. if (tp1->type == bt_unsigned ||
  2195. tp1->type == bt_unsignedchar ||
  2196. tp1->type == bt_unsignedshort)
  2197. op = en_asrsh;
  2198. else
  2199.                               op = en_asarsh;
  2200.                                 goto ascomm;
  2201.                         case asand:
  2202.                                 op = en_asand;
  2203.                                 goto ascomm;
  2204.                         case asor:
  2205.                                 op = en_asor;
  2206.                                 goto ascomm;
  2207.                         case asxor:
  2208.                                 op = en_asxor;
  2209.                                 goto ascomm;
  2210.                         default:
  2211.                                 goto asexit;
  2212.                         }
  2213.                 }
  2214. asexit: *node = ep1;
  2215. asntyp = oldastyp;
  2216.         return tp1;
  2217. }
  2218. TYP     *exprnc(ENODE **node)
  2219. /*
  2220.  *      evaluate an expression where the comma operator is not legal.
  2221.  * e.g. a function argument
  2222.  */
  2223. {       TYP     *tp;
  2224.         tp = asnop(node,0);
  2225.         if( tp == 0 )
  2226.                 *node = 0;
  2227. else if ((*node)->nodetype == en_fcallb || (*node)->nodetype == en_pfcallb) {
  2228. if ((*node)->nodetype == en_pfcallb) 
  2229. (*node) = makenode(en_pcallblock,dummyvar(tp->size,tp),(*node));
  2230.    else
  2231. (*node) = makenode(en_callblock,dummyvar(tp->size,tp),(*node));
  2232. }
  2233. if (tp && tp->type == bt_void)
  2234. goodcode |= GF_ASSIGN;
  2235.         return tp;
  2236. }
  2237. TYP     *commaop(ENODE **node)
  2238. /*
  2239.  *      evaluate the comma operator. comma operators are kept as
  2240.  *      void nodes.
  2241.  */
  2242. {       TYP             *tp1;
  2243.         ENODE    *ep1, *ep2;
  2244. int ocode;
  2245.         tp1 = asnop(&ep1,0);
  2246.         if( tp1 == 0 )
  2247.                 return 0;
  2248.         if( lastst == comma ) {
  2249. ocode = goodcode | ~GF_ASSIGN;
  2250. goodcode &= ~GF_ASSIGN;
  2251. getsym();
  2252.                 tp1 = commaop(&ep2);
  2253. goodcode &= ocode;
  2254.                 if( tp1 == 0 ) {
  2255.                         generror(ERR_IDEXPECT,0,0);
  2256.                         goto coexit;
  2257.                         }
  2258.                 ep1 = makenode(en_void,ep1,ep2);
  2259.                 }
  2260. coexit: *node = ep1;
  2261.         return tp1;
  2262. }
  2263. TYP     *expression(ENODE **node)
  2264. /*
  2265.  *      evaluate an expression where all operators are legal.
  2266.  */
  2267. {       TYP     *tp;
  2268.         tp = commaop(node);
  2269.         if( tp == 0 )
  2270.                 *node = 0;
  2271. else if ((*node)->nodetype == en_fcallb || (*node)->nodetype == en_pfcallb) {
  2272. if ((*node)->nodetype == en_pfcallb) 
  2273. (*node) = makenode(en_pcallblock,dummyvar(tp->size,tp),(*node));
  2274.    else
  2275. (*node) = makenode(en_callblock,dummyvar(tp->size,tp),(*node));
  2276. }
  2277. if (tp && tp->type == bt_void)
  2278. goodcode |= GF_ASSIGN;
  2279.         return tp;
  2280. }