Files
Work/as68hc11/backup/Scan.cpp
2024-08-07 09:12:07 -04:00

201 lines
4.6 KiB
C++

#include <as68hc11/scan.hpp>
#include <as68hc11/symbol.hpp>
#include <as68hc11/table.hpp>
#include <common/pointer.hpp>
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> 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);}
}