Files
TempleOS-Rijn/LT/Compiler/Lex.CPZ
T
2018-09-08 21:45:20 +02:00

1222 lines
27 KiB
Plaintext

I1 *CmpPmt(BoolU4 double_semicolon=FALSE)
{
I8 i;
I1 *s,*result;
for (i=Fs->answers_displayed-1;i>=0;i--) {
if (Fs->answers_types[i]==IT_DOUBLE)
PrintF("ansd%d=%15.7g=%15e\r\n",i,
Fs->double_answers[i],Fs->double_answers[i]);
else
PrintF("ans%d=0x%016X=%d\r\n",i,
Fs->answers[i],Fs->answers[i]);
}
s=CurDir;
PutS(s);
Free(s);
PutChar('>');
s=MGetS;
if (double_semicolon) {
i=StrLen(s);
result=MAlloc(i+4);
MemCpy(result,s,i+1);
i--;
while (i>=0 && (result[i]==CH_SPACE || result[i]==CH_SHIFT_SPACE || result[i]==CH_TAB))
i--;
i++;
if (i>0 && result[i-1]==';')
result[i++]=';'; //The Lex goes one beyond
result[i++]=13;//#define goes to <cr>
result[i++]=10;
result[i]=0;
} else
result=NewStr(s);
Free(s);
return result;
}
LexStruct *LexNew(I1 *buf,U8 flags,I1 *filename)
{
LexStruct *lx=MAlloc(sizeof(LexStruct));
LexFileStruct *tempf=&lx->lfns[0];
MemSet(lx,0,offset(LexStruct.lfns)+sizeof(LexFileStruct));
lx->next=lx;
lx->last=lx;
lx->flags=flags;
lx->lag_line_num=1;
lx->pass_trace_mask=0b100111111;
lx->hash_mask=HTT_ALL;
lx->hash_table_list=Fs->hash_table;
lx->define_hash_table=Fs->hash_table;
lx->cur_lfn=tempf;
lx->next_exe_blk=&lx->next_exe_blk;
lx->last_exe_blk=&lx->next_exe_blk;
if (!filename)
tempf->name=NewStr(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;
lx->cur_buf_ptr=buf;
return lx;
}
void LexDel(LexStruct *lx)
{
LexFileStruct *tempf=lx->cur_lfn;
Ltf *l;
while (tempf!=&lx->lfns[0]) {
if (l=tempf->l)
CallExtNum(EXT_LTF_DEL,l);
Free(tempf->buf);
Free(tempf->name);
tempf-=sizeof(LexFileStruct);
}
Free(tempf->name);
if (!(lx->flags & LF_DONT_FREE_BUFFER))
Free(tempf->buf);
Free(lx->ident);
Free(lx);
}
void SetSourceFileInfo(LexStruct *lx,SysHashEntry *h)
{
LexFileStruct *tempf=lx->cur_lfn;
h->source_link=MSPrintF("FL:%s,%d",tempf->name,tempf->line_num);
if (Bt(&lx->flags,LFf_KEEP_PRIVATE))
h->type|=HTT_PRIVATE;
if (lx->cur_index)
h->index=NewStr(lx->cur_index);
else
h->index=NULL;
}
void LexPutToken(LexStruct *lx)
{
PutChar('"');
if (lx->token==TK_IDENT || lx->token==TK_STR)
PutS(lx->ident);
else if (lx->token==TK_INTEGER)
cout "INT:",lx->cur_i;
else if (lx->token==TK_DOUBLE)
cout "DBL:",lx->cur_d;
else if (lx->token>=CH_SHIFT_SPACE && lx->token<=0x7E)
PutChar(lx->token);
else {
cout "T:",lx->token;
}
PutS("\" ");
}
U4 lex_zeros=0,lex_line_feed=0x000A;
void LexBackupLastChar(LexStruct *lx)
{
LexFileStruct *tempf=lx->cur_lfn;
tempf->buf_ptr=lx->cur_buf_ptr;
if (lx->flags & LF_USE_LAST_I1) {
tempf->last_I1=lx->last_I1;
lx->flags&=~LF_USE_LAST_I1;
} else
tempf->last_I1=0;
}
U8 LexGetChar(LexStruct *lx)
{
U1 *src;
LexFileStruct *tempf,*tempf1;
BoolU4 cont;
U8 result;
Ltf *l;
LtfEntry *cl;
U1 *ptr;
if (lx->flags & LF_USE_LAST_I1) {
lx->flags&=~LF_USE_LAST_I1;
if (lx->last_I1==CH_SHIFT_SPACE)
return CH_SPACE;
else
return lx->last_I1;
}
do {
lex_getchar_start:
src=lx->cur_buf_ptr++;
switch (lx->last_I1=result=*src++) {
case 0:
tempf=lx->cur_lfn;
if (tempf->flags & LFSF_IS_LTF) {
l=tempf->l;
cl=tempf->cur_entry;
cl=cl->next;
while (cl!=l) {
cont=FALSE;
tempf->cur_entry=cl;
switch (cl->btype) {
case LTFT_TEXT:
if (*(src=cl->display))
tempf->buf=tempf->buf_ptr=lx->cur_buf_ptr=src;
else {
cont=TRUE;
cl=cl->next;
}
break;
case LTFT_CR:
src=&lex_line_feed;
tempf->buf=tempf->buf_ptr=lx->cur_buf_ptr=src;
tempf->line_start=cl->next;
tempf->line_num=cl->y+2; //+1 because CR is on previous line, +1 because l y starts at zero
compiled_lines++;
if (lx->flags & LF_ECHO)
CrLf;
lx->last_I1=CH_CR;
return CH_CR;
case LTFT_TAB:
src=&lex_zeros;
tempf->buf=tempf->buf_ptr=lx->cur_buf_ptr=src;
tempf->line_num=cl->y+1;
if (lx->flags & LF_ECHO)
PutChar(CH_TAB);
lx->last_I1=CH_TAB;
return CH_TAB;
case LTFT_PAGE_BREAK:
src=&lex_zeros;
tempf->buf=tempf->buf_ptr=lx->cur_buf_ptr=src;
tempf->line_num=cl->y+2; //TODO: should be a page down
if (lx->flags & LF_ECHO)
PutChar(CH_FORM_FEED);
lx->last_I1=CH_FORM_FEED;
return CH_FORM_FEED;
case LTFT_INSERT_BINARY:
src=&lex_zeros;
tempf->buf=tempf->buf_ptr=lx->cur_buf_ptr=src;
tempf->line_num=cl->y+1;
Free(lx->ident);
lx->ident=NULL;
lx->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);
lx->ident=ptr;
lx->ident_len=cl->bin_data->size;
}
lx->last_I1=TK_INSERT_BINARY;
return TK_INSERT_BINARY;
case LTFT_INSERT_BINARY_TYPE:
src=&lex_zeros;
tempf->buf=tempf->buf_ptr=lx->cur_buf_ptr=src;
if (cl->bin_data)
lx->cur_i=cl->bin_data->type;
else
lx->cur_i=0;
tempf->line_num=cl->y+1;
lx->last_I1=TK_INSERT_BINARY_TYPE;
return TK_INSERT_BINARY_TYPE;
case LTFT_INSERT_BINARY_SIZE:
src=&lex_zeros;
tempf->buf=tempf->buf_ptr=lx->cur_buf_ptr=src;
if (cl->bin_data)
lx->cur_i=cl->bin_data->size;
else
lx->cur_i=0;
tempf->line_num=cl->y+1;
lx->last_I1=TK_INSERT_BINARY_SIZE;
return TK_INSERT_BINARY_SIZE;
default:
cont=TRUE;
cl=cl->next;
}
if (!cont) break;
}
if (cl==l) {
CallExtNum(EXT_LTF_DEL,l);
tempf->l=tempf->buf=NULL;
Free(tempf->name);
tempf->name=NULL;
goto here;
}
} else {
here:
tempf=lx->cur_lfn;
if (tempf!=&lx->lfns[0]) {
Free(tempf->name);
tempf->name=NULL;
Free(tempf->buf);
tempf->buf=NULL;
tempf1=tempf;
lx->cur_lfn=tempf-=sizeof(LexFileStruct);
lx->cur_buf_ptr=tempf->buf_ptr;
if (lx->last_I1=tempf->last_I1) {
lx->flags&=~LF_USE_LAST_I1;
if (lx->last_I1==CH_SHIFT_SPACE)
return CH_SPACE;
else
return lx->last_I1;
} else
lx->flags&=~LF_USE_LAST_I1;
} else {
if (lx->flags & LF_PROMPT) {
Free(tempf->buf);
lx->cur_buf_ptr=tempf->line_start=
tempf->buf_ptr=tempf->buf=CmpPmt(TRUE);
} else {
lx->last_I1=TK_EOF;
lx->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=lx->cur_lfn;
if (tempf->flags & LFSF_IS_LTF)
if (result==CH_SHIFT_SPACE)
return CH_SPACE;
else
return result;
else {
tempf->line_num++;
compiled_lines++;
tempf->line_start=src;
}
default:
if (lx->flags & LF_ECHO)
PutChar(result);
if (result==CH_SHIFT_SPACE)
return CH_SPACE;
else
return result;
}
} while (TRUE);
}
void LexSkipEol(LexStruct *lx)
{
U1 ch;
do ch=LexGetChar(lx);
while (ch && ch!=CH_CR && ch!=CH_LINE_FEED);
}
void DelExpression(U1 *code)
{
Free(code);
}
U8 EvalExpression(LexStruct *lx)
{
U1 *exp;
U8 result=0;
if (!GetExpression(lx,&exp))
LexSkipEol(lx);
else {
result=Call(exp);
DelExpression(exp);
}
return result;
}
void LexIncludeStr(LexStruct *lx,I1 *filename,
I1 *src,BoolU4 actual_file)
{
LexFileStruct *tempf;
LexBackupLastChar(lx);
tempf=lx->cur_lfn+sizeof(LexFileStruct);
lx->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=NewStr(sys_temp_filename);
tempf->flags=0;
}
lx->cur_buf_ptr=src;
}
void LexIncludeLtf(LexStruct *lx,I1 *filename)
{
BoolU4 is_null;
LtfEntry *cl;
Ltf *l;
LexFileStruct *tempf;
LexBackupLastChar(lx);
tempf=lx->cur_lfn+sizeof(LexFileStruct);
lx->cur_lfn=tempf;
tempf->line_start=&lex_zeros;
if (ext[EXT_LTF_READ])
l=CallExtNum(EXT_LTF_READ,filename,LTFF_DOUBLE_DOLLARS+LTFF_NO_PICWORDS);
else
throw(EXCEPT_COMPILER,1); //This should never happen
tempf->l=l;
cl=l->dummy.next;
while (cl!=l) {
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!=l) {
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) {
// LtfDel(lx); TODO
tempf->flags=LFSF_IS_INCLUDED;
tempf->buf=MAllocZ(1);
tempf->buf_ptr=&lex_zeros;
tempf->line_num=1;
} else
tempf->flags=LFSF_IS_INCLUDED|LFSF_IS_LTF;
tempf->last_I1=0;
lx->cur_buf_ptr=tempf->buf_ptr;
}
void LexPush(LexStruct *lx)
{
LexFileStruct *tempf=lx->cur_lfn,
*tempf1=&lx->stack[lx->stack_ptr++];
if (lx->stack_ptr>=LFN_STACK_CNT)
PrsExcept(lx,"ST_LEX_STACK_OVERFLOW");
LexBackupLastChar(lx);
if (tempf->last_I1)
lx->flags|=LF_USE_LAST_I1;
MemCpy(tempf1,tempf,sizeof(LexFileStruct));
}
void LexPop(LexStruct *lx)
{
LexFileStruct *tempf=lx->cur_lfn,
*tempf1=&lx->stack[--lx->stack_ptr];
lx->cur_buf_ptr=tempf1->buf_ptr;
if (lx->last_I1=tempf1->last_I1)
lx->flags|=LF_USE_LAST_I1;
else
lx->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->str,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->str);
Free(tempm->fmtstr);
Free(tempm->fmtdata);
DelLinkedList(tempm->dim_list);
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 LexInStr(LexStruct *lx,
I1 *buf,I8 size,BoolU4 *done)
{
I8 i=0,j,ch;
*done=TRUE;
while (i<size-1) {
ch=LexGetChar(lx);
if (!ch || ch=='"') {
buf[i++]=0;
return i;
} else if (ch=='\\') {
ch=LexGetChar(lx);
if (ch=='n')
buf[i++]=CH_LINE_FEED;
else if (ch=='r')
buf[i++]=CH_CR;
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++]=CH_TAB;
else if (ch=='x') {
j=0;
while (TRUE) {
ch=ToUpper(LexGetChar(lx));
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;
lx->flags|=LF_USE_LAST_I1;
} else if (ch>='0' && ch<='7') {
j=ch-'0';
do {
ch=LexGetChar(lx);
if (ch>='0' && ch<='7')
j=j<<3+ch-'0';
} while (ch>='0' && ch<='7');
buf[i++]=j;
lx->flags|=LF_USE_LAST_I1;
} else {
lx->flags|=LF_USE_LAST_I1;
buf[i++]='\\';
}
} else if (ch=='$$') {
ch=LexGetChar(lx);
buf[i++]='$$';
if (ch!='$$')
lx->flags|=LF_USE_LAST_I1;
} else
buf[i++]=ch;
}
*done=FALSE;
return i;
}
I8 Lex(LexStruct *lx)
{
U8 ch;
I8 i,j,k;
double d;
SysHashEntry *temph;
BoolU4 str_done;
I1 *fbuf;
I1 *buf2,*buf3,buf[LEX_MAX_IDENT];
lx->lag_line_num=lx->cur_lfn->line_num;
while (TRUE) {
lex_cont:
if (!(ch=LexGetChar(lx)))
return lx->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(lx)))
break;
else {
if (Bt(alpha_numeric_bitmap,ch))
buf[i++]=ch;
else {
lx->flags|=LF_USE_LAST_I1;
break;
}
}
}
} while (TRUE);
buf[i++]=0;
temph=NULL;
if (lx->local_var_list) {
lx->local_var_entry=FindMember(buf,
lx->local_var_list);
} else
lx->local_var_entry=NULL;
if (!lx->local_var_entry && lx->hash_table_list)
temph=FindHashEntry(buf,
lx->hash_table_list,lx->hash_mask);
if (temph)
j=temph->type;
else
j=0;
if (j & HTT_STR_CONST && !(lx->flags & LF_NO_DEFINES))
LexIncludeStr(lx,
temph->str,NewStr(temph><(StrConstStruct *)->data),FALSE);
else {
lx->hash_entry=temph;
Free(lx->ident);
lx->ident=NewStr(buf);
lx->ident_len=i;
lx->token=TK_IDENT;
goto lex_end;
}
} else if (Bt(dec_numeric_bitmap,ch)) {
i=ch-'0';
ch=LexGetChar(lx);
if (ch=='X' || ch=='x') {
while (TRUE) {
ch=ToUpper(LexGetChar(lx));
if (Bt(hex_numeric_bitmap,ch)) {
if (ch<='9')
i=i<<4+ch-'0';
else
i=i<<4+ch-'A'+10;
} else {
lx->cur_i=i;
lx->flags|=LF_USE_LAST_I1;
lx->token=TK_INTEGER;
goto lex_end;
}
}
}
if (ch=='B' || ch=='b') {
while (TRUE) {
ch=LexGetChar(lx);
if (ch=='0')
i=i<<1;
else if (ch=='1')
i=i<<1+1;
else {
lx->cur_i=i;
lx->flags|=LF_USE_LAST_I1;
lx->token=TK_INTEGER;
goto lex_end;
}
}
}
while (TRUE) {
if (Bt(dec_numeric_bitmap,ch))
i=i*10+ch-'0';
else {
if (ch=='.' || ch=='e' || ch=='E') break;
lx->cur_i=i;
lx->flags|=LF_USE_LAST_I1;
lx->token=TK_INTEGER;
goto lex_end;
}
ch=LexGetChar(lx);
}
if (ch=='.')
ch=LexGetChar(lx);
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=j*10+ch-'0';
k++;
} else {
d=i+j*Pow10(-k);
if (ch=='e' || ch=='E') break;
lx->cur_d=d;
lx->flags|=LF_USE_LAST_I1;
lx->token=TK_DOUBLE;
goto lex_end;
}
ch=LexGetChar(lx);
}
ch=LexGetChar(lx);
k=1;
if (ch=='-') {
k=-1;
ch=LexGetChar(lx);
}
j=0;
while (TRUE) {
//TODO: maybe replace with log2 and insert bit field
if (Bt(dec_numeric_bitmap,ch))
j=j*10+ch-'0';
else {
d*=Pow10(j*k);
lx->cur_d=d;
lx->flags|=LF_USE_LAST_I1;
lx->token=TK_DOUBLE;
goto lex_end;
}
ch=LexGetChar(lx);
}
} else if (ch=='"') {
lx->flags|=LF_IN_QUOTES;
buf2=NULL;
i=0;
do {
j=LexInStr(lx,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(lx->ident);
lx->ident=MAlloc(i);
MemCpy(lx->ident,buf2,i);
Free(buf2);
lx->ident_len=i;
lx->flags&=~LF_IN_QUOTES;
lx->token=TK_STR;
goto lex_end;
} else if (ch==0x27) { // "'"
ch=LexGetChar(lx);
if (!ch || ch==0x27) i=0x27;
else if (ch=='\\') {
ch=LexGetChar(lx);
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(lx));
if (Bt(hex_numeric_bitmap,ch)) {
if (ch<='9')
i=i<<4+ch-'0';
else
i=i<<4+ch-'A'+10;
} else
break;
}
lx->flags|=LF_USE_LAST_I1;
} else if (ch>='0' && ch<='7') {
i=ch-'0';
do {
ch=LexGetChar(lx);
if (ch>='0' && ch<='7')
i=i<<3+ch-'0';
} while (ch>='0' && ch<='7');
lx->flags|=LF_USE_LAST_I1;
} else {
lx->flags|=LF_USE_LAST_I1;
i='\\';
}
} else if (ch=='$$') {
ch=LexGetChar(lx);
i='$$';
if (ch!='$$')
lx->flags|=LF_USE_LAST_I1;
} else
i=ch;
ch=LexGetChar(lx);
if (ch!=0x27)
lx->flags|=LF_USE_LAST_I1;
lx->cur_i=i;
lx->token=TK_INTEGER;
goto lex_end;
} else if (ch=='#') {
if (Lex(lx)!=TK_IDENT) //skip '#'
goto lex_end;
if (!(temph=lx->hash_entry))
goto lex_end;
if (!(temph->type & HTT_KEYWORD))
goto lex_end;
switch (i=temph->user_data0) {
case KW_INCLUDE:
if (Lex(lx)!=TK_STR)
goto lex_end;
if (lx->flags & LF_ASM_EXPRESSIONS)
fbuf=DefaultExtension(lx->ident,"ASZ");
else if (Fs==adam_tss)
fbuf=DefaultExtension(lx->ident,"APZ");
else
fbuf=DefaultExtension(lx->ident,"CPZ");
if (ext[EXT_LTF_READ])
LexIncludeLtf(lx,fbuf);
else
LexIncludeStr(lx,fbuf,ReadTextFile(fbuf),TRUE);
Free(fbuf);
break;
case KW_DEFINE:
lx->flags|=LF_NO_DEFINES;
if (Lex(lx)==TK_IDENT) {
temph=MAllocZ(sizeof(StrConstStruct));
temph->str=lx->ident;
lx->ident=0;
temph->use_cnt=0;
temph->type=HTT_STR_CONST;
SetSourceFileInfo(lx,temph);
i=0;
do ch=LexGetChar(lx);
while (ch && (ch<=CH_SPACE || ch>0x7E) && ch!=CH_CR);
if (ch>CH_SPACE && ch<=0x7E || ch==CH_CR) {
if (ch!=CH_CR)
buf[i++]=ch;
while (i<LEX_MAX_IDENT-1) {
ch=LexGetChar(lx);
if (ch=='/') {
ch=LexGetChar(lx);
if (ch=='/') {
do ch=LexGetChar(lx);
while (ch>=CH_SHIFT_SPACE && ch<=0x7E || ch==CH_TAB);
break;
} else {
buf[i++]='/';
lx->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><(StrConstStruct *)->data=NewStr(buf);
AddSysHashEntry(temph,lx->define_hash_table);
}
lx->flags&=~LF_NO_DEFINES;
break;
case KW_ELSE:
if (lx->flags & LF_IN_IF) {
lx->token=TK_ELSE;
goto lex_end;
}
lex_else:
j=1;
do {
if (ch=LexGetChar(lx)) {
if (ch=='#') {
if (!Lex(lx))
goto lex_end;
i=CmpKeyWord(lx);
if (i==KW_IF || i==KW_IFDEF || i==KW_IFNDEF)
j++;
else if (i==KW_ENDIF)
j--;
}
} else {
lx->token=TK_EOF;
goto lex_end;
}
} while (j);
break;
case KW_IF:
if (lx->flags & LF_IN_IF) {
lx->token=TK_IF;
goto lex_end;
}
lex_if:
lx->flags|=LF_IN_IF;
if (!Lex(lx)) {
lx->flags&=~LF_IN_IF;
goto lex_end;
}
if (Expression(lx)) {
lx->flags&=~LF_IN_IF;
if (lx->token==TK_IF)
goto lex_if;
else if (lx->token==TK_IFDEF)
goto lex_ifdef;
else if (lx->token==TK_IFNDEF)
goto lex_ifndef;
else if (lx->token==TK_ELSE)
goto lex_else;
else if (lx->token==TK_ENDIF)
goto lex_cont;
else
goto lex_end;
} else {
lx->flags&=~LF_IN_IF;
if (lx->token!=TK_ENDIF && lx->token!=TK_ELSE) {
if (lx->token==TK_IF || lx->token==KW_IFDEF || lx->token==KW_IFNDEF)
j=2;
else
j=1;
do {
if (ch=LexGetChar(lx)) {
if (ch=='#') {
if (!Lex(lx))
goto lex_end;
i=CmpKeyWord(lx);
if (i==KW_IF || i==KW_IFDEF || i==KW_IFNDEF)
j++;
else if (i==KW_ENDIF)
j--;
else if (i==KW_ELSE && j==1)
break;
}
} else {
lx->token=TK_EOF;
goto lex_end;
}
} while (j);
}
}
break;
case KW_IFDEF:
if (lx->flags & LF_IN_IF) {
lx->token=TK_IFDEF;
goto lex_end;
}
lex_ifdef:
lx->flags|=LF_NO_DEFINES;
if (!Lex(lx)) {
lx->flags&=~LF_NO_DEFINES;
goto lex_end;
}
lx->flags&=~LF_NO_DEFINES;
if (lx->token!=TK_IDENT)
goto lex_end;
if (lx->hash_entry)
goto lex_cont;
j=1;
do {
if (ch=LexGetChar(lx)) {
if (ch=='#') {
if (!Lex(lx))
goto lex_end;
i=CmpKeyWord(lx);
if (i==KW_IF || i==KW_IFDEF || i==KW_IFNDEF)
j++;
else if (i==KW_ENDIF)
j--;
else if (i==KW_ELSE && j==1)
break;
}
} else {
lx->token=TK_EOF;
goto lex_end;
}
} while (j);
break;
case KW_IFNDEF:
if (lx->flags & LF_IN_IF) {
lx->token=TK_IFNDEF;
goto lex_end;
}
lex_ifndef:
lx->flags|=LF_NO_DEFINES;
if (!Lex(lx)) {
lx->flags&=~LF_NO_DEFINES;
goto lex_end;
}
lx->flags&=~LF_NO_DEFINES;
if (lx->token!=TK_IDENT)
goto lex_end;
if (!lx->hash_entry)
goto lex_cont;
j=1;
do {
if (ch=LexGetChar(lx)) {
if (ch=='#') {
if (!Lex(lx))
goto lex_end;
i=CmpKeyWord(lx);
if (i==KW_IF || i==KW_IFDEF || i==KW_IFNDEF)
j++;
else if (i==KW_ENDIF)
j--;
else if (i==KW_ELSE && j==1)
break;
}
} else {
lx->token=TK_EOF;
goto lex_end;
}
} while (j);
break;
case KW_ENDIF:
if (lx->flags & LF_IN_IF) {
lx->token=TK_ENDIF;
goto lex_end;
}
break;
case KW_ASSERT:
if (!Lex(lx))
goto lex_end;
if (!Expression(lx))
PutLexWarning(lx,"ST_ASSERT_FAILED");
goto lex_end;
case KW_EXE:
if (!Lex(lx))
goto lex_end;
CallExtNum(EXT_CMP_EXE_BLK,lx);
goto lex_end;
case KW_HELP_INDEX:
if (Lex(lx)!=TK_STR)
goto lex_end;
Free(lx->cur_index);
lx->cur_index=lx->ident;
lx->ident=NULL;
break;
case KW_HELP_FILE:
if (Lex(lx)!=TK_STR)
goto lex_end;
temph=MAllocZ(sizeof(SysHashEntry));
temph->str=AbsoluteFileName(lx->ident);
temph->type=HTT_HELP_FILE|HTT_PUBLIC;
SetSourceFileInfo(lx,temph);
AddSysHashEntry(temph,lx->hash_table_list);
break;
}
} else if (ch==TK_INSERT_BINARY ||
ch==TK_INSERT_BINARY_TYPE ||
ch==TK_INSERT_BINARY_SIZE) {
lx->token=ch;
goto lex_end;
} else if (ch=='.') {
ch=LexGetChar(lx);
if (ch>='0' && ch<='9') {
i=0;
goto float_start;
}
lx->flags|=LF_USE_LAST_I1;
lx->token='.';
goto lex_end;
} else if (ch>=0x21 && ch<=0x7E) {
i=duel_I1_tokens1[ch];
if (!i) {
if (ch=='$$') {
do ch=LexGetChar(lx);
while (ch && ch!='$$');
goto lex_cont;
} else {
lx->token=ch;
goto lex_end;
}
} else {
j=LexGetChar(lx);
if (i.u1[0]==j) {
i>>=8;
if (!i) { // "/*"
j=1;
do {
if (!(ch=LexGetChar(lx)))
return lx->token=TK_EOF;
lex_check_comment:
if (ch=='*') {
if (!(ch=LexGetChar(lx)))
return lx->token=TK_EOF;
if (ch=='/')
j--;
else
goto lex_check_comment;
} else if (ch=='/') {
if (!(ch=LexGetChar(lx)))
return lx->token=TK_EOF;
if (ch=='*')
j++;
else
goto lex_check_comment;
}
} while (j);
goto lex_cont;
} else {
lx->token=i;
goto lex_end;
}
}
if (i=duel_I1_tokens2[ch]) {
if (i.u1[0]==j) {
i>>=8;
if (!i) { // "//"
LexSkipEol(lx);
goto lex_cont;
} else {
if (i==TK_SHL || i==TK_SHR) {
j=LexGetChar(lx);
if (j=='=') {
if (i==TK_SHL)
i=TK_SHL_EQUAL;
else
i=TK_SHR_EQUAL;
} else
lx->flags|=LF_USE_LAST_I1;
}
lx->token=i;
goto lex_end;
}
}
if (i=duel_I1_tokens3[ch]) {
if (i.u1[0]==j) {
lx->token=i.u1[1];
goto lex_end;
}
}
}
lx->flags|=LF_USE_LAST_I1;
lx->token=ch;
goto lex_end;
}
}
}
lex_end:
if (Bt(&lx->flags,LFf_LEX_TRACE))
LexPutToken(lx);
return lx->token;
}
I1 *LexExtendStr(LexStruct *lx,U8 *size=NULL)
{
U8 len=lx->ident_len,len1,len2;
I1 *st=lx->ident,*st1,*st2;
lx->ident=NULL;
while (lx->token==TK_STR) {
st1=st;
len1=len;
if (Lex(lx)==TK_STR) {
len2=lx->ident_len;
st2=lx->ident;
lx->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);
}
}
if (size)
*size=len;
return st;
}
I1 *LexPutLine(LexStruct *lx,I1 *start)
{
I1 *ptr;
if (!start) return;
if (lx->cur_lfn->flags&LFSF_IS_LTF)
return CallExtStr("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 *lx)
{
return lx->cur_lfn->line_num;
}
void LexPutLink(LexStruct *lx)
{
if (IsRaw)
PrintF("%s,%d ",lx->cur_lfn->name,lx->cur_lfn->line_num);
else {
PutFileLink(lx->cur_lfn->name,lx->cur_lfn->line_num);
AdamErr("%s,%d\r",lx->cur_lfn->name,lx->cur_lfn->line_num);
PutS(" ");
}
}
void PutLexError(LexStruct *lx,I1 *name=NULL,I1 *msg=NULL)
{
PutErr;
lx->error_cnt++;
if (!IsRaw)
AdamErr("Tsk:%08X ",Fs);
if (name) {
PutSysText(name);
if (!IsRaw)
AdamErr("%S",name);
}
if (msg) {
PutS(msg);
if (!IsRaw)
AdamErr("%s\r\n",msg);
}
LexPutToken(lx);
LexPutLink(lx);
LexPutLine(lx,lx->cur_lfn->line_start);
}
void PutLexWarning(LexStruct *lx,I1 *name=NULL,I1 *msg=NULL)
{
PrintFWarn("%S%s",name,msg);
lx->warning_cnt++;
LexPutToken(lx);
LexPutLink(lx);
LexPutLine(lx,lx->cur_lfn->line_start);
}
void PutAsmError(LexStruct *lx,I1 *name)
{
PutLexError(lx,name);
LexSkipEol(lx);
Lex(lx);
}
void PutAsmWarning(LexStruct *lx,I1 *name)
{
PutLexWarning(lx,name);
LexSkipEol(lx);
Lex(lx);
}
void PrsExcept(LexStruct *lx,I1 *name=NULL,I1 *msg=NULL)
{
PutLexError(lx,name,msg);
CallExtNum(EXT_FLUSH_MSGS,NULL);
throw(EXCEPT_COMPILER,0);
}