.
This commit is contained in:
@@ -84,6 +84,7 @@ add_library(lib${PROJECT_NAME} SHARED
|
|||||||
src/assembler/lexer.hh
|
src/assembler/lexer.hh
|
||||||
src/assembler/assembler.cc
|
src/assembler/assembler.cc
|
||||||
src/assembler/assembler.hh
|
src/assembler/assembler.hh
|
||||||
|
src/assembler/as_exceptions.hh
|
||||||
)
|
)
|
||||||
|
|
||||||
target_compile_options(lib${PROJECT_NAME} PRIVATE ${warnings})
|
target_compile_options(lib${PROJECT_NAME} PRIVATE ${warnings})
|
||||||
|
|||||||
17
src/assembler/as_exceptions.hh
Normal file
17
src/assembler/as_exceptions.hh
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#ifndef TYCHE_VM_EXCEPTIONS_HH
|
||||||
|
#define TYCHE_VM_EXCEPTIONS_HH
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace tyche::as {
|
||||||
|
|
||||||
|
class AssemblyError : public std::runtime_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit AssemblyError(std::string const& str) : std::runtime_error(str.c_str()) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //TYCHE_VM_EXCEPTIONS_HH
|
||||||
@@ -1,20 +1,46 @@
|
|||||||
#include "lexer.hh"
|
#include "lexer.hh"
|
||||||
|
|
||||||
|
#include "as_exceptions.hh"
|
||||||
|
|
||||||
namespace tyche::as {
|
namespace tyche::as {
|
||||||
|
|
||||||
void Lexer::reset()
|
void Lexer::reset()
|
||||||
{
|
{
|
||||||
|
pos_ = 0;
|
||||||
|
ingest_next_token();
|
||||||
}
|
}
|
||||||
|
|
||||||
Token Lexer::peek() const
|
Token Lexer::peek() const
|
||||||
{
|
{
|
||||||
return {};
|
return look_ahead_;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token Lexer::ingest()
|
Token Lexer::ingest()
|
||||||
{
|
{
|
||||||
return {};
|
Token t = look_ahead_;
|
||||||
|
ingest_next_token();
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lexer::ingest_next_token()
|
||||||
|
{
|
||||||
|
char c = source_.at(pos_);
|
||||||
|
|
||||||
|
if (pos_ >= source_.size()) {
|
||||||
|
look_ahead_ = { TokenType::EOF_, "" };
|
||||||
|
} else if (c == '.') {
|
||||||
|
|
||||||
|
} else if (c == '"') {
|
||||||
|
|
||||||
|
} else if (isdigit(c)) {
|
||||||
|
|
||||||
|
} else if (isalpha(c)) {
|
||||||
|
|
||||||
|
} else if (c == '\n') {
|
||||||
|
|
||||||
|
} else if (c != ' ' && c != '\t' && c != '\r') {
|
||||||
|
throw AssemblyError(std::string("Unexpected character '") + c + "' (ascii: " + std::to_string((int) c) + ")");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // tyche
|
} // tyche
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
namespace tyche::as {
|
namespace tyche::as {
|
||||||
|
|
||||||
enum class TokenType { Directive, Instruction, Number, Float, String, Enter, EOF_ };
|
enum class TokenType { BOF, Directive, Instruction, Number, Float, String, Enter, EOF_ };
|
||||||
|
|
||||||
struct Token {
|
struct Token {
|
||||||
TokenType type;
|
TokenType type;
|
||||||
@@ -15,14 +15,18 @@ struct Token {
|
|||||||
|
|
||||||
class Lexer {
|
class Lexer {
|
||||||
public:
|
public:
|
||||||
explicit Lexer(std::string source) : source_(std::move(source)) {}
|
explicit Lexer(std::string source) : source_(std::move(source) + "\n") { reset(); }
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
[[nodiscard]] Token peek() const;
|
[[nodiscard]] Token peek() const;
|
||||||
[[nodiscard]] Token ingest();
|
[[nodiscard]] Token ingest();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string source_;
|
const std::string source_;
|
||||||
|
size_t pos_ = 0;
|
||||||
|
Token look_ahead_;
|
||||||
|
|
||||||
|
void ingest_next_token();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // tyche
|
} // tyche
|
||||||
|
|||||||
Reference in New Issue
Block a user