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 }