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 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 (iflags|=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=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); }