1687 lines
39 KiB
Plaintext
1687 lines
39 KiB
Plaintext
extern BoolU4 GetExpression(LexStruct *l,U1 **exp);
|
|
extern I8 Lex(LexStruct *l);
|
|
extern U8 PrsUnaryTerm(LexStruct *l,ParseStack *ps);
|
|
extern U8 PrsUnaryModifier(LexStruct *l,ParseStack *ps);
|
|
extern U8 PrsDereferrence(LexStruct *l,ParseStack *ps);
|
|
extern ClassStruct *CmpParseClass(LexStruct *l,BoolU4 is_union,BoolU4 is_public);
|
|
extern void PrsExcept(LexStruct *l,I1 *name=NULL,I1 *msg=NULL);
|
|
extern void CmpParseVarList(LexStruct *l,ClassStruct *tempc,
|
|
I8 mode,U8 union_base=MAX_I4);
|
|
extern BoolU4 CmpParseStatement(LexStruct *l,ClassStruct *locals,I8 try_count=0,
|
|
CbMiscStruct *break_label=NULL,CbMiscStruct *continue_label=NULL,
|
|
BoolU4 saved_prs_semicolon=TRUE);
|
|
extern I8 ExecuteCmdLine(LexStruct *l);
|
|
extern I8 ExecuteString(I1 *buf,I1 *filename=NULL);
|
|
extern I8 ExecuteFile(I1 *name);
|
|
extern void ContinueUserTask();
|
|
extern IntermediateCode *CmpOptPass1(LexStruct *l,ClassStruct *fun_class,BoolU4 combined);
|
|
extern void CmpOptPass2(LexStruct *l,ClassStruct *fun_class);
|
|
extern void CmpOptPass3(LexStruct *l,ClassStruct *fun_class);
|
|
extern void CmpOptPass4(LexStruct *l,ClassStruct *fun_class);
|
|
|
|
LTextern CODE_TABLE U4 code_table[1];
|
|
LTextern UNSIGNED_CODE_TABLE U4 unsigned_code_table[1];
|
|
LTextern DOUBLE_CODE_TABLE U4 double_code_table[1];
|
|
LTextern INTERNAL_TYPES_TABLE U1 internal_types_table[1];
|
|
|
|
SysHashTable *asm_hash;
|
|
BoolU4 is_first_compiler;
|
|
SysHashEntry *sys_internal_types[IT_NUM_IT];
|
|
U1 it_to_ec_offset[IT_NUM_IT]={0,0,3,3,2,2,1,1,0,0,0,0};
|
|
|
|
|
|
#define FUT_NULL 0
|
|
#define FUT_8_1 1
|
|
#define FUT_8_2 2
|
|
#define FUT_8_4 3
|
|
#define FUT_8_5 4
|
|
#define FUT_8_6 5
|
|
#define FUT_8_10 6
|
|
#define FUT_8_JMP_1 7
|
|
#define FUT_32_4 8
|
|
#define FUT_32_4_CALL 9
|
|
#define FUT_32_4_ABS 10
|
|
#define FUT_32_4_ABS2 11
|
|
#define FUT_32_5 12
|
|
#define FUT_32_6 13
|
|
#define FUT_32_7 14
|
|
#define FUT_32_9 15
|
|
#define FUT_32_4_ENTER 16
|
|
#define FUT_32_4P11_4 17
|
|
#define FUT_32_JMP_4 18
|
|
#define FUT_64_H9_L4 19
|
|
#define FUT_ENTER1 20
|
|
#define FUT_ENTER2 21
|
|
#define FUT_32_4P10_4 22
|
|
|
|
U1 *signed_fix_up_table,*unsigned_fix_up_table,*double_fix_up_table;
|
|
|
|
U2 *duel_I1_tokens1,*duel_I1_tokens2,*duel_I1_tokens3;
|
|
U4 *binary_ops_table,*unary_ops_table;
|
|
U1 *deref_bitmap,*assign_bitmap,
|
|
*push_bitmap;
|
|
U2 *push_map;
|
|
|
|
LexStruct *LexNew(I1 *buf,U8 flags,I1 *filename)
|
|
{
|
|
LexStruct *l=MAlloc(sizeof(LexStruct));
|
|
LexFileStruct *tempf=&l->lfns[0];
|
|
MemSet(l,0,offset(LexStruct.lfns)+sizeof(LexFileStruct));
|
|
l->next=l;
|
|
l->last=l;
|
|
l->flags=flags;
|
|
l->ESI_offset=MAX_I8;
|
|
l->EDI_offset=MAX_I8;
|
|
l->hash_mask=HTT_ALL;
|
|
l->hash_table_list=Fs->hash_table;
|
|
l->define_hash_table=Fs->hash_table;
|
|
l->cur_lfn=tempf;
|
|
l->next_exe_blk=&l->next_exe_blk;
|
|
l->last_exe_blk=&l->next_exe_blk;
|
|
if (!filename)
|
|
tempf->name=NewString(sys_temp_filename);
|
|
else
|
|
tempf->name=filename;
|
|
if (flags & LF_PROMPT)
|
|
buf=MAllocZ(4);
|
|
tempf->buf=buf;
|
|
tempf->buf_ptr=buf;
|
|
tempf->line_start=buf;
|
|
tempf->line_num=1;
|
|
l->cur_buf_ptr=buf;
|
|
return l;
|
|
}
|
|
|
|
void LexDel(LexStruct *l)
|
|
{
|
|
LexFileStruct *tempf=l->cur_lfn;
|
|
void my_LtfDel(Ltf *l,BoolU4 adam_mem);
|
|
Ltf *ltf;
|
|
|
|
while (tempf!=&l->lfns[0]) {
|
|
if (ltf=tempf->l) {
|
|
if (ext[EXT_LTF_DEL]) {
|
|
my_LtfDel=ext[EXT_LTF_DEL];
|
|
my_LtfDel(ltf,FALSE);
|
|
}
|
|
}
|
|
Free(tempf->buf);
|
|
Free(tempf->name);
|
|
tempf-=sizeof(LexFileStruct);
|
|
}
|
|
Free(tempf->name);
|
|
if (!(l->flags & LF_DONT_FREE_BUFFER))
|
|
Free(tempf->buf);
|
|
Free(l->ident);
|
|
Free(l);
|
|
}
|
|
|
|
|
|
void SetSourceFileInfo(LexStruct *l,SysHashEntry *h)
|
|
{
|
|
LexFileStruct *tempf=l->cur_lfn;
|
|
h->source_link=MSPrintF("FL:%s,%d",tempf->name,tempf->line_num);
|
|
if (Bt(&l->flags,LFf_KEEP_PRIVATE))
|
|
h->type|=HTT_PRIVATE;
|
|
}
|
|
|
|
void LexPutToken(LexStruct *l)
|
|
{
|
|
PutChar('"');
|
|
if (l->token==TK_IDENT || l->token==TK_STRING)
|
|
PutS(l->ident);
|
|
else if (l->token==TK_INTEGER)
|
|
cout "INT:",l->cur_i;
|
|
else if (l->token==TK_DOUBLE)
|
|
cout "DBL:",l->cur_d;
|
|
else if (l->token>=CH_SHIFT_SPACE && l->token<=0x7E)
|
|
PutChar(l->token);
|
|
else {
|
|
cout "T:",l->token;
|
|
}
|
|
PutS("\" ");
|
|
}
|
|
|
|
U4 lex_zeros=0,lex_line_feed=0x000A;
|
|
|
|
void LexBackupLastChar(LexStruct *l)
|
|
{
|
|
LexFileStruct *tempf=l->cur_lfn;
|
|
tempf->buf_ptr=l->cur_buf_ptr;
|
|
if (l->flags & LF_USE_LAST_I1) {
|
|
tempf->last_I1=l->last_I1;
|
|
l->flags&=~LF_USE_LAST_I1;
|
|
} else
|
|
tempf->last_I1=0;
|
|
}
|
|
|
|
U8 LexGetChar(LexStruct *l)
|
|
{
|
|
U1 *src;
|
|
LexFileStruct *tempf,*tempf1;
|
|
BoolU4 cont;
|
|
U8 result;
|
|
U1 *my_SysPrompt(BoolU4 double_semicolon);
|
|
Ltf *ltf;
|
|
LtfEntry *cl;
|
|
U1 *ptr;
|
|
void my_LtfDel(Ltf *l,BoolU4 adam_mem);
|
|
if (l->flags & LF_USE_LAST_I1) {
|
|
l->flags&=~LF_USE_LAST_I1;
|
|
return l->last_I1;
|
|
}
|
|
do {
|
|
lex_getchar_start:
|
|
src=l->cur_buf_ptr++;
|
|
switch (l->last_I1=result=*src++) {
|
|
case 0:
|
|
tempf=l->cur_lfn;
|
|
if (tempf->flags & LFSF_IS_LTF) {
|
|
ltf=tempf->l;
|
|
cl=tempf->cur_entry;
|
|
cl=cl->next;
|
|
while (cl!=ltf) {
|
|
cont=FALSE;
|
|
tempf->cur_entry=cl;
|
|
switch (cl->btype) {
|
|
case LTFT_TEXT:
|
|
if (*(src=cl->display))
|
|
tempf->buf=tempf->buf_ptr=l->cur_buf_ptr=src;
|
|
else {
|
|
cont=TRUE;
|
|
cl=cl->next;
|
|
}
|
|
break;
|
|
case LTFT_CR:
|
|
src=&lex_line_feed;
|
|
tempf->buf=tempf->buf_ptr=l->cur_buf_ptr=src;
|
|
|
|
tempf->line_start=cl->next;
|
|
tempf->line_num=cl->y+2; //+1 because CR is on previous line, +1 because ltf y starts at zero
|
|
compiled_lines++;
|
|
if (l->flags & LF_ECHO)
|
|
CrLf;
|
|
l->last_I1=CH_CR;
|
|
return CH_CR;
|
|
case LTFT_TAB:
|
|
src=&lex_zeros;
|
|
tempf->buf=tempf->buf_ptr=l->cur_buf_ptr=src;
|
|
|
|
tempf->line_num=cl->y+1;
|
|
if (l->flags & LF_ECHO)
|
|
PutChar(CH_TAB);
|
|
l->last_I1=CH_TAB;
|
|
return CH_TAB;
|
|
case LTFT_PAGE_BREAK:
|
|
src=&lex_zeros;
|
|
tempf->buf=tempf->buf_ptr=l->cur_buf_ptr=src;
|
|
|
|
tempf->line_num=cl->y+2; //TODO: should be a page down
|
|
if (l->flags & LF_ECHO)
|
|
PutChar(CH_FORM_FEED);
|
|
l->last_I1=CH_FORM_FEED;
|
|
return CH_FORM_FEED;
|
|
case LTFT_INSERT_BINARY:
|
|
src=&lex_zeros;
|
|
tempf->buf=tempf->buf_ptr=l->cur_buf_ptr=src;
|
|
|
|
tempf->line_num=cl->y+1;
|
|
Free(l->ident);
|
|
l->ident=NULL;
|
|
l->ident_len=0;
|
|
if (cl->bin_data) {
|
|
ptr=MAlloc(cl->bin_data->size);
|
|
if (cl->bin_data->data)
|
|
MemCpy(ptr,cl->bin_data->data,cl->bin_data->size);
|
|
l->ident=ptr;
|
|
l->ident_len=cl->bin_data->size;
|
|
}
|
|
l->last_I1=TK_INSERT_BINARY;
|
|
return TK_INSERT_BINARY;
|
|
case LTFT_INSERT_BINARY_TYPE:
|
|
src=&lex_zeros;
|
|
tempf->buf=tempf->buf_ptr=l->cur_buf_ptr=src;
|
|
|
|
if (cl->bin_data)
|
|
l->cur_i=cl->bin_data->type;
|
|
else
|
|
l->cur_i=0;
|
|
tempf->line_num=cl->y+1;
|
|
l->last_I1=TK_INSERT_BINARY_TYPE;
|
|
return TK_INSERT_BINARY_TYPE;
|
|
case LTFT_INSERT_BINARY_SIZE:
|
|
src=&lex_zeros;
|
|
tempf->buf=tempf->buf_ptr=l->cur_buf_ptr=src;
|
|
|
|
if (cl->bin_data)
|
|
l->cur_i=cl->bin_data->size;
|
|
else
|
|
l->cur_i=0;
|
|
tempf->line_num=cl->y+1;
|
|
l->last_I1=TK_INSERT_BINARY_SIZE;
|
|
return TK_INSERT_BINARY_SIZE;
|
|
default:
|
|
cont=TRUE;
|
|
cl=cl->next;
|
|
}
|
|
if (!cont) break;
|
|
}
|
|
if (cl==ltf) {
|
|
if (ext[EXT_LTF_DEL]) {
|
|
my_LtfDel=ext[EXT_LTF_DEL];
|
|
my_LtfDel(ltf,FALSE);
|
|
}
|
|
tempf->l=tempf->buf=NULL;
|
|
Free(tempf->name);
|
|
tempf->name=NULL;
|
|
goto here;
|
|
}
|
|
} else {
|
|
here:
|
|
tempf=l->cur_lfn;
|
|
if (tempf!=&l->lfns[0]) {
|
|
Free(tempf->name);
|
|
tempf->name=NULL;
|
|
Free(tempf->buf);
|
|
tempf->buf=NULL;
|
|
tempf1=tempf;
|
|
l->cur_lfn=tempf-=sizeof(LexFileStruct);
|
|
l->cur_buf_ptr=tempf->buf_ptr;
|
|
if (l->last_I1=tempf->last_I1) {
|
|
l->flags&=~LF_USE_LAST_I1;
|
|
return l->last_I1;
|
|
} else
|
|
l->flags&=~LF_USE_LAST_I1;
|
|
} else {
|
|
if (l->flags & LF_PROMPT) {
|
|
Free(tempf->buf);
|
|
my_SysPrompt=FindExtern("SysPrompt");
|
|
l->cur_buf_ptr=tempf->line_start=
|
|
tempf->buf_ptr=tempf->buf=my_SysPrompt(TRUE);
|
|
} else {
|
|
l->last_I1=TK_EOF;
|
|
l->cur_buf_ptr=src-1;
|
|
return TK_EOF;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case CH_CURSOR:
|
|
case CH_FORM_FEED:
|
|
goto lex_getchar_start;
|
|
case CH_LINE_FEED:
|
|
tempf=l->cur_lfn;
|
|
if (tempf->flags & LFSF_IS_LTF)
|
|
return result;
|
|
else {
|
|
tempf->line_num++;
|
|
compiled_lines++;
|
|
tempf->line_start=src;
|
|
}
|
|
default:
|
|
if (l->flags & LF_ECHO)
|
|
PutChar(result);
|
|
return result;
|
|
}
|
|
} while (TRUE);
|
|
}
|
|
|
|
void LexSkipEol(LexStruct *l)
|
|
{
|
|
U1 ch;
|
|
do ch=LexGetChar(l);
|
|
while (ch && ch!=CH_CR && ch!=CH_LINE_FEED);
|
|
}
|
|
|
|
void DelExpression(U1 *code)
|
|
{
|
|
Free(code);
|
|
}
|
|
|
|
|
|
U8 EvalExpression(LexStruct *l)
|
|
{
|
|
U1 *exp;
|
|
U8 result=0;
|
|
if (!GetExpression(l,&exp))
|
|
LexSkipEol(l);
|
|
else {
|
|
result=Run(exp);
|
|
DelExpression(exp);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void LexIncludeString(LexStruct *l,I1 *filename,
|
|
I1 *src,BoolU4 actual_file)
|
|
{
|
|
LexFileStruct *tempf;
|
|
LexBackupLastChar(l);
|
|
tempf=l->cur_lfn+sizeof(LexFileStruct);
|
|
l->cur_lfn=tempf;
|
|
tempf->buf=src;
|
|
tempf->buf_ptr=src;
|
|
tempf->line_num=1;
|
|
tempf->line_start=src;
|
|
tempf->last_I1=0;
|
|
if (actual_file) {
|
|
tempf->name=AbsoluteFileName(filename);
|
|
tempf->flags=LFSF_IS_INCLUDED;
|
|
} else {
|
|
tempf->name=NewString(sys_temp_filename);
|
|
tempf->flags=0;
|
|
}
|
|
l->cur_buf_ptr=src;
|
|
}
|
|
|
|
void LexIncludeLtf(LexStruct *l,I1 *filename)
|
|
{
|
|
BoolU4 is_null;
|
|
LtfEntry *cl;
|
|
Ltf *my_LtfRead(I1 *name,U8 flags);
|
|
Ltf *ltf;
|
|
LexFileStruct *tempf;
|
|
|
|
LexBackupLastChar(l);
|
|
tempf=l->cur_lfn+sizeof(LexFileStruct);
|
|
l->cur_lfn=tempf;
|
|
tempf->line_start=&lex_zeros;
|
|
if (!ext[EXT_LTF_READ])
|
|
throw(EXCEPT_COMPILER,1); //This should never happen
|
|
my_LtfRead=ext[EXT_LTF_READ];
|
|
ltf=my_LtfRead(filename,LTFF_DOUBLE_DOLLARS);
|
|
if (!ltf)
|
|
is_null=TRUE;
|
|
else {
|
|
tempf->l=ltf;
|
|
cl=ltf->dummy.next;
|
|
while (cl!=ltf) {
|
|
if (cl->btype==LTFT_TEXT)
|
|
break;
|
|
if (cl->btype==LTFT_TAB)
|
|
break;
|
|
if (cl->btype==LTFT_CR)
|
|
break;
|
|
if (cl->btype==LTFT_INSERT_BINARY)
|
|
break;
|
|
if (cl->btype==LTFT_INSERT_BINARY_TYPE)
|
|
break;
|
|
if (cl->btype==LTFT_INSERT_BINARY_SIZE)
|
|
break;
|
|
cl=cl->next;
|
|
}
|
|
if (cl!=ltf) {
|
|
tempf->line_start=cl;
|
|
tempf->line_num=cl->y+1;
|
|
if (cl->btype==LTFT_TEXT) {
|
|
tempf->cur_entry=cl;
|
|
tempf->buf=cl->display;
|
|
tempf->buf_ptr=cl->display;
|
|
} else {
|
|
tempf->cur_entry=cl->last; //TODO might be problem at begining of file
|
|
tempf->buf=&lex_zeros;
|
|
tempf->buf_ptr=&lex_zeros;
|
|
}
|
|
is_null=FALSE;
|
|
} else
|
|
is_null=TRUE;
|
|
}
|
|
tempf->name=AbsoluteFileName(filename);
|
|
if (is_null) {
|
|
tempf->flags=LFSF_IS_INCLUDED;
|
|
tempf->buf=&lex_zeros;
|
|
tempf->buf_ptr=&lex_zeros;
|
|
tempf->line_num=1;
|
|
} else
|
|
tempf->flags=LFSF_IS_INCLUDED|LFSF_IS_LTF;
|
|
tempf->last_I1=0;
|
|
l->cur_buf_ptr=tempf->buf_ptr;
|
|
}
|
|
|
|
void LexPush(LexStruct *l)
|
|
{
|
|
LexFileStruct *tempf=l->cur_lfn,
|
|
*tempf1=&l->stack[l->stack_ptr++];
|
|
if (l->stack_ptr>=LFN_STACK_CNT)
|
|
PrsExcept(l,"ST_LEX_STACK_OVERFLOW");
|
|
LexBackupLastChar(l);
|
|
if (tempf->last_I1)
|
|
l->flags|=LF_USE_LAST_I1;
|
|
MemCpy(tempf1,tempf,sizeof(LexFileStruct));
|
|
}
|
|
|
|
void LexPop(LexStruct *l)
|
|
{
|
|
LexFileStruct *tempf=l->cur_lfn,
|
|
*tempf1=&l->stack[--l->stack_ptr];
|
|
l->cur_buf_ptr=tempf1->buf_ptr;
|
|
if (l->last_I1=tempf1->last_I1)
|
|
l->flags|=LF_USE_LAST_I1;
|
|
else
|
|
l->flags&=~LF_USE_LAST_I1;
|
|
MemCpy(tempf,tempf1,sizeof(LexFileStruct));
|
|
}
|
|
|
|
MemberListStruct *FindMember(I1 *st,ClassStruct *c)
|
|
{
|
|
MemberListStruct *ml=c->member_list;
|
|
while (ml) {
|
|
if (!StrCmp(ml->string,st)) {
|
|
ml->use_cnt++;
|
|
return ml;
|
|
}
|
|
ml=ml->next;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void DelMemberList(ClassStruct *tempc)
|
|
{
|
|
MemberListStruct *tempm,*tempm1;
|
|
tempm=tempc->member_list;
|
|
while (tempm) {
|
|
tempm1=tempm->next;
|
|
Free(tempm->string);
|
|
Free(tempm->fmtstr);
|
|
Free(tempm->fmtdata);
|
|
if (tempm->flags & MLF_DEFAULT_AVAILABLE &&
|
|
tempm->member_class==sys_internal_types[IT_I1]+sizeof(ClassStruct))
|
|
Free(tempm->default_value);
|
|
Free(tempm);
|
|
tempm=tempm1;
|
|
}
|
|
tempc->size=0;
|
|
tempc->last_in_member_list=&tempc->member_list;
|
|
tempc->member_list=NULL;
|
|
tempc->member_cnt=0;
|
|
tempc->parameter_cnt=0;
|
|
}
|
|
|
|
|
|
I8 LexInString(LexStruct *l,
|
|
I1 *buf,I8 size,BoolU4 *done)
|
|
{
|
|
I8 i=0,j,ch;
|
|
*done=TRUE;
|
|
while (i<size-1) {
|
|
ch=LexGetChar(l);
|
|
if (!ch || ch=='"') {
|
|
buf[i++]=0;
|
|
return i;
|
|
} else if (ch=='\\') {
|
|
ch=LexGetChar(l);
|
|
if (ch=='n')
|
|
buf[i++]=10;
|
|
else if (ch=='r')
|
|
buf[i++]=13;
|
|
else if (ch=='"')
|
|
buf[i++]='"';
|
|
else if (ch==0x27) // "\'"
|
|
buf[i++]=0x27;
|
|
else if (ch=='\`')
|
|
buf[i++]='\`';
|
|
else if (ch=='\\')
|
|
buf[i++]='\\';
|
|
else if (ch=='t')
|
|
buf[i++]=9;
|
|
else if (ch=='x') {
|
|
j=0;
|
|
while (TRUE) {
|
|
ch=ToUpper(LexGetChar(l));
|
|
if (Bt(hex_numeric_bitmap,ch)) {
|
|
if (ch<='9')
|
|
j=j<<4+ch-'0';
|
|
else
|
|
j=j<<4+ch-'A'+10;
|
|
} else
|
|
break;
|
|
}
|
|
buf[i++]=j;
|
|
l->flags|=LF_USE_LAST_I1;
|
|
} else if (ch>='0' && ch<='7') {
|
|
j=ch-'0';
|
|
do {
|
|
ch=LexGetChar(l);
|
|
if (ch>='0' && ch<='7')
|
|
j=j<<3+ch-'0';
|
|
} while (ch>='0' && ch<='7');
|
|
buf[i++]=j;
|
|
l->flags|=LF_USE_LAST_I1;
|
|
} else {
|
|
l->flags|=LF_USE_LAST_I1;
|
|
buf[i++]='\\';
|
|
}
|
|
} else if (ch=='$$') {
|
|
ch=LexGetChar(l);
|
|
buf[i++]='$$';
|
|
if (ch!='$$')
|
|
l->flags|=LF_USE_LAST_I1;
|
|
} else
|
|
buf[i++]=ch;
|
|
}
|
|
*done=FALSE;
|
|
return i;
|
|
}
|
|
|
|
I8 Lex(LexStruct *l)
|
|
{
|
|
U8 ch;
|
|
I8 i,j,k;
|
|
double d;
|
|
SysHashEntry *temph,**temph1;
|
|
BoolU4 cont,str_done;
|
|
I1 *fbuf;
|
|
I1 *buf2,*buf3,buf[LEX_MAX_IDENT];
|
|
while (TRUE) {
|
|
lex_cont:
|
|
if (!(ch=LexGetChar(l)))
|
|
return l->token=TK_EOF;
|
|
if (Bt(alpha_bitmap,ch)) {
|
|
i=0;
|
|
buf[i++]=ch;
|
|
do {
|
|
if (i>=LEX_MAX_IDENT-1)
|
|
break;
|
|
else {
|
|
if (!(ch=LexGetChar(l)))
|
|
break;
|
|
else {
|
|
if (Bt(alpha_numeric_bitmap,ch))
|
|
buf[i++]=ch;
|
|
else {
|
|
l->flags|=LF_USE_LAST_I1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
} while (TRUE);
|
|
buf[i++]=0;
|
|
temph=NULL;
|
|
if (l->local_var_list) {
|
|
l->local_var_entry=FindMember(buf,
|
|
l->local_var_list);
|
|
} else
|
|
l->local_var_entry=NULL;
|
|
if (!l->local_var_entry && l->hash_table_list)
|
|
temph=FindHashEntry(buf,
|
|
l->hash_table_list,l->hash_mask);
|
|
if (temph && !(l->flags & LF_NO_DEFINES))
|
|
j=temph->type;
|
|
else
|
|
j=0;
|
|
if (j & HTT_STRING_CONSTANT)
|
|
LexIncludeString(l,
|
|
temph->string,NewString(temph><(StringConstantStruct *)->data),FALSE);
|
|
else {
|
|
l->hash_entry=temph;
|
|
Free(l->ident);
|
|
l->ident=NewString(buf);
|
|
l->ident_len=i;
|
|
l->token=TK_IDENT;
|
|
goto lex_end;
|
|
}
|
|
} else if (Bt(dec_numeric_bitmap,ch)) {
|
|
i=ch-'0';
|
|
ch=LexGetChar(l);
|
|
if (ch=='X' || ch=='x') {
|
|
while (TRUE) {
|
|
ch=ToUpper(LexGetChar(l));
|
|
if (Bt(hex_numeric_bitmap,ch)) {
|
|
if (ch<='9')
|
|
i=i<<4+ch-'0';
|
|
else
|
|
i=i<<4+ch-'A'+10;
|
|
} else {
|
|
l->cur_i=i;
|
|
l->flags|=LF_USE_LAST_I1;
|
|
l->token=TK_INTEGER;
|
|
goto lex_end;
|
|
}
|
|
}
|
|
}
|
|
while (TRUE) {
|
|
if (Bt(dec_numeric_bitmap,ch))
|
|
i=MulU8(i,10)+ch-'0';
|
|
else {
|
|
if (ch=='.' || ch=='e' || ch=='E') break;
|
|
l->cur_i=i;
|
|
l->flags|=LF_USE_LAST_I1;
|
|
l->token=TK_INTEGER;
|
|
goto lex_end;
|
|
}
|
|
ch=LexGetChar(l);
|
|
}
|
|
if (ch=='.')
|
|
ch=LexGetChar(l);
|
|
float_start:
|
|
//TODO:back-up for cases where i overflows
|
|
// (people should use 'e', so might not be worth it)
|
|
j=0;
|
|
k=0;
|
|
while (TRUE) {
|
|
//TODO: maybe replace with log2 and insert bit field
|
|
if (Bt(dec_numeric_bitmap,ch)) {
|
|
j=MulU8(j,10)+ch-'0';
|
|
k++;
|
|
} else {
|
|
d=i+j*Pow10(-k);
|
|
if (ch=='e' || ch=='E') break;
|
|
l->cur_d=d;
|
|
l->flags|=LF_USE_LAST_I1;
|
|
l->token=TK_DOUBLE;
|
|
goto lex_end;
|
|
}
|
|
ch=LexGetChar(l);
|
|
}
|
|
ch=LexGetChar(l);
|
|
k=1;
|
|
if (ch=='-') {
|
|
k=-1;
|
|
ch=LexGetChar(l);
|
|
}
|
|
j=0;
|
|
while (TRUE) {
|
|
//TODO: maybe replace with log2 and insert bit field
|
|
if (Bt(dec_numeric_bitmap,ch))
|
|
j=MulU8(j,10)+ch-'0';
|
|
else {
|
|
d*=Pow10(j*k);
|
|
l->cur_d=d;
|
|
l->flags|=LF_USE_LAST_I1;
|
|
l->token=TK_DOUBLE;
|
|
goto lex_end;
|
|
}
|
|
ch=LexGetChar(l);
|
|
}
|
|
} else if (ch=='"') {
|
|
l->flags|=LF_IN_QUOTES;
|
|
buf2=NULL;
|
|
i=0;
|
|
do {
|
|
j=LexInString(l,buf,LEX_MAX_IDENT,&str_done);
|
|
buf3=MAlloc(i+j);
|
|
if (buf2) {
|
|
MemCpy(buf3,buf2,i);
|
|
Free(buf2);
|
|
buf2=buf3;
|
|
MemCpy(buf2+i,buf,j);
|
|
} else {
|
|
buf2=buf3;
|
|
MemCpy(buf2,buf,j);
|
|
}
|
|
i+=j;
|
|
} while (!str_done);
|
|
Free(l->ident);
|
|
l->ident=MAlloc(i);
|
|
MemCpy(l->ident,buf2,i);
|
|
Free(buf2);
|
|
l->ident_len=i;
|
|
l->flags&=~LF_IN_QUOTES;
|
|
l->token=TK_STRING;
|
|
goto lex_end;
|
|
} else if (ch==0x27) { // "'"
|
|
ch=LexGetChar(l);
|
|
if (!ch || ch==0x27) i=0x27;
|
|
else if (ch=='\\') {
|
|
ch=LexGetChar(l);
|
|
if (ch=='n')
|
|
i=10;
|
|
else if (ch=='r')
|
|
i=13;
|
|
else if (ch=='"')
|
|
i='"';
|
|
else if (ch==0x27)
|
|
i=0x27;
|
|
else if (ch=='\`')
|
|
i='\`';
|
|
else if (ch=='\\')
|
|
i='\\';
|
|
else if (ch=='t')
|
|
i=9;
|
|
else if (ch=='x') {
|
|
i=0;
|
|
while (TRUE) {
|
|
ch=ToUpper(LexGetChar(l));
|
|
if (Bt(hex_numeric_bitmap,ch)) {
|
|
if (ch<='9')
|
|
i=i<<4+ch-'0';
|
|
else
|
|
i=i<<4+ch-'A'+10;
|
|
} else
|
|
break;
|
|
}
|
|
l->flags|=LF_USE_LAST_I1;
|
|
} else if (ch>='0' && ch<='7') {
|
|
i=ch-'0';
|
|
do {
|
|
ch=LexGetChar(l);
|
|
if (ch>='0' && ch<='7')
|
|
i=i<<3+ch-'0';
|
|
} while (ch>='0' && ch<='7');
|
|
l->flags|=LF_USE_LAST_I1;
|
|
} else {
|
|
l->flags|=LF_USE_LAST_I1;
|
|
i='\\';
|
|
}
|
|
} else if (ch=='$$') {
|
|
ch=LexGetChar(l);
|
|
i='$$';
|
|
if (ch!='$$')
|
|
l->flags|=LF_USE_LAST_I1;
|
|
} else
|
|
i=ch;
|
|
ch=LexGetChar(l);
|
|
if (ch!=0x27)
|
|
l->flags|=LF_USE_LAST_I1;
|
|
l->cur_i=i;
|
|
l->token=TK_INTEGER;
|
|
goto lex_end;
|
|
} else if (ch=='#') {
|
|
if (Lex(l)!=TK_IDENT) //skip '#'
|
|
goto lex_end;
|
|
if (!(temph=l->hash_entry))
|
|
goto lex_end;
|
|
if (!(temph->type & HTT_KEYWORD))
|
|
goto lex_end;
|
|
i=temph->user0;
|
|
if (i==KW_INCLUDE) {
|
|
if (Lex(l)!=TK_STRING)
|
|
goto lex_end;
|
|
if (l->flags & LF_ASM_EXPRESSIONS)
|
|
fbuf=DefaultExtension(l->ident,"ASZ");
|
|
else
|
|
fbuf=DefaultExtension(l->ident,"CPZ");
|
|
if (ext[EXT_LTF_READ])
|
|
LexIncludeLtf(l,fbuf);
|
|
else
|
|
LexIncludeString(l,fbuf,ReadTextFile(fbuf),TRUE);
|
|
Free(fbuf);
|
|
} else if (i==KW_DEFINE) {
|
|
l->flags|=LF_NO_DEFINES;
|
|
if (Lex(l)==TK_IDENT) {
|
|
temph=MAllocZ(sizeof(StringConstantStruct));
|
|
temph->string=l->ident;
|
|
l->ident=0;
|
|
temph->use_cnt=0;
|
|
temph->type=HTT_STRING_CONSTANT;
|
|
SetSourceFileInfo(l,temph);
|
|
i=0;
|
|
do ch=LexGetChar(l);
|
|
while (ch && (ch<=CH_SPACE || ch>0x7E));
|
|
if (ch>CH_SPACE && ch<=0x7E) {
|
|
buf[i++]=ch;
|
|
while (i<LEX_MAX_IDENT-1) {
|
|
ch=LexGetChar(l);
|
|
if (ch=='/') {
|
|
ch=LexGetChar(l);
|
|
if (ch=='/') {
|
|
do ch=LexGetChar(l);
|
|
while (ch>=CH_SHIFT_SPACE && ch<=0x7E || ch==CH_TAB);
|
|
break;
|
|
} else {
|
|
buf[i++]='/';
|
|
l->flags|=LF_USE_LAST_I1;
|
|
}
|
|
} else if (ch>=CH_SHIFT_SPACE && ch<=0x7E || ch==CH_TAB)
|
|
buf[i++]=ch;
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
buf[i++]=0;
|
|
temph><(StringConstantStruct *)->data=NewString(buf);
|
|
temph1=FindHashBucket(temph->string,l->define_hash_table);
|
|
temph->next=*temph1;
|
|
*temph1=temph;
|
|
}
|
|
l->flags&=~LF_NO_DEFINES;
|
|
}
|
|
} else if (ch==TK_INSERT_BINARY ||
|
|
ch==TK_INSERT_BINARY_TYPE ||
|
|
ch==TK_INSERT_BINARY_SIZE) {
|
|
l->token=ch;
|
|
goto lex_end;
|
|
} else if (ch=='.') {
|
|
ch=LexGetChar(l);
|
|
if (ch>='0' && ch<='9') {
|
|
i=0;
|
|
goto float_start;
|
|
}
|
|
l->flags|=LF_USE_LAST_I1;
|
|
l->token='.';
|
|
goto lex_end;
|
|
} else if (ch>=0x21 && ch<=0x7E) {
|
|
i=duel_I1_tokens1[ch];
|
|
if (!i) {
|
|
if (ch=='$$') {
|
|
do ch=LexGetChar(l);
|
|
while (ch && ch!='$$');
|
|
goto lex_cont;
|
|
} else {
|
|
l->token=ch;
|
|
goto lex_end;
|
|
}
|
|
} else {
|
|
j=LexGetChar(l);
|
|
if (i.u1[0]==j) {
|
|
i>>=8;
|
|
if (!i) { // "/*"
|
|
cont=TRUE;
|
|
while (cont) {
|
|
do ch=LexGetChar(l);
|
|
while (ch && ch!='*');
|
|
while (cont && ch=='*') {
|
|
ch=LexGetChar(l);
|
|
if (ch=='/')
|
|
cont=FALSE;
|
|
}
|
|
}
|
|
goto lex_cont;
|
|
} else {
|
|
l->token=i;
|
|
goto lex_end;
|
|
}
|
|
}
|
|
if (i=duel_I1_tokens2[ch]) {
|
|
if (i.u1[0]==j) {
|
|
i>>=8;
|
|
if (!i) { // "//"
|
|
LexSkipEol(l);
|
|
goto lex_cont;
|
|
} else {
|
|
if (i==TK_SHL || i==TK_SHR) {
|
|
j=LexGetChar(l);
|
|
if (j=='=') {
|
|
if (i==TK_SHL)
|
|
i=TK_SHL_EQUAL;
|
|
else
|
|
i=TK_SHR_EQUAL;
|
|
} else
|
|
l->flags|=LF_USE_LAST_I1;
|
|
}
|
|
l->token=i;
|
|
goto lex_end;
|
|
}
|
|
}
|
|
if (i=duel_I1_tokens3[ch]) {
|
|
if (i.u1[0]==j) {
|
|
l->token=i.u1[1];
|
|
goto lex_end;
|
|
}
|
|
}
|
|
}
|
|
l->flags|=LF_USE_LAST_I1;
|
|
l->token=ch;
|
|
goto lex_end;
|
|
}
|
|
}
|
|
}
|
|
lex_end:
|
|
if (Bt(&l->flags,LFf_LEX_TRACE))
|
|
LexPutToken(l);
|
|
return l->token;
|
|
}
|
|
|
|
I1 *LexExtendString(LexStruct *l,U8 *size)
|
|
{
|
|
U8 len=l->ident_len,len1,len2;
|
|
I1 *st=l->ident,*st1,*st2;
|
|
l->ident=NULL;
|
|
while (l->token==TK_STRING) {
|
|
st1=st;
|
|
len1=len;
|
|
if (Lex(l)==TK_STRING) {
|
|
len2=l->ident_len;
|
|
st2=l->ident;
|
|
l->ident=NULL;
|
|
len=len1+len2-1;
|
|
st=MAlloc(len);
|
|
if (len1>1)
|
|
MemCpy(st,st1,len1-1);
|
|
MemCpy(st+len1-1,st2,len2);
|
|
Free(st1);
|
|
Free(st2);
|
|
}
|
|
}
|
|
*size=len;
|
|
return st;
|
|
}
|
|
|
|
I1 *LexPutLine(LexStruct *l,I1 *start)
|
|
{
|
|
LtfEntry *my_LtfPutLine(LtfEntry *cl);
|
|
I1 *ptr;
|
|
if (!start) return;
|
|
if (l->cur_lfn->flags&LFSF_IS_LTF) {
|
|
if (my_LtfPutLine=FindExtern("LtfPutLine"))
|
|
return my_LtfPutLine(start);
|
|
} else {
|
|
ptr=start;
|
|
while (*ptr && *ptr!=CH_LINE_FEED && *ptr!=CH_CR)
|
|
PutChar(*ptr++);
|
|
CrLf;
|
|
return (*ptr) ? ptr+1:ptr;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
I8 LexLineNum(LexStruct *l)
|
|
{
|
|
return l->cur_lfn->line_num;
|
|
}
|
|
|
|
void LexPutLink(LexStruct *l)
|
|
{
|
|
PutFileLink(l->cur_lfn->name,l->cur_lfn->line_num);
|
|
AdamErr("%s,%d\r",l->cur_lfn->name,l->cur_lfn->line_num);
|
|
PutS(" ");
|
|
}
|
|
|
|
void PutLexError(LexStruct *l,I1 *name=NULL,I1 *msg=NULL)
|
|
{
|
|
PutSysText("ST_ERROR");
|
|
l->error_cnt++;
|
|
AdamErr("Tsk:%08X ",Fs);
|
|
if (name) {
|
|
PutSysText(name);
|
|
AdamErr("%S",name);
|
|
}
|
|
if (msg) {
|
|
PutS(msg);
|
|
AdamErr("%s\r\n",msg);
|
|
}
|
|
LexPutToken(l);
|
|
LexPutLink(l);
|
|
LexPutLine(l,l->cur_lfn->line_start);
|
|
}
|
|
|
|
void PutLexWarning(LexStruct *l,I1 *name=NULL,I1 *msg=NULL)
|
|
{
|
|
PutSysText("ST_WARNING");
|
|
l->warning_cnt++;
|
|
if (name)
|
|
PutSysText(name);
|
|
if (msg)
|
|
PutS(msg);
|
|
LexPutToken(l);
|
|
LexPutLink(l);
|
|
LexPutLine(l,l->cur_lfn->line_start);
|
|
}
|
|
|
|
void PutAsmError(LexStruct *l,I1 *name)
|
|
{
|
|
PutLexError(l,name);
|
|
LexSkipEol(l);
|
|
Lex(l);
|
|
}
|
|
|
|
void PutAsmWarning(LexStruct *l,I1 *name)
|
|
{
|
|
PutLexWarning(l,name);
|
|
LexSkipEol(l);
|
|
Lex(l);
|
|
}
|
|
|
|
void PrsExcept(LexStruct *l,I1 *name=NULL,I1 *msg=NULL)
|
|
{
|
|
PutLexError(l,name,msg);
|
|
IntFlushMsgs;
|
|
throw(EXCEPT_COMPILER,0);
|
|
}
|
|
|
|
void CbPutClass(ClassStruct *c)
|
|
{
|
|
I8 i;
|
|
if (!c) return;
|
|
if (c->pointer_cnt>4) {
|
|
coutln "ERROR:put_class ptrcnt=",c->pointer_cnt;
|
|
while (TRUE)
|
|
//TODO:
|
|
SwapInNext;
|
|
}
|
|
for (i=0;i<c->pointer_cnt;i++)
|
|
PutChar('*');
|
|
c-=sizeof(ClassStruct)*c->pointer_cnt;
|
|
if (c->string)
|
|
PutS(c->string);
|
|
else {
|
|
coutln "ERROR:put_class string=NULL";
|
|
while (TRUE)
|
|
//TODO:
|
|
SwapInNext;
|
|
}
|
|
PutChar(CH_SPACE);
|
|
}
|
|
|
|
|
|
void CbPutIc(IntermediateCode *tempi)
|
|
{
|
|
I1 *st;
|
|
U8 opcode=tempi->ic_code.u2[0];
|
|
if (opcode>EC_NOP) {
|
|
st=PointAtListEntry(opcode,SysText("ST_INTERMEDIATE_CODE"));
|
|
PrintF("%20ts %016X ",
|
|
st+1,tempi->ic_data);
|
|
if (tempi->ic_flags & ICF_NO_PUSHES)
|
|
PutS("!PUSH ");
|
|
CbPutClass(tempi->ic_class);
|
|
if (tempi->ic_flags & ICF_TO_DOUBLE)
|
|
PutS("->double ");
|
|
if (tempi->ic_flags & ICF_TO_INT)
|
|
PutS("->int ");
|
|
if (tempi->ic_flags & ICF_NO_PUSHES_TO_DOUBLE_OR_INT)
|
|
PutS("!PUSH2 ");
|
|
if (tempi->ic_flags & ICF_USE_DOUBLE_TEMPLATE)
|
|
PutS("[double] ");
|
|
if (tempi->ic_flags & ICF_USE_UNSIGNED_TEMPLATE)
|
|
PutS("[unsigned] ");
|
|
CrLf;
|
|
}
|
|
}
|
|
|
|
|
|
void CbInitOutPtrs(LexCbStack *ll)
|
|
{
|
|
CodeBlk *cb=MAlloc(sizeof(CodeBlk));
|
|
cb->next=NULL;
|
|
ll->cb_out_first=cb;
|
|
ll->cb_out_last=cb;
|
|
ll->cb_misc_list=NULL;
|
|
ll->cb_misc_list_end=&ll->cb_misc_list;
|
|
ll->cb_out_end=cb+sizeof(CodeBlk);
|
|
ll->cb_out_ptr=&cb->data;
|
|
ll->cb_last_out_ptr=&cb->data;
|
|
}
|
|
|
|
void CbInitInPtrs(LexCbStack *ll)
|
|
{
|
|
CodeBlk *cb=ll->cb_out_first;
|
|
ll->cb_in_first=cb;
|
|
ll->cb_in_end=cb+sizeof(CodeBlk);
|
|
ll->cb_in_ptr=&cb->data;
|
|
}
|
|
|
|
void CbPutAllIc(LexStruct *l)
|
|
{
|
|
IntermediateCode *tempi;
|
|
CbInitInPtrs(&l->cb);
|
|
tempi=l->cb.cb_in_ptr;
|
|
while (tempi->ic_code) {
|
|
CbPutIc(tempi);
|
|
tempi+=sizeof(IntermediateCode);
|
|
}
|
|
}
|
|
|
|
void CbAddIc(LexStruct *l,
|
|
U8 opcode,U8 arg, ClassStruct *c,U8 flags=0)
|
|
{
|
|
IntermediateCode *tempi=l->cb.cb_out_ptr;
|
|
CodeBlk *cb,*cb1;
|
|
l->cb.cb_last_out_ptr=tempi;
|
|
tempi->ic_code=opcode;
|
|
tempi->ic_data=arg;
|
|
tempi->ic_class=c;
|
|
tempi->ic_flags=flags;
|
|
tempi->ic_line=l->cur_lfn->line_num;
|
|
if (l->flags & LF_PARSE_TRACE)
|
|
CbPutIc(tempi);
|
|
|
|
tempi+=sizeof(IntermediateCode);
|
|
if (tempi==l->cb.cb_out_end) {
|
|
cb=MAlloc(sizeof(CodeBlk));
|
|
cb->next=NULL;
|
|
cb1=l->cb.cb_out_last;
|
|
cb1->next=cb;
|
|
l->cb.cb_out_last=cb;
|
|
tempi=&cb->data;
|
|
l->cb.cb_out_end=cb+sizeof(CodeBlk);
|
|
}
|
|
l->cb.cb_out_ptr=tempi;
|
|
}
|
|
|
|
IntermediateCode *CbGetIc1(LexCbStack *l)
|
|
{
|
|
IntermediateCode *tempi=l->cb_in_ptr,
|
|
*tempi1=tempi+sizeof(IntermediateCode);
|
|
CodeBlk *cb;
|
|
if (tempi1==l->cb_in_end) {
|
|
cb=tempi1-sizeof(CodeBlk);
|
|
cb=cb->next;
|
|
l->cb_in_end=cb+sizeof(CodeBlk);
|
|
tempi1=&cb->data;
|
|
}
|
|
l->cb_in_ptr=tempi1;
|
|
return tempi;
|
|
}
|
|
|
|
void CbPush(LexStruct *l)
|
|
{
|
|
LexCbStack *templ=MAlloc(sizeof(LexCbStack));
|
|
MemCpy(templ,&l->cb,sizeof(LexCbStack));
|
|
if (l->cb.cb_misc_list_end==&l->cb.cb_misc_list)
|
|
templ->cb_misc_list_end=&templ->cb_misc_list;
|
|
l->cb.cb_next=templ;
|
|
}
|
|
|
|
void CbPop(LexStruct *l)
|
|
{
|
|
LexCbStack *templ=l->cb.cb_next;
|
|
MemCpy(&l->cb,templ,sizeof(LexCbStack));
|
|
if (templ->cb_misc_list_end==&templ->cb_misc_list)
|
|
l->cb.cb_misc_list_end=&l->cb.cb_misc_list;
|
|
Free(templ);
|
|
}
|
|
|
|
CbMiscStruct *CbFindGotoLabel(LexStruct *l,I1 *name)
|
|
{
|
|
CbMiscStruct *templ=l->cb.cb_misc_list;
|
|
while (templ) {
|
|
if (templ->type==CBMT_GOTO_LABEL) {
|
|
if (!StrCmp(templ->string,name))
|
|
return templ;
|
|
}
|
|
templ=templ->next;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
CbMiscStruct *CbMiscNew(LexStruct *l,U8 t)
|
|
{
|
|
CbMiscStruct *result=MAllocZ(sizeof(CbMiscStruct));
|
|
l->cb.cb_misc_list_end->next=result;
|
|
l->cb.cb_misc_list_end=result;
|
|
result->address=INVALID_PTR;
|
|
result->type=t;
|
|
return result;
|
|
}
|
|
|
|
|
|
void DelCbMiscList(LexStruct *l)
|
|
{
|
|
CbMiscStruct *mc=l->cb.cb_misc_list,*mc1;
|
|
while (mc) {
|
|
mc1=mc->next;
|
|
if (mc->type==CBMT_GOTO_LABEL &&
|
|
!mc->address) {
|
|
l->cb.cb_misc_list=NULL; //prevent recursion
|
|
cout SysText("ST_ERROR"),SysText("ST_UNDEFINED_GOTO_LABEL");
|
|
coutln mc->string;
|
|
throw(EXCEPT_COMPILER,1);
|
|
}
|
|
Free(mc->string);
|
|
Free(mc->jmp_table);
|
|
Free(mc);
|
|
mc=mc1;
|
|
}
|
|
}
|
|
|
|
LexStruct *CbPopNoFree(LexStruct *l)
|
|
{
|
|
LexCbStack *templ=l->cb.cb_next;
|
|
MemCpy(&l->cb,templ,sizeof(LexCbStack));
|
|
if (templ->cb_misc_list_end==&templ->cb_misc_list)
|
|
l->cb.cb_misc_list_end=&l->cb.cb_misc_list;
|
|
return templ;
|
|
}
|
|
|
|
void CbAppend(LexStruct *l, LexCbStack *ll)
|
|
{
|
|
IntermediateCode *tempi;
|
|
CbInitInPtrs(ll);
|
|
do {
|
|
tempi=CbGetIc1(ll);
|
|
if (tempi->ic_code) {
|
|
CbAddIc(l,tempi->ic_code,tempi->ic_data,
|
|
tempi->ic_class,tempi->ic_flags);
|
|
}
|
|
} while (tempi->ic_code);
|
|
DelLinkedList(ll->cb_out_first);
|
|
|
|
if (ll->cb_misc_list_end!=&ll->cb_misc_list) {
|
|
l->cb.cb_misc_list_end->next=ll->cb_misc_list;
|
|
l->cb.cb_misc_list_end=ll->cb_misc_list_end;
|
|
}
|
|
Free(ll);
|
|
}
|
|
|
|
void CbCombine(LexStruct *l)
|
|
{
|
|
CodeBlk *cb=l->cb.cb_out_first,*cb1,*cb2;
|
|
I8 i=0,j=sizeof(CodeBlk)-4;
|
|
U4 *ptr;
|
|
while (cb) {
|
|
i++;
|
|
cb=cb->next;
|
|
}
|
|
if (i>1) {
|
|
cb1=MAlloc(i*j+4);
|
|
cb1->next=NULL;
|
|
cb=l->cb.cb_out_first;
|
|
ptr=&cb1->data;
|
|
while (cb) {
|
|
cb2=cb->next;
|
|
MemCpy(ptr,&cb->data,j);
|
|
ptr+=j;
|
|
Free(cb);
|
|
cb=cb2;
|
|
}
|
|
l->cb.cb_out_first=cb1;
|
|
}
|
|
}
|
|
|
|
U8 CbCountCode(LexStruct *l,I8 pass,I8 *min_line,I8 *max_line)
|
|
{
|
|
U8 result=0,code;
|
|
I8 i,min_line2=-1,last_line=0;
|
|
ClassStruct *tempc;
|
|
IntermediateCode *tempi;
|
|
CbMiscStruct *lb;
|
|
CbInitInPtrs(&l->cb);
|
|
tempi=l->cb.cb_in_ptr;
|
|
while (code=tempi->ic_code.u2[0]) {
|
|
if (code>EC_END_EXP) {
|
|
if (code==EC_LABEL) {
|
|
lb=tempi->ic_data;
|
|
lb->address=result;
|
|
} else if (code>=EC_SKIPZ && code<=EC_OR_OR_SKIPNZ2) {
|
|
if (pass==2) {
|
|
lb=tempi->ic_data;
|
|
if (lb->address!=INVALID_PTR) {
|
|
i=lb->address-result;
|
|
if (i<116 && i>-116) //U1 disp
|
|
tempi->ic_code= --code;
|
|
}
|
|
}
|
|
}
|
|
i=unsigned_code_table[code+1]-unsigned_code_table[code];
|
|
tempc=tempi->ic_class;
|
|
if (!(tempi->ic_flags & ICF_USE_UNSIGNED_TEMPLATE)) {
|
|
if (tempc->sub_type==IT_DOUBLE ||
|
|
tempi->ic_flags & ICF_USE_DOUBLE_TEMPLATE) {
|
|
if (double_code_table[code+1]-double_code_table[code])
|
|
i=double_code_table[code+1]-double_code_table[code];
|
|
} else if (!(tempc->sub_type & 1) && code_table[code+1]-code_table[code])
|
|
i=code_table[code+1]-code_table[code];
|
|
}
|
|
result+=i;
|
|
if (tempi->ic_flags & ICF_NO_PUSHES)
|
|
result-=2;
|
|
if (tempi->ic_flags & ICF_TO_DOUBLE) {
|
|
result+=unsigned_code_table[EC_TO_DOUBLE+1]-
|
|
unsigned_code_table[EC_TO_DOUBLE];
|
|
if (tempi->ic_flags & ICF_NO_PUSHES_TO_DOUBLE_OR_INT)
|
|
result-=2;
|
|
}
|
|
if (tempi->ic_flags & ICF_TO_INT) {
|
|
result+=unsigned_code_table[EC_TO_INT+1]-
|
|
unsigned_code_table[EC_TO_INT];
|
|
if (tempi->ic_flags & ICF_NO_PUSHES_TO_DOUBLE_OR_INT)
|
|
result-=2;
|
|
}
|
|
if (pass==2 && i) {
|
|
i=tempi->ic_line;
|
|
if (i>=last_line) {
|
|
last_line=i;
|
|
if (i<*min_line)
|
|
*min_line=i;
|
|
if (i>*min_line && i<min_line2)
|
|
min_line2=i;
|
|
if (i>*max_line)
|
|
*max_line=i;
|
|
}
|
|
}
|
|
}
|
|
tempi+=sizeof(IntermediateCode);
|
|
}
|
|
lb=l->cb.cb_misc_list;
|
|
while (lb) {
|
|
if (lb->type==CBMT_STRING_CONSTANT) {
|
|
// lb->address=result+sizeof(U4);
|
|
// result+=sizeof(U4)+lb->st_len;
|
|
lb->address=result;
|
|
result+=lb->st_len;
|
|
} else if (lb->type==CBMT_JMP_TABLE) {
|
|
lb->address=result;
|
|
result+=lb->st_len<<2;
|
|
}
|
|
lb=lb->next;
|
|
}
|
|
if (pass==2) {
|
|
if (min_line2!=-1 &&
|
|
(min_line2-*min_line)>10) //Defines screw things up
|
|
*min_line=min_line2;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
U1 *CbCompile(LexStruct *l,ClassStruct *fun_class,
|
|
U8 *code_size,DbgInfo **dbg_info,U8 *type=NULL)
|
|
{
|
|
U1 *result,*dst,*bb;
|
|
I8 min_line=MAX_I8,max_line=0;
|
|
U8 i,code,p1,p2,size,fix_up_type;
|
|
U4 *dd;
|
|
ClassStruct *tempc;
|
|
IntermediateCode *tempi;
|
|
CbMiscStruct *lb,*lb1;
|
|
DbgInfo *my_dbg=NULL;
|
|
ExeAbsoluteAddressStruct *tempa;
|
|
AsmCtrlStruct *a=l->a;
|
|
U8 Dasm2(U1 *ip,I8 cnt,BoolU4 use16);
|
|
|
|
CbCombine(l);
|
|
if (Bt(&l->flags,LFf_OPT_TRACE)) {
|
|
coutln "$$IV 1$$Before Pass 1:$$IV 0$$";
|
|
CbPutAllIc(l);
|
|
}
|
|
CmpOptPass1(l,fun_class,TRUE);
|
|
if (Bt(&l->flags,LFf_OPT_TRACE)) {
|
|
coutln "$$IV 1$$After Pass 1:$$IV 0$$";
|
|
CbPutAllIc(l);
|
|
}
|
|
CmpOptPass2(l,fun_class);
|
|
if (Bt(&l->flags,LFf_OPT_TRACE)) {
|
|
coutln "$$IV 1$$After Pass 2:$$IV 0$$";
|
|
CbPutAllIc(l);
|
|
}
|
|
CmpOptPass3(l,fun_class);
|
|
if (Bt(&l->flags,LFf_OPT_TRACE)) {
|
|
coutln "$$IV 1$$After Pass 3:$$IV 0$$";
|
|
CbPutAllIc(l);
|
|
}
|
|
CmpOptPass4(l,fun_class);
|
|
if (Bt(&l->flags,LFf_OPT_TRACE)) {
|
|
coutln "$$IV 1$$After Pass 4:$$IV 0$$";
|
|
CbPutAllIc(l);
|
|
}
|
|
|
|
CbCountCode(l,1,NULL,NULL);
|
|
*code_size=CbCountCode(l,2,&min_line,&max_line);
|
|
result=MAlloc(*code_size);
|
|
if (max_line>=min_line && max_line-min_line<10000) {
|
|
my_dbg=MAllocZ(offset(DbgInfo.body)+sizeof(U4)*(max_line-min_line+1));
|
|
my_dbg->min_line=min_line;
|
|
my_dbg->max_line=max_line;
|
|
}
|
|
if (dbg_info)
|
|
*dbg_info=my_dbg;
|
|
|
|
dst=result;
|
|
CbInitInPtrs(&l->cb);
|
|
tempi=l->cb.cb_in_ptr;
|
|
while (code=tempi->ic_code.u2[0]) {
|
|
if (code>EC_END_EXP) {
|
|
if (type) {
|
|
if (tempc=tempi->ic_class) {
|
|
if (tempi->ic_flags & ICF_TO_DOUBLE)
|
|
*type=IT_DOUBLE;
|
|
else if (tempi->ic_flags & ICF_TO_INT)
|
|
*type=IT_I8;
|
|
else
|
|
*type=tempc->sub_type;
|
|
}
|
|
}
|
|
p1=unsigned_code_table[code];
|
|
p2=unsigned_code_table[code+1];
|
|
size=p2-p1;
|
|
fix_up_type=unsigned_fix_up_table[code];
|
|
tempc=tempi->ic_class;
|
|
if (!(tempi->ic_flags & ICF_USE_UNSIGNED_TEMPLATE)) {
|
|
if (tempc->sub_type==IT_DOUBLE ||
|
|
tempi->ic_flags & ICF_USE_DOUBLE_TEMPLATE) {
|
|
if (double_code_table[code+1]-double_code_table[code]) {
|
|
p1=double_code_table[code];
|
|
p2=double_code_table[code+1];
|
|
size=p2-p1;
|
|
fix_up_type=double_fix_up_table[code];
|
|
}
|
|
} else if (!(tempc->sub_type & 1) && code_table[code+1]-code_table[code]) {
|
|
p1=code_table[code];
|
|
p2=code_table[code+1];
|
|
size=p2-p1;
|
|
fix_up_type=signed_fix_up_table[code];
|
|
}
|
|
}
|
|
if (tempi->ic_flags & ICF_NO_PUSHES) {
|
|
p1+=2;
|
|
size-=2;
|
|
}
|
|
if (size) {
|
|
MemCpy(dst,p1,size);
|
|
if (my_dbg) {
|
|
if (tempi->ic_line>=min_line && tempi->ic_line<=max_line) {
|
|
i=tempi->ic_line-min_line;
|
|
if (!my_dbg->body[i]) {
|
|
if (a)
|
|
my_dbg->body[i]=a->ip+dst-result;
|
|
else
|
|
my_dbg->body[i]=dst;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
dst+=size;
|
|
switch (fix_up_type) {
|
|
case FUT_8_1:
|
|
bb=dst-1;
|
|
*bb=tempi->ic_data;
|
|
break;
|
|
case FUT_8_2:
|
|
bb=dst-2;
|
|
*bb=tempi->ic_data;
|
|
break;
|
|
case FUT_8_4:
|
|
bb=dst-4;
|
|
*bb=tempi->ic_data;
|
|
break;
|
|
case FUT_8_5:
|
|
bb=dst-5;
|
|
*bb=tempi->ic_data;
|
|
break;
|
|
case FUT_8_6:
|
|
bb=dst-6;
|
|
*bb=tempi->ic_data;
|
|
break;
|
|
case FUT_8_10:
|
|
bb=dst-10;
|
|
*bb=tempi->ic_data;
|
|
break;
|
|
case FUT_8_JMP_1:
|
|
lb=tempi->ic_data;
|
|
if (a)
|
|
i=lb->address-(dst-result);
|
|
else
|
|
i=(result+lb->address)-dst;
|
|
bb=dst-1;
|
|
*bb=i;
|
|
break;
|
|
case FUT_32_4:
|
|
dd=dst-4;
|
|
*dd=tempi->ic_data;
|
|
break;
|
|
case FUT_32_4_CALL:
|
|
if (a)
|
|
i=tempi->ic_data-(a->ip+dst-result);
|
|
else
|
|
i=tempi->ic_data-dst;
|
|
dd=dst-4;
|
|
*dd=i;
|
|
break;
|
|
case FUT_32_4_ABS:
|
|
dd=dst-4;
|
|
*dd=tempi->ic_data;
|
|
if (a && !(l->flags & LF_ASM_EXPRESSIONS)) {
|
|
tempa=MAllocZ(sizeof(ExeAbsoluteAddressStruct));
|
|
tempa->next=a->absolutes;
|
|
a->absolutes=tempa;
|
|
tempa->ip=a->ip+dd-result;
|
|
}
|
|
break;
|
|
case FUT_32_4_ABS2:
|
|
lb=tempi->ic_data;
|
|
if (a)
|
|
i=lb->address+a->ip;
|
|
else
|
|
i=lb->address+result;
|
|
dd=dst-4;
|
|
*dd=i;
|
|
if (a && !(l->flags & LF_ASM_EXPRESSIONS)) {
|
|
tempa=MAllocZ(sizeof(ExeAbsoluteAddressStruct));
|
|
tempa->next=a->absolutes;
|
|
a->absolutes=tempa;
|
|
tempa->ip=a->ip+dd-result;
|
|
}
|
|
break;
|
|
case FUT_32_5:
|
|
dd=dst-5;
|
|
*dd=tempi->ic_data;
|
|
break;
|
|
case FUT_32_6:
|
|
dd=dst-6;
|
|
*dd=tempi->ic_data;
|
|
break;
|
|
case FUT_32_7:
|
|
dd=dst-7;
|
|
*dd=tempi->ic_data;
|
|
break;
|
|
case FUT_32_9:
|
|
dd=dst-9;
|
|
*dd=tempi->ic_data;
|
|
break;
|
|
case FUT_32_4P10_4:
|
|
dd=dst-4;
|
|
*dd=tempi->ic_data;
|
|
dd=dst-10;
|
|
*dd=tempi->ic_data+4;
|
|
break;
|
|
case FUT_32_4P11_4:
|
|
dd=dst-4;
|
|
*dd=tempi->ic_data;
|
|
dd=dst-11;
|
|
*dd=tempi->ic_data+4;
|
|
break;
|
|
case FUT_32_JMP_4:
|
|
lb=tempi->ic_data;
|
|
if (a)
|
|
i=lb->address-(dst-result);
|
|
else
|
|
i=(result+lb->address)-dst;
|
|
dd=dst-4;
|
|
*dd=i;
|
|
break;
|
|
case FUT_64_H9_L4:
|
|
dd=dst-4;
|
|
*dd=tempi->ic_data.u4[0];
|
|
dd=dst-9;
|
|
*dd=tempi->ic_data.u4[1];
|
|
break;
|
|
case FUT_ENTER1:
|
|
dd=dst-11;
|
|
*dd=tempi->ic_data;
|
|
dd=dst-4;
|
|
*dd=l->ESI_offset;
|
|
break;
|
|
case FUT_ENTER2:
|
|
dd=dst-18;
|
|
*dd=tempi->ic_data;
|
|
dd=dst-10;
|
|
*dd=l->ESI_offset;
|
|
dd=dst-4;
|
|
*dd=l->EDI_offset;
|
|
break;
|
|
}
|
|
if (tempi->ic_flags & ICF_TO_DOUBLE) {
|
|
p1=unsigned_code_table[EC_TO_DOUBLE];
|
|
p2=unsigned_code_table[EC_TO_DOUBLE+1];
|
|
size=p2-p1;
|
|
if (tempi->ic_flags & ICF_NO_PUSHES_TO_DOUBLE_OR_INT) {
|
|
p1+=2;
|
|
size-=2;
|
|
}
|
|
MemCpy(dst,p1,size);
|
|
dst+=size;
|
|
}
|
|
if (tempi->ic_flags & ICF_TO_INT) {
|
|
p1=unsigned_code_table[EC_TO_INT];
|
|
p2=unsigned_code_table[EC_TO_INT+1];
|
|
size=p2-p1;
|
|
if (tempi->ic_flags & ICF_NO_PUSHES_TO_DOUBLE_OR_INT) {
|
|
p1+=2;
|
|
size-=2;
|
|
}
|
|
MemCpy(dst,p1,size);
|
|
dst+=size;
|
|
}
|
|
}
|
|
tempi+=sizeof(IntermediateCode);
|
|
}
|
|
lb=l->cb.cb_misc_list;
|
|
while (lb) {
|
|
if (lb->type==CBMT_STRING_CONSTANT) {
|
|
/*
|
|
i=(lb->st_len+7) & -4;
|
|
MemCpy(result+lb->address-sizeof(U4),&i,sizeof(U4));
|
|
*/
|
|
MemCpy(result+lb->address,lb->string,lb->st_len);
|
|
} else if (lb->type==CBMT_JMP_TABLE) {
|
|
for (i=0;i<lb->st_len;i++) {
|
|
lb1=lb->jmp_table[i];
|
|
dd=result+lb->address+i<<2;
|
|
if (a) {
|
|
tempa=MAllocZ(sizeof(ExeAbsoluteAddressStruct));
|
|
tempa->next=a->absolutes;
|
|
a->absolutes=tempa;
|
|
tempa->ip=a->ip+dd-result;
|
|
*dd=lb1->address+a->ip;
|
|
} else
|
|
*dd=lb1->address+result;
|
|
}
|
|
}
|
|
lb=lb->next;
|
|
}
|
|
Free(l->cb.cb_out_first);
|
|
DelCbMiscList(l);
|
|
if (Bt(&l->flags,LFf_COMPILE_TRACE)) {
|
|
if (Dasm2=FindExtern("Dasm2"))
|
|
Dasm2(result,*code_size,FALSE);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void DelHashTable(SysHashTable *tempht)
|
|
{
|
|
I8 i;
|
|
SysHashEntry *temph,*temph1;
|
|
ClassStruct *tempc;
|
|
GlblVarStruct *tempg;
|
|
if (!tempht) return;
|
|
for (i=0;i<=tempht->mask;i++) {
|
|
temph=tempht->body[i];
|
|
while (temph) {
|
|
temph1=temph->next;
|
|
Free(temph->string);
|
|
if (temph->type & (HTT_FUNCTION | HTT_CLASS |
|
|
HTT_STRING_CONSTANT | HTT_GLBL_VAR |
|
|
HTT_SYS_SYMBOL)) {
|
|
Free(temph->source_link);
|
|
if (temph->type & (HTT_FUNCTION | HTT_CLASS)) {
|
|
tempc=temph;
|
|
Free(tempc->debug);
|
|
Free(tempc->import_name);
|
|
DelMemberList(tempc);
|
|
//assumes code not on heap
|
|
} else if (temph->type&HTT_STRING_CONSTANT)
|
|
Free(temph><(StringConstantStruct *)->data);
|
|
else if (temph->type&HTT_GLBL_VAR) {
|
|
tempg=temph;
|
|
Free(tempg->import_name);
|
|
}
|
|
}
|
|
Free(temph);
|
|
temph=temph1;
|
|
}
|
|
}
|
|
Free(tempht);
|
|
}
|
|
|
|
|