#include #include #include #include Scan::Scan(PureViewOfFile &inFile,PureViewOfFile &outFile,Table &symbolTable) : Emit(inFile,outFile), mSymbolTable(symbolTable) { } Scan::~Scan(void) { } void Scan::analyze(void) { readch(); while((int)mChar!=-1&&mChar!=0x001A) { skipSeparators(); if(0xFFFF==mChar||0x001A==mChar)break; if(isdigit(mChar))scanNumeral(); else if('\r'==mChar)scanNewLine(); else if(','==mChar){emit(comma1);readch();} else if('['==mChar){emit(leftbracket1);readch();} else if(']'==mChar){emit(rightbracket1);readch();} else if('*'==mChar){emit(asterisk1);readch();} else if('/'==mChar){emit(divide1);readch();} else if('+'==mChar){emit(plus1);readch();} else if('-'==mChar){emit(minus1);readch();} else if('('==mChar){emit(leftparen1);readch();} else if(')'==mChar){emit(rightparen1);readch();} else if('\''==mChar)scanCharacter(); else if(';'==mChar)scanComment(); else if(isalpha(mChar))scanWord(); else scanUnknown(); } emit(endtext1); } void Scan::scanNewLine(void) { emit(newline1); readch(); if(mChar=='\n')readch(); } void Scan::skipSeparators(void) { while(mChar==SpaceChar||mChar==TabChar)readch(); } void Scan::scanComment(void) { readch(); while(mChar!='\r'&&mChar!=0xFFFF)readch(); } void Scan::scanCharacter(void) { int character; readch(); character=mChar; readch(); *((char*)mWordString)=0; mWordString+=character; while(0xFFFF!=mChar&&'\''!=mChar&&0x0D!=mChar) { mWordString+=mChar; readch(); } readch(); emit(apostrophe1); emit(literal1); emit(mWordString); emit(apostrophe1); } BOOL Scan::scanNumeral(void) { char chBuffer[128]; char chIndex(0); int value(0); while(0xFFFF!=mChar&&(isdigit(mChar)||isInHex(mChar))) { if(chIndex>=sizeof(chBuffer))return FALSE; chBuffer[chIndex++]=mChar; readch(); } if('h'==mChar||'H'==mChar){hex(chBuffer,chIndex);readch();} else if('b'==mChar||'B'==mChar){binary(chBuffer,chIndex);readch();} else if(chIndex>0&&('b'==chBuffer[chIndex-1]||'B'==chBuffer[chIndex-1]))binary(chBuffer,chIndex-1); else decimal(chBuffer,chIndex); return TRUE; } void Scan::hex(char chBuffer[],int chIndex) { int value(0); int multiplier(1); for(--chIndex;chIndex>=0;chIndex--) { switch(chBuffer[chIndex]) { case '0' : break; case '1' : {value+=multiplier;break;} case '2' : {value+=multiplier*2;break;} case '3' : {value+=multiplier*3;break;} case '4' : {value+=multiplier*4;break;} case '5' : {value+=multiplier*5;break;} case '6' : {value+=multiplier*6;break;} case '7' : {value+=multiplier*7;break;} case '8' : {value+=multiplier*8;break;} case '9' : {value+=multiplier*9;break;} case 'a' : case 'A' : {value+=multiplier*10;break;} case 'b' : case 'B' : {value+=multiplier*11;break;} case 'c' : case 'C' : {value+=multiplier*12;break;} case 'd' : case 'D' : {value+=multiplier*13;break;} case 'e' : case 'E' : {value+=multiplier*14;break;} case 'f' : case 'F' : {value+=multiplier*15;break;} default : {emit(unknown1);return;} } multiplier*=16; } emit(numeral1,value); } void Scan::binary(char chBuffer[],int chIndex) { int value(0); int multiplier(1); for(--chIndex;chIndex>=0;chIndex--) { switch(chBuffer[chIndex]) { case '0' : break; case '1' : {value+=multiplier;break;} default : {emit(unknown1);return;} } multiplier*=2; } emit(numeral1,value); } void Scan::decimal(char chBuffer[],int chIndex) { int value(0); int multiplier(1); for(--chIndex;chIndex>=0;chIndex--) { switch(chBuffer[chIndex]) { case '0' : break; case '1' : {value+=multiplier;break;} case '2' : {value+=multiplier*2;break;} case '3' : {value+=multiplier*3;break;} case '4' : {value+=multiplier*4;break;} case '5' : {value+=multiplier*5;break;} case '6' : {value+=multiplier*6;break;} case '7' : {value+=multiplier*7;break;} case '8' : {value+=multiplier*8;break;} case '9' : {value+=multiplier*9;break;} default : {emit(unknown1);return;} } multiplier*=10; } emit(numeral1,value); } void Scan::scanWord(void) { SmartPointer symbol; *((char*)mWordString)=0; while(0x0D!=mChar&&!isKeySymbol()&&0xFFFF!=mChar&&SpaceChar!=mChar&&TabChar!=mChar) { mWordString+=mChar; readch(); } if(mWordString.isNull())return; if(mSymbolTable.locateSymbol(mWordString,symbol)) { if(Symbol::DirectiveSymbol==symbol->symbolType())emit(symbol->identifier()); else emit(name1,int((Symbol*)symbol)); } else if(':'==mChar){emit(label1);emit(mWordString);readch();} else {emit(literal1);emit(mWordString);} }