LTCD_060719.ISO
This commit is contained in:
commit
f86e69648b
156 files changed
+49537
No files matched your search
@@ -0,0 +1,773 @@
|
||||
/*
|
||||
void PrsPush(ParseStack *ps,U4 val)
|
||||
{
|
||||
ps->stk[ps->ptr++]=val;
|
||||
}
|
||||
U8 PrsPop(ParseStack *ps)
|
||||
{
|
||||
return ps->stk[--ps->ptr];
|
||||
}
|
||||
*/
|
||||
|
||||
LTextern CP_PRSPUSH void PrsPush(ParseStack *ps,U4 val);
|
||||
LTextern CP_PRSPOP U4 PrsPop(ParseStack *ps);
|
||||
|
||||
#define PRST_UNARY_TERM 0
|
||||
#define PRST_UNARY_MODIFIERS 1
|
||||
#define PRST_DEREFERRENCE 2
|
||||
#define PRST_CHECK_BINARY_OPS 3
|
||||
|
||||
BoolU4 PrsParseExpression(LexStruct *l,BoolU4 add_esp=FALSE)
|
||||
{
|
||||
BoolU4 result=TRUE,question_clause=FALSE,
|
||||
cont_unary,cont_check_binary_ops,is_lower;
|
||||
I8 i,j,k;
|
||||
IntermediateCode *tempi,*tempi_first=l->cb.cb_out_ptr;
|
||||
ClassStruct *tempc;
|
||||
ParseStack *ps=MAlloc(sizeof(ParseStack));
|
||||
|
||||
ps->ptr=0;
|
||||
PrsPush(ps,0); //terminate
|
||||
PrsPush(ps,0); //terminate
|
||||
try {
|
||||
do {
|
||||
l->flags&=~(LF_PREINC+LF_PREDEC+LF_POSTINC+LF_POSTDEC+LF_FUNCTION);
|
||||
do i=PrsUnaryTerm(l,ps);
|
||||
while (i==PRST_UNARY_TERM);
|
||||
|
||||
while (i==PRST_UNARY_MODIFIERS)
|
||||
i=PrsUnaryModifier(l,ps);
|
||||
|
||||
if (i==PRST_DEREFERRENCE)
|
||||
PrsDereferrence(l,ps);
|
||||
|
||||
//Check for binary Ops
|
||||
do {
|
||||
i=PrsPop(ps);
|
||||
tempc=PrsPop(ps);
|
||||
if (i && i.u2[1]<=1) {
|
||||
tempi=l->cb.cb_last_out_ptr;
|
||||
i&=0xFFFF;
|
||||
tempc=tempi->ic_class;
|
||||
if (Bt(deref_bitmap,i) && tempc->pointer_cnt) {
|
||||
tempc=tempc-sizeof(ClassStruct);
|
||||
while (tempc->return_class)
|
||||
tempc=tempc->return_class;
|
||||
if (tempc->type & HTT_INTERNAL_TYPE)
|
||||
i=EC_DEREF_U8+0x10000+it_to_ec_offset[tempc->sub_type];
|
||||
else
|
||||
i=EC_DEREF_U4+0x10000;
|
||||
} else {
|
||||
if (i==EC_ADDRESS) {
|
||||
if (!(l->flags & (LF_EAX|LF_ARRAY))) {
|
||||
j=tempi->ic_code.u2[0];
|
||||
if (!Bt(deref_bitmap,j))
|
||||
PrsExcept(l,"ST_INVALID_LVALUE");
|
||||
tempi->ic_code=EC_NOP;
|
||||
tempc=tempc+sizeof(ClassStruct);
|
||||
}
|
||||
}
|
||||
}
|
||||
CbAddIc(l,i,0,tempc);
|
||||
cont_check_binary_ops=TRUE;
|
||||
} else {
|
||||
PrsPush(ps,tempc);
|
||||
PrsPush(ps,i);
|
||||
i=l->token;
|
||||
k=binary_ops_table[i];
|
||||
if (k.u2[0]==EC_QUESTION)
|
||||
question_clause=TRUE;
|
||||
else if (k.u2[0]==EC_COLON) {
|
||||
if (!question_clause)
|
||||
k=0;
|
||||
else
|
||||
question_clause=FALSE;
|
||||
}
|
||||
if (!k.u2[1]) {
|
||||
cont_check_binary_ops=FALSE;
|
||||
cont_unary=FALSE; //DONE
|
||||
} else {
|
||||
Lex(l); //skip op
|
||||
if (Bt(assign_bitmap,k.u2[0])) {
|
||||
tempi=l->cb.cb_last_out_ptr;
|
||||
tempc=tempi->ic_class;
|
||||
j=tempi->ic_code.u2[0];
|
||||
if (!Bt(deref_bitmap,j))
|
||||
PrsExcept(l,"ST_INVALID_LVALUE");
|
||||
tempi->ic_code=EC_NOP;
|
||||
while (tempc->return_class)
|
||||
tempc=tempc->return_class;
|
||||
if (!(tempc->type & HTT_INTERNAL_TYPE))
|
||||
k=k.u2[0]+0x100000+it_to_ec_offset[IT_U4];
|
||||
else
|
||||
k=k.u2[0]+0x100000+it_to_ec_offset[tempc->sub_type];
|
||||
}
|
||||
do {
|
||||
i=PrsPop(ps); //pop ops of higher prec
|
||||
tempc=PrsPop(ps);
|
||||
is_lower=FALSE;
|
||||
if (i) {
|
||||
if (k.u2[1]==i.u2[1]) {
|
||||
if (!Bt(assign_bitmap,k.u2[0]) ||
|
||||
!Bt(assign_bitmap,i.u2[0]))
|
||||
is_lower=TRUE;
|
||||
} else if (k.u2[1]>i.u2[1])
|
||||
is_lower=TRUE;
|
||||
}
|
||||
if (is_lower)
|
||||
CbAddIc(l,i,0,tempc);
|
||||
else {
|
||||
PrsPush(ps,tempc);
|
||||
PrsPush(ps,i);
|
||||
tempi=l->cb.cb_last_out_ptr;
|
||||
tempc=tempi->ic_class;
|
||||
PrsPush(ps,tempc);
|
||||
PrsPush(ps,k);
|
||||
cont_check_binary_ops=FALSE;
|
||||
cont_unary=TRUE;
|
||||
break;
|
||||
}
|
||||
} while (TRUE);
|
||||
}
|
||||
}
|
||||
} while (cont_check_binary_ops);
|
||||
} while (cont_unary);
|
||||
while (TRUE) {
|
||||
i=PrsPop(ps);
|
||||
tempc=PrsPop(ps);
|
||||
if (i)
|
||||
CbAddIc(l,i,0,tempc);
|
||||
else
|
||||
break;
|
||||
}
|
||||
} catch {
|
||||
if (Fs->except_argc>0) {
|
||||
if (Fs->except_argv[0]==EXCEPT_COMPILER) {
|
||||
l->statement_cnt=0;
|
||||
l->braces_cnt=0;
|
||||
result=FALSE;
|
||||
Fs->catch_except=TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
Free(ps);
|
||||
if (add_esp && result) {
|
||||
if (Bt(push_bitmap,tempi_first->ic_code.u2[0])) {
|
||||
tempi_first->ic_flags|=ICF_NO_PUSHES;
|
||||
CbAddIc(l,EC_END_EXP,0,0);
|
||||
} else
|
||||
CbAddIc(l,EC_ADD_ESP32,8,0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
U8 PrsUnaryTerm(LexStruct *l,ParseStack *ps)
|
||||
{
|
||||
I8 i,*i_ptr;
|
||||
I8 argc_cnt,size;
|
||||
U8 d;
|
||||
SysHashEntry *temph,**temph1;
|
||||
ClassStruct *tempc,*tempc1,*tempc2;
|
||||
GlblVarStruct *tempg;
|
||||
MemberListStruct *tempm;
|
||||
LexUndefEntry *templu;
|
||||
CbMiscStruct *tempmc;
|
||||
IntermediateCode *tempi;
|
||||
BoolU4 needs_right_paren;
|
||||
LexCbStack *templ,*templ1;
|
||||
|
||||
if (l->token==TK_INTEGER) {
|
||||
if (l->cur_i<0)
|
||||
CbAddIc(l,EC_U8,l->cur_i,sys_internal_types[IT_U8]);
|
||||
else
|
||||
CbAddIc(l,EC_U8,l->cur_i,sys_internal_types[IT_I8]);
|
||||
Lex(l);
|
||||
return PRST_CHECK_BINARY_OPS;
|
||||
}
|
||||
if (l->token==TK_DOUBLE) {
|
||||
i_ptr=&l->cur_d;
|
||||
CbAddIc(l,EC_DOUBLE,*i_ptr,sys_internal_types[IT_DOUBLE]);
|
||||
Lex(l);
|
||||
return PRST_CHECK_BINARY_OPS;
|
||||
}
|
||||
if (l->token==TK_STRING) {
|
||||
d=LexExtendString(l,&size);
|
||||
if (l->flags & LF_ASM_EXPRESSIONS)
|
||||
CbAddIc(l,EC_U8,d,sys_internal_types[IT_I1]+sizeof(ClassStruct));
|
||||
else {
|
||||
tempmc=CbMiscNew(l,CBMT_STRING_CONSTANT);
|
||||
CbAddIc(l,EC_STRING_CONSTANT,tempmc,sys_internal_types[IT_I1]+sizeof(ClassStruct));
|
||||
tempmc->st_len=size;
|
||||
tempmc->string=d;
|
||||
l->flags|=LF_HAS_MISC_DATA;
|
||||
}
|
||||
return PRST_CHECK_BINARY_OPS;
|
||||
}
|
||||
if (l->token==TK_INSERT_BINARY) {
|
||||
d=l->ident;
|
||||
size=l->ident_len;
|
||||
l->ident=NULL;
|
||||
Lex(l);
|
||||
if (l->flags & LF_ASM_EXPRESSIONS)
|
||||
CbAddIc(l,EC_U8,d,sys_internal_types[IT_I1]+sizeof(ClassStruct));
|
||||
else {
|
||||
tempmc=CbMiscNew(l,CBMT_STRING_CONSTANT);
|
||||
CbAddIc(l,EC_STRING_CONSTANT,tempmc,sys_internal_types[IT_I1]+sizeof(ClassStruct));
|
||||
tempmc->st_len=size;
|
||||
tempmc->string=d;
|
||||
l->flags|=LF_HAS_MISC_DATA;
|
||||
}
|
||||
return PRST_CHECK_BINARY_OPS;
|
||||
}
|
||||
if (l->token==TK_INSERT_BINARY_TYPE ||
|
||||
l->token==TK_INSERT_BINARY_SIZE) {
|
||||
CbAddIc(l,EC_U8,l->cur_i,sys_internal_types[IT_U8]);
|
||||
Lex(l);
|
||||
return PRST_CHECK_BINARY_OPS;
|
||||
}
|
||||
if (l->token=='(') {
|
||||
Lex(l); //Skip (
|
||||
if (!PrsParseExpression(l))
|
||||
throw(EXCEPT_COMPILER,2);
|
||||
if (l->token!=')')
|
||||
PrsExcept(l,"ST_MISSING_RIGHT_PAREN");
|
||||
Lex(l); //skip )
|
||||
l->flags=(l->flags & ~(LF_ARRAY+LF_FUNCTION)) | LF_EAX;
|
||||
return PRST_UNARY_MODIFIERS;
|
||||
}
|
||||
|
||||
i=unary_ops_table[l->token];
|
||||
if (i.u2[1]) {
|
||||
Lex(l); //Skip op
|
||||
if (i.u2[0]==EC_ADDRESS && l->token==TK_IDENT) {
|
||||
if (tempc=l->hash_entry) {
|
||||
if (tempc->type & HTT_FUNCTION) {
|
||||
if (!Bt(&tempc->flags,Cf_INTERNAL)) {
|
||||
Lex(l); //skip fun name
|
||||
if (Bt(&tempc->flags,Cf_EXTERN)) {
|
||||
if (l->a)
|
||||
CbAddIc(l,EC_ABSOLUTE_ADDRESS,
|
||||
tempc->executable_address,sys_internal_types[IT_U4]);
|
||||
else
|
||||
CbAddIc(l,EC_U8,
|
||||
&tempc->executable_address,sys_internal_types[IT_U4]);
|
||||
CbAddIc(l,EC_DEREF_U4,0,
|
||||
sys_internal_types[IT_U4]);
|
||||
} else {
|
||||
if (l->a)
|
||||
CbAddIc(l,EC_ABSOLUTE_ADDRESS,
|
||||
tempc->executable_address,sys_internal_types[IT_U4]);
|
||||
else
|
||||
CbAddIc(l,EC_U8,
|
||||
tempc->executable_address,sys_internal_types[IT_U4]);
|
||||
}
|
||||
return PRST_CHECK_BINARY_OPS;
|
||||
} //TODO: is this an error?
|
||||
}//TODO: is this an error?
|
||||
}//TODO: is this an error?
|
||||
}
|
||||
PrsPush(ps,tempc);
|
||||
PrsPush(ps,i);
|
||||
return PRST_UNARY_TERM;
|
||||
}
|
||||
if (l->token=='+') {
|
||||
Lex(l);
|
||||
return PRST_UNARY_TERM;
|
||||
}
|
||||
|
||||
if (l->token!=TK_IDENT) {
|
||||
if (l->token==TK_PLUS_PLUS) {
|
||||
Lex(l);
|
||||
l->flags|=LF_PREINC;
|
||||
return PRST_UNARY_TERM;
|
||||
}
|
||||
if (l->token==TK_MINUS_MINUS) {
|
||||
Lex(l);
|
||||
l->flags|=LF_PREDEC;
|
||||
return PRST_UNARY_TERM;
|
||||
}
|
||||
if (l->token=='$$' && l->flags & LF_ASM_EXPRESSIONS) {
|
||||
Lex(l);
|
||||
CbAddIc(l,EC_U8,l->instruction_pointer,sys_internal_types[IT_U4]);
|
||||
return PRST_CHECK_BINARY_OPS;
|
||||
}
|
||||
PrsExcept(l,"ST_MISSING_EXPRESSION");
|
||||
}
|
||||
|
||||
if (tempm=l->local_var_entry) {
|
||||
l->flags&=~(LF_EAX+LF_ARRAY+LF_FUNCTION);
|
||||
tempc=tempm->member_class+sizeof(ClassStruct);
|
||||
if (tempm->flags & MLF_FUNCTION) {
|
||||
l->flags|=LF_FUNCTION;
|
||||
PrsPush(ps,0);
|
||||
PrsPush(ps,tempm->parameter_cnt);
|
||||
}
|
||||
if (tempm->cnt) {
|
||||
l->flags|=LF_ARRAY;
|
||||
tempc+=sizeof(ClassStruct);
|
||||
}
|
||||
CbAddIc(l,EC_EBP,0,tempc);
|
||||
CbAddIc(l,EC_U8,tempm->offset,tempc);
|
||||
CbAddIc(l,EC_ADDITION,0,tempc);
|
||||
Lex(l); //skip var name
|
||||
return PRST_UNARY_MODIFIERS;
|
||||
}
|
||||
|
||||
if (!(temph=l->hash_entry)) {
|
||||
if (!(l->flags & LF_ASM_EXPRESSIONS))
|
||||
PrsExcept(l,"ST_INVALID_LVALUE");
|
||||
temph=MAllocZ(sizeof(SysHashEntry));
|
||||
temph->string=l->ident;
|
||||
l->ident=NULL;
|
||||
if (temph->string[0]=='@' &&
|
||||
temph->string[1]=='@') {
|
||||
temph->type=HTT_SYS_SYMBOL | HTT_UNRESOLVED_LOCAL;
|
||||
temph1=FindHashBucket(temph->string,l->local_hash_table);
|
||||
} else {
|
||||
temph->type=HTT_SYS_SYMBOL | HTT_UNRESOLVED_GLBL;
|
||||
temph1=FindHashBucket(temph->string,l->glbl_hash_table);
|
||||
}
|
||||
temph->use_cnt=0;
|
||||
SetSourceFileInfo(l,temph);
|
||||
temph->next=*temph1;
|
||||
*temph1=temph;
|
||||
temph->user0=0;
|
||||
}
|
||||
|
||||
if (temph->type & HTT_SYS_SYMBOL) {
|
||||
if (!(temph->type & HTT_LITERAL) &&
|
||||
!(temph->type & HTT_IMPORT))
|
||||
l->absolute_address_cnt++;
|
||||
if (temph->type & (HTT_UNRESOLVED_LOCAL|HTT_UNRESOLVED_GLBL)) {
|
||||
templu=MAlloc(sizeof(LexUndefEntry));
|
||||
templu->hash=temph;
|
||||
templu->next=l->undef_hash_entry;
|
||||
l->undef_hash_entry=templu;
|
||||
if (temph->type & HTT_UNRESOLVED_LOCAL)
|
||||
l->flags|=LF_UNRESOLVED_LOCAL;
|
||||
else
|
||||
l->flags|=LF_UNRESOLVED_GLBL;
|
||||
CbAddIc(l,EC_U8,&temph->user0,sys_internal_types[IT_U4]);
|
||||
CbAddIc(l,EC_DEREF_U4,0,sys_internal_types[IT_U4]);
|
||||
} else {
|
||||
if (l->a && !(temph->type & HTT_LITERAL))
|
||||
CbAddIc(l,EC_ABSOLUTE_ADDRESS,temph->user0,sys_internal_types[IT_U4]);
|
||||
else
|
||||
CbAddIc(l,EC_U8,temph->user0,sys_internal_types[IT_U4]);
|
||||
}
|
||||
Lex(l);
|
||||
return PRST_CHECK_BINARY_OPS;
|
||||
}
|
||||
|
||||
if (temph->type & HTT_FUNCTION) {
|
||||
Lex(l); //skip fun name
|
||||
CbPush(l);
|
||||
templ=l->cb.cb_next;
|
||||
l->cb.cb_next=NULL;
|
||||
tempc=temph;
|
||||
i=tempc->parameter_cnt;
|
||||
tempm=tempc->member_list;
|
||||
argc_cnt=0;
|
||||
if (l->token!='(')
|
||||
needs_right_paren=FALSE;
|
||||
else {
|
||||
Lex(l);
|
||||
needs_right_paren=TRUE;
|
||||
}
|
||||
while (i--) {
|
||||
if (l->token==',')
|
||||
Lex(l);
|
||||
CbInitOutPtrs(&l->cb);
|
||||
if (tempm->flags & MLF_DEFAULT_AVAILABLE &&
|
||||
(l->token==')' || !needs_right_paren))
|
||||
CbAddIc(l,EC_U8,tempm->default_value,tempm->member_class);
|
||||
else
|
||||
if (!PrsParseExpression(l))
|
||||
throw(EXCEPT_COMPILER,3);
|
||||
else {
|
||||
CbPush(l);
|
||||
CbAddIc(l,0,0,0);
|
||||
tempi=CmpOptPass1(l,NULL,FALSE);
|
||||
CbPop(l);
|
||||
tempc1=tempi->ic_class;
|
||||
while (tempc1->return_class)
|
||||
tempc1=tempc1->return_class;
|
||||
tempc2=tempm->member_class;
|
||||
while (tempc2->return_class)
|
||||
tempc2=tempc2->return_class;
|
||||
if (tempc2->sub_type==IT_DOUBLE &&
|
||||
tempc1->sub_type!=IT_DOUBLE)
|
||||
tempi->ic_flags|=ICF_TO_DOUBLE;
|
||||
else
|
||||
if (tempc2->sub_type!=IT_DOUBLE &&
|
||||
tempc1->sub_type==IT_DOUBLE)
|
||||
tempi->ic_flags|=ICF_TO_INT;
|
||||
}
|
||||
CbAddIc(l,0,0,0);
|
||||
CbPush(l);
|
||||
tempm=tempm->next;
|
||||
}
|
||||
if (tempm && tempm->flags & MLF_DOT_DOT_DOT) {
|
||||
CbInitOutPtrs(&l->cb);
|
||||
CbAddIc(l,EC_U8,0,tempm->member_class);
|
||||
tempi=l->cb.cb_last_out_ptr;
|
||||
CbAddIc(l,0,0,0);
|
||||
CbPush(l);
|
||||
if (needs_right_paren) {
|
||||
if (l->token!=')') {
|
||||
do {
|
||||
if (l->token==',')
|
||||
Lex(l);
|
||||
CbInitOutPtrs(&l->cb);
|
||||
if (!PrsParseExpression(l))
|
||||
throw(EXCEPT_COMPILER,4);
|
||||
CbAddIc(l,0,0,0);
|
||||
CbPush(l);
|
||||
argc_cnt++;
|
||||
} while (l->token==',');
|
||||
}
|
||||
}
|
||||
tempi->ic_data=argc_cnt++; //++ so add_esp latter works
|
||||
}
|
||||
if (needs_right_paren) {
|
||||
if (l->token!=')')
|
||||
PrsExcept(l,"ST_MISSING_RIGHT_PAREN");
|
||||
Lex(l);
|
||||
}
|
||||
templ1=templ->cb_next;
|
||||
templ->cb_next=l->cb.cb_next;
|
||||
l->cb.cb_next=templ;
|
||||
CbPop(l);
|
||||
templ=l->cb.cb_next;
|
||||
l->cb.cb_next=templ1;
|
||||
while (templ) {
|
||||
templ1=templ->cb_next;
|
||||
CbAppend(l,templ);
|
||||
templ=templ1;
|
||||
}
|
||||
if (Bt(&tempc->flags,Cf_INTERNAL))
|
||||
CbAddIc(l,tempc->executable_address,0,tempc->return_class);
|
||||
else if (Bt(&tempc->flags,Cf_EXTERN)) {
|
||||
if (l->a)
|
||||
CbAddIc(l,EC_CALL_INDIRECT2,tempc->executable_address,tempc->return_class);
|
||||
else
|
||||
CbAddIc(l,EC_CALL_INDIRECT2,&tempc->executable_address,tempc->return_class);
|
||||
CbAddIc(l,EC_ADD_ESP32,(argc_cnt+tempc->parameter_cnt)<<3,tempc->return_class);
|
||||
} else {
|
||||
CbAddIc(l,EC_CALL,tempc->executable_address,tempc->return_class);
|
||||
CbAddIc(l,EC_ADD_ESP32,(argc_cnt+tempc->parameter_cnt)<<3,tempc->return_class);
|
||||
}
|
||||
l->flags=(l->flags|LF_EAX) & ~(LF_ARRAY|LF_FUNCTION);
|
||||
return PRST_UNARY_MODIFIERS;
|
||||
}
|
||||
if (temph->type & HTT_GLBL_VAR) {
|
||||
tempg=temph;
|
||||
tempc=tempg->var_class+sizeof(ClassStruct);
|
||||
l->flags&=~(LF_EAX|LF_ARRAY|LF_FUNCTION);
|
||||
if (tempg->cnt) {
|
||||
tempc+=sizeof(ClassStruct);
|
||||
l->flags|=LF_ARRAY;
|
||||
}
|
||||
if (tempg->flags & GVAF_FUNCTION) {
|
||||
//TODO:Not implemented
|
||||
l->flags|=LF_FUNCTION;
|
||||
}
|
||||
if (l->a) {
|
||||
if (tempg->flags & GVAF_EXTERN) { //TODO: Untested
|
||||
CbAddIc(l,EC_U8,&tempg->data_address,tempc);
|
||||
CbAddIc(l,EC_DEREF_U4,0,tempc);
|
||||
} else {
|
||||
CbAddIc(l,EC_ABSOLUTE_ADDRESS,tempg->data_address,tempc);
|
||||
if (tempg->flags & GVAF_IMPORT)
|
||||
CbAddIc(l,EC_DEREF_U4,0,tempc);
|
||||
}
|
||||
} else {
|
||||
if (tempg->flags & GVAF_EXTERN) {
|
||||
CbAddIc(l,EC_U8,&tempg->data_address,tempc);
|
||||
CbAddIc(l,EC_DEREF_U4,0,tempc);
|
||||
} else
|
||||
CbAddIc(l,EC_U8,tempg->data_address,tempc);
|
||||
}
|
||||
Lex(l);
|
||||
return PRST_UNARY_MODIFIERS;
|
||||
}
|
||||
if (!(temph->type & HTT_KEYWORD))
|
||||
PrsExcept(l,"ST_MISSING_EXPRESSION");
|
||||
if (temph->user0==KW_SIZEOF) {
|
||||
if (Lex(l)!='(') PrsExcept(l,"ST_EXPECTING_LEFT_PAREN");
|
||||
if (Lex(l)!=TK_IDENT)
|
||||
PrsExcept(l,"ST_INVALID_CLASS");
|
||||
if (tempm=l->local_var_entry) {
|
||||
tempc=tempm->member_class;
|
||||
i=(tempm->cnt) ? tempm->cnt:1;
|
||||
CbAddIc(l,EC_U8,tempc->size*i,sys_internal_types[IT_U4]);
|
||||
} else {
|
||||
tempc=l->hash_entry;
|
||||
if (!tempc || !(tempc->type & (HTT_CLASS|HTT_INTERNAL_TYPE|HTT_GLBL_VAR)))
|
||||
PrsExcept(l,"ST_INVALID_CLASS");
|
||||
CbAddIc(l,EC_U8,tempc->size,sys_internal_types[IT_U4]);
|
||||
} //TODO: should allow '*' and '.member', etc;
|
||||
if (Lex(l)!=')')
|
||||
PrsExcept(l,"ST_MISSING_RIGHT_PAREN");
|
||||
Lex(l);
|
||||
return PRST_CHECK_BINARY_OPS;
|
||||
} else if (temph->user0==KW_OFFSET) {
|
||||
if (Lex(l)!='(') PrsExcept(l,"ST_EXPECTING_LEFT_PAREN");
|
||||
if (Lex(l)!=TK_IDENT)
|
||||
PrsExcept(l,"ST_INVALID_CLASS");
|
||||
if (tempm=l->local_var_entry)
|
||||
tempc=tempm->member_class;
|
||||
else {
|
||||
tempc=l->hash_entry;
|
||||
if (!tempc || !(tempc->type & (HTT_CLASS|HTT_GLBL_VAR)))
|
||||
PrsExcept(l,"ST_INVALID_CLASS");
|
||||
else if (tempc->type & HTT_GLBL_VAR) {
|
||||
tempg=tempc;
|
||||
tempc=tempg->var_class;
|
||||
}
|
||||
}
|
||||
if (Lex(l)!='.')
|
||||
PrsExcept(l,"ST_EXPECTING_DOT");
|
||||
if (Lex(l)!=TK_IDENT)
|
||||
PrsExcept(l,"ST_INVALID_MEMBER");
|
||||
if (!(tempm=FindMember(l->ident,tempc)))
|
||||
PrsExcept(l,"ST_INVALID_MEMBER");
|
||||
CbAddIc(l,EC_U8,tempm->offset,sys_internal_types[IT_U4]);
|
||||
if (Lex(l)!=')')
|
||||
PrsExcept(l,"ST_MISSING_RIGHT_PAREN");
|
||||
Lex(l);
|
||||
return PRST_CHECK_BINARY_OPS;
|
||||
}
|
||||
PrsExcept(l,"ST_MISSING_EXPRESSION");
|
||||
}
|
||||
|
||||
U8 PrsUnaryModifier(LexStruct *l,ParseStack *ps)
|
||||
{
|
||||
I8 i,j;
|
||||
LexCbStack *templ,*templ2,*templl;
|
||||
ClassStruct *tempc,*tempc1;
|
||||
MemberListStruct *tempm;
|
||||
IntermediateCode *tempi;
|
||||
if (l->flags & LF_ASM_EXPRESSIONS)
|
||||
return PRST_CHECK_BINARY_OPS;
|
||||
if (l->token==TK_DEREFERRENCE) {
|
||||
tempi=l->cb.cb_last_out_ptr;
|
||||
if (!(l->flags & (LF_EAX | LF_ARRAY))) {
|
||||
tempc=tempi->ic_class-sizeof(ClassStruct);
|
||||
CbAddIc(l,EC_DEREF_U4+0x10000,0,tempc);
|
||||
} else
|
||||
tempi->ic_class-=sizeof(ClassStruct);
|
||||
}
|
||||
if (l->token=='.' || l->token==TK_DEREFERRENCE) {
|
||||
tempi=l->cb.cb_last_out_ptr;
|
||||
tempc=tempi->ic_class;
|
||||
if (!(l->flags & LF_EAX))
|
||||
tempc-=sizeof(ClassStruct);
|
||||
if (!(tempc->type & HTT_CLASS))
|
||||
PrsExcept(l,"ST_INVALID_CLASS");
|
||||
if (Lex(l)!=TK_IDENT)
|
||||
PrsExcept(l,"ST_INVALID_MEMBER");
|
||||
if (!(tempm=FindMember(l->ident,tempc)))
|
||||
PrsExcept(l,"ST_INVALID_MEMBER");
|
||||
Lex(l); //skip member name
|
||||
tempc1=tempm->member_class+sizeof(ClassStruct);
|
||||
CbAddIc(l,EC_U8,tempm->offset,tempc1);
|
||||
l->flags&=~(LF_EAX|LF_ARRAY|LF_FUNCTION);
|
||||
if (tempm->cnt) {
|
||||
tempc1+=sizeof(ClassStruct);
|
||||
l->flags|=LF_ARRAY;
|
||||
}
|
||||
if(tempm->flags & MLF_FUNCTION) {
|
||||
PrsPush(ps,0);
|
||||
PrsPush(ps,tempm->parameter_cnt);
|
||||
l->flags|=LF_FUNCTION;
|
||||
}
|
||||
CbAddIc(l,EC_ADDITION,0,tempc1);
|
||||
return PRST_UNARY_MODIFIERS;
|
||||
}
|
||||
if (l->token==TK_CAST) {
|
||||
if (Lex(l)!='(')
|
||||
PrsExcept(l,"ST_EXPECTING_LEFT_PAREN");
|
||||
if (Lex(l)!=TK_IDENT)
|
||||
PrsExcept(l,"ST_INVALID_CLASS");
|
||||
tempc=l->hash_entry;
|
||||
if (!tempc || !(tempc->type & (HTT_CLASS|HTT_INTERNAL_TYPE)))
|
||||
PrsExcept(l,"ST_INVALID_CLASS");
|
||||
while (Lex(l)=='*')
|
||||
tempc+=sizeof(ClassStruct);
|
||||
tempc+=sizeof(ClassStruct);
|
||||
tempi=l->cb.cb_last_out_ptr;
|
||||
tempi->ic_class=tempc;
|
||||
if (l->token!=')')
|
||||
PrsExcept(l,"ST_MISSING_RIGHT_PAREN");
|
||||
Lex(l);
|
||||
return PRST_UNARY_MODIFIERS;
|
||||
}
|
||||
if (l->token=='[') {
|
||||
Lex(l);
|
||||
tempi=l->cb.cb_last_out_ptr;
|
||||
if (!(l->flags & (LF_ARRAY | LF_EAX))) {
|
||||
tempc=tempi->ic_class-sizeof(ClassStruct);
|
||||
while (!(tempc->type & HTT_INTERNAL_TYPE) && tempc->return_class)
|
||||
tempc=tempc->return_class;
|
||||
if (tempc->type==HTT_INTERNAL_TYPE)
|
||||
i=EC_DEREF_U8+0x10000+it_to_ec_offset[tempc->sub_type];
|
||||
else
|
||||
i=EC_DEREF_U4+0x10000;
|
||||
CbAddIc(l,i,0,tempc);
|
||||
} else {
|
||||
tempc=tempi->ic_class;
|
||||
if (!(l->flags & LF_EAX))
|
||||
tempc-=sizeof(ClassStruct);
|
||||
}
|
||||
tempc1=tempc-sizeof(ClassStruct);
|
||||
CbAddIc(l,EC_U8,tempc1->size,tempc);
|
||||
if (!PrsParseExpression(l))
|
||||
throw(EXCEPT_COMPILER,5);
|
||||
if (l->token!=']')
|
||||
PrsExcept(l,"ST_MISSING_RIGHT_BRACKET");
|
||||
Lex(l); //skip ]
|
||||
CbAddIc(l,EC_MULTIPLICATION,0,tempc);
|
||||
CbAddIc(l,EC_ADDITION,0,tempc);
|
||||
l->flags&=~(LF_EAX|LF_ARRAY);
|
||||
return PRST_UNARY_MODIFIERS;
|
||||
}
|
||||
if (l->token=='(' && l->flags & LF_FUNCTION) {
|
||||
tempi=l->cb.cb_last_out_ptr;
|
||||
if (!(l->flags & (LF_EAX | LF_ARRAY))) {
|
||||
tempc=tempi->ic_class-sizeof(ClassStruct);
|
||||
CbAddIc(l,EC_DEREF_U4+0x10000,0,tempc);
|
||||
} else {
|
||||
tempi->ic_class=tempi->ic_class-sizeof(ClassStruct);
|
||||
tempc=tempi;
|
||||
}
|
||||
i=PrsPop(ps);
|
||||
PrsPop(ps);
|
||||
j=i;
|
||||
Lex(l); //skip '('
|
||||
CbPush(l);
|
||||
templ=l->cb.cb_next;
|
||||
l->cb.cb_next=NULL;
|
||||
while (i--) {
|
||||
if (l->token==',')
|
||||
Lex(l);
|
||||
CbInitOutPtrs(&l->cb);
|
||||
if (!PrsParseExpression(l))
|
||||
throw(EXCEPT_COMPILER,6);
|
||||
CbAddIc(l,0,0,0);
|
||||
CbPush(l);
|
||||
}
|
||||
if (l->token!=')')
|
||||
PrsExcept(l,"ST_MISSING_RIGHT_PAREN");
|
||||
Lex(l); //skip ')'
|
||||
templl=templ->cb_next;
|
||||
templ->cb_next=l->cb.cb_next;
|
||||
l->cb.cb_next=templ;
|
||||
CbPop(l);
|
||||
templ=l->cb.cb_next;
|
||||
l->cb.cb_next=templl;
|
||||
while (templ) {
|
||||
templ2=templ->cb_next;
|
||||
CbAppend(l,templ);
|
||||
templ=templ2;
|
||||
}
|
||||
CbAddIc(l,EC_CALL_INDIRECT,j<<3,tempc);
|
||||
CbAddIc(l,EC_ADD_ESP32,j<<3+8,tempc);
|
||||
l->flags=(l->flags | LF_EAX)&~(LF_ARRAY | LF_FUNCTION);
|
||||
return PRST_UNARY_MODIFIERS;
|
||||
}
|
||||
if (l->token==TK_PLUS_PLUS) {
|
||||
Lex(l);
|
||||
l->flags|=LF_POSTINC;
|
||||
return PRST_DEREFERRENCE;
|
||||
}
|
||||
if (l->token==TK_MINUS_MINUS) {
|
||||
Lex(l);
|
||||
l->flags|=LF_POSTDEC;
|
||||
return PRST_DEREFERRENCE;
|
||||
}
|
||||
return PRST_DEREFERRENCE;
|
||||
}
|
||||
|
||||
U8 PrsDereferrence(LexStruct *l,ParseStack *ps)
|
||||
{
|
||||
I8 i;
|
||||
ClassStruct *tempc;
|
||||
IntermediateCode *tempi;
|
||||
if (l->flags & LF_FUNCTION) {
|
||||
i=PrsPop(ps);
|
||||
tempc=PrsPop(ps);
|
||||
}
|
||||
if (l->flags & LF_EAX)
|
||||
return PRST_CHECK_BINARY_OPS;
|
||||
tempi=l->cb.cb_last_out_ptr;
|
||||
tempc=tempi->ic_class-sizeof(ClassStruct);
|
||||
if (l->flags & LF_ARRAY) {
|
||||
tempi->ic_class=tempc;
|
||||
return PRST_CHECK_BINARY_OPS;
|
||||
}
|
||||
|
||||
if (l->flags & LF_PREINC) {
|
||||
l->flags&=~LF_PREINC;
|
||||
i=EC_PP_U8;
|
||||
} else if (l->flags & LF_PREDEC) {
|
||||
l->flags&=~LF_PREDEC;
|
||||
i=EC_MM_U8;
|
||||
} else if (l->flags & LF_POSTINC) {
|
||||
l->flags&=~LF_POSTINC;
|
||||
i=EC_U8_PP;
|
||||
} else if (l->flags & LF_POSTDEC) {
|
||||
l->flags&=~LF_POSTDEC;
|
||||
i=EC_U8_MM;
|
||||
} else
|
||||
i=EC_DEREF_U8;
|
||||
|
||||
while (tempc->return_class)
|
||||
tempc=tempc->return_class;
|
||||
if (tempc->type & HTT_INTERNAL_TYPE)
|
||||
i+=it_to_ec_offset[tempc->sub_type];
|
||||
else
|
||||
i+=it_to_ec_offset[IT_U4];
|
||||
CbAddIc(l,i+0x10000,0,tempc);
|
||||
return PRST_CHECK_BINARY_OPS;
|
||||
}
|
||||
|
||||
U1 *CompileExpression(LexStruct *l)
|
||||
{
|
||||
U1 *result;
|
||||
U8 size;
|
||||
DbgInfo *dbg=NULL;
|
||||
CbPush(l);
|
||||
CbInitOutPtrs(&l->cb);
|
||||
if (PrsParseExpression(l,TRUE)) {
|
||||
CbAddIc(l,EC_RET,0,0);
|
||||
CbAddIc(l,0,0,0);
|
||||
result=CbCompile(l,NULL,&size,&dbg);
|
||||
} else
|
||||
result=NULL;
|
||||
CbPop(l);
|
||||
Free(dbg);
|
||||
return result;
|
||||
}
|
||||
|
||||
BoolU4 GetExpression(LexStruct *l,U1 **e) //FALSE=no err
|
||||
{
|
||||
*e=CompileExpression(l);
|
||||
if (*e)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
I8 Expression(LexStruct *l) //FALSE=no err
|
||||
{
|
||||
I8 result;
|
||||
U1 *e=CompileExpression(l);
|
||||
if (e) {
|
||||
result=Run(e);
|
||||
DelExpression(e);
|
||||
} else
|
||||
result=0;
|
||||
return result;
|
||||
}
|
||||
Reference in new issue
Block a user