0001 class CRPN:CQue {
0002   I64 type,ic_line,ic_flags;
0003   CHashClass *ic_class;
0004   CHashFun *ic_fun;
0005   CArrayDim *ic_dim;  
0006   CICTreeLinks t;
0007   union {
0008     I64 length;
0009     I64 imm_i64;
0010     I64 inc_amt;
0011     F64 imm_f64;
0012     CHashGlblVar *glbl_var;
0013     CHashClass *cls;
0014     I64 ic_data;
0015   };
0016   union {
0017     CCodeMisc *misc;
0018   };
0019 };
0020 
0021 Bool IsPtrNode(CRPN *rpn) {
0022   return rpn->ic_class->ptr_stars_cnt||rpn->ic_dim;
0023 }
0024 
0025 U0 RPNDel(CRPN *rpn) {
0026   QueRem(rpn);
0027   Free(rpn);
0028 }
0029 //This accounts for CHashClass/CHashFun
0030 CHashClass *DerefType(CHashClass *cls) {
0031   if(!cls->ptr_stars_cnt) return cmp.internal_types[RT_I64];
0032   if(cls->type&HTT_FUN)
0033     return cls(CHashFun*)-1;
0034   return cls-1;
0035 }
0036 CHashClass *AddrOfType(CHashClass *cls) {
0037   if(cls->type&HTT_FUN)
0038     return cls(CHashFun*)+1;
0039   return cls+1;
0040 }
0041 I64 RPNPtrWidth(CRPN *r) {
0042   I64 mul=1;
0043   if(r->ic_dim)
0044     mul=r->ic_dim->total_cnt;
0045   if(r->ic_class->type&HTT_CLASS&&r->ic_class->ptr_stars_cnt)
0046     return mul*DerefType(r->ic_class)->size;
0047   //Is a function pointer???
0048   return 1*mul;
0049 }
0050 CHashClass *AssignRawTypeToNode(CRPN *r) {
0051   CHashClass *cls;
0052   I64 rt1,rt2;
0053   if(r->ic_class)
0054     return r->ic_class;
0055   switch(r->type) {
0056     break;case IC_IMM_I64: return r->ic_class=cmp.internal_types[RT_I64];
0057     break;case IC_IMM_F64: return r->ic_class=cmp.internal_types[RT_F64];
0058     break;case IC_STR_CONST: return r->ic_class=cmp.internal_types[RT_PTR];
0059     break;case IC_ADDR_IMPORT:
0060     if(r->glbl_var->type&HTT_FUN) {
0061       return r->glbl_var;
0062     } else if(r->glbl_var->type&HTT_GLBL_VAR) {
0063       if(r->glbl_var->fun_ptr) {
0064         return r->ic_class=cmp.internal_types[RT_PTR];
0065       }
0066       return r->ic_class=AddrOfType(r->glbl_var->var_class);
0067     }
0068     throw('Compiler');
0069     break;case IC_HEAP_GLBL:
0070     r->ic_dim=r->glbl_var->dim.next;
0071     return r->ic_class=r->glbl_var->var_class;
0072     break;case IC_SIZEOF:
0073     return r->ic_class=cmp.internal_types[RT_I64];
0074     break;case IC_TYPE:
0075     goto unimp;
0076     break;case IC_GET_LABEL:
0077     goto unimp;
0078     break;case IC_REG:
0079     goto unimp;
0080     break;case IC_TO_I64: return r->ic_class=cmp.internal_types[RT_I64];
0081     break;case IC_TO_F64: return r->ic_class=cmp.internal_types[RT_F64];
0082     break;case IC_TO_BOOL: return r->ic_class=cmp.internal_types[RT_I64];
0083     break;case IC_TOUPPER: return r->ic_class=cmp.internal_types[RT_U8];
0084     break;case IC_HOLYC_TYPECAST: return r->ic_class;
0085     break;case IC_COMMA:
0086     r->ic_dim=r->next(CRPN*)->ic_dim;
0087     return r->ic_class=AssignRawTypeToNode(r->next);
0088     break;case IC_ADDR:
0089     //Address of array reduces to itself
0090     if(r->t.arg1_tree->ic_dim) {
0091       r->ic_class=r->t.arg1_class;
0092       r->ic_dim=r->t.arg1_tree->ic_dim;
0093       return r->t.arg1_class;
0094     }
0095     return r->ic_class=AddrOfType(AssignRawTypeToNode(r->next));
0096     break;case IC_COM: //bitwiase COMMPLEMENT
0097     r->ic_class=AssignRawTypeToNode(r->next);
0098     r->ic_dim=r->next(CRPN*)->ic_dim;
0099     return r->ic_class;
0100     break;case IC_NOT:
0101     return r->ic_class=cmp.internal_types[RT_I64];
0102     break;case IC_UNARY_MINUS:
0103     r->ic_class=AssignRawTypeToNode(r->next);
0104     r->ic_dim=r->next(CRPN*)->ic_dim;
0105     return r->ic_class;
0106     break;case IC_DEREF:
0107 deref:
0108     r->ic_class=r->t.arg1_class;
0109     r->ic_dim=r->t.arg1_tree->ic_dim;
0110     if(r->ic_dim)
0111       r->ic_dim=r->ic_dim->next;
0112     else
0113       r->ic_class=DerefType(r->ic_class);
0114     return r->ic_class;
0115     break;case IC_DEREF_PP: goto deref;
0116     break;case IC__PP:
0117     return r->ic_class=r->t.arg1_class;
0118     break;case IC__MM:
0119     return r->ic_class=r->t.arg1_class;
0120     break;case IC_PP_:
0121     return r->ic_class=r->t.arg1_class;
0122     break;case IC_MM_:
0123     return r->ic_class=r->t.arg1_class;
0124     break;case IC_SHL:
0125 binop:
0126     switch(r->type) {
0127       break;case IC_SUB:
0128       rt1=r->t.arg1_class->raw_type;
0129       rt2=r->t.arg2_class->raw_type;
0130       if(IsPtrNode(r->t.arg1_tree)&&IsPtrNode(r->t.arg2_tree))
0131         return r->ic_class=cmp.internal_types[RT_I64];
0132       default:
0133 binop_dft:
0134       rt1=r->t.arg1_class->raw_type;
0135       rt2=r->t.arg2_class->raw_type;  
0136       if(rt1>rt2)
0137         return r->ic_class=r->t.arg1_class;
0138       return r->ic_class=r->t.arg2_class;    
0139       break;case IC_ADD:
0140       if(r->t.arg1_tree->ic_dim)
0141         r->ic_dim=r->t.arg1_tree->ic_dim;
0142       else if(r->t.arg2_tree->ic_dim)
0143         r->ic_dim=r->t.arg2_tree->ic_dim;
0144       else if(r->t.arg1_class->ptr_stars_cnt)
0145         return r->ic_class=r->t.arg1_class;
0146       else if(r->t.arg2_class->ptr_stars_cnt)
0147         return r->ic_class=r->t.arg2_class;
0148       goto binop_dft;
0149     }
0150     break;
0151     case IC_MAX_I64:
0152     case IC_MIN_I64:
0153     case IC_FS:
0154     case IC_GS:
0155     case IC_BT:
0156     case IC_BTS:
0157     case IC_BTR:
0158     case IC_BTC:
0159     case IC_LBTS:
0160     case IC_LBTR:
0161     case IC_LBTC:
0162     r->ic_class=cmp.internal_types[RT_I64];
0163     break;
0164     case IC_MAX_U64:
0165     case IC_MIN_U64:
0166     r->ic_class=cmp.internal_types[RT_U64];
0167     break;
0168     break;case IC_SHR:
0169     goto binop;
0170     break;case IC_SHL_CONST:
0171     goto binop;
0172     break;case IC_SHR_CONST:
0173     goto binop;
0174     break;case IC_POWER:
0175     return r->ic_class=cmp.internal_types[RT_F64];
0176     break;case IC_MUL:
0177     goto binop;
0178     break;case IC_DIV:
0179     goto binop;
0180     break;case IC_MOD:
0181     goto binop;
0182     break;case IC_AND:
0183     goto binop;
0184     break;case IC_OR:
0185     goto binop;
0186     break;case IC_XOR:
0187     goto binop;
0188     break;case IC_ADD:
0189     goto binop;
0190     break;case IC_SUB:
0191     goto binop;
0192     break;case IC_ADD_CONST:
0193     goto binop;
0194     break;case IC_SUB_CONST:
0195     goto binop;
0196     break;case IC_EQU_EQU:
0197     return r->ic_class=cmp.internal_types[RT_I64];
0198     break;case IC_NOT_EQU:
0199     return r->ic_class=cmp.internal_types[RT_I64];
0200     break;case IC_LESS:
0201     return r->ic_class=cmp.internal_types[RT_I64];
0202     break;case IC_GREATER_EQU:
0203     return r->ic_class=cmp.internal_types[RT_I64];
0204     break;case IC_GREATER:
0205     return r->ic_class=cmp.internal_types[RT_I64];
0206     break;case IC_LESS_EQU:
0207     return r->ic_class=cmp.internal_types[RT_I64];
0208     break;case IC_PUSH_CMP: //???
0209 unimp:
0210     throw('Compiler');
0211     break;case IC_AND_AND:
0212     return r->ic_class=cmp.internal_types[RT_I64];
0213     break;case IC_OR_OR:
0214     return r->ic_class=cmp.internal_types[RT_I64];
0215     break;case IC_XOR_XOR:
0216     return r->ic_class=cmp.internal_types[RT_I64];
0217     break;case IC_ASSIGN:
0218 assign:
0219     if(r->t.arg1_tree->ic_dim) {
0220       r->ic_dim=r->t.arg1_tree->ic_dim;
0221       return r->ic_class=r->t.arg1_class;
0222     }
0223     if(r->t.arg1_class->raw_type<RT_I64)
0224       return r->ic_class=cmp.internal_types[RT_I64];
0225     return r->ic_class=r->t.arg1_class;
0226     break;case IC_ASSIGN_PP:
0227     goto assign;
0228     break;case IC_ASSIGN_MM:
0229     goto assign;
0230     break;case IC_SHL_EQU:
0231     goto assign;
0232     break;case IC_SHR_EQU:
0233     goto assign;
0234     break;case IC_MUL_EQU:
0235     goto assign;
0236     break;case IC_DIV_EQU:
0237     goto assign;
0238     break;case IC_MOD_EQU:
0239     goto assign;
0240     break;case IC_AND_EQU:
0241     goto assign;
0242     break;case IC_OR_EQU:
0243     goto assign;
0244     break;case IC_XOR_EQU:
0245     goto assign;
0246     break;case IC_ADD_EQU:
0247     goto assign;
0248     break;case IC_SUB_EQU:
0249     goto assign;
0250     //TODO actually do something
0251     break;default: 
0252     return r->ic_class=cmp.internal_types[RT_U0];
0253   }
0254 }
0255 
0256 U0 PrsOffsetOf(CCmpCtrl *cc)
0257 {
0258   CHashClass *tmpc;
0259   CMemberLst *tmpm;
0260   CRPN *rpn;
0261   I64 i;
0262   if (cc->token!=TK_IDENT)
0263     LexExcept(cc,"Invalid class at ");
0264   if (tmpm=cc->local_var_entry)
0265     tmpc=tmpm->member_class;
0266   else {
0267     tmpc=cc->hash_entry;
0268     if (!tmpc || !(tmpc->type & (HTT_CLASS|HTT_GLBL_VAR)))
0269       LexExcept(cc,"Invalid class at ");
0270     else if (tmpc->type & HTT_GLBL_VAR)
0271       tmpc=tmpc(CHashGlblVar *)->var_class;
0272   }
0273   if (Lex(cc)!='.')
0274     LexExcept(cc,"Expecting '.' at ");
0275   i=0;
0276   do {
0277     if (Lex(cc)!=TK_IDENT || !(tmpm=MemberFind(cc->cur_str,tmpc)))
0278       LexExcept(cc,"Invalid member at ");
0279     else if (cc->local_var_entry)
0280       cc->local_var_entry->use_cnt--;
0281     i+=tmpm->offset;
0282     tmpc=tmpm->member_class;
0283   } while (Lex(cc)=='.');
0284   RPNAddNew(
0285     cc,
0286     IC_IMM_I64,
0287     i,
0288     cmp.internal_types[RT_I64]
0289   );
0290 }
0291 U0 PrsSizeOf(CCmpCtrl *cc)
0292 {
0293   CRPN *rpn;
0294   CHashClass *tmpc;
0295   CMemberLst *tmpm;
0296   CDbgInfo *dbg_info;
0297   I64 i;
0298   if (cc->token!=TK_IDENT)
0299     LexExcept(cc,"Invalid class at ");
0300   if (tmpm=cc->local_var_entry) {
0301     tmpc=tmpm->member_class;
0302     i=tmpc->size*tmpm->dim.total_cnt;
0303     if (Lex(cc)=='.')
0304       goto pu_sizeof_member;
0305   } else {
0306     if (!(tmpc=cc->hash_entry) || !(tmpc->type &
0307           (HTT_CLASS|HTT_INTERNAL_TYPE|HTT_GLBL_VAR|
0308           HTT_FUN|HTT_EXPORT_SYS_SYM)))
0309       LexExcept(cc,"Invalid class at ");
0310     if (tmpc->type&(HTT_FUN|HTT_EXPORT_SYS_SYM)) {
0311       if (!(dbg_info=tmpc(CHashFun *)->dbg_info))
0312         LexExcept(cc,"Size not defined at ");
0313       i=dbg_info->body[dbg_info->max_line+1-dbg_info->min_line]
0314             -dbg_info->body[0];
0315       Lex(cc);
0316     } else {
0317       i=tmpc->size;
0318       while (Lex(cc)=='.') {
0319 pu_sizeof_member:
0320         if (!(tmpc->type & (HTT_CLASS|HTT_GLBL_VAR)))
0321           LexExcept(cc,"Invalid class at ");
0322         else if (tmpc->type & HTT_GLBL_VAR)
0323           tmpc=tmpc(CHashGlblVar *)->var_class;
0324         if (Lex(cc)!=TK_IDENT || !(tmpm=MemberFind(cc->cur_str,tmpc)))
0325           LexExcept(cc,"Invalid member at ");
0326         else if (cc->local_var_entry)
0327           cc->local_var_entry->use_cnt--;
0328         tmpc=tmpm->member_class;
0329 //Probably others like this:
0330         //#assert offset(CHashClass.size)==offset(CHashGlblVar.size)
0331         i=tmpc->size*tmpm->dim.total_cnt;
0332       }
0333     }
0334   }
0335   if (cc->token=='*') {
0336     while (Lex(cc)=='*');
0337     i=sizeof(U8 *);
0338   }
0339   RPNAddNew(
0340     cc,
0341     IC_IMM_I64,
0342     i,
0343     cmp.internal_types[RT_I64],
0344   );
0345 }
0346 extern U0 DumpRPN(CRPN*,I64 x=0);
0347 CRPN *ICNext(CRPN *rpn) {
0348   CRPN *next=rpn->next;
0349   I64 cnt;
0350   switch(intermediate_code_table[rpn->type].arg_cnt) {
0351     case IS_V_ARG:
0352     cnt=rpn->length;
0353     while(cnt--)
0354       next=ICNext(next);
0355     break;
0356     case IS_2_ARG:
0357       next=ICNext(next);
0358       next=ICNext(next);
0359     break;
0360     case IS_1_ARG:
0361       next=ICNext(next);
0362     break;
0363     case IS_0_ARG:
0364   }
0365   return next;
0366 }
0367 //
0368 // add_to_prs_stk will also not assign the tree args
0369 //
0370 U0 RPNAdd(CCmpCtrl *cc,CRPN *rpn,Bool add_to_prs_stk=TRUE) {
0371   CRPN *rpn2,*a,*b,*rpn3;
0372   I64 width;
0373   CHashClass *ic_class;
0374   CHashFun *powh;
0375   Bool divide=FALSE;
0376   if(!(cc->lex_include_stk->flags&LFSF_DEFINE))
0377     rpn->ic_line=cc->lex_include_stk->line_num;
0378   QueIns(rpn,&cc->coc.coc_head);
0379   if(add_to_prs_stk) {
0380     switch(intermediate_code_table[rpn->type].arg_cnt) {
0381         break;case IS_V_ARG:
0382         width=rpn->length;
0383         while(width--) {
0384           if(!PrsPop3(cc->ps))
0385             LexExcept(cc,"Unexpected end of expression at ");
0386         }
0387         break;case IS_2_ARG:
0388         rpn->t.arg2_tree=PrsPop3(cc->ps);
0389         rpn->t.arg1_tree=PrsPop3(cc->ps);
0390         if(!rpn->t.arg1_tree||!rpn->t.arg2_tree)
0391           LexExcept(cc,"Unexpected end of expression at ");
0392         rpn->t.arg2_class=rpn->t.arg2_tree->ic_class;
0393         rpn->t.arg1_class=rpn->t.arg1_tree->ic_class;
0394         break;case IS_1_ARG:
0395         rpn->t.arg1_tree=PrsPop3(cc->ps);
0396         if(!rpn->t.arg1_tree)
0397           LexExcept(cc,"Unexpected end of expression at ");
0398         rpn->t.arg1_class=rpn->t.arg1_tree->ic_class;
0399         break;case IS_0_ARG:
0400     }
0401     switch(rpn->type) {
0402         break;case IC_POWER:
0403         a=ICNext(rpn);
0404         if(rpn->t.arg1_class->raw_type!=RT_F64) {
0405           b=CAlloc(sizeof CRPN);
0406           if(cc->lock_cnt) b->ic_flags|=ICF_LOCK;
0407           b->type=IC_TO_F64;
0408           b->ic_class=cmp.internal_types[RT_F64];
0409           QueInsRev(b,rpn->t.arg1_tree);
0410           rpn->t.arg1_tree=b;
0411           rpn->t.arg1_class=cmp.internal_types[RT_F64];
0412         }
0413         if(rpn->t.arg2_class->raw_type!=RT_F64) {
0414           b=CAlloc(sizeof CRPN);
0415           if(cc->lock_cnt) b->ic_flags|=ICF_LOCK;
0416           b->type=IC_TO_F64;
0417           b->ic_class=cmp.internal_types[RT_F64];
0418           QueInsRev(b,rpn->t.arg2_tree);
0419           rpn->t.arg2_tree=b;
0420           rpn->t.arg2_class=cmp.internal_types[RT_F64];
0421         }
0422         rpn->type=IC_CALL_INDIRECT;
0423         rpn->length=3;
0424         powh=HashFind("Pow",cc->htc.hash_table_lst,HTT_FUN);
0425         if(!powh)
0426           throw('Compiler');
0427         if(cc->flags&CCF_AOT_COMPILE||Bt(&powh->flags,Cf_EXTERN)) {
0428           b=CAlloc(sizeof CRPN);
0429           if(cc->lock_cnt) b->ic_flags|=ICF_LOCK;
0430           b->type=IC_ADDR_IMPORT;
0431           b->ic_data=CodeMiscHashNew(cc,powh);
0432           b->ic_class=powh;
0433         } else {
0434           b=CAlloc(sizeof CRPN);
0435           if(cc->lock_cnt) b->ic_flags|=ICF_LOCK;
0436           b->type=IC_IMM_I64;
0437           b->ic_data=powh->exe_addr;
0438           b->ic_class=powh;
0439         }
0440         QueInsRev(b,a);
0441         rpn->ic_class=powh->return_class;
0442         break;case IC_PP_:
0443       case IC_MM_:
0444       case IC__PP:
0445       case IC__MM:
0446         a=rpn->t.arg1_tree;
0447         if(a->ic_dim||a->ic_class->ptr_stars_cnt) {
0448           rpn->ic_data=RPNPtrWidth(a);
0449         } else
0450           rpn->ic_data=1;
0451         break;case IC_DEREF:
0452 //
0453       //Dereferencing an array of an array does nothing.
0454       // Arrays are flat so we only take off a dim,derefence the pointer
0455       // I64i arr[2][2]={{1,2},{3,4}};
0456       //   is
0457       // [1,2,3,4]
0458       //
0459         a=rpn->t.arg1_tree;
0460         if(a->ic_dim)
0461           if(a->ic_dim->next) {
0462             a->ic_dim=a->ic_dim->next;
0463             RPNDel(rpn);
0464             PrsPush3(cc->ps,a); //Put back on the stack
0465             return;
0466           }
0467 //Can't "Derefence" a function pointer,it is symbolic
0468         if(a->ic_class->ptr_stars_cnt==1&&(a->ic_class->type&HTT_FUN)) {
0469           a->ic_class=DerefType(a->ic_class);
0470           RPNDel(rpn);
0471           PrsPush3(cc->ps,a); //Put back on the stack
0472           return;
0473         }
0474         break;case IC_ADDR:
0475 //Address of dereference does nothing.
0476       //&*a;
0477         if(rpn->t.arg1_tree->type==IC_DEREF) {
0478 //rpn=='&'
0479           //b=='*'
0480           //a=='var'
0481           b=rpn->t.arg1_tree;
0482           a=b->t.arg1_tree;
0483           RPNDel(rpn);
0484           PrsPush3(cc->ps,a); //Put back on the stack
0485           if(b->ic_dim) {
0486             a->ic_class=b->ic_class;
0487             a->ic_dim=b->ic_dim;
0488           } else {
0489             a->ic_dim=NULL;
0490             a->ic_class=AddrOfType(b->ic_class);
0491           }
0492           RPNDel(b);
0493           return;
0494         }
0495         break;case IC_SUB:
0496         a=rpn->t.arg1_tree;
0497         b=rpn->t.arg2_tree;
0498         if(IsPtrNode(a)) {
0499           width=RPNPtrWidth(a);
0500           rpn2=CAlloc(sizeof CRPN);
0501           if(cc->lock_cnt) rpn2->ic_flags|=ICF_LOCK;
0502           rpn2->type=IC_IMM_I64;
0503           rpn2->imm_i64=width;
0504           rpn2->ic_class=cmp.internal_types[RT_I64];
0505           if(IsPtrNode(b)) {
0506             divide=TRUE;
0507           } else {
0508 //Use a's class for rpn
0509             rpn->ic_class=a->ic_class;          
0510 mul:
0511             rpn3=CAlloc(sizeof CRPN);
0512             if(cc->lock_cnt) rpn3->ic_flags|=ICF_LOCK;
0513             rpn3->type=IC_MUL;
0514             rpn3->ic_class=cmp.internal_types[RT_I64];
0515             rpn3->t.arg2_tree=rpn2;
0516             rpn3->t.arg1_class=cmp.internal_types[RT_I64];
0517             rpn3->t.arg2_class=cmp.internal_types[RT_I64];
0518             rpn3->t.arg1_tree=b;
0519             rpn->t.arg2_tree=rpn3;
0520             rpn2->ic_line=rpn->ic_line;
0521             rpn3->ic_line=rpn->ic_line;
0522             QueIns(rpn3,rpn);
0523             QueIns(rpn2,rpn3);
0524           }
0525         }
0526         break;case IC_ADD_EQU:
0527       case IC_SUB_EQU:
0528         a=rpn->t.arg1_tree;
0529         b=rpn->t.arg2_tree;
0530         if(a->ic_dim) {
0531           width=a->ic_class->size*a->ic_dim->total_cnt;
0532           rpn2=CAlloc(sizeof CRPN);
0533           if(cc->lock_cnt) rpn2->ic_flags|=ICF_LOCK;
0534           rpn2->type=IC_IMM_I64;
0535           rpn2->imm_i64=width;
0536           rpn2->ic_class=cmp.internal_types[RT_I64];
0537           rpn->ic_dim=a->ic_dim;
0538 //Use a's class for rpn
0539           rpn->ic_class=a->ic_class;
0540           goto mul;
0541         } else if(IsPtrNode(a)) {
0542           width=RPNPtrWidth(a);
0543           rpn2=CAlloc(sizeof CRPN);
0544           if(cc->lock_cnt) rpn2->ic_flags|=ICF_LOCK;
0545           rpn2->type=IC_IMM_I64;
0546           rpn2->imm_i64=width;
0547 //Use a's class for rpn
0548           rpn->ic_class=a->ic_class;
0549           goto mul;    
0550         }
0551         break;case IC_ADD:
0552         a=rpn->t.arg1_tree;
0553         b=rpn->t.arg2_tree;
0554 #ifdef TARGET_X86
0555         //I will implement this later for ARM64
0556         if(cc->flags&CCF_AOT_COMPILE) {
0557           if(a->type==IC_ADDR_IMPORT&&b->type==IC_IMM_I64) {
0558             width=1;
0559             if(a->ic_dim)
0560               width=a->ic_class->size*a->ic_dim->total_cnt;
0561             else if(IsPtrNode(a))
0562               width=RPNPtrWidth(a);
0563             a->ic_data(CCodeMisc*)->offset+=b->imm_i64*width;
0564             RPNDel(rpn);
0565             RPNDel(b);
0566             PrsPush3(cc->ps,a); //Put back on the stack
0567             return;
0568           }
0569           if(b->type==IC_ADDR_IMPORT&&a->type==IC_IMM_I64) {
0570             width=1;
0571             if(b->ic_dim)
0572               width=b->ic_class->size*b->ic_dim->total_cnt;
0573             else if(IsPtrNode(b))
0574               width=RPNPtrWidth(b);
0575             b->ic_data(CCodeMisc*)->offset+=a->imm_i64*width;
0576             RPNDel(rpn);
0577             RPNDel(a);
0578             PrsPush3(cc->ps,b); //Put back on the stack
0579             return;
0580           }
0581         }
0582 #endif
0583         if(a->ic_dim) {
0584           width=a->ic_class->size*a->ic_dim->total_cnt;
0585           rpn2=CAlloc(sizeof CRPN);
0586           if(cc->lock_cnt) rpn2->ic_flags|=ICF_LOCK;
0587           rpn2->type=IC_IMM_I64;
0588           rpn2->imm_i64=width;
0589           rpn2->ic_class=cmp.internal_types[RT_I64];
0590           rpn->ic_dim=a->ic_dim;
0591 //Use a's class for rpn
0592           rpn->ic_class=a->ic_class;
0593           goto mul;
0594         } else if(IsPtrNode(a)) {
0595           width=RPNPtrWidth(a);
0596           rpn2=CAlloc(sizeof CRPN);
0597           if(cc->lock_cnt) rpn2->ic_flags|=ICF_LOCK;
0598           rpn2->type=IC_IMM_I64;
0599           rpn2->imm_i64=width;
0600 //Use a's class for rpn
0601           rpn->ic_class=a->ic_class;
0602           goto mul;    
0603         }
0604         if(b->ic_dim) {
0605           width=b->ic_class->size*b->ic_dim->total_cnt;
0606           rpn2=CAlloc(sizeof CRPN);
0607           if(cc->lock_cnt) rpn2->ic_flags|=ICF_LOCK;
0608           rpn2->type=IC_IMM_I64;
0609           rpn2->imm_i64=width;
0610           rpn2->ic_class=cmp.internal_types[RT_PTR];
0611           rpn->ic_dim=b->ic_dim;
0612           rpn->ic_class=b->ic_class;
0613 mul2:
0614           rpn3=CAlloc(sizeof CRPN);
0615           if(cc->lock_cnt) rpn3->ic_flags|=ICF_LOCK;
0616           rpn3->type=IC_MUL;
0617           rpn3->ic_class=cmp.internal_types[RT_I64];
0618           rpn3->t.arg2_tree=rpn2;
0619           rpn3->t.arg1_class=cmp.internal_types[RT_I64];
0620           rpn3->t.arg2_class=cmp.internal_types[RT_I64];
0621           rpn3->t.arg1_tree=a;
0622           rpn->t.arg1_tree=rpn3;
0623           rpn3->ic_line=rpn->ic_line;
0624           QueInsRev(rpn3,a);
0625           QueIns(rpn2,rpn3);
0626         } else if(IsPtrNode(b)) {
0627           width=RPNPtrWidth(b);
0628           rpn2=CAlloc(sizeof CRPN);
0629           if(cc->lock_cnt) rpn2->ic_flags|=ICF_LOCK;
0630           rpn2->type=IC_IMM_I64;
0631           rpn2->imm_i64=width;
0632 //Use b's class for rpn
0633           rpn->ic_class=b->ic_class;
0634           goto mul2;    
0635         }
0636     } 
0637   }
0638   if(add_to_prs_stk) {
0639     PrsPush3(cc->ps,rpn);
0640   }
0641   if(!rpn->ic_class)
0642     AssignRawTypeToNode(rpn);
0643   if(divide) {
0644     RPNAdd(cc,rpn2,add_to_prs_stk);
0645     rpn3=CAlloc(sizeof CRPN);
0646     if(cc->lock_cnt) rpn3->ic_flags|=ICF_LOCK;
0647     rpn3->type=IC_DIV;
0648     rpn3->ic_class=cmp.internal_types[RT_I64];
0649     RPNAdd(cc,rpn3,add_to_prs_stk);
0650   }
0651 } 
0652 CRPN *RPNAddNew(CCmpCtrl *cc,I64 type,I64 data=0,CHashClass *cls=NULL,Bool add_to_prs_stk=TRUE) {
0653   CRPN *rpn=CAlloc(sizeof CRPN);
0654   if(cc->lock_cnt) rpn->ic_flags|=ICF_LOCK;
0655   rpn->type=type;
0656   rpn->ic_data=data;
0657   rpn->ic_class=cls;
0658   RPNAdd(cc,rpn,add_to_prs_stk);
0659   return rpn;
0660 }
0661 U0 PushOpers(CCmpCtrl *cc,I64 cur_prec,Bool fin=FALSE) {
0662   CRPN *rpn,*r2;
0663   I64 v;
0664   while(cc->ps->ptr>0) { //cc->ps->stk starts at 1
0665     v=PrsPop(cc->ps);
0666     rpn=PrsPop2(cc->ps); //NULL if paren
0667     if(PREC_NULL==v.u32[1]&&!fin) {
0668       //Put back on stack
0669       PrsPush(cc->ps,v);
0670       PrsPush2(cc->ps,rpn);
0671       break;
0672     } else if(cur_prec.u32[1]==PREC_NULL&&!fin) {
0673       //PREC_NULL is a paren,so if we have a paren,pop until will get another paren
0674       goto pop;
0675     }
0676     if(v.u32[1]<cur_prec.u32[1]||fin) {
0677 pop:
0678       if(!rpn) LexExcept(cc,"Invalid expression at ");
0679       if(rpn->type==IC_ADDR) {
0680         //
0681         //Address of array does nothing in terms of SYNTAX
0682         // But is used internaly so we check ONLY here.
0683         r2=cc->coc.coc_head.next;
0684         if(&cc->coc.coc_head==r2) LexExcept(cc,"Can't get address of nothing at ");
0685         if(r2->ic_dim) {
0686           Free(rpn);
0687           goto next;
0688         }
0689       } else if(rpn->type==IC_DEREF) {
0690          r2=cc->coc.coc_head.next;
0691         if(&cc->coc.coc_head==r2) LexExcept(cc,"Can't get derefernce nothing at ");
0692          if(!r2->ic_dim&&!r2->ic_class->ptr_stars_cnt)
0693            LexExcept(cc,"Expected pointer type at ");
0694       }
0695       if(rpn)
0696         RPNAdd(cc,rpn);
0697 next:;
0698     } else if(v.u32[1]==cur_prec.u32[1]&&!(cur_prec.u32[1]&ASSOCF_RIGHT)) {
0699       goto pop;
0700     } else {
0701       //Put it back on the stack
0702       PrsPush(cc->ps,v);
0703       PrsPush2(cc->ps,rpn);
0704       break;
0705     }
0706   }
0707 }
0708 
0709 //start_idx is the first argument
0710 I64 ImplicitFunCall(CCmpCtrl *cc,CHashFun *fun,I64 start_idx=0) {
0711   I64 idx;
0712   CRPN *rpn;
0713   CMemberLst *lst=fun->member_lst_and_root;
0714   CHashClass *last_c=cc->coc.coc_head.next(CRPN*)->ic_class;
0715   CCodeMisc *cm;
0716   for(idx=0;idx!=fun->arg_cnt;idx++) {
0717     if(idx<start_idx)
0718       goto next;
0719     while(last_c->ptr_stars_cnt)
0720       last_c=DerefType(last_c);
0721     if(lst->flags&MLF_LASTCLASS&&last_c) {
0722       cm=COCMiscNew(cc,CMT_STR_CONST);
0723       cc->flags|=CCF_HAS_MISC_DATA;
0724       cm->str=StrNew(last_c->str);
0725       cm->st_len=StrLen(last_c->str)+1;
0726       RPNAddNew(
0727           cc,
0728           IC_STR_CONST,
0729           cm,
0730           last_c=cmp.internal_types[RT_U8]+1
0731         );
0732     } else if(lst->flags&(MLF_DFT_AVAILABLE|MLF_STR_DFT_AVAILABLE)) {
0733       last_c=lst->member_class;
0734       if(lst->member_class->raw_type==RT_F64) {
0735         RPNAddNew(
0736           cc,
0737           IC_IMM_F64,
0738           lst->dft_val,
0739           cmp.internal_types[RT_F64]
0740         );
0741       } else {
0742         RPNAddNew(
0743           cc,
0744           IC_IMM_I64,
0745           lst->dft_val,
0746           cmp.internal_types[RT_I64]
0747         );
0748       }
0749     } else if(lst->flags&MLF_DOT_DOT_DOT) {
0750       //Do nothing ,argc/argv are implicit
0751     } else {
0752       LexExcept(cc,"Missing dft value for argument at: ");
0753     }
0754 next:
0755     lst=lst->next;
0756   }
0757   return idx;
0758 }
0759 
0760 CCodeMisc *CodeMiscHashNew(CCmpCtrl *cc,CHash* h) {
0761   CCodeMisc *head=&cc->coc.coc_next_misc,*cur;
0762   #ifdef TARGET_X86
0763   //In X86_64,I will do every relocation as a short one that isnt an import
0764   if(cc->flags&CCF_AOT_COMPILE) {
0765     if(!(h->type&HTF_IMPORT)) {
0766       cur=COCMiscNew(cc,CMT_HASH_ENTRY);
0767       cur->flags|=CMF_SHORT_ADDR;
0768       cur->h=h;
0769       return cur;
0770     }
0771   }
0772   #endif
0773   for(cur=head->next;cur!=head;cur=cur->next) {
0774     if(cur->h==h)
0775       return cur;
0776   }
0777   cur=COCMiscNew(cc,CMT_HASH_ENTRY);
0778   cur->h=h;
0779   return cur;
0780 }
0781 
0782 U0 DbgPrint(U8 *fmt,...) {
0783   U8 *s=StrPrintJoin(NULL,fmt,argc,argv);
0784   DbgPutS(s);
0785   Free(s);
0786 }
0787 CRPN *DumpRPN(CRPN *rpn,I64 indent=0) {
0788   I64 idx=0;
0789   CHashClass *cls=rpn->ic_class;
0790   CRPN *next=rpn->next;
0791   if(cls) {
0792     while(cls->ptr_stars_cnt)
0793       cls=DerefType(cls);
0794     DbgPrint("%x%*c%s(%s*%d)",rpn,indent+1,' ',intermediate_code_table[rpn->type].name,cls->str,rpn->ic_class->ptr_stars_cnt);
0795   } else
0796         DbgPrint("%x%*c%s",rpn,indent+1,' ',intermediate_code_table[rpn->type].name);
0797   switch(rpn->type) {
0798     break;case IC_IMM_I64:
0799     case IC_FRAME:
0800     DbgPrint(",%d,",rpn->imm_i64);
0801     break;case IC_IMM_F64:
0802     ",%n,",rpn->imm_f64;
0803   }
0804   
0805   switch(intermediate_code_table[rpn->type].arg_cnt) {
0806     break;case IS_V_ARG:
0807     DbgPrint("(%d)\n",rpn->length);
0808     for(idx=0;idx!=rpn->length;idx++)
0809       next=DumpRPN(next,indent+1);
0810     break;case IS_2_ARG: 
0811     DbgPrint(",%x,%x\n",rpn->t.arg1_tree,rpn->t.arg2_tree);
0812     next=DumpRPN(next,indent+1);
0813     next=DumpRPN(next,indent+1);
0814     break;case IS_1_ARG:
0815     DbgPrint(",%x\n",rpn->t.arg1_tree);
0816     next=DumpRPN(next,indent+1);
0817     break;case IS_0_ARG:
0818     DbgPrint("\n");
0819   }
0820   return next;
0821 }
0822 
0823 U0 PrsMembers(CCmpCtrl *cc) {
0824   CRPN *head=cc->coc.coc_head.next,*added,*new;
0825   if(head==&cc->coc.coc_head.next)
0826     LexExcept(cc,"Expected to get the member of something!");
0827   CHashClass *cls=head->ic_class;
0828   CArrayDim *ic_dim=head->ic_dim;
0829   CMemberLst *mlst;
0830   I64 off=0;
0831   Bool needs_addr=!(cls->ptr_stars_cnt||ic_dim);
0832   Bool needs_flush=FALSE;
0833   while(TRUE) {
0834     if(cc->token=='.') {
0835       if(needs_addr) {
0836         needs_addr=FALSE;
0837         RPNAddNew(cc,IC_ADDR,,cmp.internal_types[RT_I64],TRUE);
0838       }
0839       //
0840       // Nroot here: Here's the deal.
0841       //  If we get the address of an array access,the derefence gets removed
0842       //    &a[1]==a+1 //a has ic_dim
0843       //  So I will remove the ic_dim and make it a pointer as it will be "a pointer"
0844       //
0845       added=cc->coc.coc_head.next;
0846       if(added->ic_dim) {
0847         added->ic_dim=NULL;
0848         cls=added->ic_class;
0849       }
0850       Lex(cc);
0851       mlst=MemberFind(cc->cur_str,cls);
0852       if(!mlst||ic_dim)
0853         LexExcept(cc,"Invalid member at");
0854       off+=mlst->offset;
0855       cls=mlst->member_class;
0856       ic_dim=mlst->dim.next;
0857       Lex(cc);
0858       needs_flush=TRUE;
0859     } else if(cc->token==TK_DEREFERENCE) {
0860       if(needs_flush) {
0861         if(off) {
0862           //Prevent from expading ptr airth.
0863           cc->coc.coc_head.next(CRPN*)->ic_class=cmp.internal_types[RT_I64];
0864           RPNAddNew(cc,IC_IMM_I64,off,,TRUE);
0865           RPNAddNew(cc,IC_ADD,,,TRUE);
0866         }
0867         RPNAddNew(cc,IC_DEREF,off,cmp.internal_types[RT_I64],TRUE);
0868       }
0869       needs_flush=TRUE;
0870       off=0;
0871       if(Lex(cc)!=TK_IDENT)
0872         LexExcept(cc,"Expected an identifier at");
0873       needs_addr=FALSE; 
0874       if(ic_dim) {
0875         ic_dim=ic_dim->next;
0876         RPNAddNew(cc,IC_DEREF,,,TRUE);
0877         mlst=MemberFind(cc->cur_str,cls);
0878       } else if(DerefType(cls)) {
0879         mlst=MemberFind(cc->cur_str,DerefType(cls));
0880       } else {
0881         LexExcept(cc,"Use '.' at");
0882       }
0883       if(!mlst)
0884         LexExcept(cc,"Invalid member at");
0885       off+=mlst->offset;
0886       Lex(cc);
0887       cls=mlst->member_class;
0888       ic_dim=mlst->dim.next;
0889     } else
0890       break;
0891   }
0892   if(off) {
0893     //Prevent from expading ptr airth.
0894     cc->coc.coc_head.next(CRPN*)->ic_class=cmp.internal_types[RT_I64];
0895     RPNAddNew(cc,IC_IMM_I64,off,,TRUE);
0896     RPNAddNew(cc,IC_ADD,off,,TRUE);
0897   }
0898   if(mlst->flags&MLF_FUN) {
0899     //TempleOS stores Function class in ->fun_ptr for some reason(when MLF_FUN is set) 
0900     cls=mlst->fun_ptr;
0901   }
0902             
0903   if(!ic_dim)
0904     new=RPNAddNew(cc,IC_DEREF,off,cls,TRUE);
0905   else {
0906     added=cc->coc.coc_head.next;
0907     //Here's the deal
0908     // IC_DEREF's act on their ic_class,so if our last item is a IC_DEFEF
0909     //  Derefernece as usual,THEN use our dim
0910     //  a->some_class->array_u8 
0911     // a->some_class must derefnce to a pointer(8 bytes),then we switch the result type to
0912     // array of u8[0]. I do this by adding 0 to the result
0913     if(added->type==IC_DEREF) {
0914       RPNAddNew(cc,IC_IMM_I64,0,cmp.internal_types[RT_I64],TRUE);
0915       added=RPNAddNew(cc,IC_ADD,0,cls,TRUE);
0916     }
0917     added->ic_dim=ic_dim;
0918     added->ic_class=cls;
0919   }
0920 }
0921 
0922 Bool PrsExpression(CCmpCtrl *cc,U8 **ul=NULL,I64 flags=0,CPrsStk *_ps=NULL) { //TODO REMOVE Ul
0923   I64 cur_prec,stk_ptr,tok=cc->token,idx,arity,v,mode,str_len;
0924   CRPN *orig_next=cc->coc.coc_head.next,*argc,*argv,*next;
0925   CCodeMisc *misc;
0926   I64 intern_code;
0927   Bool finish=FALSE;
0928   CPrsStk *old=cc->ps;
0929   CArrayDim tmpad,*ic_dim;
0930   if(!_ps) {
0931     cc->ps=MAlloc(sizeof CPrsStk);
0932     cc->ps->ptr=0;
0933     cc->ps->ptr2=0;
0934     cc->ps->ptr3=0;
0935   } else {
0936     cc->ps=_ps;
0937   }
0938   I64 last_consumes_right=1;
0939   CHashFun *ic_fun=NULL,*last_c=NULL;
0940   CHashExport *tmpex;
0941   CHashClass *tmpc;
0942   CMemberLst *mlst;
0943   CAsmUndefHash *tmpauh;
0944 //u32[0] is type
0945   //u32[1] is prec
0946   CRPN *rpn,*rpn2;
0947   while(!finish) {
0948     rpn=NULL;
0949     cur_prec=-1;
0950     tok=cc->token;
0951     if((flags&PEF_NO_COMMA)&&(tok==',')) {
0952       finish=TRUE;
0953       break;
0954     }
0955     switch(tok) {
0956         break;start:
0957         case TK_PLUS_PLUS:
0958           if(last_consumes_right) {
0959             cur_prec=((PREC_UNARY_PRE|ASSOCF_RIGHT)<<32|IC_PP_);
0960             last_consumes_right=1;
0961           } else {
0962             cur_prec=(PREC_UNARY_POST<<32|IC__PP);
0963             last_consumes_right=0;
0964           }
0965           break;case TK_MINUS_MINUS:
0966           if(last_consumes_right) {
0967             cur_prec=((PREC_UNARY_PRE|ASSOCF_RIGHT)<<32|IC_MM_);
0968             last_consumes_right=1;
0969           } else {
0970             cur_prec=(PREC_UNARY_POST<<32|IC__MM);
0971             last_consumes_right=0;
0972           }
0973           break;case '&':
0974           if(last_consumes_right) {
0975             cur_prec=((PREC_UNARY_PRE|ASSOCF_RIGHT)<<32|IC_ADDR);
0976           } else {
0977             cur_prec=(PREC_AND<<32|IC_AND);
0978           }
0979           last_consumes_right=1;
0980           break;case '*':
0981           if(last_consumes_right) {
0982             cur_prec=((PREC_UNARY_PRE|ASSOCF_RIGHT)<<32|IC_DEREF);
0983             last_consumes_right=1;
0984           } else {
0985             cur_prec=(PREC_MUL<<32|IC_MUL);
0986             last_consumes_right=1;
0987           }
0988           break;case ',':
0989           if(last_consumes_right)
0990             LexExcept(cc,"Unexpected ',' at ");
0991           cur_prec=(PREC_MAX<<32|IC_COMMA);
0992           last_consumes_right=1;
0993           break;case '+':
0994           if(last_consumes_right) {
0995 //Positive does nothing
0996             cur_prec=-1;
0997           } else {
0998             cur_prec=(PREC_ADD<<32|IC_ADD);
0999             last_consumes_right=1;
1000           }
1001           break;case '-':
1002           if(last_consumes_right) {
1003             cur_prec=((PREC_UNARY_PRE|ASSOCF_RIGHT)<<32|IC_UNARY_MINUS);
1004             last_consumes_right=1;
1005           } else {
1006             cur_prec=(PREC_ADD<<32|IC_SUB);
1007             last_consumes_right=1;
1008           }
1009           break;case '~':
1010           if(last_consumes_right) {
1011             cur_prec=((PREC_UNARY_PRE|ASSOCF_RIGHT)<<32|IC_COM);
1012             last_consumes_right=1;
1013           } else
1014             LexExcept(cc,"Expected '~'.");
1015           break;case '!':
1016           if(last_consumes_right) {
1017             cur_prec=((PREC_UNARY_PRE|ASSOCF_RIGHT)<<32|IC_NOT);
1018             last_consumes_right=1;
1019           } else
1020             LexExcept(cc,"Expected '!'.");
1021           break;end:
1022         if(cur_prec!=-1) { //See above '+' operator
1023           if(cur_prec.u32[0]==IC_ADDR) {
1024             flags|=PEF_ADDR_OF;
1025           } else
1026             flags&=~PEF_ADDR_OF;
1027           PushOpers(cc,cur_prec);
1028           rpn=CAlloc(sizeof CRPN);
1029           if(cc->lock_cnt) rpn->ic_flags|=ICF_LOCK;
1030           rpn->type=cur_prec.u32[0];
1031           PrsPush(cc->ps,cur_prec);
1032           PrsPush2(cc->ps,rpn);
1033           QueInit(rpn);
1034         }
1035 //After getting an operator,we are no longer accepting function calls for now
1036         flags&=~PEF_FUN_BEFORE;
1037         tok=Lex(cc);
1038         break;start:
1039         if(last_consumes_right)
1040           LexExcept(cc,"Unexpected operator.");
1041         case '`':
1042           cur_prec=(PREC_EXP<<32|IC_POWER);
1043           last_consumes_right=1;
1044           break;case TK_SHL:
1045           cur_prec=(PREC_EXP<<32|IC_SHL);
1046           last_consumes_right=1;
1047           break;case TK_SHR:
1048           cur_prec=(PREC_EXP<<32|IC_SHR);
1049           last_consumes_right=1;
1050           break;case '/':
1051           cur_prec=(PREC_MUL<<32|IC_DIV);
1052           last_consumes_right=1;
1053           break;case '%':
1054           cur_prec=(PREC_MUL<<32|IC_MOD);
1055           last_consumes_right=1;
1056           break;case '|':
1057           cur_prec=(PREC_OR<<32|IC_OR);
1058           last_consumes_right=1;
1059           break;case '^':
1060           cur_prec=(PREC_XOR<<32|IC_XOR);
1061           last_consumes_right=1;
1062           break;case '<':
1063           cur_prec=(PREC_CMP<<32|IC_LESS);
1064           last_consumes_right=1;
1065           break;case '>':
1066           cur_prec=(PREC_CMP<<32|IC_GREATER);
1067           last_consumes_right=1;
1068           break;case TK_GREATER_EQU:
1069           cur_prec=(PREC_CMP<<32|IC_GREATER_EQU);
1070           last_consumes_right=1;      
1071           break;case TK_LESS_EQU:
1072           cur_prec=(PREC_CMP<<32|IC_LESS_EQU);
1073           last_consumes_right=1;
1074           break;case TK_EQU_EQU:
1075           cur_prec=(PREC_CMP2<<32|IC_EQU_EQU);
1076           last_consumes_right=1;      
1077           break;case TK_NOT_EQU:
1078           cur_prec=(PREC_CMP2<<32|IC_NOT_EQU);
1079           last_consumes_right=1;
1080           break;case TK_AND_AND:
1081           cur_prec=(PREC_AND_AND<<32|IC_AND_AND);
1082           last_consumes_right=1;
1083           break;case TK_XOR_XOR:
1084           cur_prec=(PREC_XOR_XOR<<32|IC_XOR_XOR);
1085           last_consumes_right=1;
1086           break;case TK_OR_OR:
1087           cur_prec=(PREC_OR_OR<<32|IC_OR_OR);
1088           last_consumes_right=1;
1089           break;case TK_SUB_EQU:
1090           cur_prec=((PREC_ASSIGN|ASSOCF_RIGHT)<<32|IC_SUB_EQU);
1091           last_consumes_right=1;
1092           break;case TK_ADD_EQU:
1093           cur_prec=((PREC_ASSIGN|ASSOCF_RIGHT)<<32|IC_ADD_EQU);
1094           last_consumes_right=1;
1095           break;case TK_XOR_EQU:
1096           cur_prec=((PREC_ASSIGN|ASSOCF_RIGHT)<<32|IC_XOR_EQU);
1097           last_consumes_right=1;
1098           break;case TK_OR_EQU:
1099           cur_prec=((PREC_ASSIGN|ASSOCF_RIGHT)<<32|IC_OR_EQU);
1100           last_consumes_right=1;
1101           break;case TK_AND_EQU:
1102           cur_prec=((PREC_ASSIGN|ASSOCF_RIGHT)<<32|IC_AND_EQU);
1103           last_consumes_right=1;
1104           break;case TK_DIV_EQU:
1105           cur_prec=((PREC_ASSIGN|ASSOCF_RIGHT)<<32|IC_DIV_EQU);
1106           last_consumes_right=1;
1107           break;case TK_MOD_EQU:
1108           cur_prec=((PREC_ASSIGN|ASSOCF_RIGHT)<<32|IC_MOD_EQU);
1109           last_consumes_right=1;
1110           break;case TK_MUL_EQU:
1111           cur_prec=((PREC_ASSIGN|ASSOCF_RIGHT)<<32|IC_MUL_EQU);
1112           last_consumes_right=1;
1113           break;case TK_SHL_EQU:
1114           cur_prec=((PREC_ASSIGN|ASSOCF_RIGHT)<<32|IC_SHL_EQU);
1115           last_consumes_right=1;
1116           break;case TK_SHR_EQU:
1117           cur_prec=((PREC_ASSIGN|ASSOCF_RIGHT)<<32|IC_SHR_EQU);
1118           last_consumes_right=1;
1119           break;case '=':
1120           cur_prec=((PREC_ASSIGN|ASSOCF_RIGHT)<<32|IC_ASSIGN);
1121           last_consumes_right=1;
1122       end:
1123         PushOpers(cc,cur_prec);
1124         flags&=~PEF_ADDR_OF;
1125         rpn=CAlloc(sizeof CRPN);
1126         if(cc->lock_cnt) rpn->ic_flags|=ICF_LOCK;
1127         rpn->type=cur_prec.u32[0];
1128         PrsPush(cc->ps,cur_prec);
1129         PrsPush2(cc->ps,rpn);
1130         Lex(cc);
1131 //After getting an operator,we are no longer accepting function calls for now
1132         flags&=~PEF_FUN_BEFORE;
1133         break;case TK_DEREFERENCE: //->,not *
1134       case '.':
1135         PrsMembers(cc);
1136         next=cc->coc.coc_head.next;
1137         if(next->ic_class->type&HTT_FUN) {
1138           flags|=PEF_FUN_BEFORE;
1139         } else
1140           flags&=~PEF_FUN_BEFORE;
1141         break;case '(':
1142         tok=Lex(cc);
1143         next=cc->coc.coc_head.next;
1144         if((flags&PEF_FUN_BEFORE)&&next->ic_class->type&HTT_FUN) {
1145           last_consumes_right=0;
1146           if(tok==TK_IDENT&&cc->hash_entry) {
1147 //Check for typecast 
1148             if(cc->hash_entry->type&(HTT_CLASS|HTT_INTERNAL_TYPE)) {
1149 //
1150               // Heres the Donald Trump deal. If we have a (implicit) function call before a typecast 
1151               //  we will first call the function,it makes no sense to typecast a function
1152               //
1153               ic_fun=cc->ps->stk3[cc->ps->ptr3](CRPN*)->ic_class;
1154               if(!ic_fun->ptr_stars_cnt) {
1155                 arity=ImplicitFunCall(cc,cc->coc.coc_head.next(CRPN*)->ic_class);
1156                 RPNAddNew(
1157                       cc,
1158                       IC_CALL_INDIRECT,
1159                       arity+1,
1160                       ic_fun->return_class
1161                       );
1162               }
1163 typecast:
1164               tmpc=cc->hash_entry;
1165 //TODO release tmpad
1166               Lex(cc);
1167               mode=PRS0_TYPECAST|PRS1_NULL;
1168               tmpc=PrsType(cc,&tmpc,&mode,NULL,NULL,&ic_fun,NULL,&tmpad,0);
1169               if(ic_fun) //ic_funs are extensions of CHashClass
1170                 tmpc=ic_fun;
1171               rpn=RPNAddNew(cc,IC_HOLYC_TYPECAST,tmpc,tmpc);
1172               rpn->ic_dim=tmpad.next;
1173               if(cc->token!=')') {
1174                 LexExcept(cc,"Expected a ')'.");
1175               } else
1176                 Lex(cc);
1177               goto end_paren;
1178             }
1179           }
1180           ic_fun=AssignRawTypeToNode(cc->coc.coc_head.next);
1181           if(ic_fun->ptr_stars_cnt)
1182             ic_fun=DerefType(ic_fun);
1183           if(!(ic_fun->type&HTT_FUN)) {
1184             LexExcept(cc,"Invalid type to call at ");
1185           }
1186           mlst=ic_fun->member_lst_and_root;
1187           arity=0;
1188           for(idx=0;idx!=ic_fun->arg_cnt;idx++) {
1189             if(mlst->flags&MLF_DOT_DOT_DOT) goto vargs;
1190             if(cc->token==',') {
1191               if(mlst->flags&MLF_LASTCLASS) {
1192                 while(last_c->ptr_stars_cnt)
1193                   last_c=DerefType(last_c);
1194                 misc=COCMiscNew(cc,CMT_STR_CONST);
1195                 cc->flags|=CCF_HAS_MISC_DATA;
1196                 misc->str=StrNew(last_c->str);
1197                 misc->st_len=StrLen(last_c->str)+1;
1198                 RPNAddNew(
1199                       cc,
1200                       IC_STR_CONST,
1201                       misc,
1202                       last_c=cmp.internal_types[RT_U8]+1
1203                       );
1204                 arity++;
1205               } else if(mlst->flags&(MLF_DFT_AVAILABLE|MLF_STR_DFT_AVAILABLE)) {
1206                 last_c=mlst->member_class;
1207                 if(mlst->member_class->raw_type==RT_F64) {
1208                   RPNAddNew(
1209                         cc,
1210                         IC_IMM_F64,
1211                         mlst->dft_val,
1212                         cmp.internal_types[RT_F64]
1213                         );
1214                   arity++;
1215                 } else {
1216                   RPNAddNew(
1217                         cc,
1218                         IC_IMM_I64,
1219                         mlst->dft_val,
1220                         cmp.internal_types[RT_I64]
1221                         );
1222                   arity++;
1223                 }
1224               } else
1225                 LexExcept(cc,"Missing dft argument at:");
1226               Lex(cc);
1227             } else if(cc->token!=')') {
1228               if(!PrsExpression(cc,,PEF_NO_COMMA))
1229                 LexExcept(cc,"Expected a function argument at:");
1230               PrsPush3(cc->ps,cc->coc.coc_head.next);
1231               arity++;
1232               rpn=cc->coc.coc_head.next;
1233               last_c=rpn->ic_class;
1234               if(rpn->ic_class->raw_type==RT_F64&&mlst->member_class->raw_type!=RT_F64) {
1235                 RPNAddNew(cc,IC_TO_I64,,cmp.internal_types[RT_I64],TRUE);
1236               } else if(rpn->ic_class->raw_type!=RT_F64&&mlst->member_class->raw_type==RT_F64) {
1237                 RPNAddNew(cc,IC_TO_F64,,cmp.internal_types[RT_F64],TRUE);
1238               }
1239               if(cc->token==',') {
1240                 Lex(cc);
1241               }
1242               else if(cc->token==')') {
1243                 goto end_call;
1244               } else
1245                 LexExcept(cc,"Expected a ')'.");
1246             } else {
1247 end_call:
1248               break;
1249             }
1250             mlst=mlst->next;
1251           }
1252           arity=ImplicitFunCall(cc,ic_fun,arity);
1253 vargs:
1254           if(Bt(&ic_fun->flags,Ff_DOT_DOT_DOT)) {
1255             arity+=2;
1256             argc=RPNAddNew(cc,IC_IMM_I64,0);
1257             idx=0;
1258             while(cc->token!=')') {
1259               if(PrsExpression(cc,NULL,PEF_NO_COMMA)) {
1260                 PrsPush3(cc->ps,cc->coc.coc_head.next);
1261                 idx++;
1262               }
1263               if(cc->token==',')
1264                 Lex(cc);
1265               else if(cc->token==')') {
1266                 break;
1267               } else
1268                 LexExcept(cc,"Expected a ')'.");
1269             }
1270             argv=RPNAddNew(cc,IC_VARGS,idx);
1271             argc->ic_data=idx;
1272           }
1273           if(cc->token!=')')
1274             LexExcept(cc,"Expected a ')'.");
1275           Lex(cc);
1276           arity++; //Include the function in the arity
1277 //Check for _intern functions 
1278           if(!(ic_fun->flags&(1<<Ff_INTERNAL))) {
1279             RPNAddNew(
1280                   cc,
1281                   IC_CALL_INDIRECT,
1282                   arity,
1283                   ic_fun->return_class
1284                   );
1285           } else {
1286 use_intern:
1287             rpn=RPNAddNew(
1288                   cc,
1289                   IC_CALL_INDIRECT,
1290                   arity,
1291                   ic_fun->return_class
1292                   );
1293 //"SWAP" out the new rpn type with the desired one
1294             rpn->type=ic_fun->exe_addr;                   
1295             rpn->ic_data=0;
1296 //next is the old dummy function,not needed as we are using an intermendiate
1297             RPNDel(next);
1298           }
1299         } else {
1300           if(tok==TK_IDENT&&cc->hash_entry) {
1301             if(cc->hash_entry->type&(HTT_CLASS|HTT_INTERNAL_TYPE))
1302               goto typecast;
1303           }
1304           cur_prec=PREC_NULL<<32;
1305           PrsPush(cc->ps,cur_prec);
1306           PrsPush2(cc->ps,NULL);
1307           last_consumes_right=1;
1308         }
1309 end_paren:
1310         break;case ')':
1311         last_consumes_right=0;
1312 //PrsPush starts at 1,and top is ->ptr
1313         for(idx=1;idx<=cc->ps->ptr;idx++) {
1314           if(cc->ps->stk[idx].u32[1]==PREC_NULL) {
1315             goto found_end_paren;
1316           }
1317         }
1318 //LexExcept(cc,"Unexpected ')'.");
1319         finish=TRUE;
1320         goto paren_unexp;
1321 found_end_paren:;
1322         Lex(cc);
1323         PushOpers(cc,PREC_NULL<<32);
1324 //PushOpers doesnt POP parens
1325         PrsPop(cc->ps);
1326         PrsPop2(cc->ps);
1327         next=cc->coc.coc_head.next;
1328         if(next!=&cc->coc.coc_head.next&&next->ic_class->type&HTT_FUN) {
1329           flags|=PEF_FUN_BEFORE;
1330         } else
1331           flags&=~PEF_FUN_BEFORE;
1332 paren_unexp:;
1333         break;case '[':
1334         if(cc->flags&CCF_ASM_EXPRESSIONS) {
1335           finish=TRUE;
1336           break;
1337         }
1338         Lex(cc);
1339         PrsPush(cc->ps,(PREC_NULL<<32)|'[]');
1340         PrsPush2(cc->ps,NULL);
1341         last_consumes_right=1;
1342         break;case ']':
1343 //PrsPush starts at 1,and top is ->ptr
1344         for(idx=1;idx<=cc->ps->ptr;idx++) {
1345           if(cc->ps->stk[idx]==(PREC_NULL<<32)|'[]') {
1346             goto found_end_square;
1347           }
1348         }
1349         finish=TRUE;
1350         goto paren_unexp;
1351 found_end_square:
1352 //[] doesnt pop the (PREC_NULL<<32)|'[]'
1353         PushOpers(cc,PREC_NULL);
1354         PrsPop(cc->ps);
1355         PrsPop2(cc->ps);
1356         Lex(cc);
1357         next=cc->coc.coc_head.next;
1358         if(next==&cc->coc.coc_head.next)
1359           LexExcept(cc,"Expected not empty '[]' at ");
1360         if(next->ic_class->raw_type==RT_F64)
1361           RPNAddNew(cc,IC_TO_I64);
1362         RPNAddNew(cc,IC_ADD);
1363         RPNAddNew(cc,IC_DEREF);
1364         last_consumes_right=0;
1365         next=cc->coc.coc_head.next;
1366         if(next->ic_class->type&HTT_FUN) {
1367           flags|=PEF_FUN_BEFORE;
1368         } else
1369           flags&=~PEF_FUN_BEFORE;
1370         break;start:
1371         if(!last_consumes_right)
1372           finish=TRUE;
1373         case TK_STR:
1374           if(finish) break;
1375           cc->flags|=CCF_HAS_MISC_DATA;
1376           misc=COCMiscNew(cc,CMT_STR_CONST);
1377           misc->str=LexExtStr(cc,&str_len);
1378           misc->st_len=str_len;
1379           RPNAddNew(cc,IC_STR_CONST,misc);
1380           last_consumes_right=0;
1381           break;case TK_INS_BIN:
1382           if(finish) break;
1383           cc->flags|=CCF_HAS_MISC_DATA;
1384           misc=COCMiscNew(cc,CMT_STR_CONST);
1385           misc->st_len=cc->cur_str_len;
1386           misc->str=MAlloc(misc->st_len+1);
1387           MemCpy(misc->str,cc->cur_str,cc->cur_str_len);
1388           RPNAddNew(cc,IC_STR_CONST,misc);
1389           last_consumes_right=0;
1390           Lex(cc);
1391           break;case TK_CHAR_CONST:
1392           if(finish) break;
1393           RPNAddNew(cc,IC_IMM_I64,cc->cur_i64,cmp.internal_types[RT_I64]);
1394           last_consumes_right=0;
1395           Lex(cc);
1396           break;case TK_I64:
1397           if(finish) break;
1398           RPNAddNew(cc,IC_IMM_I64,cc->cur_i64,cmp.internal_types[RT_I64]);
1399           last_consumes_right=0;
1400           Lex(cc);
1401           break;case TK_F64:
1402           if(finish) break;
1403           RPNAddNew(cc,IC_IMM_F64,cc->cur_f64(I64),cmp.internal_types[RT_F64]);
1404           last_consumes_right=0;
1405           Lex(cc);
1406           break;case TK_IDENT:
1407           if(finish) break;
1408           last_consumes_right=0;
1409           if(cc->flags&CCF_ASM_EXPRESSIONS) {
1410             if(cc->local_var_entry&&cc->htc.fun) {
1411               if(flags&PEF_ADDR_OF) {
1412                 PrsPop(cc->ps);
1413                 RPNDel(PrsPop2(cc->ps));
1414               } else
1415                 LexExcept(cc,"Expected a '&' at ");
1416               cc->local_var_entry->reg=REG_NONE;
1417               tmpex=CAlloc(sizeof(CHashExport));
1418               tmpex->str=MStrPrint("%s.%s",cc->htc.fun->str,cc->cur_str);
1419               tmpex->type=HTT_EXPORT_SYS_SYM | HTF_UNRESOLVED;
1420               goto ins_label;
1421             } else if(cc->hash_entry&&cc->hash_entry->type&HTT_CLASS) {
1422 //MOV RAX, CTask.addr[RBX]
1423               PrsOffsetOf(cc);
1424               break;
1425             } else if(!cc->hash_entry) {
1426 new:
1427               tmpex=CAlloc(sizeof(CHashExport));
1428               tmpex->str=StrNew(cc->cur_str);
1429               if (*tmpex->str=='@' && tmpex->str[1]=='@') {
1430                 tmpex->type=HTT_EXPORT_SYS_SYM | HTF_UNRESOLVED | HTF_LOCAL;
1431 //
1432                 //Nroot here,I turn local labels into scope.@@local
1433                 //
1434                 Free(tmpex->str);
1435                 tmpex->str=MStrPrint("%d.%s",cc->asm_local_scope,cc->cur_str);
1436 //HashAdd(tmpex,cc->htc.local_hash_table);
1437                 cc->flags|=CCF_LOCAL;
1438                 goto ins_label;
1439               } else {
1440                 tmpex->type=HTT_EXPORT_SYS_SYM | HTF_UNRESOLVED;
1441 ins_label:
1442                 tmpc=HashFind(tmpex->str,cc->htc.glbl_hash_table,HTT_EXPORT_SYS_SYM);
1443                 if (tmpc)
1444                   HashAddAfter(tmpex,tmpc,cc->htc.glbl_hash_table);
1445                 else
1446                   HashAdd(tmpex,cc->htc.glbl_hash_table);
1447               }
1448               cc->flags|=CCF_UNRESOLVED;
1449               rpn=RPNAddNew(
1450                     cc,
1451                     IC_ADDR_IMPORT,
1452                     CodeMiscHashNew(cc,tmpex),
1453                     cmp.internal_types[RT_I64],
1454                     );
1455               Lex(cc);
1456               tmpauh=CAlloc(sizeof CAsmUndefHash);
1457               tmpauh->hash=tmpex;
1458               tmpauh->next=cc->asm_undef_hash;
1459               cc->asm_undef_hash=tmpauh;
1460               goto fin_ident;
1461             } else if(cc->hash_entry->type&HTT_EXPORT_SYS_SYM&&cc->hash_entry->type&HTF_RESOLVE) {
1462               rpn=RPNAddNew(
1463                     cc,
1464                     IC_ADDR_IMPORT,
1465                     CodeMiscHashNew(cc,cc->hash_entry),
1466                     cmp.internal_types[RT_I64],
1467                     );
1468               Lex(cc);
1469               goto fin_ident;
1470             } else if(cc->hash_entry->type&HTT_EXPORT_SYS_SYM) {
1471               goto new;
1472             }
1473           }
1474           if(cc->local_var_entry) {
1475             if(cc->local_var_entry->flags&MLF_STATIC) {
1476               rpn=RPNAddNew(cc,IC_STATIC,
1477                     cc->local_var_entry->static_data,
1478                     cc->local_var_entry->member_class
1479                     );
1480             } else {
1481               rpn=RPNAddNew(cc,IC_FRAME,
1482                     cc->local_var_entry->offset,
1483                     cc->local_var_entry->member_class
1484                     );
1485             }
1486             if(cc->local_var_entry->flags&MLF_FUN) {
1487 //TempleOS stores Function class in ->fun_ptr for some reason(when MLF_FUN is set) 
1488               rpn->ic_class=cc->local_var_entry->fun_ptr;
1489             }
1490             rpn->ic_dim=cc->local_var_entry->dim.next;
1491             Lex(cc);
1492           } else if(cc->hash_entry) {
1493             if(cc->hash_entry->type&HTT_OPCODE||cc->hash_entry->type&HTT_REG) {
1494               finish=TRUE;
1495               goto fin_ident;
1496             }
1497             if(cc->hash_entry->type&HTT_FUN) {
1498               ic_fun=cc->hash_entry;
1499               if(Bt(&ic_fun->flags,Ff_INTERNAL)) {
1500                 rpn=RPNAddNew(
1501                       cc,
1502                       IC_IMM_I64,
1503                       cc->hash_entry(CHashFun*)->exe_addr,
1504                       cc->hash_entry,
1505                       );
1506               } else if(cc->flags&CCF_AOT_COMPILE||Bt(&cc->hash_entry(CHashFun*)->flags,Cf_EXTERN))
1507                 rpn=RPNAddNew(
1508                       cc,
1509                       IC_ADDR_IMPORT,
1510                       CodeMiscHashNew(cc,cc->hash_entry),
1511                       cc->hash_entry,
1512                       );
1513               else
1514                 rpn=RPNAddNew(
1515                       cc,
1516                       IC_IMM_I64,
1517                       cc->hash_entry(CHashFun*)->exe_addr,
1518                       cc->hash_entry,
1519                       );
1520               Lex(cc);
1521               next=rpn;
1522               if(cc->ps->ptr&&cc->ps->stk[cc->ps->ptr].u32[0]==IC_ADDR) {
1523                 if(ic_fun->flags&(1<<Ff_INTERNAL)) {
1524 //Account for &Fs->task_flags
1525                   if(cc->token=='('||cc->token=='.'||cc->token==TK_DEREFERENCE) {
1526 //All is good,not '(' so continue as usal
1527                     if(cc->token!='(')
1528                       goto implicit_call;
1529                   } else
1530                     LexExcept(cc,"Can't get address of internal function at ");
1531                 } else {
1532 //Continue as usual
1533                   //Dont derefernce to function pointer if it is a call or "&Call()->member"
1534                   if(cc->token=='('||cc->token=='.'||cc->token==TK_DEREFERENCE) {
1535                     if(cc->token!='(')
1536                       goto implicit_call;
1537                   } else {
1538                     rpn->ic_class=AddrOfType(rpn->ic_class); //Emulate a pointer star
1539                     PrsPop(cc->ps);
1540                     Free(PrsPop2(cc->ps)); //Free node
1541                   }
1542                 }
1543               } else if(cc->token!='(') {
1544 //Is an implicit function call
1545                 implicit_call:
1546                 arity=ImplicitFunCall(cc,ic_fun,0);
1547                 if(ic_fun->flags&(1<<Ff_DOT_DOT_DOT)) {
1548                   RPNAddNew(cc,IC_IMM_I64,0); //Add argc,argv not needed
1549                   arity++;
1550                 }
1551                 arity++;//Include function
1552                 if(Bt(&ic_fun->flags,Ff_INTERNAL)) {
1553                   goto use_intern;
1554                 } else
1555                   RPNAddNew(
1556                         cc,
1557                         IC_CALL_INDIRECT,
1558                         arity,
1559                         ic_fun->return_class
1560                         );
1561                 goto fin_ident;
1562               }
1563             } else if(cc->hash_entry->type&HTT_GLBL_VAR) {
1564               if(cc->hash_entry(CHashGlblVar*)->data_addr&&!(cc->flags&CCF_AOT_COMPILE)) {
1565                 rpn=RPNAddNew(
1566                       cc,
1567                       IC_IMM_I64,
1568                       cc->hash_entry(CHashGlblVar*)->data_addr,
1569                       cmp.internal_types[RT_I64],
1570                       );
1571               } else {
1572                 rpn=RPNAddNew(
1573                       cc,
1574                       IC_ADDR_IMPORT,
1575                       CodeMiscHashNew(cc,cc->hash_entry),
1576                       cc->hash_entry(CHashGlblVar*)->var_class,
1577                       );
1578               }
1579               if(cc->hash_entry(CHashGlblVar*)->fun_ptr) {
1580                 rpn=RPNAddNew(
1581                       cc,
1582                       IC_DEREF,
1583                       0,
1584                       cc->hash_entry(CHashGlblVar*)->fun_ptr,
1585                       );
1586               } else {
1587                 rpn=RPNAddNew(
1588                       cc,
1589                       IC_DEREF,
1590                       0,
1591                       cc->hash_entry(CHashGlblVar*)->var_class,
1592                       );
1593               }
1594               rpn->ic_dim=cc->hash_entry(CHashGlblVar*)->dim.next;
1595               Lex(cc);
1596             } else if(cc->hash_entry->type&HTT_KEYWORD) {
1597               switch(cc->hash_entry(CHashGeneric *)->user_data0) {
1598                   break;case KW_SIZEOF:
1599                   idx=0;
1600                   while (Lex(cc)=='(')
1601                     idx++;
1602                   PrsSizeOf(cc);
1603                   while (idx--) {
1604                     if (cc->token!=')')
1605                       LexExcept(cc,"Missing ')' at ");
1606                     Lex(cc);
1607                   }
1608                   break;case KW_OFFSET:
1609                   idx=0;
1610                   while (Lex(cc)=='(')
1611                     idx++;
1612                   PrsOffsetOf(cc);
1613                   while (idx--) {
1614                     if (cc->token!=')')
1615                       LexExcept(cc,"Missing ')' at ");
1616                     Lex(cc);
1617                   }
1618                   break;default:
1619                   LexExcept(cc,"Unexpected keyword at: ");
1620               }
1621             } else {
1622               LexExcept(cc,"Unknown symbol at ");
1623             }
1624           } else
1625             LexExcept(cc,"Unknown symbol at ");
1626           rpn=cc->coc.coc_head.next;
1627           if(ic_dim=rpn->ic_dim) {
1628             RPNAddNew(cc,IC_ADDR,,,TRUE);
1629 //IC_ADDR of IC_DEREF will cancel each other out,so re-assign the dim
1630             rpn=cc->coc.coc_head.next;
1631             rpn->ic_dim=ic_dim;
1632           }
1633 fin_ident:
1634           next=cc->coc.coc_head.next;
1635           if(next!=&cc->coc.coc_head&&next->ic_class->type&HTT_FUN) {
1636             flags|=PEF_FUN_BEFORE;
1637           } else
1638             flags&=~PEF_FUN_BEFORE;
1639 fin_ident_final:;
1640           break;end:
1641         flags&=~PEF_ADDR_OF;
1642         break;default:
1643         goto fin;
1644     }
1645   }
1646 fin:
1647   PushOpers(cc,PREC_NULL<<32,TRUE);
1648   if(!_ps)
1649     Free(cc->ps);
1650   cc->ps=old;
1651   return cc->coc.coc_head.next!=orig_next;
1652 }
1653 
1654 U0 ParserTest() {
1655   CCmpCtrl *cctrl=CmpCtrlNew(
1656     "1+3/4+5 ",
1657     CCF_DONT_FREE_BUF,
1658     "TEST.HC"
1659   );
1660   Lex(cctrl);
1661   QueInit(&cctrl->coc.coc_head);
1662   PrsExpression(cctrl,NULL,0);
1663   DumpRPN(cctrl->coc.coc_head.next);
1664   cctrl=CmpCtrlNew(
1665     "(1+(3))/(4+5) ",
1666     CCF_DONT_FREE_BUF,
1667     "TEST.HC"
1668   );
1669   Lex(cctrl);
1670   QueInit(&cctrl->coc.coc_head);
1671   PrsExpression(cctrl,NULL,0);
1672   "FIN2\n";
1673   DumpRPN(cctrl->coc.coc_head.next);
1674   cctrl=CmpCtrlNew(
1675     "(1+2)(I64i*)[3+4] ",
1676     CCF_DONT_FREE_BUF,
1677     "TEST.HC"
1678   );
1679   Lex(cctrl);
1680   QueInit(&cctrl->coc.coc_head);
1681   PrsExpression(cctrl,NULL,0);
1682   DumpRPN(cctrl->coc.coc_head.next);  
1683 }
1684 
1685 U8 *LexExpression2Bin(CCmpCtrl *cc,I64 *_type=NULL)
1686 {//Compile cc expression. You call the code.
1687   U8 *res;
1688   I64 size;
1689   CHashFun *old_fun;
1690   Bool old_trace=LBtr(&cc->flags,CCf_PASS_TRACE_PRESENT);
1691   COCPush(cc);
1692   COCInit(cc);
1693   if (PrsExpression(cc,NULL,PEF_NO_COMMA)) {
1694     RPNAddNew(cc,IC_RET,0,AssignRawTypeToNode(cc->coc.coc_head.next),FALSE);
1695     old_fun=cc->htc.fun; //Changed by nroot
1696     cc->htc.fun=NULL;
1697     res=AiwniosCompile(cc);
1698     cc->htc.fun=old_fun;
1699     if(_type) *_type=AssignRawTypeToNode(cc->coc.coc_head.next)->raw_type; 
1700   } else
1701     res=NULL;
1702   COCPop(cc);
1703   if(old_trace)
1704     LBts(&cc->flags,CCf_PASS_TRACE_PRESENT);
1705   else
1706     LBtr(&cc->flags,CCf_PASS_TRACE_PRESENT);
1707   return res;
1708 }
1709 
1710 Bool IsLexExpression2Bin(CCmpCtrl *cc,U8 **_machine_code)
1711 {//Compile cc expression to bin. Return err status.
1712   return !!(*_machine_code=LexExpression2Bin(cc));
1713 }
1714 
1715 I64 LexExpressionI64(CCmpCtrl *cc)
1716 {//Compile cc expression, forcing to I64 and eval.
1717   I64 (*machine_code)();
1718   I64 res,type;
1719   if (machine_code=LexExpression2Bin(cc,&type)) {
1720     res=(*machine_code)();
1721     Free(machine_code);
1722     if (type==RT_F64)
1723       res=ToI64(res(F64));
1724   } else
1725     res=0;
1726   return res;
1727 }
1728 
1729 F64 LexExpressionF64(CCmpCtrl *cc)
1730 {//Compile cc expression, forcing to F64 and eval.
1731   F64 (*machine_code)();
1732   I64 res,type;
1733   if (machine_code=LexExpression2Bin(cc,&type)) {
1734     res=(*machine_code)();
1735     Free(machine_code);
1736     if (type!=RT_F64)
1737       res(F64)=ToF64(res);
1738   } else
1739     res=0;
1740   return res(F64);
1741 }
1742 
1743 I64 LexExpression(CCmpCtrl *cc)
1744 {//Compile cc expression and eval.  Might be I64 or F64.
1745   I64 (*machine_code)();
1746   I64 res;
1747   if (machine_code=LexExpression2Bin(cc)) {
1748     res=(*machine_code)();
1749     Free(machine_code);
1750   } else
1751     res=0;
1752   return res;
1753 }
1754 
1755 CRPN *RPNNext(CRPN *rpn) {
1756   I64 i,to;
1757   switch(intermediate_code_table[rpn->type].arg_cnt) {
1758     break;case IS_0_ARG:
1759       return rpn->next;
1760     break;case IS_1_ARG:
1761       return RPNNext(rpn->next);
1762     break;case IS_2_ARG:
1763       return RPNNext(RPNNext(rpn->next));
1764     break;case IS_V_ARG:
1765     to=rpn->length;
1766     rpn=rpn->next;
1767     for(i=0;i!=to;i++)
1768       rpn=RPNNext(rpn);
1769     return rpn;
1770   }
1771 }
1772 CRPN *RPNArgN(CRPN *rpn,I64 arg) {
1773   I64 i;
1774   rpn=rpn->next;
1775   for(i=0;i!=arg;i++) {
1776     rpn=RPNNext(rpn);
1777   }
1778   return rpn;
1779 }