I8 CmpKeyWord(LexStruct *l) { I8 result=-1; SysHashEntry *temph; if (l->token==TK_IDENT) if (temph=l->hash_entry) if (temph->type == HTT_KEYWORD) result=temph->user0; return result; } #define PVLM_LOCAL_VAR 0 #define PVLM_FUNCTION_PARAM 1 #define PVLM_CLASS 2 #define PVLM_UNION 3 void CmpParseVarList(LexStruct *l,ClassStruct *tempc, I8 mode,U8 union_base=MAX_I4) { I8 i,j,k,old_flags; U8 ptr_cnt,size; ClassStruct *tempc1,*tempc2; SysHashEntry *temph; MemberListStruct *tempm; U1 *e; if (mode!=PVLM_LOCAL_VAR || union_base!=MAX_I4) { if (l->token=='(' || l->token=='{') Lex(l); } while (TRUE) { while (l->token==';') Lex(l); if (l->token==')' || l->token=='}') { Lex(l); return; } if (l->token=='.') { if (Lex(l)=='.') { if (Lex(l)=='.') { Lex(l); tempm=MAllocZ(sizeof(MemberListStruct)); tempm->flags=MLF_DOT_DOT_DOT; tempm->member_class=sys_internal_types[IT_U4]; tempm->string=NewString("argc"); tempc2=tempc->last_in_member_list; tempc2->next=tempm; tempc->last_in_member_list=tempm; tempm->offset=tempc->size; tempc->size+=8; tempm=MAllocZ(sizeof(MemberListStruct)); tempm->flags=MLF_DOT_DOT_DOT; tempm->member_class=sys_internal_types[IT_I8]+sizeof(ClassStruct); tempm->string=NewString("argv"); tempm->cnt=127; //nonzero tempc2=tempc->last_in_member_list; tempc2->next=tempm; tempc->last_in_member_list=tempm; tempm->offset=tempc->size; tempc->size+=8; if (l->token==')' || l->token=='}') Lex(l); return; } else PrsExcept(l,"ST_EXPECTING_TYPE"); } else PrsExcept(l,"ST_EXPECTING_TYPE"); } temph=NULL; if (l->token==TK_IDENT) { temph=l->hash_entry; k=CmpKeyWord(l); } if (!temph) PrsExcept(l,"ST_EXPECTING_TYPE"); if (k==KW_UNION) { Lex(l); CmpParseVarList(l,tempc,mode,tempc->size); } else { tempc1=temph; if (!(tempc1->type & (HTT_CLASS | HTT_INTERNAL_TYPE))) PrsExcept(l,"ST_EXPECTING_TYPE"); do { LexPush(l); Lex(l); //skip type ptr_cnt=0; while (l->token=='*') { l->stack_ptr--; //grows up LexPush(l); Lex(l); ptr_cnt++; } if (l->token!=TK_IDENT) PrsExcept(l,"ST_EXPECTING_IDENTIFIER"); tempm=MAllocZ(sizeof(MemberListStruct)); tempm->member_class=tempc1; tempm->string=l->ident; l->ident=NULL; tempc2=tempc->last_in_member_list; tempc2->next=tempm; tempc->last_in_member_list=tempm; tempc->member_cnt++; if (Lex(l)=='(') { tempm->flags|=MLF_FUNCTION; if (Lex(l)!=')') { tempm->parameter_cnt++; while (l->token!=')') { if (l->token==',') tempm->parameter_cnt++; Lex(l); } } Lex(l); //skip ) } if (l->token=='[') { if (Lex(l)==']) ptr_cnt++; else tempm->cnt=Expression(l); if (l->token!=']') PrsExcept(l,"ST_MISSING_RIGHT_BRACKET"); Lex(l); } tempm->member_class+=ptr_cnt*sizeof(ClassStruct); if (tempm->flags & MLF_FUNCTION) tempm->member_class=sys_internal_types[IT_U4]+sizeof(ClassStruct); tempc2=tempm->member_class; i=tempc2->size; j=(tempm->cnt)? tempm->cnt:1; i*=j; if (mode==PVLM_LOCAL_VAR) { if (union_base!=0x7FFFFFFF) { if (union_base-tempc->sizesize=union_base-i; } else tempc->size=tempc->size-i; tempm->offset=tempc->size; if (l->token=='=') { LexPop(l); Lex(l); if (!PrsParseExpression(l,TRUE)) throw(EXCEPT_COMPILER,7); } else l->stack_ptr--; } else if (mode==PVLM_FUNCTION_PARAM) { if (union_base!=0x7FFFFFFF) { tempm->offset=union_base; if (tempc->size-union_base<8) tempc->size=8+union_base; } else { tempm->offset=tempc->size; tempc->size+=8; } if (l->token=='=') { Lex(l); old_flags=l->flags; l->flags&=~LF_HAS_MISC_DATA; e=CompileExpression(l); if (!e) throw(EXCEPT_COMPILER,8); tempm->default_value=Run(e); //TODO: if l->a if (!(l->flags & LF_HAS_MISC_DATA)) DelExpression(e); else if (l->a) PrsExcept(l,"ST_STRING_DEFAULT"); tempm->flags|=MLF_DEFAULT_AVAILABLE; l->flags|=old_flags&LF_HAS_MISC_DATA; } l->stack_ptr--; } else { //CLASS if (union_base!=MAX_I4) { tempm->offset=union_base; if (tempc->size-union_basesize=i+union_base; } else { tempm->offset=tempc->size; tempc->size+=i; } do { temph=NULL; k=CmpKeyWord(l); if (k==KW_FMTSTR) { if (Lex(l)!=TK_STRING) PrsExcept(l,"ST_EXPECTING_STRING"); tempm->fmtstr=LexExtendString(l,&size); } else if (k==KW_FMTDATA) { if (Lex(l)!=TK_STRING) PrsExcept(l,"ST_EXPECTING_STRING"); tempm->fmtdata=LexExtendString(l,&size); } } while (k==KW_FMTSTR || k==KW_FMTDATA); l->stack_ptr--; } if (l->token==',') { if (mode==PVLM_FUNCTION_PARAM && union_base==MAX_I4) { Lex(l); break; } } else if (l->token==')' || l->token=='}') { Lex(l); return; } else if (l->token==';') { Lex(l); if (mode==PVLM_LOCAL_VAR && union_base==MAX_I4) return; break; } else PrsExcept(l,"ST_MISSING_SEMICOLON"); } while (TRUE); } } } ClassStruct *CmpParseClass(LexStruct *l,BoolU4 is_union,BoolU4 is_public) { SysHashEntry *temph1; ClassStruct *tempc; if (l->token!=TK_IDENT) PrsExcept(l,"ST_EXPECTING_IDENTIFIER"); tempc=CmpClassNew; if (is_public) tempc->type|=HTT_PUBLIC; tempc->string=l->ident; l->ident=NULL; SetSourceFileInfo(l,tempc); tempc->use_cnt=0; if (l->a) temph1=FindHashBucket(tempc->string,l->a->glbl_hash); else temph1=FindHashBucket(tempc->string,l->hash_table_list); tempc->next=temph1->next; temph1->next=tempc; Lex(l); CmpParseVarList(l,tempc,PVLM_CLASS,(is_union)?0:0x7FFFFFFF); return tempc; } void UndefinedExtern() { PutSysText("ST_UNDEFINED_EXTERN"); throw(EXCEPT_UNDEF_EXTERN); } ClassStruct *CmpParseFunctionJoin(LexStruct *l, ClassStruct *temp_return,I1 *name,BoolU4 is_public,BoolU4 needs_abs) { MemberListStruct *tempm; AsmCtrlStruct *a=l->a; SysHashEntry *temph1; SysHashTable *tempht; ClassStruct *tempc; ExeAbsoluteAddressStruct *tempa; if (a) { if (tempc=FindHashEntry(name,a->glbl_hash,HTT_ALL)) { if (!(tempc->type & HTT_FUNCTION)) tempc=NULL; } if (!tempc) temph1=FindHashBucket(name,a->glbl_hash); } else { tempht=l->hash_table_list->next; l->hash_table_list->next=NULL; if (tempc=FindHashEntry(name,l->hash_table_list,HTT_ALL)) { if (!(tempc->type & HTT_FUNCTION)) tempc=NULL; } l->hash_table_list->next=tempht; if (!tempc) temph1=FindHashBucket(name,l->hash_table_list); } if (!tempc) { tempc=CmpClassNew; tempc->next=temph1->next; temph1->next=tempc; tempc->type=HTT_FUNCTION; tempc->string=name; if (a) { tempc->executable_address=a->ip; if (needs_abs) { tempa=MAllocZ(sizeof(ExeAbsoluteAddressStruct)); tempa->next=a->absolutes; a->absolutes=tempa; tempa->ip=a->ip; } AsmStoreCodeU1(l,0); AsmStoreCodeU1(l,0); AsmStoreCodeU1(l,0); AsmStoreCodeU1(l,0); } else tempc->executable_address=&UndefinedExtern; Bts(&tempc->flags,Cf_EXTERN); } else { Free(tempc->source_link); Free(name); DelMemberList(tempc); } if (is_public) tempc->type|=HTT_PUBLIC; else tempc->type&=~HTT_PUBLIC; tempc->return_class=temp_return; tempc->use_cnt=0; SetSourceFileInfo(l,tempc); CmpParseVarList(l,tempc,PVLM_FUNCTION_PARAM); tempc->parameter_cnt=tempc->member_cnt; tempm=tempc->member_list; while (tempm) { tempm->offset+=8; //EBP+RETURN tempm=tempm->next; } tempc->size=0; return tempc; } void CmpParseFunction(LexStruct *l, ClassStruct *temp_return,I1 *name,BoolU4 is_public) { U1 *result; AsmCtrlStruct *a=l->a; ClassStruct *tempc; MemberListStruct *tempm; U8 i,j,size; DbgInfo *dbg=NULL; l->flags&=~LF_NO_REG_OPT; tempc=CmpParseFunctionJoin(l,temp_return,name,is_public,TRUE); l->local_var_list=tempc; CbPush(l); CbInitOutPtrs(&l->cb); CbAddIc(l,EC_ENTER,0,0); CmpParseStatement(l,tempc,0,NULL,NULL,FALSE); CbAddIc(l,EC_LEAVE,0,0); CbAddIc(l,0,0,0); tempc->size&=-8; if (a) { i=a->ip; j=tempc->executable_address; if (Bt(&tempc->flags,Cf_EXTERN)) { AsmStoreCodeU1At(l,i.u1[0],j); AsmStoreCodeU1At(l,i.u1[1],j+1); AsmStoreCodeU1At(l,i.u1[2],j+2); AsmStoreCodeU1At(l,i.u1[3],j+3); } tempc->executable_address=i; tempc->type|=HTT_EXPORT; result=CbCompile(l,tempc,&size,&dbg); tempc->debug=dbg; if (result) { for (i=0;iexecutable_address=CbCompile(l,tempc,&size,&dbg); tempc->debug=dbg; } Btr(&tempc->flags,Cf_EXTERN); CbPop(l); l->local_var_list=NULL; tempm=tempc->member_list; while (tempm) { if (!tempm->use_cnt) { coutln SysText("ST_WARNING"),SysText("ST_UNUSED_VAR"); PrintF(" $$LK -A \"FL:%s,%d\"$$ '", l->cur_lfn->name,l->cur_lfn->line_num); coutln tempm->string,"' in '",tempc->string,"'"; } tempm=tempm->next; } } void CatchAll() { I8 i; if (Fs->except_argc>0) { if (Fs->except_argv[0]except_argv[0],"ST_EXCEPT_TYPES"); if (Fs->except_argv[0]==EXCEPT_UNDEF_SYSTEXT) PrintF("Name:'%s'\r\n",Fs->except_argv[1]); else if (Fs->except_argv[0]==EXCEPT_ARITHMETIC) PrintF("Address:%P\r\n",Fs->except_argv[1]); else if (Fs->except_argv[0]==EXCEPT_FLOATING) PrintF("Address:%P\r\n",Fs->except_argv[1]); else { for (i=1;iexcept_argc;i++) cout Fs->except_argv[i]," "; CrLf; } } else { cout "Exception:"; for (i=1;iexcept_argc;i++) cout Fs->except_argv[i]," "; CrLf; } } else PrintF("Generic Exception\r\n"); Fs->catch_except=TRUE; } BoolU4 PrsVarInit(LexStruct *l,U1 **dd,ClassStruct *cl,U8 cnt) { U1 *d=*dd,*e; U8 i,j,r,old_flags; BoolU4 result=FALSE,stop; MemberListStruct *ml; while (cl->return_class) cl=cl->return_class; if (ml=cl->member_list) { if (l->token!='{') PrsExcept(l,"ST_EXPECTING_LEFT_BRACE"); Lex(l); while (ml) { if (ml->cnt && l->token=='{') Lex(l); j=(ml->cnt) ? ml->cnt:1; stop=FALSE; for (i=0;imember_class,ml->cnt); if (l->token==',') Lex(l); } if (ml->cnt && l->token=='}') Lex(l); ml=ml->next; } if (l->token!='}') PrsExcept(l,"ST_MISSING_RIGHT_BRACE"); Lex(l); } else { if (cl->type & HTT_INTERNAL_TYPE && !cl->pointer_cnt && cnt && (cl->sub_type==IT_I1 || cl->sub_type==IT_U1) && l->token==TK_STRING) { e=LexExtendString(l,&i); MemCpy(d,e,i); d+=cnt; result=TRUE; } else { old_flags=l->flags; l->flags&=~LF_HAS_MISC_DATA; e=CompileExpression(l); if (!e) throw(EXCEPT_COMPILER,10); r=Run(e); if (!(l->flags & LF_HAS_MISC_DATA)) DelExpression(e); MemCpy(d,&r,cl->size); d+=cl->size; l->flags|=old_flags&LF_HAS_MISC_DATA; } } *dd=d; return result; } void PrsParseGlblInit(LexStruct *l,GlblVarStruct *tempg) { U1 *dd=&tempg->data; U8 i,j; ClassStruct *cl=tempg->var_class; BoolU4 stop=FALSE; while (cl->return_class) cl=cl->return_class; if (tempg->cnt && l->token=='{') Lex(l); j=(tempg->cnt) ? tempg->cnt:1; for (i=0;icnt); if (j>1 && l->token==',') Lex(l); } if (tempg->cnt && l->token=='}') Lex(l); } #define PG_NULL 0 #define PG_LTEXTERN 1 #define PG_LTINTERN 2 #define PG_LTIMPORT 3 #define PG_EXTERN 4 #define PG_IMPORT 5 void CmpParseGlblVarList(LexStruct *l,I8 saved_mode,ClassStruct *saved_tempc, U8 saved_val,BoolU4 is_public) { I8 i,j,mode; U8 k,val; I1 *st; SysHashEntry *temph,*temph1; GlblVarStruct *tempg,*tempg1; AsmCtrlStruct *a=l->a; ClassStruct *tempc,*tempc1; U1 *u1; while (TRUE) { Lex(l); tempc=saved_tempc; val=saved_val; mode=saved_mode; while (l->token=='*') { Lex(l); tempc+=sizeof(ClassStruct); } if (l->token!=TK_IDENT) PrsExcept(l,"ST_EXPECTING_IDENTIFIER"); if ((temph=l->hash_entry) && mode==PG_EXTERN && !a) { if (temph->type & HTT_SYS_SYMBOL) { val=temph->user0; mode=PG_LTEXTERN; } } if (CmpKeyWord(l)==KW_UNION) { Lex(l); tempc1=CmpParseClass(l,TRUE,is_public); tempc1->return_class=tempc; return; } else if (CmpKeyWord(l)==KW_CLASS) { Lex(l); tempc1=CmpParseClass(l,FALSE,is_public); tempc1->return_class=tempc; return; } st=l->ident; l->ident=NULL; if (Lex(l)=='(') { if (mode==PG_LTINTERN) { tempc1=CmpParseFunctionJoin(l,tempc,st,is_public,FALSE); tempc1->executable_address=val; Bts(&tempc1->flags,Cf_INTERNAL); Btr(&tempc1->flags,Cf_EXTERN); return; } else if (mode==PG_LTEXTERN) { tempc1=CmpParseFunctionJoin(l,tempc,st,is_public,FALSE); tempc1->executable_address=val; Btr(&tempc1->flags,Cf_EXTERN); return; } else if (mode==PG_EXTERN) { CmpParseFunctionJoin(l,tempc,st,is_public,TRUE); return; } else if (mode==PG_IMPORT || mode==PG_LTIMPORT) { if (!a) PrsExcept(l,"ST_IMPORT_NOT_NEEDED"); else { tempc1=CmpParseFunctionJoin(l,tempc,st,is_public,FALSE); tempc1->type|=HTT_IMPORT; if (mode==PG_LTIMPORT) tempc1->import_name=NewString(val); else tempc1->import_name=NewString(st); } return; } else { CmpParseFunction(l,tempc,st,is_public); return; } } i=0; if (l->token=='[') { if (Lex(l)==']') tempc+=sizeof(ClassStruct); else i=Expression(l); if (l->token!=']') PrsExcept(l,"ST_MISSING_RIGHT_BRACKET"); Lex(l); } j=tempc->size; if (i) j*=i; if (mode==PG_LTEXTERN) { tempg=MAllocZ(sizeof(GlblVarStruct)-4); tempg->data_address=val; if (a) tempg->type=HTT_GLBL_VAR | HTT_EXPORT; else tempg->type=HTT_GLBL_VAR; } else if (mode==PG_LTIMPORT || mode==PG_IMPORT) { if (!a) PrsExcept(l,"ST_IMPORT_NOT_NEEDED"); else { tempg=MAllocZ(sizeof(GlblVarStruct)-4); tempg->type=HTT_GLBL_VAR | HTT_IMPORT; if (mode==PG_LTIMPORT) tempg->import_name=NewString(val); else tempg->import_name=NewString(st); tempg->data_address=a->ip; k=0; AsmStoreCodeU1(l,k.u1[0]); AsmStoreCodeU1(l,k.u1[1]); AsmStoreCodeU1(l,k.u1[2]); AsmStoreCodeU1(l,k.u1[3]); } } else if (mode==PG_EXTERN) { tempg=MAllocZ(sizeof(GlblVarStruct)-4); tempg->data_address=0; if (a) tempg->type=HTT_GLBL_VAR; else tempg->type=HTT_GLBL_VAR|HTT_UNRESOLVED_GLBL; } else { if (a) { if (l->token=='=') tempg=MAllocZ(j+sizeof(GlblVarStruct)-4); else tempg=MAllocZ(sizeof(GlblVarStruct)-4); tempg->data_address=a->ip; tempg->type=HTT_GLBL_VAR | HTT_EXPORT; if (temph && (temph->type & HTT_GLBL_VAR)) { tempg1=temph; tempg1->data_address=a->ip; } for (k=0;kdata_address=&tempg->data; tempg->type=HTT_GLBL_VAR; if (temph && temph->type&HTT_GLBL_VAR && temph->type&HTT_UNRESOLVED_GLBL) { tempg1=temph; //TODO: do not resolve extern variables in parent tasks tempg1->data_address=&tempg->data; } } } if (is_public) tempg->type|=HTT_PUBLIC; tempg->flags=0; tempg->parameter_cnt=0; tempg->var_class=tempc; tempg->string=st; tempg->size=j; tempg->cnt=i; tempg->use_cnt=0; SetSourceFileInfo(l,tempg); if (mode==PG_IMPORT || mode==PG_LTIMPORT) tempg->flags|=GVAF_IMPORT; if (mode==PG_EXTERN) tempg->flags|=GVAF_EXTERN; temph1=(a) ?FindHashBucket(st,a->glbl_hash): FindHashBucket(st,l->hash_table_list); tempg->next=temph1->next; temph1->next=tempg; if (l->token=='=') { Lex(l); PrsParseGlblInit(l,tempg); if (a) { u1=&tempg->data; for (k=0;ksize;k++) AsmStoreCodeU1At(l,u1[k],tempg->data_address+k); } } if (l->token!=',') { if (l->token!=';') PrsExcept(l,"ST_MISSING_SEMICOLON"); Lex(l); return; } } } void CmpParseIf(LexStruct *l,ClassStruct *locals,I8 try_count, CbMiscStruct *break_label,CbMiscStruct *continue_label) { CbMiscStruct *templ,*templ1; I8 k; if (l->token!='(') PrsExcept(l,"ST_EXPECTING_LEFT_PAREN"); Lex(l); if (!PrsParseExpression(l,TRUE)) throw(EXCEPT_COMPILER,11); if (l->token!=')') PrsExcept(l,"ST_MISSING_RIGHT_PAREN"); Lex(l); templ=CbMiscNew(l,CBMT_LABEL); CbAddIc(l,EC_SKIPZ2,templ,0); CmpParseStatement(l,locals,try_count,break_label,continue_label); k=CmpKeyWord(l); if (k==KW_ELSE) { Lex(l); templ1=CbMiscNew(l,CBMT_LABEL); CbAddIc(l,EC_JMP,templ1,0); CbAddIc(l,EC_LABEL,templ,0); CmpParseStatement(l,locals,try_count,break_label,continue_label); CbAddIc(l,EC_LABEL,templ1,0); } else CbAddIc(l,EC_LABEL,templ,0); } void CmpParseWhile(LexStruct *l,ClassStruct *locals,I8 try_count) { CbMiscStruct *templ,*templ1; if (l->token!='(') PrsExcept(l,"ST_EXPECTING_LEFT_PAREN"); Lex(l); templ=CbMiscNew(l,CBMT_LABEL); CbAddIc(l,EC_LABEL,templ,0); if (!PrsParseExpression(l,TRUE)) throw(EXCEPT_COMPILER,12); if (l->token!=')') PrsExcept(l,"ST_MISSING_RIGHT_PAREN"); Lex(l); templ1=CbMiscNew(l,CBMT_LABEL); CbAddIc(l,EC_SKIPZ2,templ1,0); CmpParseStatement(l,locals,try_count,templ1,templ); CbAddIc(l,EC_JMP,templ,0); CbAddIc(l,EC_LABEL,templ1,0); } void CmpParseDoWhile(LexStruct *l,ClassStruct *locals,I8 try_count) { CbMiscStruct *templ,*templ1; templ=CbMiscNew(l,CBMT_LABEL); templ1=CbMiscNew(l,CBMT_LABEL); CbAddIc(l,EC_LABEL,templ,0); CmpParseStatement(l,locals,try_count,templ1,templ); if (CmpKeyWord(l)!=KW_WHILE) PrsExcept(l,"ST_MISSING_WHILE"); if (Lex(l)!='(') PrsExcept(l,"ST_EXPECTING_LEFT_PAREN"); Lex(l); if (!PrsParseExpression(l,TRUE)) throw(EXCEPT_COMPILER,13); if (l->token!=')') PrsExcept(l,"ST_MISSING_RIGHT_PAREN"); Lex(l); CbAddIc(l,EC_SKIPNZ2,templ,0); CbAddIc(l,EC_LABEL,templ1,0); } void CmpParseFor(LexStruct *l,ClassStruct *locals,I8 try_count) { LexCbStack *templs; CbMiscStruct *templ,*templ1,*templ2; if (l->token!='(') PrsExcept(l,"ST_EXPECTING_LEFT_PAREN"); Lex(l); CmpParseStatement(l,locals,try_count); templ=CbMiscNew(l,CBMT_LABEL); CbAddIc(l,EC_LABEL,templ,0); if (!PrsParseExpression(l,TRUE)) throw(EXCEPT_COMPILER,14); templ1=CbMiscNew(l,CBMT_LABEL); CbAddIc(l,EC_SKIPZ2,templ1,0); if (l->token!=';') PrsExcept(l,"ST_MISSING_SEMICOLON"); Lex(l); CbPush(l); CbInitOutPtrs(&l->cb); templ2=CbMiscNew(l,CBMT_LABEL); CbAddIc(l,EC_LABEL,templ2,0); CmpParseStatement(l,locals,try_count,NULL,NULL,FALSE); CbAddIc(l,0,0,0); CbPush(l); templs=CbPopNoFree(l); CbPop(l); if (l->token!=')') PrsExcept(l,"ST_MISSING_RIGHT_PAREN"); Lex(l); CmpParseStatement(l,locals,try_count,templ1,templ2); CbAppend(l,templs); CbAddIc(l,EC_JMP,templ,0); CbAddIc(l,EC_LABEL,templ1,0); } class SwitchCaseEntry { SwitchCaseEntry *next; CbMiscStruct *label; U8 value; }; void CmpParseSwitch(LexStruct *l,ClassStruct *locals,I8 try_count) { SwitchCaseEntry *header=NULL,*temps,*temps1; CbMiscStruct *templ_break,*templ_default,*templ_jmp; IntermediateCode *tempi_sub,*tempi_cmp; AsmCtrlStruct *a=l->a; BoolU4 default_found=FALSE; I8 i,k; I8 lo=MAX_I8,hi=MIN_I8,range; U4 *jmp_table; if (l->token!='(') PrsExcept(l,"ST_EXPECTING_LEFT_PAREN"); Lex(l); templ_break=CbMiscNew(l,CBMT_LABEL); templ_default=CbMiscNew(l,CBMT_LABEL); templ_jmp=CbMiscNew(l,CBMT_JMP_TABLE); if (!PrsParseExpression(l,FALSE)) throw(EXCEPT_COMPILER,15); CbAddIc(l,EC_U8,0,sys_internal_types[IT_I4]); tempi_sub=l->cb.cb_last_out_ptr; CbAddIc(l,EC_SUBTRACTION,0,sys_internal_types[IT_I4]); CbAddIc(l,EC_U8,0,sys_internal_types[IT_I4]); tempi_cmp=l->cb.cb_last_out_ptr; CbAddIc(l,EC_SWITCH,templ_jmp,0); CbAddIc(l,EC_JMP,templ_default,0); if (l->token!=')') PrsExcept(l,"ST_MISSING_RIGHT_PAREN"); if (Lex(l)!='{') PrsExcept(l,"ST_EXPECTING_LEFT_BRACE"); Lex(l); while (l->token && l->token!='}') { k=CmpKeyWord(l); if (k==KW_CASE) { Lex(l); temps=MAlloc(sizeof(SwitchCaseEntry)); temps->label=CbMiscNew(l,CBMT_LABEL); CbAddIc(l,EC_LABEL,temps->label,0); k=Expression(l); if (l->token!=':') PrsExcept(l,"ST_EXPECTING_COLON"); Lex(l); if (khi) hi=k; temps->value=k; temps->next=header; header=temps; } else if (k==KW_DEFAULT) { if (Lex(l)==':') Lex(l); CbAddIc(l,EC_LABEL,templ_default,0); default_found=TRUE; } else CmpParseStatement(l,locals,try_count,templ_break,NULL); } if (!default_found) CbAddIc(l,EC_LABEL,templ_default,0); CbAddIc(l,EC_LABEL,templ_break,0); if (l->token!='}') PrsExcept(l,"ST_MISSING_RIGHT_BRACE"); Lex(l); range=hi-lo+1; if (range<=0 || range>0x4000) PrsExcept(l,"ST_CASE_RANGE_ERROR"); jmp_table=MAlloc(PTR_SIZE*range); for (i=0;iic_data=lo; tempi_cmp->ic_data=range; temps=header; while (temps) { temps1=temps->next; jmp_table[temps->value-lo]=temps->label; Free(temps); temps=temps1; } templ_jmp->jmp_table=jmp_table; templ_jmp->st_len=range; } void CmpParseCout(LexStruct *l,BoolU4 linefeed) { ClassStruct *tempc; SysHashEntry *temph; IntermediateCode *tempi; I8 cnt=0,i,j; while (l->token!=';') { cnt++; if (!PrsParseExpression(l,FALSE)) throw(EXCEPT_COMPILER,16); tempi=l->cb.cb_last_out_ptr; tempc=tempi->ic_class; j=tempc->pointer_cnt; tempc-=sizeof(ClassStruct)*j; while (tempc->return_class) tempc=tempc->return_class; temph=tempc; if (temph->type & HTT_INTERNAL_TYPE) i=tempc->sub_type+j*IT_NUM_IT; else i=IT_U4; CbAddIc(l,EC_TYPE,i,sys_internal_types[IT_U4]); if (l->token==',' || l->token==TK_SHL) Lex(l); else { if (l->token!=';') PrsExcept(l,"ST_EXPECTING_COMMA"); } } CbAddIc(l,EC_U8,cnt,sys_internal_types[IT_U4]); if (linefeed) CbAddIc(l,EC_IRQ,I_COUTLN,0); else CbAddIc(l,EC_IRQ,I_COUT,0); CbAddIc(l,EC_ADD_ESP32,cnt<<4+8,0); } void CmpParseExeBlk(LexStruct *l) { AsmCtrlStruct *a=l->a; SysHashTable *ht1=l->hash_table_list, *ht2=l->define_hash_table; U8 old_hash_mask=l->hash_mask; U8 old_flags=l->flags & (LF_ASM_EXPRESSIONS | LF_EXE_BLK); ExeBlkStruct *tempe=MAlloc(sizeof(ExeBlkStruct)); U4 *old_var_list=l->local_var_list; l->local_var_list=NULL; tempe->body=NewString(""); InsQue(tempe,l->last_exe_blk); CbPush(l); //TODO Misc lists l->hash_mask=HTT_ALL; l->hash_table_list=Fs->hash_table; l->define_hash_table=Fs->hash_table; l->flags=(l->flags & ~LF_ASM_EXPRESSIONS) | LF_EXE_BLK; l->a=NULL; if (l->token=='{') Lex(l); else PrsExcept(l,"ST_MISSING_RIGHT_BRACE"); while (l->token && l->token!='}') ExecuteCmdLine(l); l->a=a; l->hash_table_list=ht1, l->define_hash_table=ht2; l->local_var_list=old_var_list; l->hash_mask=old_hash_mask; l->flags=(l->flags&~LF_EXE_BLK) | old_flags; CbPop(l); RemQue(tempe); if (*tempe->body) LexIncludeString(l,"ExeBlk",tempe->body,FALSE); else Free(tempe->body); Free(tempe); Lex(l); //Skip "}" } void ExePutS(I1 *st) { LexStruct *l=Fs->last_lex; ExeBlkStruct *tempe=l->last_exe_blk; if (tempe!=&l->next_exe_blk) tempe->body=Add2String(tempe->body,st); else coutln "Error: No exe{} blk"; } void ExePrintF(I1 *src,...) { I1 *buf=SPrintFJoin(NULL,src,argc,argv); ExePutS(buf); Free(buf); } void CmpParseTryBlk(LexStruct *l,ClassStruct *locals,I8 try_count) { CbMiscStruct *templ,*templ1,*templ2; ClassStruct *d=sys_internal_types[IT_U4], *temp_try=FindHashEntry("SysTry",l->hash_table_list,HTT_FUNCTION), *temp_catch=FindHashEntry("SysCatch",l->hash_table_list,HTT_FUNCTION); l->flags|=LF_NO_REG_OPT; templ=CbMiscNew(l,CBMT_LABEL); templ1=CbMiscNew(l,CBMT_LABEL); templ2=CbMiscNew(l,CBMT_LABEL); CbAddIc(l,EC_GET_STACK_PTR,0,d); CbAddIc(l,EC_GET_BASE_PTR,0,d); CbAddIc(l,EC_GET_LABEL,templ2,d); CbAddIc(l,EC_GET_LABEL,templ,d); if (Bt(&temp_try->flags,Cf_EXTERN)) { if (l->a) CbAddIc(l,EC_CALL_INDIRECT2,temp_try->executable_address,d); else CbAddIc(l,EC_CALL_INDIRECT2,&temp_try->executable_address,d); } else CbAddIc(l,EC_CALL,temp_try->executable_address,d); CbAddIc(l,EC_ADD_ESP32,40,d); if (try_count<0) CmpParseStatement(l,locals,try_count-1); else CmpParseStatement(l,locals,try_count+1); CbAddIc(l,EC_LABEL,templ2,0); if (Bt(&temp_catch->flags,Cf_EXTERN)) { if (l->a) CbAddIc(l,EC_CALL_INDIRECT2,temp_catch->executable_address,d); else CbAddIc(l,EC_CALL_INDIRECT2,&temp_catch->executable_address,d); } else CbAddIc(l,EC_CALL,temp_catch->executable_address,d); CbAddIc(l,EC_ADD_ESP32,8,d); CbAddIc(l,EC_JMP,templ1,0); if (CmpKeyWord(l)!=KW_CATCH) PrsExcept(l,"ST_MISSING_CATCH"); Lex(l); CbAddIc(l,EC_LABEL,templ,0); if (try_count<0) CmpParseStatement(l,locals,try_count-1); else CmpParseStatement(l,locals,-try_count-1); CbAddIc(l,EC_RET,0,d); CbAddIc(l,EC_LABEL,templ1,0); } void CmpParseAsmBlk(LexStruct *l) { AsmCtrlStruct *a=l->a; I8 i,j; OpcodeHashEntry *tempo; SysHashEntry *temph,**temph1; U8 argcnt,saved_ip; BoolU4 is_literal; U1 *file_buf,*b; U8 file_size; U8 old_hash_mask=l->hash_mask; I1 *next_last_label; ArcCompressStruct *ac; void my_CmpParseExeBlk(LexStruct *l); if (!a) PutAsmError(l,"ST_ASM_NOT_ALLOWED"); a->use16=FALSE; l->flags|=LF_ASM_EXPRESSIONS; l->hash_mask&=~(HTT_INTERNAL_TYPE|HTT_CLASS|HTT_PUBLIC| HTT_WORD|HTT_LOCAL_VAR|HTT_GLBL_VAR|HTT_FUNCTION|HTT_FILE| HTT_MODULE|HTT_PRIVATE|HTT_EXPORT|HTT_IMPORT); if (l->token=='{') Lex(l); else PrsExcept(l,"ST_MISSING_RIGHT_BRACE"); while (l->token && l->token!='}') { AsmListLine(l); if (l->token==TK_IDENT && l->hash_entry) { if (l->hash_entry->type==HTT_KEYWORD) { i=l->hash_entry->user0; Lex(l); //skip keyword switch (i) { case AKW_IMPORT: case AKW_EXPORT: while (l->token && l->token!=';') { if (l->token=='#') { is_literal=TRUE; Lex(l); } else is_literal=FALSE; if (l->token==TK_IDENT) { if (temph=l->hash_entry) { temph=FindHashEntry(l->ident,a->glbl_hash,HTT_ALL); if (temph) temph->type=HTT_SYS_SYMBOL+HTT_UNRESOLVED_GLBL; } if (!temph) { temph=MAllocZ(sizeof(SysHashEntry)); temph->string=l->ident; l->ident=0; temph->type=HTT_SYS_SYMBOL+HTT_UNRESOLVED_GLBL; temph->use_cnt=0; temph->user0=0; temph->user1=NULL; SetSourceFileInfo(l,temph); temph1=FindHashBucket(temph->string,a->glbl_hash); temph->next=*temph1; *temph1=temph; } if (i==AKW_IMPORT) temph->type=temph->type | HTT_IMPORT; else if (i==AKW_EXPORT) temph->type=temph->type | HTT_EXPORT; if (is_literal) temph->type=temph->type | HTT_LITERAL; if (Lex(l)==',') Lex(l); //skip ',' } else { PutAsmError(l,"ST_EXPECTING_IDENTIFIER"); break; } } if (l->token!=';') PutAsmError(l,"ST_MISSING_SEMICOLON"); else Lex(l); //skip ';'; break; case AKW_ALIGN: if (l->token!=TK_INTEGER) PutAsmError(l,"ST_EXPECTING_INTEGER"); else { i=(a->ip+l->cur_i-1) & -l->cur_i; if (Lex(l)==',') Lex(l); if (l->token==TK_INTEGER) { for (j=a->ip;jcur_i); Lex(l); } else a->ip=i; } break; case AKW_END: break; //TODO case KW_EXE: my_CmpParseExeBlk=ext[EXT_CMP_EXE_BLK]; my_CmpParseExeBlk(l); break; case AKW_DU1: DefineU1s(l,a,1); break; case AKW_DU2: DefineU1s(l,a,2); break; case AKW_DU4: DefineU1s(l,a,4); break; case AKW_DU8: DefineU1s(l,a,8); break; case AKW_INSERT: if (l->token!=TK_STRING) PutAsmError(l,"ST_EXPECTING_STRING"); else { file_buf=ReadFile(l->ident,&file_size); if (file_buf) { for (i=0;itoken!=TK_STRING) PutAsmError(l,"ST_EXPECTING_STRING"); else { file_buf=ReadFile(l->ident,&file_size); if (file_buf) { ac=CompressBuf(file_buf,file_size); b=ac; for (i=0;icompressed_size;i++) AsmStoreCodeU1(l,b[i]); Free(file_buf); Free(ac); } Lex(l); } break; case AKW_LIST: a->list=TRUE; break; case AKW_NOLIST: a->list=FALSE; break; case AKW_ORG: a->ip=AsmEvalExpression(l); break; case AKW_STRUC: a->flags|=ACSF_IN_STRUCT; saved_ip=a->ip; a->ip=AsmEvalExpression(l); break; case AKW_ENDS: a->ip=saved_ip; a->flags&=~ACSF_IN_STRUCT; break; case AKW_USE16: a->use16=TRUE; break; case AKW_USE32: a->use16=FALSE; break; default: PutAsmError(l,"ST_SYNTAX_ERROR"); break; } } else if (l->hash_entry->type & HTT_OPCODE) { tempo=l->hash_entry; Lex(l); //skip opcode argcnt=0; if (tempo->ins[0].arg1) { argcnt++; ParseAsmArg(l,a,&a->arg1,a->ip); if (tempo->ins[0].arg2) { argcnt++; if (l->token!=',') PutAsmError(l,"ST_EXPECTING_COMMA"); else { Lex(l); //skip ',' ParseAsmArg(l,a,&a->arg2,a->ip); } } } AsmCodeInstruction(l,a,tempo,argcnt); } else if (l->hash_entry->type & HTT_SYS_SYMBOL) { if (a->flags & ACSF_IN_STRUCT) l->hash_entry->type|=HTT_LITERAL; else l->hash_entry->type&=~HTT_LITERAL; if (l->hash_entry->type & HTT_UNRESOLVED_LOCAL) { l->hash_entry->type&=~HTT_UNRESOLVED_LOCAL; l->hash_entry->user0=a->ip; if (Lex(l)!=':') PutAsmError(l,"ST_EXPECTING_COLON"); else Lex(l); } else if (l->hash_entry->type & HTT_UNRESOLVED_GLBL) { if (l->hash_entry->type & HTT_IMPORT) PutAsmError(l,"ST_ATTEMPT_DEFINE_IMPORT"); else { l->hash_entry->type&=~HTT_UNRESOLVED_GLBL; l->hash_entry->user0=a->ip; next_last_label=l->hash_entry->string; Lex(l); //Skip ident if (l->token!=':' && l->token!=TK_DOUBLE_COLON) PutAsmError(l,"ST_EXPECTING_COLON"); else { if (l->token==TK_DOUBLE_COLON) { l->hash_entry->type|=HTT_EXPORT; ResolveLocals(l); a->last_label=next_last_label; } if (Lex(l)=='#') { Lex(l); l->hash_entry->type|=HTT_LITERAL | HTT_EXPORT; } } } } else PutAsmError(l,"ST_REDEFINITION"); } else PutAsmError(l,"ST_SYNTAX_ERROR"); } else { if (l->token==TK_IDENT) { temph=MAllocZ(sizeof(SysHashEntry)); temph->string=l->ident; l->ident=0; temph->type=HTT_SYS_SYMBOL; if (a->flags & ACSF_IN_STRUCT) temph->type|=HTT_LITERAL; temph->use_cnt=0; SetSourceFileInfo(l,temph); temph->user0=a->ip; temph->user1=NULL; Lex(l); //Skip ident if (l->token==':' || l->token==TK_DOUBLE_COLON) { if (temph->string[0]=='@' && temph->string[1]=='@') { temph1=FindHashBucket(temph->string,a->local_hash); a->has_locals=TRUE; } else temph1=FindHashBucket(temph->string,a->glbl_hash); temph->next=*temph1; *temph1=temph; if (l->token==TK_DOUBLE_COLON) { temph->type=temph->type | HTT_EXPORT; //Export ResolveLocals(l); a->last_label=temph->string; Lex(l); } else { if (Lex(l)=='#') { temph->type=temph->type | HTT_EXPORT | HTT_LITERAL; //Export ResolveLocals(l); a->last_label=temph->string; Lex(l); } } } else { PutAsmError(l,"ST_EXPECTING_COLON"); Free(temph->string); Free(temph); } } else PutAsmError(l,"ST_SYNTAX_ERROR"); } } ResolveLocals(l); l->flags&=~LF_ASM_EXPRESSIONS; l->hash_mask=old_hash_mask; Lex(l); //Skip "}" } BoolU4 CmpParseStatement(LexStruct *l,ClassStruct *locals,I8 try_count=0, CbMiscStruct *break_label=NULL,CbMiscStruct *continue_label=NULL, BoolU4 saved_prs_semicolon=TRUE) { BoolU4 prs_exp,cont,prs_semicolon,is_asm=FALSE, is_public=FALSE,last_is_public=FALSE; U8 i; SysHashEntry *temph; CbMiscStruct *templ; I1 *import_name; ClassStruct *d,*temp_catch; void my_CmpParseExeBlk(LexStruct *l); do { is_public=FALSE; cont=FALSE; prs_exp=FALSE; prs_semicolon=saved_prs_semicolon; l->statement_cnt++; while (l->token==',') Lex(l); if (l->token=='{') { l->braces_cnt++; Lex(l); while (l->token!='}') CmpParseStatement(l,locals,try_count,break_label,continue_label); l->braces_cnt--; l->statement_cnt--; Lex(l); } else if (l->token==TK_EOF) ; else if (l->token==';') { if (prs_semicolon) { l->statement_cnt--; Lex(l); } } else { if (l->token==TK_IDENT) { if (temph=l->hash_entry) { if (temph->type & HTT_KEYWORD) { i=temph->user0; switch (i) { case KW_IF: Lex(l); CmpParseIf(l,locals,try_count,break_label,continue_label); prs_semicolon=FALSE; break; case KW_FOR: Lex(l); CmpParseFor(l,locals,try_count); prs_semicolon=FALSE; break; case KW_WHILE: Lex(l); CmpParseWhile(l,locals,try_count); prs_semicolon=FALSE; break; case KW_DO: Lex(l); CmpParseDoWhile(l,locals,try_count); prs_semicolon=FALSE; break; case KW_SWITCH: Lex(l); CmpParseSwitch(l,locals,try_count); prs_semicolon=FALSE; break; case KW_LTEXTERN: Lex(l); if (Bt(&l->flags,LFf_EXTERNS_TO_IMPORTS)) goto keyword_LTimport; if (l->token!=TK_IDENT) PrsExcept(l,"ST_EXPECTING_SYS_SYMBOL"); if (!(temph=l->hash_entry)) PrsExcept(l,"ST_EXPECTING_SYS_SYMBOL"); if (!(temph->type & HTT_SYS_SYMBOL)) PrsExcept(l,"ST_EXPECTING_SYS_SYMBOL"); i=temph->user0; if (Lex(l)!=TK_IDENT) PrsExcept(l,"ST_EXPECTING_TYPE"); if (!(temph=l->hash_entry)) PrsExcept(l,"ST_EXPECTING_TYPE"); if (!(temph->type & (HTT_CLASS|HTT_INTERNAL_TYPE))) PrsExcept(l,"ST_EXPECTING_TYPE"); if (locals) PrsExcept(l,"ST_NOT_ALLOWED_IN_FUNCTION"); CmpParseGlblVarList(l,PG_LTEXTERN,temph,i,last_is_public); prs_semicolon=FALSE; cont=TRUE; break; case KW_LTIMPORT: Lex(l); keyword_LTimport: if (l->token!=TK_IDENT) PrsExcept(l,"ST_EXPECTING_SYS_SYMBOL"); import_name=l->ident; l->ident=0; if (Lex(l)!=TK_IDENT) PrsExcept(l,"ST_EXPECTING_TYPE"); if (!(temph=l->hash_entry)) PrsExcept(l,"ST_EXPECTING_TYPE"); if (!(temph->type & (HTT_CLASS|HTT_INTERNAL_TYPE))) PrsExcept(l,"ST_EXPECTING_TYPE"); if (locals) PrsExcept(l,"ST_NOT_ALLOWED_IN_FUNCTION"); CmpParseGlblVarList(l,PG_LTIMPORT,temph,import_name,FALSE); Free(import_name); prs_semicolon=FALSE; cont=TRUE; break; case KW_INTERNAL: Lex(l); if (l->token!=TK_INTEGER) PrsExcept(l,"ST_EXPECTING_INTEGER"); i=l->cur_i; if (Lex(l)!=TK_IDENT) PrsExcept(l,"ST_EXPECTING_TYPE"); if (!(temph=l->hash_entry)) PrsExcept(l,"ST_EXPECTING_TYPE"); if (!(temph->type & (HTT_CLASS|HTT_INTERNAL_TYPE))) PrsExcept(l,"ST_EXPECTING_TYPE"); if (locals) PrsExcept(l,"ST_NOT_ALLOWED_IN_FUNCTION"); CmpParseGlblVarList(l,PG_LTINTERN,temph,i,last_is_public); prs_semicolon=FALSE; cont=TRUE; break; case KW_EXTERN: Lex(l); if (Bt(&l->flags,LFf_EXTERNS_TO_IMPORTS)) goto keyword_import; if (l->token!=TK_IDENT) PrsExcept(l,"ST_EXPECTING_TYPE"); if (!(temph=l->hash_entry)) PrsExcept(l,"ST_EXPECTING_TYPE"); if (!(temph->type & (HTT_CLASS|HTT_INTERNAL_TYPE))) PrsExcept(l,"ST_EXPECTING_TYPE"); if (locals) PrsExcept(l,"ST_NOT_ALLOWED_IN_FUNCTION"); CmpParseGlblVarList(l,PG_EXTERN,temph,0,last_is_public); prs_semicolon=FALSE; cont=TRUE; break; case KW_IMPORT: Lex(l); keyword_import: if (l->token!=TK_IDENT) PrsExcept(l,"ST_EXPECTING_TYPE"); if (!(temph=l->hash_entry)) PrsExcept(l,"ST_EXPECTING_TYPE"); if (!(temph->type & (HTT_CLASS|HTT_INTERNAL_TYPE))) PrsExcept(l,"ST_EXPECTING_TYPE"); if (locals) PrsExcept(l,"ST_NOT_ALLOWED_IN_FUNCTION"); CmpParseGlblVarList(l,PG_IMPORT,temph,0,FALSE); prs_semicolon=FALSE; cont=TRUE; break; case KW_ASM: Lex(l); CmpParseAsmBlk(l); prs_semicolon=FALSE; is_asm=TRUE; break; case KW_EXE: Lex(l); my_CmpParseExeBlk=ext[EXT_CMP_EXE_BLK]; my_CmpParseExeBlk(l); prs_semicolon=FALSE; break; case KW_TRY: Lex(l); CmpParseTryBlk(l,locals,try_count); prs_semicolon=FALSE; break; case KW_BREAK: Lex(l); if (!break_label) PrsExcept(l,"ST_BREAK_NOT_ALLOWED"); CbAddIc(l,EC_JMP,break_label,0); break; case KW_CONTINUE: Lex(l); if (!continue_label) PrsExcept(l,"ST_CONTINUE_NOT_ALLOWED"); CbAddIc(l,EC_JMP,continue_label,0); break; case KW_RETURN: Lex(l); if (l->token!=';') { if (!PrsParseExpression(l,TRUE)) throw(EXCEPT_COMPILER,17); } if (try_count<0) {//inside catch{} CbAddIc(l,EC_GET_BASE_PTR,0,0); CbAddIc(l,EC_U8,locals->size,sys_internal_types[IT_U8]); CbAddIc(l,EC_ADDITION,0,sys_internal_types[IT_U8]); CbAddIc(l,EC_SET_STACK_PTR,0,0); try_count=-try_count; //force removal from queue } if (try_count) { d=sys_internal_types[IT_U4]; temp_catch=FindHashEntry("SysCatch", l->hash_table_list,HTT_FUNCTION); for (i=0;iflags,Cf_EXTERN)) { if (l->a) CbAddIc(l,EC_CALL_INDIRECT2, temp_catch->executable_address,d); else CbAddIc(l,EC_CALL_INDIRECT2, &temp_catch->executable_address,d); } else CbAddIc(l,EC_CALL,temp_catch->executable_address,d); CbAddIc(l,EC_ADD_ESP32,8,d); } } if (locals) CbAddIc(l,EC_LEAVE,0,0); else CbAddIc(l,EC_RET,0,0); break; case KW_GOTO: Lex(l); if (l->token!=TK_IDENT) PrsExcept(l,"ST_EXPECTING_IDENTIFIER"); if (!(templ=CbFindGotoLabel(l,l->ident))) { templ=CbMiscNew(l,CBMT_GOTO_LABEL); templ->string=l->ident; l->ident=NULL; } CbAddIc(l,EC_JMP,templ,0); Lex(l); break; case KW_COUT: Lex(l); CmpParseCout(l,FALSE); break; case KW_COUTLN: Lex(l); CmpParseCout(l,TRUE); break; case KW_CLASS: Lex(l); CmpParseClass(l,FALSE,last_is_public); break; case KW_UNION: Lex(l); CmpParseClass(l,TRUE,last_is_public); break; case KW_PUBLIC: Lex(l); is_public=TRUE; cont=TRUE; prs_semicolon=FALSE; break; default: prs_exp=TRUE; break; } } else if (temph->type & (HTT_CLASS|HTT_INTERNAL_TYPE)) { if (locals) CmpParseVarList(l,locals,PVLM_LOCAL_VAR); else CmpParseGlblVarList(l,PG_NULL,temph,0,last_is_public); prs_semicolon=FALSE; cont=TRUE; } else prs_exp=TRUE; } else { if (l->local_var_entry) prs_exp=TRUE; else { if (!(templ=CbFindGotoLabel(l,l->ident))) { templ=CbMiscNew(l,CBMT_GOTO_LABEL); templ->string=l->ident; l->ident=NULL; } CbAddIc(l,EC_LABEL,templ,0); if (Lex(l)==':') //skip ident Lex(l); //skip colon else PrsExcept(l,"ST_UNDEFINED_IDENTIFIER"); prs_semicolon=FALSE; } } } else prs_exp=TRUE; if (prs_exp) { if (!PrsParseExpression(l,TRUE)) throw(EXCEPT_COMPILER,18); } if (l->token!=',') l->statement_cnt--; if (prs_semicolon && l->token!=',') { if (l->token==';') Lex(l); else PrsExcept(l,"ST_MISSING_SEMICOLON"); } } last_is_public=is_public; } while (l->token==',' || cont); return is_asm; } U1 *CompileStatement(LexStruct *l,U8 *type=NULL) { U1 *result=INVALID_PTR; AsmCtrlStruct *a=l->a; U8 size,i,j; DbgInfo *dbg=NULL; if (type) *type=IT_U8; CbInitOutPtrs(&l->cb); if (!CmpParseStatement(l,NULL)) { CbAddIc(l,EC_RET,0,0); CbAddIc(l,0,0,0); if (result=CbCompile(l,NULL,&size,&dbg,type)) { if (a) { if (size!=1) {//not just RET j=a->ip; for (i=0;icb.cb_out_first); Free(dbg); return result; } ExeStruct *CompileBuf(U1 *buf,I1 *map_name=NULL, I8 *error_cnt=NULL, I8 *warning_cnt=NULL,I1 mapfile_drive=0) { BoolU4 okay=TRUE; LexStruct *l; AsmCtrlStruct *a; U8 i,j; ExeStruct *result=NULL; AsmCodeBlk *tempc; ExeImportExportStruct *tempe,*tempe1; void my_HashRep(SysHashTable *h,U8 mask,I1 *outname,I1 *flags,I1 drive); if (!is_first_compiler) coutln "$$FG PURPLE$$**** Not First Compiler ****$$FG$$"; my_HashRep=FindExtern("HashRep"); result=MAllocZ(sizeof(ExeStruct)); l=LexNew(buf,LF_DONT_FREE_BUFFER,NULL); InsQue(l,Fs->last_lex); a=MAllocZ(sizeof(AsmCtrlStruct)); a->code=MAllocZ(sizeof(AsmCodeBlk)); a->local_hash=NewHashTable(16); a->glbl_hash=NewHashTable(2048); a->glbl_hash->next=asm_hash; a->local_hash->next=a->glbl_hash; l->a=a; l->hash_table_list=a->local_hash; l->define_hash_table=a->glbl_hash; l->local_hash_table=a->local_hash; l->glbl_hash_table=a->glbl_hash; Lex(l); try { while (l->token!=TK_EOF) { i=CompileStatement(l); if (i!=INVALID_PTR) { tempe=MAlloc(sizeof(ExeImportExportStruct)); tempe->type=EIE_MAIN; tempe->ip=i; tempe->string=NULL; tempe->next=NULL; tempe1=&result->ie; while (tempe1->next) //TODO:This could be optimized tempe1=tempe1->next; tempe1->next=tempe; } } ResolveGlbls(l,result); } catch { if (Fs->except_argc>0) if (Fs->except_argv[0]==EXCEPT_COMPILER) Fs->catch_except=TRUE; okay=FALSE; } RemQue(l); if (error_cnt) *error_cnt=l->error_cnt; if (warning_cnt) *warning_cnt=l->warning_cnt; if (!okay) { //TODO free debug info and possibly classes if (error_cnt) if (*error_cnt<1) *error_cnt=1; result=NULL; } else { if (map_name) my_HashRep(a->glbl_hash,HTT_ALL,map_name,"",mapfile_drive); LexDel(l); DelHashTable(a->local_hash); DelHashTable(a->glbl_hash); if (!a->num_code_U1s) result->code=NULL; else { result->code=MAlloc(a->num_code_U1s); result->code_U1s=a->num_code_U1s; tempc=a->code; j=0; l=a->num_code_U1s; while (tempc) { i=l; if (i>ASM_CODE_BLK_SIZE) i=ASM_CODE_BLK_SIZE; MemCpy(result->code+j,tempc->body,i); j+=i; l-=i; tempc=tempc->next; } } DelLinkedList(a->code); result->absolutes=a->absolutes; Free(a); } return result; } I8 CompileFile(I1 *filename,I1 *map_name=NULL,I1 *out_name=NULL,I1 mapfile_drive=0) { I1 *fbuf=NULL,*fbuf2=NULL,*fbuf3=NULL; ExeStruct *e; U4 *dd; U8 size=0; U1 *header=MAlloc(0x20000),*ptr; BinFileHeaderStruct *bfh; U8 i,cnt=0,error_cnt=0,warning_cnt=0; ExeImportExportStruct *tempe,*tempe1; ExeAbsoluteAddressStruct *tempa,*tempa1; fbuf=DefaultExtension(filename,"CPZ"); fbuf2=MSPrintF("#include \"%s\"",fbuf); if (map_name) fbuf3=DefaultExtension(map_name,"MPZ"); e=CompileBuf(fbuf2,fbuf3,&error_cnt,&warning_cnt,mapfile_drive); if (e) { ptr=header; tempa=e->absolutes; while (tempa) { cnt++; tempa=tempa->next; } if (cnt) { *ptr++=EIE_ABSOLUTE_ADDRESS; dd=ptr; *dd=cnt; ptr+=sizeof(U4); *ptr++=0; tempa=e->absolutes; while (tempa) { tempa1=tempa->next; dd=ptr; *dd=tempa->ip; ptr+=sizeof(U4); Free(tempa); tempa=tempa1; } } tempe=e->ie; while (tempe) { tempe1=tempe->next; *ptr++=tempe->type; dd=ptr; *dd=tempe->ip; ptr+=sizeof(U4); if (tempe->string) { i=StrLen(tempe->string); MemCpy(ptr,tempe->string,i+1); Free(tempe->string); ptr+=i+1; } else *ptr++=0; Free(tempe); tempe=tempe1; } *ptr++=EIE_END; i=(ptr-header+15) & -0x10; size=i+e->code_U1s+sizeof(BinFileHeaderStruct); bfh=MAlloc(size); MemCpy(bfh+e->code_U1s+sizeof(BinFileHeaderStruct),header,i); MemCpy(bfh+sizeof(BinFileHeaderStruct),e->code,e->code_U1s); bfh->jmp=0xE9+256*(16-3); bfh->header_offset=e->code_U1s+sizeof(BinFileHeaderStruct); bfh->file_size=size; bfh->xsum=LT_XSUM; bfh->xsum=ArcCheckSum(bfh,size); Free(fbuf2); if (out_name) fbuf2=DefaultExtension(out_name,"BIZ"); else fbuf2=ChangeExtension(fbuf,"BIZ"); WriteFile(fbuf2,bfh,size); Free(bfh); Free(e->code); Free(e); } Free(header); Free(fbuf); Free(fbuf2); Free(fbuf3); PrintF(SysText("ST_ERRORS_WARNINGS"),error_cnt,warning_cnt,size); return error_cnt; } I8 ExecuteCmdLine(LexStruct *l) { I8 result=0,i,type; double *resultd; I1 *ptr,*ptr2,*ptr3; U1 *code; LtfEntry *cl; Ltf *ltf; while (l->token && (l->token!='}' || !(l->flags & LF_EXE_BLK)) ) { ptr2=&Fs->task_descriptor; ptr3=ptr2+TSS_DESC_LENGTH; if (l->cur_lfn->flags & LFSF_IS_LTF) { cl=l->cur_lfn->line_start; ltf=l->cur_lfn->l; while (cl!=ltf && ptr2btype && ptr2display; while (*ptr && ptr2next; } } else if (ptr=l->cur_lfn->line_start) MemCpy(ptr2,ptr,TSS_DESC_LENGTH); code=CompileStatement(l,&type); if (code!=INVALID_PTR) { result=Run(code); for (i=6;i>=0;i--) { Fs->answers[i+1]=Fs->answers[i]; Fs->double_answers[i+1]=Fs->double_answers[i]; Fs->answers_types[i+1]=Fs->answers_types[i]; } Fs->answers[0]=result; resultd=&result; Fs->double_answers[0]=*resultd; Fs->answers_types[0]=type; Free(code); } } return result; } void ContinueUserTask() { LexStruct *l; while (TRUE) { l=LexNew(NULL,LF_PROMPT,NULL); InsQue(l,Fs->last_lex); try { Lex(l); ExecuteCmdLine(l); } catch CatchAll; RemQue(l); //LexDel(l); //Sometimes crashes on BREAK } } I8 ExecuteString(I1 *buf,I1 *filename=NULL) { I8 result; BoolU4 okay=TRUE; LexStruct *l; if (!filename) filename=sys_temp_filename; l=LexNew(buf,LF_DONT_FREE_BUFFER,AbsoluteFileName(filename)); InsQue(l,Fs->last_lex); try { Lex(l); result=ExecuteCmdLine(l); } catch { if (Fs->except_argc>0) if (Fs->except_argv[0]==EXCEPT_COMPILER || Fs->except_argv[0]==EXCEPT_BREAK) { Fs->catch_except=TRUE; okay=FALSE; result=0; } } RemQue(l); if (okay) LexDel(l); return result; } I8 ExecuteFile(I1 *name) { I8 result; I1 *name2=DefaultExtension(name,"CPZ"); I1 *st=MSPrintF("#include \"%s\";",name2); result=ExecuteString(st,name); Free(st); Free(name2); return result; } void LoadCompileSysText() { LoadStr("ST_ERROR","ERROR: "); LoadStr("ST_MISSING_SEMICOLON","missing ';' at"); LoadStr("ST_MISSING_EXPRESSION","missing Expression at "); LoadStr("ST_MISSING_RIGHT_PAREN","missing ')' at "); LoadStr("ST_MISSING_RIGHT_BRACKET","missing ']' at "); LoadStr("ST_UNDEFINED_SYMBOL","undefined symbol at "); LoadStr("ST_UNDEFINED_IDENTIFIER","undefined identifier at "); LoadStr("ST_INVALID_CLASS","invalid class at "); LoadStr("ST_INVALID_MEMBER","invalid member at "); LoadStr("ST_EXPECTING_TYPE","expecting type at "); LoadStr("ST_EXPECTING_IDENTIFIER","expecting identifier at "); LoadStr("ST_EXPECTING_RIGHT_PAREN","expecting ')' at "); LoadStr("ST_EXPECTING_LEFT_BRACE","expecting '{' at "); LoadStr("ST_MISSING_RIGHT_BRACE","missing '}' at "); LoadStr("ST_INVALID_LVALUE","invalid lvalue at "); LoadStr("ST_EXPECTING_EQUAL","expecting '=' at "); LoadStr("ST_NOT_POINTER_TYPE","not pointer type at "); LoadStr("ST_EXPECTING_COMMA","expecting ',' at "); LoadStr("ST_EXPECTING_SYS_SYMBOL","expecting System symbol at "); LoadStr("ST_EXPECTING_STRING","expecting string at "); LoadStr("ST_MISSING_WHILE","missing 'while' at"); LoadStr("ST_UNKNOWN_STATEMENT","unknown statement at "); LoadStr("ST_ALREADY_ONE_IMMEDIATE","already one immediate at "); LoadStr("ST_SYNTAX_ERROR","syntax error at "); LoadStr("ST_EXPECTING_SCALE_FACTOR","expecting scale factor at "); LoadStr("ST_QUESTION_NOT_ALLOWED","'?' not allowed at "); LoadStr("ST_EXPECTING_LEFT_PAREN","expecting '(' at "); LoadStr("ST_UNDEFINED_DUP_CNT","undefined DUP cnt at "); LoadStr("ST_EXPECTING_COLON","expecting ':' at "); LoadStr("ST_EXPECTING_DOUBLE_COLON","expecting '::' at "); LoadStr("ST_EXPECTING_DOT","expecting '.' at "); LoadStr("ST_REDEFINITION","redefinition at "); LoadStr("ST_INVALID_INSTRUCTION","invalid instruction at "); LoadStr("ST_INTERNAL_ERROR","LTintern error at "); LoadStr("ST_BRANCH_OUT_OF_RANGE","branch out of range at "); LoadStr("ST_ATTEMPT_DEFINE_IMPORT","attempt to define import at "); LoadStr("ST_COULD_USE_U1_DISP","could use U1 displacement at "); LoadStr("ST_WARNING","WARNING: "); LoadStr("ST_LINE","line: "); LoadStr("ST_NO_SIZE_SPECIFIED","no size specified at "); LoadList("ST_U1_REGS","AL\0CL\0DL\0BL\0AH\0CH\0DH\0BH\0"); LoadList("ST_U2_REGS","AX\0CX\0DX\0BX\0SP\0BP\0SI\0DI\0"); LoadList("ST_U4_REGS","EAX\0ECX\0EDX\0EBX\0ESP\0EBP\0ESI\0EDI\0"); LoadList("ST_OPCODE_MODIFIERS","NO\0R\0CB\0CW\0CD\0CP\0IB\0IW\0ID\0RB\0RW\0RD\0"); LoadList("ST_ARGUMENT_TYPES", "NO\0REL8\0REL16\0REL32\0UIMM8\0UIMM16\0UIMM32\0R8\0R16\0R32\0" "IMM8\0IMM16\0IMM32\0RM8\0RM16\0RM32\0M8\0M16\0M32\0" "M1616\0M1632\0M16N32\0M16N16\0M32N32\0" "MOFFS8\0MOFFS16\0MOFFS32\0CL\0" "AL\0AX\0EAX\0DX\0SS\0DS\0ES\0FS\0GS\0SREG\0CS\0"); LoadList("ST_SEG_REGS","ES\0CS\0SS\0DS\0FS\0GS\0"); LoadStr("ST_EXPECTING_INTEGER","expecting integer at "); LoadStr("ST_DIVIDE_BY_ZERO","Divide by zero at "); LoadStr("ST_OPT_INTERNAL_ERROR","Compiler Optimization Error at "); LoadStr("ST_UNRESOLVED_REFERENCE","Unresolved Reference:"); LoadStr("ST_NOT_DEFINED","Not Defined"); LoadStr("ST_SCANNING_DIRECTORY","Scanning Directory:"); LoadStr("ST_ASM_NOT_ALLOWED","ASM not allowed"); LoadStr("ST_UNUSED_VAR","Unused Var"); LoadStr("ST_NOT_ALLOWED_IN_FUNCTION","Not allowed in function"); LoadStr("ST_MISSING_CATCH","missing 'catch' at"); LoadStr("ST_UNDEFINED_GOTO_LABEL","Undefined goto label:"); LoadStr("ST_BREAK_NOT_ALLOWED","'break' not allowed\r\n"); LoadStr("ST_CONTINUE_NOT_ALLOWED","'continue' not allowed\r\n"); LoadStr("ST_ERRORS_WARNINGS","Errors:%04d Warnings:%04d Size:%08X\r\n"); LoadStr("ST_IMPORT_NOT_NEEDED","import not needed at "); LoadStr("ST_EXPECTING_CASE","expecting 'case' at "); LoadStr("ST_CASE_RANGE_ERROR","switch range error at "); LoadStr("ST_LEX_STACK_OVERFLOW","Lex Stack overflow"); LoadStr("ST_STRING_DEFAULT","String defaults not implemented in static mode at "); $AN,"Anchor for inserting Compiler systext","COMPILE_SYSTEXT"$ LoadList("ST_INTERMEDIATE_CODE", //The first character is a flag // '*' means it is a dereferrence instruction // '=' means it is an assignment instruction ".NULL\0" ".NOP\0" ".END_EXP\0" ".ZERO\0" ".U8\0" ".U4\0" ".U2\0" ".U1\0" ".DOUBLE\0" ".STRING_CONSTANT\0" ".EBP\0" ".FS\0" ".ESI\0" ".EDI\0" ".TO_DOUBLE\0" ".TO_INT\0" ".COM\0" ".NOT\0" ".UNARY_MINUS\0" ".ADDRESS\0" ".U8_DISP32\0" ".U4_DISP32\0" ".U2_DISP32\0" ".U1_DISP32\0" ".U8_DISP8\0" ".U4_DISP8\0" ".U2_DISP8\0" ".U1_DISP8\0" ".FS_U8_DISP32\0" ".FS_U4_DISP32\0" ".FS_U2_DISP32\0" ".FS_U1_DISP32\0" ".ESI_U8_DISP32\0" ".ESI_U4_DISP32\0" ".ESI_U2_DISP32\0" ".ESI_U1_DISP32\0" ".ESI_U8_DISP8\0" ".ESI_U4_DISP8\0" ".ESI_U2_DISP8\0" ".ESI_U1_DISP8\0" ".EDI_U8_DISP32\0" ".EDI_U4_DISP32\0" ".EDI_U2_DISP32\0" ".EDI_U1_DISP32\0" ".EDI_U8_DISP8\0" ".EDI_U4_DISP8\0" ".EDI_U2_DISP8\0" ".EDI_U1_DISP8\0" "*DEREF_U8\0" "*DEREF_U4\0" "*DEREF_U2\0" "*DEREF_U1\0" "*ESI_DEREF_U8\0" "*ESI_DEREF_U4\0" "*ESI_DEREF_U2\0" "*ESI_DEREF_U1\0" "*EDI_DEREF_U8\0" "*EDI_DEREF_U4\0" "*EDI_DEREF_U2\0" "*EDI_DEREF_U1\0" "*U8_PP\0" "*U4_PP\0" "*U2_PP\0" "*U1_PP\0" "*U8_MM\0" "*U4_MM\0" "*U2_MM\0" "*U1_MM\0" "*PP_U8\0" "*PP_U4\0" "*PP_U2\0" "*PP_U1\0" "*MM_U8\0" "*MM_U4\0" "*MM_U2\0" "*MM_U1\0" "*ESI_U4_PP\0" "*ESI_U4_MM\0" "*ESI_PP_U4\0" "*ESI_MM_U4\0" "*EDI_U4_PP\0" "*EDI_U4_MM\0" "*EDI_PP_U4\0" "*EDI_MM_U4\0" ".LEA_DISP32_EBP\0" ".LEA_DISP8_EBP\0" ".U8_DISP32_SCALED\0" ".U4_DISP32_SCALED\0" ".U2_DISP32_SCALED\0" ".SHL\0" ".SHR\0" ".SHL_CONSTANT1\0" ".SHL_CONSTANT2\0" ".SHR_CONSTANT1\0" ".SHR_CONSTANT2\0" ".POWER\0" ".MULTIPLICATION\0" ".DIVISION\0" ".REMAINDER\0" ".AND\0" ".OR\0" ".XOR\0" ".ADDITION\0" ".SUBTRACTION\0" ".EQUAL_EQUAL\0" ".NOT_EQUAL_TO\0" ".LESS_THAN\0" ".GREATER_THAN\0" ".LESS_OR_EQUAL\0" ".GREATER_OR_EQUAL\0" ".AND_AND\0" ".OR_OR\0" ".XOR_XOR\0" ".COLON\0" ".QUESTION\0" "=ASSIGN_U8\0" "=ASSIGN_U4\0" "=ASSIGN_U2\0" "=ASSIGN_U1\0" "=SHL_EQUAL_U8\0" "=SHL_EQUAL_U4\0" "=SHL_EQUAL_U2\0" "=SHL_EQUAL_U1\0" "=SHR_EQUAL_U8\0" "=SHR_EQUAL_U4\0" "=SHR_EQUAL_U2\0" "=SHR_EQUAL_U1\0" "=MUL_EQUAL_U8\0" "=MUL_EQUAL_U4\0" "=MUL_EQUAL_U2\0" "=MUL_EQUAL_U1\0" "=DIV_EQUAL_U8\0" "=DIV_EQUAL_U4\0" "=DIV_EQUAL_U2\0" "=DIV_EQUAL_U1\0" "=AND_EQUAL_U8\0" "=AND_EQUAL_U4\0" "=AND_EQUAL_U2\0" "=AND_EQUAL_U1\0" "=OR_EQUAL_U8\0" "=OR_EQUAL_U4\0" "=OR_EQUAL_U2\0" "=OR_EQUAL_U1\0" "=XOR_EQUAL_U8\0" "=XOR_EQUAL_U4\0" "=XOR_EQUAL_U2\0" "=XOR_EQUAL_U1\0" "=ADD_EQUAL_U8\0" "=ADD_EQUAL_U4\0" "=ADD_EQUAL_U2\0" "=ADD_EQUAL_U1\0" "=SUB_EQUAL_U8\0" "=SUB_EQUAL_U4\0" "=SUB_EQUAL_U2\0" "=SUB_EQUAL_U1\0" "=ESI_ASSIGN_U4\0" "=ESI_SHL_EQUAL_U4\0" "=ESI_SHR_EQUAL_U4\0" "=ESI_MUL_EQUAL_U4\0" "=ESI_DIV_EQUAL_U4\0" "=ESI_AND_EQUAL_U4\0" "=ESI_OR_EQUAL_U4\0" "=ESI_XOR_EQUAL_U4\0" "=ESI_ADD_EQUAL_U4\0" "=ESI_SUB_EQUAL_U4\0" "=EDI_ASSIGN_U4\0" "=EDI_SHL_EQUAL_U4\0" "=EDI_SHR_EQUAL_U4\0" "=EDI_MUL_EQUAL_U4\0" "=EDI_DIV_EQUAL_U4\0" "=EDI_AND_EQUAL_U4\0" "=EDI_OR_EQUAL_U4\0" "=EDI_XOR_EQUAL_U4\0" "=EDI_ADD_EQUAL_U4\0" "=EDI_SUB_EQUAL_U4\0" ".ADD64\0" ".ADD32\0" ".ADD8\0" ".INC\0" ".SUB64\0" ".SUB32\0" ".SUB8\0" ".DEC\0" ".ENTER\0" ".LEAVE\0" ".ENTER1\0" ".LEAVE1\0" ".ENTER2\0" ".LEAVE2\0" ".ADD_ESP32\0" ".ADD_ESP8\0" ".RET\0" ".CALL\0" ".CALL_INDIRECT\0" ".CALL_INDIRECT2\0" ".IRQ\0" ".CLI\0" ".STI\0" ".GET_FLAGS\0" ".SET_FLAGS\0" ".GET_BASE_PTR\0" ".SET_BASE_PTR\0" ".GET_STACK_PTR\0" ".SET_STACK_PTR\0" ".GET_LABEL\0" ".ABSOLUTE_ADDRESS\0" ".LABEL\0" ".TYPE\0" ".BT\0" ".BTS\0" ".BTR\0" ".BTC\0" ".BSF\0" ".BSR\0" ".INSQUE\0" ".INSQUE_REV\0" ".REMQUE\0" ".STRLEN\0" ".MEMCPY\0" ".MEMSET\0" ".INPD\0" ".INPW\0" ".INP\0" ".OUTPD\0" ".OUTPW\0" ".OUTP\0" ".JMP\0" ".SHORT_JMP\0" ".SWITCH\0" ".SKIPZ\0" ".SKIPZ2\0" ".SKIPNZ\0" ".SKIPNZ2\0" ".EQUAL_EQUAL_SKIPZ\0" ".EQUAL_EQUAL_SKIPZ2\0" ".NOT_EQUAL_TO_SKIPZ\0" ".NOT_EQUAL_TO_SKIPZ2\0" ".LESS_THAN_SKIPZ\0" ".LESS_THAN_SKIPZ2\0" ".GREATER_THAN_SKIPZ\0" ".GREATER_THAN_SKIPZ2\0" ".LESS_OR_EQUAL_SKIPZ\0" ".LESS_OR_EQUAL_SKIPZ2\0" ".GREATER_OR_EQUAL_SKIPZ\0" ".GREATER_OR_EQUAL_SKIPZ2\0" ".AND_AND_SKIPZ\0" ".AND_AND_SKIPZ2\0" ".AND_AND_SKIPNZ\0" ".AND_AND_SKIPNZ2\0" ".OR_OR_SKIPZ\0" ".OR_OR_SKIPZ2\0" ".OR_OR_SKIPNZ\0" ".OR_OR_SKIPNZ2\0" ".LEA_DISP32_ESI\0" ".LEA_DISP8_ESI\0" ".LEA_DISP32_EDI\0" ".LEA_DISP8_EDI\0" ".PUSH_U8\0" ".PUSH_U4\0" ".PUSH_U2\0" ".PUSH_U1\0" ".PUSH_NEG_U4\0" ".PUSH_NEG_U2\0" ".PUSH_NEG_U1\0" ".PUSH_DOUBLE\0" ".PUSH_U8_DISP32\0" ".PUSH_U8_DISP8\0" ".PUSH_ESI_U8_DISP32\0" ".PUSH_ESI_U8_DISP8\0" ".PUSH_EDI_U8_DISP32\0" ".PUSH_EDI_U8_DISP8\0" ".PUSH_DEREF_U8\0" ".PUSH_U8_DISP32_SCALED\0" ".BT_CONSTANT\0" ".BTS_CONSTANT\0" ".BTR_CONSTANT\0" ".BTC_CONSTANT\0" "*ESI_NEXT_EQUAL_U4\0" "*EDI_NEXT_EQUAL_U4\0" ".ADD_EQUAL_U8_CONSTANT_U1\0" ".SUB_EQUAL_U8_CONSTANT_U1\0" ".ADD_EQUAL_U4_CONSTANT_U1\0" ".ESI_ADD_EQUAL_U4_CONSTANT_U1\0" ".EDI_ADD_EQUAL_U4_CONSTANT_U1\0" ); } void FillCompilerTables() { I1 *st,buf[128]; U1 *d; U8 i; I8 j; U2 *u; U4 *d4; assign_bitmap=MAllocZ((EC_NUM_ENTRIES+7)>>3); deref_bitmap=MAllocZ((EC_NUM_ENTRIES+7)>>3); push_bitmap=MAllocZ((EC_NUM_ENTRIES+7)>>3); push_map=MAllocZ(sizeof(U2)*EC_NUM_ENTRIES); st=SysText("ST_INTERMEDIATE_CODE"); for (i=0;i=0) push_map[i]=j; st+=StrLen(st)+1; } d=MAllocZ(EC_NUM_ENTRIES); unsigned_fix_up_table=d; d[EC_ADD8]=FUT_8_4; d[EC_SUB8]=FUT_8_4; d[EC_IRQ]=FUT_8_1; d[EC_ADD_ESP8]=FUT_8_1; d[EC_U1_DISP8]=FUT_8_1; d[EC_U2_DISP8]=FUT_8_1; d[EC_U4_DISP8]=FUT_8_1; d[EC_U8_DISP8]=FUT_8_6; d[EC_PUSH_U8_DISP8]=FUT_8_6; d[EC_ESI_U1_DISP8]=FUT_8_1; d[EC_ESI_U2_DISP8]=FUT_8_1; d[EC_ESI_U4_DISP8]=FUT_8_1; d[EC_ESI_U8_DISP8]=FUT_8_6; d[EC_PUSH_ESI_U8_DISP8]=FUT_8_6; d[EC_EDI_U1_DISP8]=FUT_8_1; d[EC_EDI_U2_DISP8]=FUT_8_1; d[EC_EDI_U4_DISP8]=FUT_8_1; d[EC_EDI_U8_DISP8]=FUT_8_6; d[EC_PUSH_EDI_U8_DISP8]=FUT_8_6; d[EC_LEA_DISP8_EBP]=FUT_8_1; d[EC_LEA_DISP8_ESI]=FUT_8_1; d[EC_LEA_DISP8_EDI]=FUT_8_1; d[EC_SHL_CONSTANT1]=FUT_8_6; d[EC_SHL_CONSTANT2]=FUT_8_5; d[EC_SHR_CONSTANT1]=FUT_8_6; d[EC_SHR_CONSTANT2]=FUT_8_5; d[EC_ADD_EQUAL_U8_CONSTANT_U1]=FUT_8_10; d[EC_SUB_EQUAL_U8_CONSTANT_U1]=FUT_8_10; d[EC_ADD_EQUAL_U4_CONSTANT_U1]=FUT_8_5; d[EC_ESI_ADD_EQUAL_U4_CONSTANT_U1]=FUT_8_5; d[EC_EDI_ADD_EQUAL_U4_CONSTANT_U1]=FUT_8_5; d[EC_BT_CONSTANT]=FUT_8_6; d[EC_BTS_CONSTANT]=FUT_8_6; d[EC_BTR_CONSTANT]=FUT_8_6; d[EC_BTC_CONSTANT]=FUT_8_6; d[EC_CALL]=FUT_32_4_CALL; d[EC_U8]=FUT_64_H9_L4; d[EC_U4]=FUT_32_4; d[EC_U1]=FUT_8_1; d[EC_DOUBLE]=FUT_64_H9_L4; d[EC_PUSH_U8]=FUT_64_H9_L4; d[EC_PUSH_DOUBLE]=FUT_64_H9_L4; d[EC_PUSH_U4]=FUT_32_4; d[EC_PUSH_U2]=FUT_32_4; d[EC_PUSH_U1]=FUT_8_1; d[EC_PUSH_NEG_U4]=FUT_32_4; d[EC_PUSH_NEG_U2]=FUT_32_4; d[EC_PUSH_NEG_U1]=FUT_8_1; d[EC_ADD32]=FUT_32_7; d[EC_SUB32]=FUT_32_7; d[EC_ADD_ESP32]=FUT_32_4; d[EC_ENTER]=FUT_32_4; d[EC_ENTER1]=FUT_ENTER1; d[EC_ENTER2]=FUT_ENTER2; d[EC_LEAVE]=FUT_32_6; d[EC_LEAVE1]=FUT_32_6; d[EC_LEAVE2]=FUT_32_6; d[EC_TYPE]=FUT_32_4; d[EC_U1_DISP32]=FUT_32_4; d[EC_U2_DISP32]=FUT_32_4; d[EC_U4_DISP32]=FUT_32_4; d[EC_U8_DISP32]=FUT_32_9; d[EC_PUSH_U8_DISP32]=FUT_32_9; d[EC_ESI_U1_DISP32]=FUT_32_4; d[EC_ESI_U2_DISP32]=FUT_32_4; d[EC_ESI_U4_DISP32]=FUT_32_4; d[EC_ESI_U8_DISP32]=FUT_32_9; d[EC_PUSH_ESI_U8_DISP32]=FUT_32_9; d[EC_EDI_U1_DISP32]=FUT_32_4; d[EC_EDI_U2_DISP32]=FUT_32_4; d[EC_EDI_U4_DISP32]=FUT_32_4; d[EC_EDI_U8_DISP32]=FUT_32_9; d[EC_PUSH_EDI_U8_DISP32]=FUT_32_9; d[EC_FS_U1_DISP32]=FUT_32_4; d[EC_FS_U2_DISP32]=FUT_32_4; d[EC_FS_U4_DISP32]=FUT_32_4; d[EC_FS_U8_DISP32]=FUT_32_4P10_4; d[EC_LEA_DISP32_EBP]=FUT_32_4; d[EC_LEA_DISP32_ESI]=FUT_32_4; d[EC_LEA_DISP32_EDI]=FUT_32_4; d[EC_CALL_INDIRECT]=FUT_32_4; d[EC_U2_DISP32_SCALED]=FUT_32_6; d[EC_U4_DISP32_SCALED]=FUT_32_6; d[EC_U8_DISP32_SCALED]=FUT_32_9; d[EC_PUSH_U8_DISP32_SCALED]=FUT_32_9; d[EC_CALL_INDIRECT2]=FUT_32_4_ABS; d[EC_ABSOLUTE_ADDRESS]=FUT_32_4_ABS; d[EC_STRING_CONSTANT]=FUT_32_4_ABS2; d[EC_GET_LABEL]=FUT_32_4_ABS2; d[EC_SWITCH]=FUT_32_4_ABS2; d[EC_SKIPZ2]=FUT_32_JMP_4; d[EC_SKIPNZ2]=FUT_32_JMP_4; d[EC_OR_OR_SKIPZ2]=FUT_32_JMP_4; d[EC_OR_OR_SKIPNZ2]=FUT_32_JMP_4; d[EC_AND_AND_SKIPZ2]=FUT_32_JMP_4; d[EC_AND_AND_SKIPNZ2]=FUT_32_JMP_4; d[EC_LESS_THAN_SKIPZ2]=FUT_32_JMP_4; d[EC_GREATER_THAN_SKIPZ2]=FUT_32_JMP_4; d[EC_EQUAL_EQUAL_SKIPZ2]=FUT_32_JMP_4; d[EC_NOT_EQUAL_TO_SKIPZ2]=FUT_32_JMP_4; d[EC_GREATER_OR_EQUAL_SKIPZ2]=FUT_32_JMP_4; d[EC_LESS_OR_EQUAL_SKIPZ2]=FUT_32_JMP_4; d[EC_JMP]=FUT_32_JMP_4; d[EC_SKIPZ]=FUT_8_JMP_1; d[EC_SKIPNZ]=FUT_8_JMP_1; d[EC_OR_OR_SKIPZ]=FUT_8_JMP_1; d[EC_OR_OR_SKIPNZ]=FUT_8_JMP_1; d[EC_AND_AND_SKIPZ]=FUT_8_JMP_1; d[EC_AND_AND_SKIPNZ]=FUT_8_JMP_1; d[EC_LESS_THAN_SKIPZ]=FUT_8_JMP_1; d[EC_GREATER_THAN_SKIPZ]=FUT_8_JMP_1; d[EC_EQUAL_EQUAL_SKIPZ]=FUT_8_JMP_1; d[EC_NOT_EQUAL_TO_SKIPZ]=FUT_8_JMP_1; d[EC_GREATER_OR_EQUAL_SKIPZ]=FUT_8_JMP_1; d[EC_LESS_OR_EQUAL_SKIPZ]=FUT_8_JMP_1; d[EC_SHORT_JMP]=FUT_8_JMP_1; d=MAllocZ(EC_NUM_ENTRIES); signed_fix_up_table=d; d[EC_ADD_ESP8]=FUT_8_1; d[EC_U1_DISP8]=FUT_8_2; d[EC_U2_DISP8]=FUT_8_2; d[EC_U4_DISP8]=FUT_8_2; d[EC_ESI_U1_DISP8]=FUT_8_2; d[EC_ESI_U2_DISP8]=FUT_8_2; d[EC_ESI_U4_DISP8]=FUT_8_2; d[EC_EDI_U1_DISP8]=FUT_8_2; d[EC_EDI_U2_DISP8]=FUT_8_2; d[EC_EDI_U4_DISP8]=FUT_8_2; d[EC_SHR_CONSTANT1]=FUT_8_6; d[EC_SHR_CONSTANT2]=FUT_8_4; d[EC_ADD_EQUAL_U4_CONSTANT_U1]=FUT_8_4; d[EC_ESI_ADD_EQUAL_U4_CONSTANT_U1]=FUT_8_4; d[EC_EDI_ADD_EQUAL_U4_CONSTANT_U1]=FUT_8_4; d[EC_U4]=FUT_32_5; d[EC_U1_DISP32]=FUT_32_5; d[EC_U2_DISP32]=FUT_32_5; d[EC_U4_DISP32]=FUT_32_5; d[EC_ESI_U1_DISP32]=FUT_32_5; d[EC_ESI_U2_DISP32]=FUT_32_5; d[EC_ESI_U4_DISP32]=FUT_32_5; d[EC_EDI_U1_DISP32]=FUT_32_5; d[EC_EDI_U2_DISP32]=FUT_32_5; d[EC_EDI_U4_DISP32]=FUT_32_5; d[EC_FS_U1_DISP32]=FUT_32_5; d[EC_FS_U2_DISP32]=FUT_32_5; d[EC_FS_U4_DISP32]=FUT_32_5; d[EC_LEA_DISP32_EBP]=FUT_32_4; d[EC_U2_DISP32_SCALED]=FUT_32_5; d[EC_U4_DISP32_SCALED]=FUT_32_5; d[EC_ABSOLUTE_ADDRESS]=FUT_32_4_ABS; d[EC_GET_LABEL]=FUT_32_4_ABS2; d[EC_SWITCH]=FUT_32_4_ABS2; d[EC_SKIPZ2]=FUT_32_JMP_4; d[EC_SKIPNZ2]=FUT_32_JMP_4; d[EC_OR_OR_SKIPZ2]=FUT_32_JMP_4; d[EC_OR_OR_SKIPNZ2]=FUT_32_JMP_4; d[EC_AND_AND_SKIPZ2]=FUT_32_JMP_4; d[EC_AND_AND_SKIPNZ2]=FUT_32_JMP_4; d[EC_LESS_THAN_SKIPZ2]=FUT_32_JMP_4; d[EC_GREATER_THAN_SKIPZ2]=FUT_32_JMP_4; d[EC_EQUAL_EQUAL_SKIPZ2]=FUT_32_JMP_4; d[EC_NOT_EQUAL_TO_SKIPZ2]=FUT_32_JMP_4; d[EC_GREATER_OR_EQUAL_SKIPZ2]=FUT_32_JMP_4; d[EC_LESS_OR_EQUAL_SKIPZ2]=FUT_32_JMP_4; d[EC_SKIPZ]=FUT_8_JMP_1; d[EC_SKIPNZ]=FUT_8_JMP_1; d[EC_OR_OR_SKIPZ]=FUT_8_JMP_1; d[EC_OR_OR_SKIPNZ]=FUT_8_JMP_1; d[EC_AND_AND_SKIPZ]=FUT_8_JMP_1; d[EC_AND_AND_SKIPNZ]=FUT_8_JMP_1; d[EC_LESS_THAN_SKIPZ]=FUT_8_JMP_1; d[EC_GREATER_THAN_SKIPZ]=FUT_8_JMP_1; d[EC_EQUAL_EQUAL_SKIPZ]=FUT_8_JMP_1; d[EC_NOT_EQUAL_TO_SKIPZ]=FUT_8_JMP_1; d[EC_GREATER_OR_EQUAL_SKIPZ]=FUT_8_JMP_1; d[EC_LESS_OR_EQUAL_SKIPZ]=FUT_8_JMP_1; d=MAllocZ(EC_NUM_ENTRIES); double_fix_up_table=d; d[EC_LESS_THAN_SKIPZ2]=FUT_32_JMP_4; d[EC_GREATER_THAN_SKIPZ2]=FUT_32_JMP_4; d[EC_GREATER_OR_EQUAL_SKIPZ2]=FUT_32_JMP_4; d[EC_LESS_OR_EQUAL_SKIPZ2]=FUT_32_JMP_4; d[EC_LESS_THAN_SKIPZ]=FUT_8_JMP_1; d[EC_GREATER_THAN_SKIPZ]=FUT_8_JMP_1; d[EC_GREATER_OR_EQUAL_SKIPZ]=FUT_8_JMP_1; d[EC_LESS_OR_EQUAL_SKIPZ]=FUT_8_JMP_1; d[EC_SHORT_JMP]=FUT_8_JMP_1; u=MAllocZ(sizeof(U2)*TK_NUM_TK); duel_I1_tokens1=u; u['!']=256*TK_NOT_EQUAL+'='; u['&']=256*TK_AND_AND+'&'; u['*']=256*TK_MUL_EQUAL+'='; u['+']=256*TK_PLUS_PLUS+'+'; u['-']=256*TK_DEREFERRENCE+'>'; u['/']='*'; u[':']=256*TK_DOUBLE_COLON+':'; u['<']=256*TK_LESS_EQUAL+'='; u['=']=256*TK_EQUAL_EQUAL+'='; u['>']=256*TK_GREATER_EQUAL+'='; u['^']=256*TK_XOR_EQUAL+'='; u['|']=256*TK_OR_OR+'|'; u=MAllocZ(sizeof(U2)*TK_NUM_TK); duel_I1_tokens2=u; u['&']=256*TK_AND_EQUAL+'='; u['+']=256*TK_ADD_EQUAL+'='; u['-']=256*TK_MINUS_MINUS+'-'; u['/']='/'; u['<']=256*TK_SHL+'<'; u['>']=256*TK_SHR+'>'; u['^']=256*TK_XOR_XOR+'^'; u['|']=256*TK_OR_EQUAL+'='; u=MAllocZ(sizeof(U2)*TK_NUM_TK); duel_I1_tokens3=u; u['-']=256*TK_SUB_EQUAL+'='; u['/']=256*TK_DIV_EQUAL+'='; u['>']=256*TK_CAST+'<'; d4=MAllocZ(sizeof(U4)*TK_NUM_TK); binary_ops_table=d4; d4['`'] =0x20000+EC_POWER; d4[TK_SHL] =0x20000+EC_SHL; d4[TK_SHR] =0x20000+EC_SHR; d4['*'] =0x30000+EC_MULTIPLICATION; d4['/'] =0x30000+EC_DIVISION; d4['%'] =0x30000+EC_REMAINDER; d4['&'] =0x40000+EC_AND; d4['|'] =0x50000+EC_OR; d4['^'] =0x50000+EC_XOR; d4['+'] =0x60000+EC_ADDITION; d4['-'] =0x60000+EC_SUBTRACTION; d4[TK_EQUAL_EQUAL] =0x70000+EC_EQUAL_EQUAL; d4[TK_NOT_EQUAL] =0x70000+EC_NOT_EQUAL_TO; d4['<'] =0x70000+EC_LESS_THAN; d4['>'] =0x70000+EC_GREATER_THAN; d4[TK_LESS_EQUAL] =0x70000+EC_LESS_OR_EQUAL; d4[TK_GREATER_EQUAL]=0x70000+EC_GREATER_OR_EQUAL; d4[TK_AND_AND] =0x80000+EC_AND_AND; d4[TK_OR_OR] =0x90000+EC_OR_OR; d4[TK_XOR_XOR] =0x90000+EC_XOR_XOR; d4[':'] =0xA0000+EC_COLON; d4['?'] =0xA0000+EC_QUESTION; d4['='] =0x100000+EC_ASSIGN_U8; d4[TK_SHL_EQUAL]=0x100000+EC_SHL_EQUAL_U8; d4[TK_SHR_EQUAL]=0x100000+EC_SHR_EQUAL_U8; d4[TK_MUL_EQUAL]=0x100000+EC_MUL_EQUAL_U8; d4[TK_DIV_EQUAL]=0x100000+EC_DIV_EQUAL_U8; d4[TK_AND_EQUAL]=0x100000+EC_AND_EQUAL_U8; d4[TK_OR_EQUAL] =0x100000+EC_OR_EQUAL_U8; d4[TK_XOR_EQUAL]=0x100000+EC_XOR_EQUAL_U8; d4[TK_ADD_EQUAL]=0x100000+EC_ADD_EQUAL_U8; d4[TK_SUB_EQUAL]=0x100000+EC_SUB_EQUAL_U8; d4=MAllocZ(sizeof(U4)*TK_NUM_TK); unary_ops_table=d4; d4['~']=0x10000+EC_COM; d4['!']=0x10000+EC_NOT; d4['-']=0x10000+EC_UNARY_MINUS; d4['&']=0x10000+EC_ADDRESS; d4['*']=0x10000+EC_DEREF_U8; d4=unsigned_code_table[EC_ABSOLUTE_ADDRESS+1]-4; *d4=offset(TssStruct.absolute_address); for (i=0;ilast_lex); ext[EXT_SPRINTF_JOIN]=&SPrintFJoin2; ext[EXT_GETF_JOIN]=&GetFJoin2; ext[EXT_EXECUTE_FILE]=&ExecuteFile; ext[EXT_EXECUTE_STRING]=&ExecuteString; InitCompiler(TRUE); try { Lex(l); ExecuteCmdLine(l); } catch CatchAll; RemQue(l); LexDel(l); }