.
This commit is contained in:
@@ -9,7 +9,8 @@ namespace tyche::as {
|
|||||||
class AssemblyError : public std::runtime_error
|
class AssemblyError : public std::runtime_error
|
||||||
{
|
{
|
||||||
public:
|
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 "assembler.hh"
|
||||||
|
|
||||||
|
#include "as_exceptions.hh"
|
||||||
|
#include "../bytecode/bytecode.hh"
|
||||||
|
|
||||||
namespace tyche::as {
|
namespace tyche::as {
|
||||||
|
|
||||||
ByteArray Assembler::assemble()
|
ByteArray Assembler::assemble()
|
||||||
{
|
{
|
||||||
lexer_.reset();
|
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
|
} // tyche
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "lexer.hh"
|
#include "lexer.hh"
|
||||||
#include "../common/bytearray.hh"
|
#include "../common/bytearray.hh"
|
||||||
|
#include "../bytecode/bytecodeprototype.hh"
|
||||||
|
|
||||||
namespace tyche::as {
|
namespace tyche::as {
|
||||||
|
|
||||||
@@ -16,6 +17,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Lexer lexer_;
|
Lexer lexer_;
|
||||||
|
bc::BytecodePrototype bp_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // tyche
|
} // tyche
|
||||||
|
|||||||
@@ -24,6 +24,9 @@ Token Lexer::ingest()
|
|||||||
|
|
||||||
void Lexer::ingest_next_token()
|
void Lexer::ingest_next_token()
|
||||||
{
|
{
|
||||||
|
size_t current_line_pos = 1;
|
||||||
|
size_t current_line = 1;
|
||||||
|
|
||||||
if (pos_ >= source_.size()) {
|
if (pos_ >= source_.size()) {
|
||||||
current_token_ = { TokenType::EOF_, "" };
|
current_token_ = { TokenType::EOF_, "" };
|
||||||
return;
|
return;
|
||||||
@@ -49,7 +52,7 @@ void Lexer::ingest_next_token()
|
|||||||
++pos_;
|
++pos_;
|
||||||
break;
|
break;
|
||||||
} else if (pos_ >= source_.size()) {
|
} else if (pos_ >= source_.size()) {
|
||||||
throw AssemblyError("Unterminated string");
|
throw AssemblyError("Unterminated string", current_line, pos_ - current_line_pos);
|
||||||
}
|
}
|
||||||
token += source_.at(pos_++);
|
token += source_.at(pos_++);
|
||||||
}
|
}
|
||||||
@@ -62,7 +65,7 @@ void Lexer::ingest_next_token()
|
|||||||
if (type == TokenType::Integer)
|
if (type == TokenType::Integer)
|
||||||
type = TokenType::Float;
|
type = TokenType::Float;
|
||||||
else
|
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)) {
|
} else if (isalpha(c)) {
|
||||||
@@ -70,18 +73,23 @@ void Lexer::ingest_next_token()
|
|||||||
token += c;
|
token += c;
|
||||||
while (c = source_.at(++pos_), isalpha(c))
|
while (c = source_.at(++pos_), isalpha(c))
|
||||||
token += c;
|
token += c;
|
||||||
|
} else if (c == ':') {
|
||||||
|
type = TokenType::Colon;
|
||||||
|
++pos_;
|
||||||
} else if (c == '\n') {
|
} else if (c == '\n') {
|
||||||
type = TokenType::Enter;
|
type = TokenType::Enter;
|
||||||
++pos_;
|
++pos_;
|
||||||
|
++current_line;
|
||||||
|
current_line_pos = pos_;
|
||||||
} else {
|
} 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
|
// skip ignored tokens
|
||||||
while (pos_ < source_.size() && (source_.at(pos_) == ' ' || source_.at(pos_) == '\t' || source_.at(pos_) == '\r'))
|
while (pos_ < source_.size() && (source_.at(pos_) == ' ' || source_.at(pos_) == '\t' || source_.at(pos_) == '\r'))
|
||||||
++pos_;
|
++pos_;
|
||||||
|
|
||||||
current_token_ = { .type = type, .token = token };
|
current_token_ = { .type = type, .token = token, .line = current_line, .column = pos_ - current_line_pos };
|
||||||
}
|
}
|
||||||
|
|
||||||
} // tyche
|
} // tyche
|
||||||
|
|||||||
@@ -7,12 +7,14 @@
|
|||||||
namespace tyche::as {
|
namespace tyche::as {
|
||||||
|
|
||||||
enum class TokenType {
|
enum class TokenType {
|
||||||
BOF, Directive, Instruction, Integer, Float, String, Enter, EOF_
|
BOF, Directive, Instruction, Integer, Float, String, Enter, Colon, EOF_
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Token {
|
struct Token {
|
||||||
TokenType type;
|
TokenType type;
|
||||||
std::string token;
|
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); }
|
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