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

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&&currentSymbol->hasImmediateMode(indexForm))parseLabelImmediate(currentSymbol,indexForm);
else if(Scan::literal1==peekSymbol&&currentSymbol->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> &currentSymbol,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> &currentSymbol,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> &currentSymbol,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> &currentSymbol,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> &currentSymbol,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> &currentSymbol,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> &currentSymbol,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> &currentSymbol,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> &currentSymbol,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> &currentSymbol,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> &currentSymbol,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> &currentSymbol,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> &currentSymbol,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> &currentSymbol,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;
}