2652 lines
68 KiB
Plaintext
2652 lines
68 KiB
Plaintext
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->size<i)
|
|
tempc->size=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_base<i)
|
|
tempc->size=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;i<size;i++)
|
|
AsmStoreCodeU1(l,result[i]);
|
|
Free(result);
|
|
}
|
|
} else {
|
|
tempc->executable_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]<SysTextSubCount("ST_EXCEPT_TYPES")) {
|
|
PrintF("Exception Type :%Z\r\n",Fs->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;i<Fs->except_argc;i++)
|
|
cout Fs->except_argv[i]," ";
|
|
CrLf;
|
|
}
|
|
} else {
|
|
cout "Exception:";
|
|
for (i=1;i<Fs->except_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;i<j && !stop;i++) {
|
|
stop=PrsVarInit(l,&d,ml->member_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;i<j && !stop;i++) {
|
|
stop=PrsVarInit(l,&dd,cl,tempg->cnt);
|
|
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;k<j;k++)
|
|
AsmStoreCodeU1(l,0);
|
|
} else {
|
|
tempg=MAllocZ(j+sizeof(GlblVarStruct)-4);
|
|
tempg->data_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;k<tempg->size;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 (k<lo) lo=k;
|
|
if (k>hi) 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;i<range;i++)
|
|
jmp_table[i]=templ_default;
|
|
tempi_sub->ic_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;j<i;j++)
|
|
AsmStoreCodeU1(l,l->cur_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;i<file_size;i++)
|
|
AsmStoreCodeU1(l,file_buf[i]);
|
|
Free(file_buf);
|
|
}
|
|
Lex(l);
|
|
}
|
|
break;
|
|
case AKW_INSERT_COMPRESSED:
|
|
if (l->token!=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;i<ac->compressed_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;i<try_count;i++) {
|
|
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);
|
|
}
|
|
}
|
|
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;i<size;i++)
|
|
AsmStoreCodeU1(l,result[i]);
|
|
Free(result);
|
|
result=j;
|
|
} else {
|
|
Free(result);
|
|
result=INVALID_PTR;
|
|
}
|
|
} else {
|
|
if (size==1) {//just RET
|
|
Free(result);
|
|
result=INVALID_PTR;
|
|
}
|
|
}
|
|
} else
|
|
result=INVALID_PTR;
|
|
} else
|
|
DelLinkedList(l->cb.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 && ptr2<ptr3) {
|
|
switch (cl->btype && ptr2<ptr3) {
|
|
case LTFT_TEXT:
|
|
ptr=cl->display;
|
|
while (*ptr && ptr2<ptr3)
|
|
*ptr2++=*ptr++;
|
|
break;
|
|
case LTFT_TAB:
|
|
case LTFT_CR:
|
|
*ptr2++='.';
|
|
break;
|
|
}
|
|
cl=cl->next;
|
|
}
|
|
} 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<EC_NUM_ENTRIES;i++) {
|
|
if (*st=='*')
|
|
Bts(deref_bitmap,i);
|
|
else if (*st=='=')
|
|
Bts(assign_bitmap,i);
|
|
SPrintF(buf,"%cPUSH_%s",*st,st+1);
|
|
j=MatchSysTextEntry(buf,"ST_INTERMEDIATE_CODE");
|
|
if (j>=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;i<EC_NUM_ENTRIES;i++) {
|
|
u=unsigned_code_table[i];
|
|
if (unsigned_code_table[i+1]-u) {
|
|
if (*u==0x5052)
|
|
Bts(push_bitmap,i);
|
|
}
|
|
}
|
|
}
|
|
|
|
void InitCompiler(BoolU4 first)
|
|
{
|
|
is_first_compiler=first;
|
|
if (first)
|
|
ext[EXT_CMP_EXE_BLK]=&CmpParseExeBlk;
|
|
LoadCompileSysText;
|
|
FillCompilerTables;
|
|
LoadAsmHash(first);
|
|
}
|
|
|
|
#define ADAM_STARTUP_NAME "/LT/OSMain/ADAMK.CPZ"
|
|
void AdamStartUpFile()
|
|
{
|
|
LexStruct *l=LexNew(ReadTextFile(ADAM_STARTUP_NAME),0,
|
|
NewString(ADAM_STARTUP_NAME));
|
|
InsQue(l,Fs->last_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);
|
|
}
|