Using AssemblyParser
in Assembler::assemble
causes "unknown externals" errors, when used correctly (with the correct arguments). However if I remove the arguments (which is incorrect), I get a very sensible error: 'AssemblyParser': no appropriate default constructor available
I am definitely including the right file, because VS knows about the symbol (AssemblyParser
), knows whether I'm giving the correct arguments.
Here's the errors I get when including the correct arguments (as in the code below)
1>Assembler.obj : error LNK2019: unresolved external symbol "public: __thiscall AssemblyParser::AssemblyParser(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class SymbolTable &)" (??0AssemblyParser@@QAE@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AAVSymbolTable@@@Z) referenced in function "public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall Assembler::assemble(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,bool)" (?assemble@Assembler@@QAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V23@_N@Z)
1>Assembler.obj : error LNK2019: unresolved external symbol "public: class AssemblerInstruction * __thiscall AssemblyParser::getInstructionPtr(void)" (?getInstructionPtr@AssemblyParser@@QAEPAVAssemblerInstruction@@XZ) referenced in function "public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall Assembler::assemble(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,bool)" (?assemble@Assembler@@QAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V23@_N@Z)
1>~\HackAssembler\Debug\HackAssembler.exe : fatal error LNK1120: 2 unresolved externals
Here's the use of AssemblyParser
that causes the error (without the indicated line, the build succeeds)
string Assembler::assemble(std::string inputFileName, bool writeFile)
{
ifstream inputFile;
ofstream outputFile;
string output;
// open file
inputFile.open(inputFileName);
if (!inputFile.is_open())
throw exception("inputFile didn't open for writing");
string line;
int lineNum = 0;
// FIRST PASS
while (getline(inputFile, line)) {
if (line.find("(") == 0) {
line = line.substr(1, line.length() - 2); // length - 1 is last char
mTable.add(line, lineNum);
lineNum++;
}
}
// SECOND PASS
while (getline(inputFile, line)) {
// skip blank lines and comment lines
if (line.find("//") == 0 || line.find(" ") == 0)
continue;
string newLine = AssemblyParser(line, mTable).getInstructionPtr()->getMachineCode(); // *** THIS LINE ***
}
inputFile.close();
return output;
}
Here's the declaration of AssemblyParser
. (let me know if you want to see the definitions as well)
class AssemblyParser
{
public:
AssemblyParser(std::string assemblyCode, SymbolTable& table);
std::unique_ptr<AssemblerInstruction> getUniqueInstructionPtr();
AssemblerInstruction* getInstructionPtr();
private:
AssemblerInstruction mInstruction;
SymbolTable mSymbolTable;
std::unique_ptr<AssemblerInstruction> mUniqueInstructionPtr;
AssemblerInstruction* mInstructionPtr;
void parseCInstruction(std::string assemblyCode);
void parseAInstruction(std::string assemblyCode);
};