Split code generation from the ui

This commit is contained in:
2024-03-07 09:15:11 +01:00
parent 4dbf3ddb47
commit fe805ca893
26 changed files with 279 additions and 336 deletions

View File

@ -3,10 +3,23 @@
#include <cstdint>
#include <unordered_map>
#include "elna/source/parser.hpp"
#include "elna/result.hpp"
namespace elna
namespace elna::backend
{
enum class Target
{
text,
high20,
lower12i
};
struct Reference
{
const char* name;
std::size_t offset;
Target target;
};
enum class XRegister : std::uint8_t
{
zero = 0,
@ -135,8 +148,8 @@ namespace elna
Instruction& r(XRegister rd, Funct3 funct3, XRegister rs1, XRegister rs2, Funct7 funct7 = Funct7::none);
Instruction& u(XRegister rd, std::uint32_t imm);
const std::byte *cbegin();
const std::byte *cend();
const std::byte *cbegin() const;
const std::byte *cend() const;
private:
std::uint32_t instruction{ 0 };
@ -145,8 +158,7 @@ namespace elna
class RiscVVisitor : public source::ParserVisitor
{
public:
Instruction *instructions;
std::size_t instructionsLength;
std::vector<Instruction> instructions;
bool registerInUse{ true };
std::uint32_t variableCounter = 1;
Reference references[3];
@ -155,10 +167,8 @@ namespace elna
virtual void visit(source::definition *definition) override;
virtual void visit(source::bang_statement *statement) override;
virtual void visit(source::block *block) override;
virtual void visit(source::variable *variable) override;
virtual void visit(source::variable_expression *variable) override;
virtual void visit(source::integer_literal *number) override;
virtual void visit(source::binary_expression *expression) override;
};
Symbol writeNext(source::block *ast);
}

View File

@ -0,0 +1,7 @@
#include "elna/source/parser.hpp"
#include <filesystem>
namespace elna::backend
{
void riscv32_elf(source::block *ast, const std::filesystem::path& out_file);
}

View File

@ -2,7 +2,7 @@
#include <filesystem>
namespace elna
namespace elna::cli
{
char *readSource(const char *source);
int compile(const std::filesystem::path& in_file, const std::filesystem::path& out_file);

View File

@ -1,112 +0,0 @@
#pragma once
#include <cstddef>
#include <variant>
#include <vector>
#include <forward_list>
namespace elna
{
namespace source
{
/**
* Position in the source text.
*/
struct position
{
/// Line.
std::size_t line = 1;
/// Column.
std::size_t column = 1;
};
/**
* A compilation error consists of an error message and position.
*/
struct error
{
private:
char const *message;
source::position position;
public:
/**
* \param message Error text.
* \param position Error position in the source text.
*/
error(char const *message, const source::position position) noexcept;
/// Error text.
const char *what() const noexcept;
/// Error line in the source text.
std::size_t line() const noexcept;
/// Error column in the source text.
std::size_t column() const noexcept;
};
template<typename T>
struct result
{
using E = std::forward_list<source::error>;
template<typename... Args>
explicit result(Args&&... arguments)
: payload(std::forward<Args>(arguments)...)
{
}
explicit result(const char *message, const source::position position)
: payload(E{ source::error(message, position) })
{
}
bool has_errors() const noexcept
{
return std::holds_alternative<E>(payload);
}
bool is_success() const noexcept
{
return std::holds_alternative<T>(payload);
}
T& success()
{
return std::get<T>(payload);
}
E& errors()
{
return std::get<E>(payload);
}
private:
std::variant<T, E> payload;
};
}
enum class Target
{
text,
high20,
lower12i
};
struct Reference
{
const char* name;
size_t offset;
Target target;
};
struct Symbol
{
Symbol(const char *name);
const char *name;
std::vector<std::byte> text;
Reference symbols[3];
};
}

View File

@ -5,8 +5,8 @@
#include <string>
#include <optional>
#include "elna/state.hpp"
#include "elna/history.hpp"
#include "elna/shell/state.hpp"
#include "elna/shell/history.hpp"
#define BOOST_PROCESS_USE_STD_FS

View File

@ -2,7 +2,7 @@
#include "elna/source/parser.hpp"
namespace elna
namespace elna::source
{
class TransformVisitor final : public source::ParserVisitor
{
@ -10,7 +10,7 @@ namespace elna
void visit(source::bang_statement *statement) override;
void visit(source::block *block) override;
void visit(source::integer_literal *number) override;
void visit(source::variable *variable) override;
void visit(source::variable_expression *variable) override;
void visit(source::binary_expression *binaryExpression) override;
};
}

View File

@ -2,12 +2,10 @@
#include <cstdint>
#include <string>
#include <vector>
#include "elna/source/result.hpp"
#include "elna/result.hpp"
namespace elna
{
namespace source
namespace elna::source
{
/**
* Range over the source text that keeps track of the current position.
@ -113,4 +111,3 @@ namespace source
*/
elna::source::result<std::vector<token>> lex(const std::string& buffer);
}
}

View File

@ -4,9 +4,7 @@
#include <memory>
#include <elna/source/lexer.hpp>
namespace elna
{
namespace source
namespace elna::source
{
enum class binary_operator
{
@ -20,7 +18,7 @@ namespace source
class bang_statement;
class block;
class binary_expression;
class variable;
class variable_expression;
class integer_literal;
struct ParserVisitor
@ -29,7 +27,7 @@ namespace source
virtual void visit(bang_statement *) = 0;
virtual void visit(block *) = 0;
virtual void visit(binary_expression *) = 0;
virtual void visit(variable *) = 0;
virtual void visit(variable_expression *) = 0;
virtual void visit(integer_literal *) = 0;
};
@ -104,12 +102,12 @@ namespace source
std::int32_t number() const noexcept;
};
class variable : public expression
class variable_expression : public expression
{
std::string m_name;
public:
variable(const std::string& name);
variable_expression(const std::string& name);
virtual void accept(ParserVisitor *visitor) override;
const std::string& name() const noexcept;
@ -150,4 +148,3 @@ namespace source
std::vector<token>::const_iterator end;
};
}
}

View File

@ -0,0 +1,86 @@
#pragma once
#include <cstddef>
#include <variant>
#include <forward_list>
namespace elna::source
{
/**
* Position in the source text.
*/
struct position
{
/// Line.
std::size_t line = 1;
/// Column.
std::size_t column = 1;
};
/**
* A compilation error consists of an error message and position.
*/
struct error
{
private:
char const *message;
source::position position;
public:
/**
* \param message Error text.
* \param position Error position in the source text.
*/
error(char const *message, const source::position position) noexcept;
/// Error text.
const char *what() const noexcept;
/// Error line in the source text.
std::size_t line() const noexcept;
/// Error column in the source text.
std::size_t column() const noexcept;
};
template<typename T>
struct result
{
using E = std::forward_list<source::error>;
template<typename... Args>
explicit result(Args&&... arguments)
: payload(std::forward<Args>(arguments)...)
{
}
explicit result(const char *message, const source::position position)
: payload(E{ source::error(message, position) })
{
}
bool has_errors() const noexcept
{
return std::holds_alternative<E>(payload);
}
bool is_success() const noexcept
{
return std::holds_alternative<T>(payload);
}
T& success()
{
return std::get<T>(payload);
}
E& errors()
{
return std::get<E>(payload);
}
private:
std::variant<T, E> payload;
};
}