diff options
| Commit | 6e19bb560d474736d45f5be011ff0830c7019991 (patch) | |
|---|---|---|
| Author | 2018-11-05 23:34:00 +0200 | |
| Committer | 2018-11-05 23:34:00 +0200 | |
| Files | 42d29cf1c4e6a535ba526f434debaac3a70df2c6 /src/asm/assembler.cpp | |
| IPL-6e19bb560d474736d45f5be011ff0830c7019991.tar IPL-6e19bb560d474736d45f5be011ff0830c7019991.tar.gz IPL-6e19bb560d474736d45f5be011ff0830c7019991.zip | ||
Squashed 'spasm/' content from commit 08ee95d
git-subtree-dir: spasm
git-subtree-split: 08ee95d89054ba0d33697d613799a0a013aedf89
1 files changed, 79 insertions, 0 deletions
| -rw-r--r-- | src/asm/assembler.cpp | 79 |
diff --git a/src/asm/assembler.cpp b/src/asm/assembler.cpp new file mode 100644 index 0000000..25ed377 --- /dev/null +++ b/src/asm/assembler.cpp @@ -0,0 +1,79 @@ +#include <cassert> + +#include "assembler.hpp" +#include "bytecode.hpp" +#include "symbol.hpp" +#include "tokenizer.hpp" + +namespace SpasmImpl +{ +namespace ASM +{ +Assembler::Assembler(Lexer::Tokenizer& tokenizer, Bytecode_Stream& bytecode) + : _tokenizer(&tokenizer), _bytecode(&bytecode) +{ +} + +void Assembler::assemble() +{ + Lexer::Token token = _tokenizer->next_token(); + + while (token.type() != Lexer::Token::endinput) + { + switch (token.type()) + { + case Lexer::Token::ident: + assemble_identifier(token); + break; + case Lexer::Token::label: + token = _tokenizer->next_token(); + assert(token.type() == Lexer::Token::ident); + _symbols.define(token.value_str(), _bytecode->size()); + break; + case Lexer::Token::integer: + case Lexer::Token::xinteger: + _bytecode->push_integer(token.value_int()); + break; + default: + _bytecode->push_opcode((Bytecode_Stream::Opcode_t)token.type()); + } + + token = _tokenizer->next_token(); + } + + Symbol_Table::const_iterator i = _symbols.begin(); + while (i != _symbols.end()) + { + backpatch(i->second); + ++i; + } +} + +void Assembler::backpatch(const Symbol* symbol) +{ + Symbol::Positions_t::const_iterator i = symbol->positions_begin(); + while (i != symbol->positions_end()) + { + _bytecode->set_location(*i, symbol->definition()); + ++i; + } +} + +void Assembler::assemble_identifier(const Lexer::Token& token) +{ + Symbol* symbol = _symbols.insert(token.value_str(), _bytecode->size()); + _bytecode->push_location(symbol->definition()); +} + +bool compile(std::istream& istr, Bytecode_Memory& bytecode) +{ + Lexer::Tokenizer tokenizer(istr); + Assembler assembler(tokenizer, bytecode); + + assembler.assemble(); + + return true; +} + +} // namespace ASM +} // namespace SpasmImpl |
