Assembler #6
@@ -9,7 +9,8 @@ namespace tyche::as {
|
||||
class AssemblyError : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
explicit AssemblyError(std::string const& str) : std::runtime_error(str.c_str()) {}
|
||||
explicit AssemblyError(std::string const& str, size_t line, size_t column)
|
||||
: std::runtime_error((str + " at: line " + std::to_string(line) + ", column: " + std::to_string(column)).c_str()) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,12 +1,32 @@
|
||||
#include "assembler.hh"
|
||||
|
||||
#include "as_exceptions.hh"
|
||||
#include "../bytecode/bytecode.hh"
|
||||
|
||||
namespace tyche::as {
|
||||
|
||||
ByteArray Assembler::assemble()
|
||||
{
|
||||
lexer_.reset();
|
||||
bp_ = {};
|
||||
|
||||
return {};
|
||||
enum class Section { Const, Function } section;
|
||||
uint32_t function_id = 0;
|
||||
|
||||
for (;;) {
|
||||
Token t = lexer_.ingest();
|
||||
|
||||
if (t.type == TokenType::Directive) {
|
||||
} else if (section == Section::Const && t.type == TokenType::Integer) {
|
||||
} else if (section == Section::Function && t.type == TokenType::Instruction) {
|
||||
} else if (t.type == TokenType::EOF_) {
|
||||
break;
|
||||
} else if (t.type != TokenType::Enter) {
|
||||
throw AssemblyError("Unexpected token " + t.token, t.line, t.column);
|
||||
}
|
||||
}
|
||||
|
||||
return bc::Bytecode::generate(bp_);
|
||||
}
|
||||
|
||||
} // tyche
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "lexer.hh"
|
||||
#include "../common/bytearray.hh"
|
||||
#include "../bytecode/bytecodeprototype.hh"
|
||||
|
||||
namespace tyche::as {
|
||||
|
||||
@@ -16,6 +17,7 @@ public:
|
||||
|
||||
private:
|
||||
Lexer lexer_;
|
||||
bc::BytecodePrototype bp_;
|
||||
};
|
||||
|
||||
} // tyche
|
||||
|
||||
@@ -24,6 +24,9 @@ Token Lexer::ingest()
|
||||
|
||||
void Lexer::ingest_next_token()
|
||||
{
|
||||
size_t current_line_pos = 1;
|
||||
size_t current_line = 1;
|
||||
|
||||
if (pos_ >= source_.size()) {
|
||||
current_token_ = { TokenType::EOF_, "" };
|
||||
return;
|
||||
@@ -49,7 +52,7 @@ void Lexer::ingest_next_token()
|
||||
++pos_;
|
||||
break;
|
||||
} else if (pos_ >= source_.size()) {
|
||||
throw AssemblyError("Unterminated string");
|
||||
throw AssemblyError("Unterminated string", current_line, pos_ - current_line_pos);
|
||||
}
|
||||
token += source_.at(pos_++);
|
||||
}
|
||||
@@ -62,7 +65,7 @@ void Lexer::ingest_next_token()
|
||||
if (type == TokenType::Integer)
|
||||
type = TokenType::Float;
|
||||
else
|
||||
throw AssemblyError("Double point in floating point number");
|
||||
throw AssemblyError("Double point in floating point number", current_line, pos_ - current_line_pos);
|
||||
}
|
||||
}
|
||||
} else if (isalpha(c)) {
|
||||
@@ -70,18 +73,23 @@ void Lexer::ingest_next_token()
|
||||
token += c;
|
||||
while (c = source_.at(++pos_), isalpha(c))
|
||||
token += c;
|
||||
} else if (c == ':') {
|
||||
type = TokenType::Colon;
|
||||
++pos_;
|
||||
} else if (c == '\n') {
|
||||
type = TokenType::Enter;
|
||||
++pos_;
|
||||
++current_line;
|
||||
current_line_pos = pos_;
|
||||
} else {
|
||||
throw AssemblyError(std::string("Unexpected character '") + c + "' (ascii: " + std::to_string((int) c) + ")");
|
||||
throw AssemblyError(std::string("Unexpected character '") + c + "' (ascii: " + std::to_string((int) c) + ")", current_line, pos_ - current_line_pos);
|
||||
}
|
||||
|
||||
// skip ignored tokens
|
||||
while (pos_ < source_.size() && (source_.at(pos_) == ' ' || source_.at(pos_) == '\t' || source_.at(pos_) == '\r'))
|
||||
++pos_;
|
||||
|
||||
current_token_ = { .type = type, .token = token };
|
||||
current_token_ = { .type = type, .token = token, .line = current_line, .column = pos_ - current_line_pos };
|
||||
}
|
||||
|
||||
} // tyche
|
||||
|
||||
@@ -7,12 +7,14 @@
|
||||
namespace tyche::as {
|
||||
|
||||
enum class TokenType {
|
||||
BOF, Directive, Instruction, Integer, Float, String, Enter, EOF_
|
||||
BOF, Directive, Instruction, Integer, Float, String, Enter, Colon, EOF_
|
||||
};
|
||||
|
||||
struct Token {
|
||||
TokenType type;
|
||||
std::string token;
|
||||
size_t line;
|
||||
size_t column;
|
||||
|
||||
friend bool operator==(Token const& lhs, Token const& rhs) { return std::tie(lhs.type, lhs.token) == std::tie(rhs.type, rhs.token); }
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user