1281 lines
38 KiB
C++
1281 lines
38 KiB
C++
#include <as68hc11/table.hpp>
|
|
#include <as68hc11/parse.hpp>
|
|
#include <as68hc11/label.hpp>
|
|
#include <common/stdio.hpp>
|
|
|
|
Parse::Parse(PureViewOfFile &srcView,PureViewOfFile &dstView)
|
|
: Emit(srcView,dstView), mNumeralValue(0), mIsInError(FALSE), mLastMessage("Success"),
|
|
mLastLineNumber(FirstLine), mLineNumber(FirstLine), mCurrentSymbolType(Scan::unknown1),
|
|
mLogFile("parse.log",FileHandle::Write,FileHandle::ShareRead,FileHandle::Overwrite),
|
|
mCodeBytes(0)
|
|
{
|
|
createSimpleExpressionSymbols();
|
|
createExpressionSymbols();
|
|
createStatementSymbols();
|
|
createFactorSymbols();
|
|
createTermSymbols();
|
|
createMathSymbols();
|
|
createAddSymbols();
|
|
createSignSymbols();
|
|
}
|
|
|
|
Parse::~Parse()
|
|
{
|
|
}
|
|
|
|
BOOL Parse::parse(void)
|
|
{
|
|
mCodeBytes=0;
|
|
nextSymbol();
|
|
insertSymbols(ParseSymbol(Scan::endtext1));
|
|
while(Scan::endtext1!=currentSymbolType()&&!isInError())statement();
|
|
removeSymbols(ParseSymbol(Scan::endtext1));
|
|
if(isInError())return FALSE;
|
|
mCodeBytes=outputView().tell();
|
|
resolve();
|
|
return !isInError();
|
|
}
|
|
|
|
void Parse::statement(void)
|
|
{
|
|
if(symbolIn(ParseSymbol(Scan::origin1))){originStatement();return;}
|
|
else if(symbolIn(ParseSymbol(Scan::label1))){labelStatement();return;}
|
|
else if(symbolIn(ParseSymbol(Scan::literal1))){parseLiteral();return;}
|
|
else if(Scan::name1==currentSymbolType())
|
|
{
|
|
switch(mCurrentSymbol->symbolType())
|
|
{
|
|
case Symbol::KeywordSymbol :
|
|
keywordStatement();
|
|
break;
|
|
case Symbol::DirectiveSymbol :
|
|
syntaxError();
|
|
break;
|
|
case Symbol::UserSymbol :
|
|
userStatement();
|
|
break;
|
|
}
|
|
}
|
|
else syntaxCheck();
|
|
}
|
|
|
|
void Parse::labelStatement(void)
|
|
{
|
|
Label codeLabel;
|
|
SmartPointer<Label> nodeLabel;
|
|
|
|
codeLabel.strLabel(mLiteralValue);
|
|
codeLabel.offset(codePointer().position());
|
|
codeLabel.disposition(Label::Absolute);
|
|
insertSymbols(mStatementSymbols);
|
|
expect(currentSymbolType());
|
|
removeSymbols(mStatementSymbols);
|
|
if(isInError())return;
|
|
if(isInEquates(codeLabel.strLabel())){error(SymbolAlreadyDifferentKind,codeLabel.strLabel());return;}
|
|
if(mLabelGenerator.insert(codeLabel))return;
|
|
if(!mLabelGenerator.searchItem(codeLabel,nodeLabel))return;
|
|
if(Label::Absolute==nodeLabel->disposition()){error(SymbolAlreadyDefined);return;}
|
|
nodeLabel->disposition(Label::Absolute);
|
|
nodeLabel->offset(codePointer().position());
|
|
}
|
|
|
|
void Parse::parseLiteral(void)
|
|
{
|
|
Scan::ScanSymbols peekSymbol;
|
|
|
|
peek((int&)peekSymbol);
|
|
if(Scan::rmb1==peekSymbol)rmbStatement();
|
|
else equateStatement();
|
|
}
|
|
|
|
void Parse::rmbStatement(void)
|
|
{
|
|
SmartPointer<Equate> ptrEquate;
|
|
SmartPointer<Label> ptrLabel;
|
|
Equate equate;
|
|
Label label;
|
|
DWORD startAddress;
|
|
DWORD rmbCount(0);
|
|
|
|
equate.strLabel(mLiteralValue);
|
|
label.strLabel(mLiteralValue);
|
|
insertSymbols(ParseSymbol(Scan::rmb1));
|
|
expect(Scan::literal1);
|
|
removeSymbols(ParseSymbol(Scan::rmb1));
|
|
insertSymbols(ParseSymbol(Scan::apostrophe1));
|
|
insertSymbols(ParseSymbol(Scan::numeral1));
|
|
expect(Scan::rmb1);
|
|
removeSymbols(ParseSymbol(Scan::numeral1));
|
|
removeSymbols(ParseSymbol(Scan::apostrophe1));
|
|
if(isInError())return;
|
|
startAddress=codePointer().position();
|
|
if(symbolIn(ParseSymbol(Scan::apostrophe1)))
|
|
{
|
|
while(TRUE)
|
|
{
|
|
if(symbolIn(ParseSymbol(Scan::apostrophe1)))
|
|
{
|
|
int strLength;
|
|
insertSymbols(ParseSymbol(Scan::literal1));
|
|
expect(Scan::apostrophe1);
|
|
strLength=mLiteralValue.length();
|
|
for(int index=0;index<strLength;index++)emit(BYTE(*((char*)mLiteralValue+index)));
|
|
removeSymbols(ParseSymbol(Scan::literal1));
|
|
insertSymbols(ParseSymbol(Scan::apostrophe1));
|
|
expect(Scan::literal1);
|
|
removeSymbols(ParseSymbol(Scan::apostrophe1));
|
|
insertSymbols(mStatementSymbols);
|
|
insertSymbols(ParseSymbol(Scan::apostrophe1));
|
|
insertSymbols(ParseSymbol(Scan::comma1));
|
|
expect(Scan::apostrophe1);
|
|
removeSymbols(mStatementSymbols);
|
|
removeSymbols(ParseSymbol(Scan::apostrophe1));
|
|
removeSymbols(ParseSymbol(Scan::comma1));
|
|
}
|
|
else if(symbolIn(ParseSymbol(Scan::comma1)))
|
|
{
|
|
DWORD expressionResult;
|
|
insertSymbols(ParseSymbol(Scan::literal1));
|
|
insertSymbols(ParseSymbol(Scan::numeral1));
|
|
insertSymbols(ParseSymbol(Scan::apostrophe1));
|
|
expect(Scan::comma1);
|
|
removeSymbols(ParseSymbol(Scan::literal1));
|
|
removeSymbols(ParseSymbol(Scan::numeral1));
|
|
removeSymbols(ParseSymbol(Scan::apostrophe1));
|
|
if(symbolIn(ParseSymbol(Scan::apostrophe1)))continue;
|
|
insertSymbols(mSimpleExpressionSymbols);
|
|
insertSymbols(ParseSymbol(Scan::comma1));
|
|
insertSymbols(ParseSymbol(Scan::literal1));
|
|
insertSymbols(mStatementSymbols);
|
|
simpleExpression(expressionResult);
|
|
removeSymbols(mStatementSymbols);
|
|
removeSymbols(mSimpleExpressionSymbols);
|
|
removeSymbols(ParseSymbol(Scan::literal1));
|
|
removeSymbols(ParseSymbol(Scan::comma1));
|
|
if(expressionResult>0xFF)emit(hiByte(expressionResult));
|
|
emit(BYTE(expressionResult));
|
|
}
|
|
else break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rmbCount=mNumeralValue;
|
|
insertSymbols(mStatementSymbols);
|
|
expect(Scan::numeral1);
|
|
removeSymbols(mStatementSymbols);
|
|
}
|
|
if(isInError())return;
|
|
equate.disposition(Equate::Absolute);
|
|
if(mLabelGenerator.searchItem(label,ptrLabel))
|
|
{
|
|
if(Label::Absolute==ptrLabel->disposition()){error(SymbolAlreadyDifferentKind,equate.strLabel());return;}
|
|
else ptrLabel->disposition(Label::Ignore);
|
|
}
|
|
if(!(mEquates.searchItem(equate,ptrEquate)&&ptrEquate->value()!=startAddress))
|
|
{
|
|
equate.value(startAddress);
|
|
mEquates.insert(equate);
|
|
}
|
|
else error(SymbolAlreadyDefined,ptrEquate->strLabel());
|
|
for(int index=0;index<rmbCount;index++)emit(BYTE(0x00));
|
|
}
|
|
|
|
void Parse::equateStatement(void)
|
|
{
|
|
DWORD expressionResult;
|
|
SmartPointer<Equate> ptrEquate;
|
|
SmartPointer<Label> ptrLabel;
|
|
Equate equate;
|
|
Label label;
|
|
|
|
equate.strLabel(mLiteralValue);
|
|
label.strLabel(mLiteralValue);
|
|
insertSymbols(ParseSymbol(Scan::equ1));
|
|
expect(Scan::literal1);
|
|
removeSymbols(ParseSymbol(Scan::equ1));
|
|
insertSymbols(ParseSymbol(Scan::literal1));
|
|
insertSymbols(ParseSymbol(Scan::asterisk1));
|
|
insertSymbols(mSimpleExpressionSymbols);
|
|
expect(Scan::equ1);
|
|
removeSymbols(mSimpleExpressionSymbols);
|
|
removeSymbols(ParseSymbol(Scan::asterisk1));
|
|
removeSymbols(ParseSymbol(Scan::literal1));
|
|
if(symbolIn(ParseSymbol(Scan::asterisk1)))
|
|
{
|
|
insertSymbols(mStatementSymbols);
|
|
expect(Scan::asterisk1);
|
|
removeSymbols(mStatementSymbols);
|
|
if(isInError())return;
|
|
equate.value(codePointer().position());
|
|
equate.disposition(Equate::Reference);
|
|
expressionResult=equate.value();
|
|
}
|
|
else
|
|
{
|
|
insertSymbols(mStatementSymbols);
|
|
simpleExpression(expressionResult);
|
|
removeSymbols(mStatementSymbols);
|
|
equate.disposition(Equate::Absolute);
|
|
if(isInError())return;
|
|
}
|
|
if(mLabelGenerator.searchItem(label,ptrLabel))
|
|
{
|
|
if(Label::Absolute==ptrLabel->disposition()){error(SymbolAlreadyDifferentKind,equate.strLabel());return;}
|
|
else ptrLabel->disposition(Label::Ignore);
|
|
}
|
|
if(!(mEquates.searchItem(equate,ptrEquate)&&ptrEquate->value()!=expressionResult))
|
|
{
|
|
equate.value(expressionResult);
|
|
mEquates.insert(equate);
|
|
}
|
|
else error(SymbolAlreadyDefined,ptrEquate->strLabel());
|
|
}
|
|
|
|
void Parse::userStatement(void)
|
|
{
|
|
syntaxError();
|
|
}
|
|
|
|
void Parse::originStatement(void)
|
|
{
|
|
DWORD origin;
|
|
insertSymbols(mSimpleExpressionSymbols);
|
|
insertSymbols(ParseSymbol(Scan::literal1));
|
|
expect(currentSymbolType());
|
|
removeSymbols(ParseSymbol(Scan::literal1));
|
|
removeSymbols(mSimpleExpressionSymbols);
|
|
insertSymbols(mStatementSymbols);
|
|
simpleExpression(origin);
|
|
codePointer().origin(origin);
|
|
outputView().seek(origin,PureViewOfFile::SeekSet);
|
|
removeSymbols(mStatementSymbols);
|
|
}
|
|
|
|
void Parse::keywordStatement(void)
|
|
{
|
|
SmartPointer<Symbol> currentSymbol;
|
|
Scan::ScanSymbols peekSymbol;
|
|
WORD indexForm;
|
|
|
|
currentSymbol=mCurrentSymbol;
|
|
peek((int&)peekSymbol);
|
|
if(currentSymbol->hasInherentMode(indexForm))parseInherent(currentSymbol,indexForm);
|
|
else if(currentSymbol->hasRelativeMaskMode())parseRelativeMask(currentSymbol,peekSymbol);
|
|
else if(currentSymbol->hasMaskMode())parseMask(currentSymbol,peekSymbol);
|
|
else if(Scan::leftbracket1==peekSymbol)parseDirectExtended(currentSymbol,indexForm,peekSymbol);
|
|
else if(Scan::numeral1==peekSymbol)parseImmediate(currentSymbol,indexForm);
|
|
// else if(Scan::numeral1==peekSymbol||Scan::apostrophe1==peekSymbol)parseImmediate(currentSymbol,indexForm);
|
|
else if(Scan::literal1==peekSymbol&¤tSymbol->hasImmediateMode(indexForm))parseLabelImmediate(currentSymbol,indexForm);
|
|
else if(Scan::literal1==peekSymbol&¤tSymbol->hasExtendedMode(indexForm))parseLabelExtended(currentSymbol,indexForm);
|
|
else if(currentSymbol->hasIndexedMode(indexForm))parseIndexed(currentSymbol,indexForm);
|
|
else if(currentSymbol->hasRelativeMode(indexForm))parseRelative(currentSymbol,indexForm);
|
|
else error(IllegalAddressingModeForMnemonic);
|
|
}
|
|
|
|
void Parse::parseInherent(SmartPointer<Symbol> ¤tSymbol,WORD indexForm)
|
|
{
|
|
AddressMode &addressMode=(*currentSymbol)[indexForm];
|
|
|
|
if(addressMode.prebyte())emit(addressMode.prebyte());
|
|
emit((*mCurrentSymbol)[0].opcode());
|
|
insertSymbols(mStatementSymbols);
|
|
nextSymbol();
|
|
removeSymbols(mStatementSymbols);
|
|
return;
|
|
}
|
|
|
|
void Parse::parseDirectExtended(SmartPointer<Symbol> ¤tSymbol,WORD indexForm,Scan::ScanSymbols peekSymbol)
|
|
{
|
|
DWORD expressionResult;
|
|
|
|
insertSymbols(ParseSymbol(peekSymbol));
|
|
expect(currentSymbolType());
|
|
removeSymbols(ParseSymbol(peekSymbol));
|
|
|
|
// This is new code for handling direct and extended references to labels and macros.
|
|
// Since it is difficult to determine whether to use the direct or indirect form
|
|
// of an instruction, because the label or macro may be forward referenced, the code
|
|
// here emits the extended mode of an instruction even though this may not be the
|
|
// most optimal. For instructions that do not have the extended form of an instruction
|
|
// the solution is trivial. However, an optimizer would need to determine the most efficient
|
|
// encoding of forward referenced labels and macros when direct and extended forms are both
|
|
// available for encoding.
|
|
|
|
peek((int&)peekSymbol);
|
|
if(peekSymbol==Scan::literal1)
|
|
{
|
|
if(currentSymbol->hasExtendedMode(indexForm))
|
|
{
|
|
insertSymbols(ParseSymbol(Scan::rightbracket1));
|
|
parseLabelExtended(currentSymbol,indexForm);
|
|
removeSymbols(ParseSymbol(Scan::rightbracket1));
|
|
insertSymbols(mStatementSymbols);
|
|
expect(Scan::rightbracket1);
|
|
removeSymbols(mStatementSymbols);
|
|
return;
|
|
}
|
|
else if(currentSymbol->hasDirectMode(indexForm))
|
|
{
|
|
insertSymbols(ParseSymbol(Scan::rightbracket1));
|
|
parseLabelDirect(currentSymbol,indexForm);
|
|
removeSymbols(ParseSymbol(Scan::rightbracket1));
|
|
insertSymbols(mStatementSymbols);
|
|
expect(Scan::rightbracket1);
|
|
removeSymbols(mStatementSymbols);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
error(IllegalAddressingModeForMnemonic);
|
|
return;
|
|
}
|
|
}
|
|
// *********************
|
|
insertSymbols(ParseSymbol(Scan::literal1));
|
|
insertSymbols(ParseSymbol(Scan::numeral1));
|
|
expect(Scan::leftbracket1);
|
|
removeSymbols(ParseSymbol(Scan::numeral1));
|
|
removeSymbols(ParseSymbol(Scan::literal1));
|
|
insertSymbols(ParseSymbol(Scan::rightbracket1));
|
|
insertSymbols(ParseSymbol(Scan::literal1));
|
|
simpleExpression(expressionResult);
|
|
removeSymbols(ParseSymbol(Scan::literal1));
|
|
removeSymbols(ParseSymbol(Scan::rightbracket1));
|
|
insertSymbols(mStatementSymbols);
|
|
expect(Scan::rightbracket1);
|
|
removeSymbols(mStatementSymbols);
|
|
if(!inRange(expressionResult)){error(ValueOutOfRangeForInstruction);return;}
|
|
if(expressionResult>0xFF)
|
|
{
|
|
if(currentSymbol->hasExtendedMode(indexForm))
|
|
{
|
|
AddressMode &addressMode=(*currentSymbol)[indexForm];
|
|
if(addressMode.prebyte())emit(addressMode.prebyte());
|
|
emit(addressMode.opcode());
|
|
emit(hiByte(expressionResult));
|
|
emit(loByte(expressionResult));
|
|
}
|
|
else error(IllegalAddressingModeForMnemonic);
|
|
}
|
|
else
|
|
{
|
|
if(currentSymbol->hasDirectMode(indexForm))
|
|
{
|
|
AddressMode &addressMode=(*currentSymbol)[indexForm];
|
|
if(addressMode.prebyte())emit(addressMode.prebyte());
|
|
emit(addressMode.opcode());
|
|
emit(loByte(expressionResult));
|
|
}
|
|
else
|
|
{
|
|
if(currentSymbol->hasExtendedMode(indexForm))
|
|
{
|
|
AddressMode &addressMode=(*currentSymbol)[indexForm];
|
|
if(addressMode.prebyte())emit(addressMode.prebyte());
|
|
emit(addressMode.opcode());
|
|
emit(hiByte(expressionResult));
|
|
emit(loByte(expressionResult));
|
|
}
|
|
else error(IllegalAddressingModeForMnemonic);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Parse::parseImmediate(SmartPointer<Symbol> ¤tSymbol,WORD indexForm)
|
|
{
|
|
DWORD value;
|
|
|
|
insertSymbols(ParseSymbol(Scan::numeral1));
|
|
expect(mCurrentSymbolType);
|
|
removeSymbols(ParseSymbol(Scan::numeral1));
|
|
value=mNumeralValue;
|
|
insertSymbols(mStatementSymbols);
|
|
expect(Scan::numeral1);
|
|
removeSymbols(mStatementSymbols);
|
|
if(currentSymbol->hasImmediateMode(indexForm))
|
|
{
|
|
AddressMode &addressMode=(*currentSymbol)[indexForm];
|
|
if(!inRange(value))error(ValueOutOfRangeForInstruction);
|
|
else if(Instruction::SingleByte==currentSymbol->registerLength())
|
|
{
|
|
if(value<=0xFF)
|
|
{
|
|
if(addressMode.prebyte())emit(addressMode.prebyte());
|
|
emit(addressMode.opcode());
|
|
emit(loByte(value));
|
|
}
|
|
else error(OperandSizeMustMatch);
|
|
}
|
|
else
|
|
{
|
|
if(addressMode.prebyte())emit(addressMode.prebyte());
|
|
emit(addressMode.opcode());
|
|
emit(hiByte(value));
|
|
emit(loByte(value));
|
|
}
|
|
}
|
|
else if(currentSymbol->hasRelativeMode(indexForm))
|
|
{
|
|
AddressMode &addressMode=(*currentSymbol)[indexForm];
|
|
if(addressMode.prebyte())emit(addressMode.prebyte());
|
|
emit(addressMode.opcode());
|
|
emit(hiByte(value));
|
|
emit(loByte(value));
|
|
}
|
|
else error(IllegalAddressingModeForMnemonic);
|
|
}
|
|
|
|
void Parse::parseMask(SmartPointer<Symbol> ¤tSymbol,Scan::ScanSymbols peekSymbol)
|
|
{
|
|
SmartPointer<AddressMode> addressMode;
|
|
WORD indexForm;
|
|
DWORD expressionResult;
|
|
DWORD maskValue;
|
|
|
|
if(Scan::leftbracket1==peekSymbol)
|
|
{
|
|
if(!currentSymbol->hasDirectMode(indexForm)){error(IllegalAddressingModeForMnemonic);return;}
|
|
addressMode=&(*currentSymbol)[indexForm];
|
|
insertSymbols(ParseSymbol(peekSymbol));
|
|
expect(currentSymbolType());
|
|
removeSymbols(ParseSymbol(peekSymbol));
|
|
insertSymbols(ParseSymbol(Scan::literal1));
|
|
insertSymbols(ParseSymbol(Scan::numeral1));
|
|
expect(Scan::leftbracket1);
|
|
removeSymbols(ParseSymbol(Scan::numeral1));
|
|
insertSymbols(ParseSymbol(Scan::rightbracket1));
|
|
simpleExpression(expressionResult);
|
|
removeSymbols(ParseSymbol(Scan::literal1));
|
|
removeSymbols(ParseSymbol(Scan::rightbracket1));
|
|
if(isInError())return;
|
|
if(expressionResult>0xFF){error(ValueOutOfRangeForInstruction);return;}
|
|
insertSymbols(ParseSymbol(Scan::comma1));
|
|
expect(Scan::rightbracket1);
|
|
removeSymbols(ParseSymbol(Scan::comma1));
|
|
insertSymbols(ParseSymbol(Scan::numeral1));
|
|
insertSymbols(ParseSymbol(Scan::literal1));
|
|
expect(Scan::comma1);
|
|
removeSymbols(ParseSymbol(Scan::numeral1));
|
|
insertSymbols(mStatementSymbols);
|
|
simpleExpression(maskValue);
|
|
removeSymbols(ParseSymbol(Scan::literal1));
|
|
removeSymbols(mStatementSymbols);
|
|
if(maskValue>0xFF){error(ValueOutOfRangeForInstruction);return;}
|
|
emit(addressMode->opcode());
|
|
emit(loByte(expressionResult));
|
|
emit(BYTE(loByte(maskValue)));
|
|
}
|
|
else
|
|
{
|
|
if(!currentSymbol->hasIndexedMode(indexForm)){error(IllegalAddressingModeForMnemonic);return;}
|
|
insertSymbols(ParseSymbol(Scan::comma1));
|
|
parseIndex(currentSymbol,addressMode,expressionResult);
|
|
removeSymbols(ParseSymbol(Scan::comma1));
|
|
insertSymbols(ParseSymbol(Scan::numeral1));
|
|
expect(Scan::comma1);
|
|
maskValue=mNumeralValue;
|
|
removeSymbols(ParseSymbol(Scan::numeral1));
|
|
insertSymbols(mStatementSymbols);
|
|
expect(Scan::numeral1);
|
|
removeSymbols(mStatementSymbols);
|
|
if(isInError())return;
|
|
if(addressMode->prebyte())emit(addressMode->prebyte());
|
|
emit(addressMode->opcode());
|
|
emit(loByte(expressionResult));
|
|
emit(BYTE(loByte(maskValue)));
|
|
}
|
|
}
|
|
|
|
void Parse::parseIndex(SmartPointer<Symbol> ¤tSymbol,SmartPointer<AddressMode> &addressMode,DWORD &expressionResult)
|
|
{
|
|
SmartPointer<Symbol> nextSymbol;
|
|
WORD indexForm;
|
|
|
|
insertSymbols(ParseSymbol(Scan::name1));
|
|
expect(Scan::name1);
|
|
nextSymbol=mCurrentSymbol;
|
|
if(!nextSymbol.isOkay())
|
|
{
|
|
error(ExpectedIndexRegister);
|
|
removeSymbols(ParseSymbol(Scan::name1));
|
|
return;
|
|
}
|
|
insertSymbols(ParseSymbol(Scan::comma1));
|
|
expect(Scan::name1);
|
|
removeSymbols(ParseSymbol(Scan::comma1));
|
|
insertSymbols(mSimpleExpressionSymbols);
|
|
removeSymbols(ParseSymbol(Scan::name1));
|
|
this->nextSymbol();
|
|
removeSymbols(mSimpleExpressionSymbols);
|
|
insertSymbols(mStatementSymbols);
|
|
simpleExpression(expressionResult);
|
|
removeSymbols(mStatementSymbols);
|
|
if(!inRange(expressionResult,MaxBit8))error(ValueOutOfRangeForInstruction);
|
|
else if(int(Scan::ix1)==nextSymbol->identifier())
|
|
{
|
|
currentSymbol->hasIndexedMode(indexForm);
|
|
addressMode=&(*currentSymbol)[indexForm];
|
|
}
|
|
else if(int(Scan::iy1)==nextSymbol->identifier())
|
|
{
|
|
currentSymbol->hasPreByte(indexForm);
|
|
addressMode=&(*currentSymbol)[indexForm];
|
|
}
|
|
else error(ExpectedIndexRegister);
|
|
}
|
|
|
|
void Parse::parseRelativeMask(SmartPointer<Symbol> ¤tSymbol,Scan::ScanSymbols peekSymbol)
|
|
{
|
|
SmartPointer<AddressMode> addressMode;
|
|
SmartPointer<Symbol> nextSymbol;
|
|
DWORD expressionResult(0);
|
|
WORD indexForm(0);
|
|
BYTE maskValue;
|
|
BOOL needsFixup(FALSE);
|
|
Label branchLabel;
|
|
Equate branchEquate;
|
|
|
|
if(Scan::leftbracket1==peekSymbol)
|
|
{
|
|
if(!currentSymbol->hasDirectMode(indexForm)){error(IllegalAddressingModeForMnemonic);return;}
|
|
addressMode=&(*currentSymbol)[indexForm];
|
|
insertSymbols(ParseSymbol(Scan::leftbracket1));
|
|
expect(currentSymbolType());
|
|
removeSymbols(ParseSymbol(Scan::leftbracket1));
|
|
insertSymbols(ParseSymbol(Scan::numeral1));
|
|
expect(Scan::leftbracket1);
|
|
removeSymbols(ParseSymbol(Scan::numeral1));
|
|
expressionResult=mNumeralValue;
|
|
insertSymbols(ParseSymbol(Scan::rightbracket1));
|
|
expect(Scan::numeral1);
|
|
removeSymbols(ParseSymbol(Scan::rightbracket1));
|
|
insertSymbols(ParseSymbol(Scan::comma1));
|
|
expect(Scan::rightbracket1);
|
|
removeSymbols(ParseSymbol(Scan::comma1));
|
|
insertSymbols(ParseSymbol(Scan::numeral1));
|
|
expect(Scan::comma1);
|
|
removeSymbols(ParseSymbol(Scan::numeral1));
|
|
maskValue=mNumeralValue;
|
|
insertSymbols(ParseSymbol(Scan::comma1));
|
|
expect(Scan::numeral1);
|
|
removeSymbols(ParseSymbol(Scan::comma1));
|
|
emit(addressMode->opcode());
|
|
emit(loByte(expressionResult));
|
|
emit(maskValue);
|
|
}
|
|
else
|
|
{
|
|
if(!currentSymbol->hasIndexedMode(indexForm)){error(IllegalAddressingModeForMnemonic);return;}
|
|
addressMode=&(*currentSymbol)[indexForm];
|
|
insertSymbols(ParseSymbol(Scan::name1));
|
|
expect(Scan::name1);
|
|
nextSymbol=mCurrentSymbol;
|
|
if(!nextSymbol.isOkay())
|
|
{
|
|
error(ExpectedIndexRegister);
|
|
removeSymbols(ParseSymbol(Scan::name1));
|
|
return;
|
|
}
|
|
insertSymbols(ParseSymbol(Scan::comma1));
|
|
expect(Scan::name1);
|
|
removeSymbols(ParseSymbol(Scan::comma1));
|
|
insertSymbols(mSimpleExpressionSymbols);
|
|
removeSymbols(ParseSymbol(Scan::name1));
|
|
this->nextSymbol();
|
|
removeSymbols(mSimpleExpressionSymbols);
|
|
insertSymbols(ParseSymbol(Scan::comma1));
|
|
insertSymbols(ParseSymbol(Scan::literal1));
|
|
simpleExpression(expressionResult);
|
|
removeSymbols(ParseSymbol(Scan::literal1));
|
|
removeSymbols(ParseSymbol(Scan::comma1));
|
|
if(!inRange(expressionResult,MaxBit8))error(ValueOutOfRangeForInstruction);
|
|
else if(int(Scan::ix1)==nextSymbol->identifier())
|
|
{
|
|
emit(addressMode->opcode());
|
|
emit(loByte(expressionResult));
|
|
}
|
|
else if(int(Scan::iy1)==nextSymbol->identifier())
|
|
{
|
|
currentSymbol->hasPreByte(indexForm);
|
|
addressMode=&(*currentSymbol)[indexForm];
|
|
emit(addressMode->prebyte());
|
|
emit(addressMode->opcode());
|
|
emit(loByte(expressionResult));
|
|
}
|
|
else error(ExpectedIndexRegister);
|
|
insertSymbols(ParseSymbol(Scan::numeral1));
|
|
expect(Scan::comma1);
|
|
maskValue=mNumeralValue;
|
|
emit(maskValue);
|
|
removeSymbols(ParseSymbol(Scan::numeral1));
|
|
maskValue=mNumeralValue;
|
|
insertSymbols(ParseSymbol(Scan::comma1));
|
|
expect(currentSymbolType());
|
|
removeSymbols(ParseSymbol(Scan::comma1));
|
|
}
|
|
parseBranch();
|
|
}
|
|
|
|
void Parse::parseBranch(void)
|
|
{
|
|
Label branchLabel;
|
|
Equate branchEquate;
|
|
|
|
insertSymbols(ParseSymbol(Scan::literal1));
|
|
expect(currentSymbolType());
|
|
removeSymbols(ParseSymbol(Scan::literal1));
|
|
if(isInError())return;
|
|
branchLabel.strLabel(mLiteralValue);
|
|
branchEquate.strLabel(mLiteralValue);
|
|
insertSymbols(mStatementSymbols);
|
|
expect(Scan::literal1);
|
|
removeSymbols(mStatementSymbols);
|
|
if(!mLabelGenerator.find(branchLabel)||Label::Ignore==branchLabel.disposition())
|
|
{
|
|
if(mEquates.find(branchEquate))
|
|
{
|
|
if(Equate::Reference==branchEquate.disposition())
|
|
{
|
|
if(!jumpInRange(-(codePointer().position()-branchEquate.value())-1))error(BranchOutOfRange);
|
|
else emit(BYTE(-(codePointer().position()-branchEquate.value())-1));
|
|
}
|
|
else
|
|
{
|
|
if(!jumpInRange((branchEquate.value()-codePointer().origin())))error(BranchOutOfRange);
|
|
else emit(BYTE((branchEquate.value()-codePointer().position()-1)));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
branchLabel.offset(codePointer().position());
|
|
branchLabel.disposition(Label::Reference);
|
|
mLabelGenerator.insert(branchLabel);
|
|
mFixups.insert(&Fixup(branchLabel.strLabel(),outputView().tell(),codePointer().position(),Fixup::Label));
|
|
emit(BYTE(0xCC));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(Label::Reference==branchLabel.disposition())
|
|
{
|
|
mFixups.insert(&Fixup(branchLabel.strLabel(),outputView().tell(),codePointer().position(),Fixup::Label));
|
|
emit(BYTE(0xCC));
|
|
}
|
|
else
|
|
{
|
|
if(!jumpInRange(-(codePointer().position()-branchLabel.offset())-1))error(BranchOutOfRange);
|
|
else emit(BYTE(-(codePointer().position()-branchLabel.offset())-1));
|
|
}
|
|
}
|
|
}
|
|
|
|
void Parse::parseIndexed(SmartPointer<Symbol> ¤tSymbol,WORD indexForm)
|
|
{
|
|
SmartPointer<AddressMode> addressMode;
|
|
DWORD expressionResult(0);
|
|
|
|
parseIndex(currentSymbol,addressMode,expressionResult);
|
|
if(isInError())return;
|
|
if(addressMode->prebyte())emit(addressMode->prebyte());
|
|
emit(addressMode->opcode());
|
|
emit(loByte(expressionResult));
|
|
}
|
|
|
|
void Parse::parseLabelImmediate(SmartPointer<Symbol> ¤tSymbol,WORD indexForm)
|
|
{
|
|
Equate equate;
|
|
Label label;
|
|
|
|
AddressMode &addressMode=(*currentSymbol)[indexForm];
|
|
insertSymbols(ParseSymbol(Scan::literal1));
|
|
expect(currentSymbolType());
|
|
removeSymbols(ParseSymbol(Scan::literal1));
|
|
equate.strLabel(mLiteralValue);
|
|
label.strLabel(mLiteralValue);
|
|
insertSymbols(mStatementSymbols);
|
|
expect(Scan::literal1);
|
|
removeSymbols(mStatementSymbols);
|
|
if(addressMode.prebyte())emit(addressMode.prebyte());
|
|
emit(addressMode.opcode());
|
|
if(!mLabelGenerator.find(label)||Label::Ignore==label.disposition())
|
|
{
|
|
Equate equate(label.strLabel());
|
|
if(mEquates.find(equate))
|
|
{
|
|
if(!emitEquate(currentSymbol,equate))return;
|
|
}
|
|
else
|
|
{
|
|
label.offset(codePointer().position());
|
|
label.disposition(Label::Reference);
|
|
mLabelGenerator.insert(label);
|
|
insertLabelFixup(currentSymbol,label);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(Label::Reference==label.disposition())insertLabelFixup(currentSymbol,label);
|
|
else emitLabel(currentSymbol,label);
|
|
}
|
|
}
|
|
|
|
void Parse::parseLabelExtended(SmartPointer<Symbol> ¤tSymbol,WORD indexForm)
|
|
{
|
|
Label branchLabel;
|
|
Fixup fixup;
|
|
|
|
AddressMode &addressMode=(*currentSymbol)[indexForm];
|
|
insertSymbols(ParseSymbol(Scan::literal1));
|
|
expect(currentSymbolType());
|
|
removeSymbols(ParseSymbol(Scan::literal1));
|
|
branchLabel.strLabel(mLiteralValue);
|
|
insertSymbols(mStatementSymbols);
|
|
expect(Scan::literal1);
|
|
removeSymbols(mStatementSymbols);
|
|
if(addressMode.prebyte())emit(addressMode.prebyte());
|
|
emit(addressMode.opcode());
|
|
if(!mLabelGenerator.find(branchLabel)||Label::Ignore==branchLabel.disposition())
|
|
{
|
|
Equate equate(branchLabel.strLabel());
|
|
if(mEquates.find(equate))
|
|
{
|
|
if(!inRange(equate.value(),MaxBit16)){error(ValueOutOfRangeForInstruction);return;}
|
|
emit(WORD(equate.value()));
|
|
}
|
|
else
|
|
{
|
|
branchLabel.offset(codePointer().position());
|
|
branchLabel.disposition(Label::Reference);
|
|
mLabelGenerator.insert(branchLabel);
|
|
mFixups.insert(&Fixup(branchLabel.strLabel(),outputView().tell(),codePointer().position(),Fixup::Label,Fixup::Bit16,Fixup::Absolute));
|
|
emit(BYTE(0xCC));
|
|
emit(BYTE(0xCC));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(Label::Reference==branchLabel.disposition())
|
|
{
|
|
mFixups.insert(&Fixup(branchLabel.strLabel(),outputView().tell(),codePointer().position(),Fixup::Label,Fixup::Bit16,Fixup::Absolute));
|
|
emit(BYTE(0xCC));
|
|
emit(BYTE(0xCC));
|
|
}
|
|
else
|
|
{
|
|
if(!inRange(branchLabel.offset(),MaxBit16)){error(ValueOutOfRangeForInstruction);return;}
|
|
emit(WORD(branchLabel.offset()));
|
|
}
|
|
}
|
|
}
|
|
|
|
void Parse::parseLabelDirect(SmartPointer<Symbol> ¤tSymbol,WORD indexForm)
|
|
{
|
|
Label branchLabel;
|
|
Fixup fixup;
|
|
|
|
AddressMode &addressMode=(*currentSymbol)[indexForm];
|
|
insertSymbols(ParseSymbol(Scan::literal1));
|
|
expect(currentSymbolType());
|
|
removeSymbols(ParseSymbol(Scan::literal1));
|
|
branchLabel.strLabel(mLiteralValue);
|
|
insertSymbols(mStatementSymbols);
|
|
expect(Scan::literal1);
|
|
removeSymbols(mStatementSymbols);
|
|
if(addressMode.prebyte())emit(addressMode.prebyte());
|
|
emit(addressMode.opcode());
|
|
if(!mLabelGenerator.find(branchLabel)||Label::Ignore==branchLabel.disposition())
|
|
{
|
|
Equate equate(branchLabel.strLabel());
|
|
if(mEquates.find(equate))
|
|
{
|
|
if(!inRange(equate.value(),MaxBit8)){error(ValueOutOfRangeForInstruction);return;}
|
|
emit(BYTE(equate.value()));
|
|
}
|
|
else
|
|
{
|
|
branchLabel.offset(codePointer().position());
|
|
branchLabel.disposition(Label::Reference);
|
|
mLabelGenerator.insert(branchLabel);
|
|
mFixups.insert(&Fixup(branchLabel.strLabel(),outputView().tell(),codePointer().position(),Fixup::Label,Fixup::Bit8,Fixup::Absolute));
|
|
emit(BYTE(0xCC));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(Label::Reference==branchLabel.disposition())
|
|
{
|
|
mFixups.insert(&Fixup(branchLabel.strLabel(),outputView().tell(),codePointer().position(),Fixup::Label,Fixup::Bit8,Fixup::Absolute));
|
|
emit(BYTE(0xCC));
|
|
}
|
|
else
|
|
{
|
|
if(!inRange(branchLabel.offset(),MaxBit16)){error(ValueOutOfRangeForInstruction);return;}
|
|
emit(BYTE(branchLabel.offset()));
|
|
}
|
|
}
|
|
}
|
|
|
|
void Parse::parseRelative(SmartPointer<Symbol> ¤tSymbol,WORD indexForm)
|
|
{
|
|
BOOL needsFixup(FALSE);
|
|
Label branchLabel;
|
|
Equate branchEquate;
|
|
|
|
AddressMode &addressMode=(*currentSymbol)[indexForm];
|
|
if(addressMode.prebyte())emit(addressMode.prebyte());
|
|
emit(addressMode.opcode());
|
|
parseBranch();
|
|
}
|
|
|
|
void Parse::simpleExpression(DWORD &expressionResult)
|
|
{
|
|
insertSymbols(mAddSymbols);
|
|
insertSymbols(mTermSymbols);
|
|
insertSymbols(mSignSymbols);
|
|
syntaxCheck();
|
|
removeSymbols(mSignSymbols);
|
|
if(symbolIn(mSignSymbols))
|
|
{
|
|
DWORD indexItem;
|
|
Scan::ScanSymbols currSymbol(mCurrentSymbolType);
|
|
expect(mCurrentSymbolType);
|
|
if(Scan::minus1==currSymbol)expressionResult=-expressionResult;
|
|
removeSymbols(mTermSymbols);
|
|
}
|
|
else
|
|
{
|
|
removeSymbols(mTermSymbols);
|
|
expressionResult=term();
|
|
}
|
|
while(symbolIn(mAddSymbols))
|
|
{
|
|
DWORD localExpression;
|
|
Scan::ScanSymbols currSymbol(mCurrentSymbolType);
|
|
insertSymbols(mTermSymbols);
|
|
expect(mCurrentSymbolType);
|
|
removeSymbols(mTermSymbols);
|
|
localExpression=term();
|
|
if(Scan::plus1==currSymbol)expressionResult+=localExpression;
|
|
else if(Scan::minus1==currSymbol)expressionResult-=localExpression;
|
|
else syntaxError();
|
|
}
|
|
removeSymbols(mAddSymbols);
|
|
}
|
|
|
|
DWORD Parse::term(void)
|
|
{
|
|
DWORD termResult;
|
|
|
|
insertSymbols(mMathSymbols);
|
|
factor(termResult);
|
|
while(symbolIn(mMathSymbols))
|
|
{
|
|
DWORD localTerm;
|
|
Scan::ScanSymbols currSymbol(mCurrentSymbolType);
|
|
insertSymbols(mFactorSymbols);
|
|
expect(mCurrentSymbolType);
|
|
removeSymbols(mFactorSymbols);
|
|
factor(localTerm);
|
|
if(Scan::asterisk1==currSymbol)termResult*=localTerm;
|
|
else if(Scan::divide1==currSymbol)
|
|
{
|
|
if(!localTerm)error(DivideByZero);
|
|
else termResult/=localTerm;
|
|
}
|
|
}
|
|
removeSymbols(mMathSymbols);
|
|
return termResult;
|
|
}
|
|
|
|
void Parse::factor(DWORD &expressionResult)
|
|
{
|
|
if(Scan::numeral1==mCurrentSymbolType)
|
|
{
|
|
expressionResult=mNumeralValue;
|
|
expect(mCurrentSymbolType);
|
|
}
|
|
else if(Scan::leftparen1==mCurrentSymbolType)
|
|
{
|
|
insertSymbols(ParseSymbol(Scan::rightparen1));
|
|
insertSymbols(mExpressionSymbols);
|
|
expect(mCurrentSymbolType);
|
|
removeSymbols(mExpressionSymbols);
|
|
expression(expressionResult);
|
|
removeSymbols(ParseSymbol(Scan::rightparen1));
|
|
expect(Scan::rightparen1);
|
|
}
|
|
else if(Scan::literal1==mCurrentSymbolType)
|
|
{
|
|
Equate equate(mLiteralValue);
|
|
if(!mEquates.searchItem(equate))error(SymbolNotDefined,mLiteralValue);
|
|
else expressionResult=equate.value();
|
|
expect(mCurrentSymbolType);
|
|
}
|
|
else syntaxError();
|
|
}
|
|
|
|
void Parse::expression(DWORD &expressionResult)
|
|
{
|
|
simpleExpression(expressionResult);
|
|
}
|
|
|
|
BOOL Parse::emitEquate(SmartPointer<Symbol> ¤tSymbol,Equate &equate)
|
|
{
|
|
if(Instruction::SingleByte==currentSymbol->registerLength())
|
|
{
|
|
if(!inRange(equate.value(),MaxBit8)){error(ValueOutOfRangeForInstruction);return FALSE;}
|
|
emit(BYTE(equate.value()));
|
|
}
|
|
else
|
|
{
|
|
if(!inRange(equate.value(),MaxBit16)){error(ValueOutOfRangeForInstruction);return FALSE;}
|
|
emit(WORD(equate.value()));
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL Parse::emitLabel(SmartPointer<Symbol> ¤tSymbol,Label &label)
|
|
{
|
|
if(Instruction::SingleByte==currentSymbol->registerLength())
|
|
{
|
|
if(!inRange(label.offset(),MaxBit8)){error(ValueOutOfRangeForInstruction);return FALSE;}
|
|
emit(BYTE(label.offset()));
|
|
}
|
|
else
|
|
{
|
|
if(!inRange(label.offset(),MaxBit16)){error(ValueOutOfRangeForInstruction);return FALSE;}
|
|
emit(WORD(label.offset()));
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void Parse::insertLabelFixup(SmartPointer<Symbol> ¤tSymbol,Label &label)
|
|
{
|
|
if(Instruction::SingleByte==currentSymbol->registerLength())
|
|
{
|
|
mFixups.insert(&Fixup(label.strLabel(),outputView().tell(),codePointer().position(),Fixup::Label,Fixup::Bit8,Fixup::Absolute));
|
|
emit(BYTE(0xCC));
|
|
}
|
|
else
|
|
{
|
|
mFixups.insert(&Fixup(label.strLabel(),outputView().tell(),codePointer().position(),Fixup::Label,Fixup::Bit16,Fixup::Absolute));
|
|
emit(BYTE(0xCC));
|
|
emit(BYTE(0xCC));
|
|
}
|
|
}
|
|
|
|
WORD Parse::nextSymbol(void)
|
|
{
|
|
mNumeralValue=0;
|
|
mCurrentSymbolType=Scan::unknown1;
|
|
mCurrentSymbol=(Symbol*)0;
|
|
if(0xFFFF==read((int&)mCurrentSymbolType))return FALSE;
|
|
while(Scan::newline1==mCurrentSymbolType)
|
|
{
|
|
if(0xFFFF==read((int&)mCurrentSymbolType))return FALSE;
|
|
mLineNumber++;
|
|
}
|
|
if(Scan::numeral1==mCurrentSymbolType)read((int&)mNumeralValue);
|
|
else if(Scan::name1==mCurrentSymbolType)
|
|
{
|
|
int address;
|
|
if(0xFFFF==read(address))return FALSE;
|
|
mCurrentSymbol=(Symbol*)address;
|
|
}
|
|
else if(Scan::label1==mCurrentSymbolType)read(mLiteralValue);
|
|
else if(Scan::literal1==mCurrentSymbolType)read(mLiteralValue);
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL Parse::isInEquates(const String &strLabel)
|
|
{
|
|
Equate equate(strLabel);
|
|
return mEquates.find(equate);
|
|
}
|
|
|
|
BOOL Parse::isInLabels(const String &strLabel)
|
|
{
|
|
Label label(strLabel);
|
|
return mLabelGenerator.find(label);
|
|
}
|
|
|
|
|
|
BOOL Parse::symbolIn(Block<ParseSymbol> &parseSymbols)const
|
|
{
|
|
ParseSymbol currentSymbol(mCurrentSymbolType);
|
|
int size((size_t)parseSymbols.size());
|
|
for(int index=0;index<size;index++)if(currentSymbol==parseSymbols[index])return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL Parse::symbolIn(const ParseSymbol &parseSymbol)const
|
|
{
|
|
if(ParseSymbol(mCurrentSymbolType)==parseSymbol)return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL Parse::peekSymbolIn(const ParseSymbol &parseSymbol)
|
|
{
|
|
Scan::ScanSymbols peekSymbol;
|
|
|
|
peek((int&)peekSymbol);
|
|
if(ParseSymbol(peekSymbol)==parseSymbol)return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
void Parse::syntaxError(void)
|
|
{
|
|
if(!isInError())
|
|
{
|
|
mLastMessage=String("<Syntax error.>");
|
|
mLastLineNumber=mLineNumber;
|
|
mIsInError=TRUE;
|
|
}
|
|
while(!mParseSymbols.symbolIn(mCurrentSymbolType)&&nextSymbol());
|
|
}
|
|
|
|
void Parse::syntaxError(int symbol)
|
|
{
|
|
errorExpect(symbol);
|
|
while(!mParseSymbols.symbolIn(mCurrentSymbolType)&&nextSymbol());
|
|
}
|
|
|
|
void Parse::errorExpect(Symbol::SymbolType symbolType)
|
|
{
|
|
if(isInError())return;
|
|
switch(symbolType)
|
|
{
|
|
case Symbol::ConstantSymbol :
|
|
mLastMessage=String("<Expected Constant.>");
|
|
mLastLineNumber=mLineNumber;
|
|
break;
|
|
case Symbol::KeywordSymbol :
|
|
mLastMessage=String("<Expected Keyword.>");
|
|
mLastLineNumber=mLineNumber;
|
|
break;
|
|
case Symbol::RegisterSymbol :
|
|
mLastMessage=String("<Expected Register (ix,iy).>");
|
|
mLastLineNumber=mLineNumber;
|
|
break;
|
|
case Symbol::DirectiveSymbol :
|
|
mLastMessage=String("<Expected Directive.>");
|
|
mLastLineNumber=mLineNumber;
|
|
break;
|
|
case Symbol::UserSymbol :
|
|
mLastMessage=String("<Expected User Defined Type.>");
|
|
mLastLineNumber=mLineNumber;
|
|
break;
|
|
}
|
|
mIsInError=TRUE;
|
|
}
|
|
|
|
void Parse::errorExpect(int scanSymbol)
|
|
{
|
|
if(isInError())return;
|
|
switch(scanSymbol)
|
|
{
|
|
case Scan::name1 :
|
|
mLastMessage=String("<Expected Keyword.>");
|
|
mLastLineNumber=mLineNumber;
|
|
break;
|
|
case Scan::comma1 :
|
|
mLastMessage=String("<Expected ','.>");
|
|
mLastLineNumber=mLineNumber;
|
|
break;
|
|
case Scan::leftbracket1 :
|
|
mLastMessage=String("<Expected '['.>");
|
|
mLastLineNumber=mLineNumber;
|
|
break;
|
|
case Scan::rightbracket1 :
|
|
mLastMessage=String("<Expected ']'.>");
|
|
mLastLineNumber=mLineNumber;
|
|
break;
|
|
default :
|
|
mLastMessage=String("<Expected symbol.>");
|
|
mLastLineNumber=mLineNumber;
|
|
break;
|
|
}
|
|
mIsInError=TRUE;
|
|
}
|
|
|
|
void Parse::error(ErrorCode errorCode,const String &strExtraMessage)
|
|
{
|
|
if(isInError())return;
|
|
switch(errorCode)
|
|
{
|
|
case OperandSizeMustMatch :
|
|
mLastMessage=String("Operand size must match.");
|
|
mLastLineNumber=mLineNumber;
|
|
break;
|
|
case IllegalAddressingModeForMnemonic :
|
|
mLastMessage=String("Illegal addressing mode requested for mnemonic.");
|
|
mLastLineNumber=mLineNumber;
|
|
break;
|
|
case ExpectedIndexRegister :
|
|
mLastMessage=String("Expected index register {ix/iy}.");
|
|
mLastLineNumber=mLineNumber;
|
|
break;
|
|
case ValueOutOfRangeForInstruction :
|
|
mLastMessage=String("Value out of range for instruction.");
|
|
mLastLineNumber=mLineNumber;
|
|
break;
|
|
case SymbolAlreadyDifferentKind :
|
|
if(!strExtraMessage.isNull())mLastMessage=String("Symbol already different kind ")+String("'")+strExtraMessage+String("'.");
|
|
else mLastMessage=String("Symbol already different kind.");
|
|
mLastLineNumber=mLineNumber;
|
|
case SymbolAlreadyDefined :
|
|
if(!strExtraMessage.isNull())mLastMessage=String("Symbol already defined ")+String("'")+strExtraMessage+String("'.");
|
|
else mLastMessage=String("Symbol already defined.");
|
|
mLastLineNumber=mLineNumber;
|
|
break;
|
|
case SymbolNotDefined :
|
|
if(!strExtraMessage.isNull())mLastMessage=String("Undefined symbol ")+String("'")+strExtraMessage+String("'.");
|
|
else mLastMessage=String("Undefined symbol.");
|
|
mLastLineNumber=mLineNumber;
|
|
break;
|
|
case BranchOutOfRange :
|
|
mLastMessage=String("<Branch is out of range.>");
|
|
mLastLineNumber=mLineNumber;
|
|
break;
|
|
case DivideByZero :
|
|
mLastMessage=String("<Divide by zero.>");
|
|
mLastLineNumber=mLineNumber;
|
|
break;
|
|
default :
|
|
mLastMessage=String("<Unknown error interpreting mnemonic.>");
|
|
mLastLineNumber=mLineNumber;
|
|
break;
|
|
}
|
|
mIsInError=TRUE;
|
|
}
|
|
|
|
void Parse::createStatementSymbols(void)
|
|
{
|
|
mStatementSymbols.remove();
|
|
mStatementSymbols.insert(&ParseSymbol(Scan::name1));
|
|
mStatementSymbols.insert(&ParseSymbol(Scan::label1));
|
|
mStatementSymbols.insert(&ParseSymbol(Scan::literal1));
|
|
mStatementSymbols.insert(&ParseSymbol(Scan::origin1));
|
|
}
|
|
|
|
void Parse::createSimpleExpressionSymbols(void)
|
|
{
|
|
mSimpleExpressionSymbols.remove();
|
|
mSimpleExpressionSymbols.insert(&ParseSymbol(Scan::plus1));
|
|
mSimpleExpressionSymbols.insert(&ParseSymbol(Scan::minus1));
|
|
mSimpleExpressionSymbols.insert(&ParseSymbol(Scan::leftparen1));
|
|
mSimpleExpressionSymbols.insert(&ParseSymbol(Scan::numeral1));
|
|
}
|
|
|
|
void Parse::createMathSymbols(void)
|
|
{
|
|
mMathSymbols.remove();
|
|
mMathSymbols.insert(&ParseSymbol(Scan::asterisk1));
|
|
mMathSymbols.insert(&ParseSymbol(Scan::divide1));
|
|
}
|
|
|
|
void Parse::createTermSymbols(void)
|
|
{
|
|
mTermSymbols.remove();
|
|
mTermSymbols.insert(&ParseSymbol(Scan::leftparen1));
|
|
mTermSymbols.insert(&ParseSymbol(Scan::numeral1));
|
|
}
|
|
|
|
void Parse::createFactorSymbols(void)
|
|
{
|
|
mFactorSymbols.remove();
|
|
mFactorSymbols.insert(&ParseSymbol(Scan::leftparen1));
|
|
mFactorSymbols.insert(&ParseSymbol(Scan::numeral1));
|
|
}
|
|
|
|
void Parse::createAddSymbols(void)
|
|
{
|
|
mAddSymbols.remove();
|
|
mAddSymbols.insert(&ParseSymbol(Scan::minus1));
|
|
mAddSymbols.insert(&ParseSymbol(Scan::plus1));
|
|
}
|
|
|
|
void Parse::createSignSymbols(void)
|
|
{
|
|
mSignSymbols.remove();
|
|
mSignSymbols.insert(&ParseSymbol(Scan::minus1));
|
|
mSignSymbols.insert(&ParseSymbol(Scan::plus1));
|
|
}
|
|
|
|
void Parse::createExpressionSymbols(void)
|
|
{
|
|
mExpressionSymbols.remove();
|
|
mExpressionSymbols.insert(&ParseSymbol(Scan::leftparen1));
|
|
mExpressionSymbols.insert(&ParseSymbol(Scan::minus1));
|
|
mExpressionSymbols.insert(&ParseSymbol(Scan::plus1));
|
|
mExpressionSymbols.insert(&ParseSymbol(Scan::numeral1));
|
|
}
|
|
|
|
BOOL Parse::resolve(void)
|
|
{
|
|
BYTE charByte;
|
|
|
|
for(int index=0;index<mFixups.size();index++)
|
|
{
|
|
Fixup &fixup=mFixups[index];
|
|
Label label(fixup.strLabel());
|
|
Equate equate(fixup.strLabel());
|
|
|
|
if(!mLabelGenerator.find(label))
|
|
{
|
|
if(!mEquates.find(equate)){error(SymbolNotDefined);return FALSE;}
|
|
if(Fixup::Label==fixup.kind()){error(SymbolAlreadyDifferentKind,equate.strLabel());return FALSE;}
|
|
outputView().seek(fixup.offset(),PureViewOfFile::SeekSet);
|
|
if(Fixup::Bit8==fixup.bitCount())outputView().write(BYTE(fixup.offset()));
|
|
else outputView().write(WORD(fixup.offset()));
|
|
}
|
|
else
|
|
{
|
|
if(Label::Ignore==label.disposition())
|
|
{
|
|
if(!mEquates.find(equate)){error(SymbolNotDefined);return FALSE;}
|
|
outputView().seek(fixup.offset(),PureViewOfFile::SeekSet);
|
|
if(Fixup::Relative==fixup.addressMode())
|
|
{
|
|
if(Equate::Reference==equate.disposition())
|
|
{
|
|
if(!jumpInRange(equate.value()-fixup.position()-1)){error(BranchOutOfRange);return FALSE;}
|
|
if(Fixup::Bit8==fixup.bitCount())emit(BYTE(equate.value()-fixup.position()-1));
|
|
else emit(WORD(equate.value()-fixup.position()-1));
|
|
}
|
|
else
|
|
{
|
|
if(!jumpInRange(equate.value())){error(BranchOutOfRange);return FALSE;}
|
|
if(Fixup::Bit8==fixup.bitCount())emit(BYTE(equate.value()));
|
|
else emit(WORD(equate.value()));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(Fixup::Bit8==fixup.bitCount())emit(BYTE(equate.value()));
|
|
else emit(WORD(equate.value()));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(Fixup::Equate==fixup.kind()){error(SymbolAlreadyDifferentKind,label.strLabel());return FALSE;}
|
|
if(Label::Reference==label.disposition()){error(SymbolNotDefined,label.strLabel());return FALSE;}
|
|
outputView().seek(fixup.offset(),PureViewOfFile::SeekSet);
|
|
if(Fixup::Relative==fixup.addressMode())
|
|
{
|
|
if(!jumpInRange(label.offset()-fixup.position()-1)){error(BranchOutOfRange);return FALSE;}
|
|
if(Fixup::Bit8==fixup.bitCount())emit(BYTE(label.offset()-fixup.position()-1));
|
|
else emit(WORD(label.offset()-fixup.position()-1));
|
|
}
|
|
else
|
|
{
|
|
if(Fixup::Bit8==fixup.bitCount())emit(BYTE(label.offset()));
|
|
else emit(WORD(label.offset()));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|