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