Files
TempleOS-Rijn/LT/COMPILE/LEX.CPZ
T
2018-09-08 21:45:17 +02:00

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);
}