Replace ! with a function call writei

This commit is contained in:
2024-03-19 09:35:50 +01:00
parent e7d8f9116a
commit c210c55a17
25 changed files with 315 additions and 159 deletions

View File

@ -1,7 +1,6 @@
#pragma once
#include <cstdint>
#include <functional>
#include "elna/source/parser.hpp"
namespace elna::riscv
@ -160,8 +159,7 @@ namespace elna::riscv
class visitor final : public source::parser_visitor
{
std::function<void(const std::string&, const std::byte *, std::size_t)> write_text;
std::function<std::string_view(const std::byte *, std::size_t)> write_read_only;
std::shared_ptr<source::writer> writer;
public:
std::vector<instruction> instructions;
@ -170,12 +168,11 @@ namespace elna::riscv
std::vector<reference> references;
std::shared_ptr<source::symbol_table> table;
visitor(std::function<void(const std::string&, const std::byte *, std::size_t)> write_text,
std::function<std::string_view(const std::byte *, std::size_t)> write_read_only);
visitor(std::shared_ptr<source::writer> writer);
virtual void visit(source::declaration *declaration) override;
virtual void visit(source::definition *definition) override;
virtual void visit(source::bang_statement *statement) override;
virtual void visit(source::call_statement *statement) override;
virtual void visit(source::question_mark_statement *statement) override;
virtual void visit(source::compound_statement *statement) override;
virtual void visit(source::assign_statement *statement) override;

View File

@ -4,7 +4,10 @@
namespace elna::riscv
{
struct elfio_writer
/**
* Writer to a single label.
*/
struct elfio_section_writer
{
struct entry
{
@ -51,30 +54,50 @@ namespace elna::riscv
{
}
friend elfio_writer;
friend elfio_section_writer;
};
explicit elfio_writer(ELFIO::section *text);
explicit elfio_section_writer(ELFIO::section *section);
void operator()(const std::string& label, const std::byte *data, std::size_t size);
std::string_view operator()(const std::byte *data, std::size_t size);
std::pair<std::string_view, bool> operator()(const std::byte *data, std::size_t size);
iterator begin() const;
iterator end() const;
/**
* Searches the content by label and returns its index or -1 when the
* label does not exist.
*
* \param needle Label name.
* \return Data index.
*/
std::ptrdiff_t lookup(const std::string& label);
ELFIO::section *section() noexcept;
private:
std::shared_ptr<std::vector<std::string>> labels;
std::shared_ptr<std::vector<std::size_t>> sizes;
ELFIO::section *text;
std::vector<std::string> labels;
std::vector<std::size_t> sizes;
ELFIO::section *m_section;
};
class elfio_writer final : public source::writer
{
ELFIO::section *text;
elfio_section_writer read_only;
ELFIO::symbol_section_accessor symbol_accessor;
ELFIO::string_section_accessor string_accessor;
public:
elfio_writer(ELFIO::section *text, ELFIO::section *read_only, ELFIO::symbol_section_accessor symbol_accessor,
ELFIO::string_section_accessor string_accessor);
std::size_t sink(const std::string& label, const std::byte *data, std::size_t size) override;
std::string_view sink(const std::byte *data, std::size_t size) override;
void sink(const std::string& label) override;
std::size_t size() const override;
};
/**
* Searches the content by label and returns its index or -1 when the
* label does not exist.
*
* \param symbol_accessor Object accessor.
* \param needle Label name.
* \return Data index.
*/
std::ptrdiff_t lookup(ELFIO::symbol_section_accessor symbol_accessor, const std::string& label);
void riscv32_elf(source::program *ast, const std::filesystem::path& out_file);
}

View File

@ -62,7 +62,6 @@ namespace elna::source
semicolon,
left_paren,
right_paren,
bang,
dot,
comma,
factor_operator,
@ -110,7 +109,7 @@ namespace elna::source
private:
type m_type;
value m_value;
value m_value{};
elna::source::position m_position;
bool has_identifier() const noexcept;

View File

@ -16,7 +16,7 @@ namespace elna::source
class declaration;
class definition;
class bang_statement;
class call_statement;
class question_mark_statement;
class compound_statement;
class assign_statement;
@ -33,7 +33,7 @@ namespace elna::source
{
virtual void visit(declaration *) = 0;
virtual void visit(definition *) = 0;
virtual void visit(bang_statement *) = 0;
virtual void visit(call_statement *) = 0;
virtual void visit(question_mark_statement *) = 0;
virtual void visit(compound_statement *) = 0;
virtual void visit(assign_statement *) = 0;
@ -51,7 +51,7 @@ namespace elna::source
{
virtual void visit(declaration *declaration) override;
virtual void visit(definition *definition) override;
virtual void visit(bang_statement *statement) override;
virtual void visit(call_statement *statement) override;
virtual void visit(question_mark_statement *statement) override;
virtual void visit(compound_statement *statement) override;
virtual void visit(assign_statement *statement) override;
@ -116,15 +116,17 @@ namespace elna::source
integer_literal& body();
};
class bang_statement : public statement
class call_statement : public statement
{
std::string m_name;
std::unique_ptr<expression> m_body;
public:
bang_statement(std::unique_ptr<expression>&& body);
call_statement(const std::string& name, std::unique_ptr<expression>&& body);
virtual void accept(parser_visitor *visitor) override;
expression& body();
std::string& name() noexcept;
expression& arguments();
};
class question_mark_statement : public statement
@ -275,7 +277,7 @@ namespace elna::source
std::unique_ptr<definition> parse_definition();
std::unique_ptr<declaration> parse_declaration();
std::unique_ptr<statement> parse_statement();
std::unique_ptr<bang_statement> parse_bang_statement();
std::unique_ptr<call_statement> parse_call_statement();
std::unique_ptr<question_mark_statement> parse_question_mark_statement();
std::unique_ptr<compound_statement> parse_compound_statement();
std::unique_ptr<assign_statement> parse_assign_statement();

View File

@ -140,6 +140,9 @@ namespace elna::source
~variable_info() override;
};
/**
* Procedure information.
*/
class procedure_info final : public info
{
std::size_t local_stack_size{ 0 };
@ -151,6 +154,15 @@ namespace elna::source
std::size_t stack_size() const noexcept;
};
/**
* Intrinsic and external procedure information.
*/
class intrinsic_info final : public info
{
public:
~intrinsic_info() override;
};
/**
* Symbol table.
*/
@ -159,9 +171,43 @@ namespace elna::source
std::unordered_map<std::string, std::shared_ptr<info>> entries;
public:
symbol_table() = default;
symbol_table();
std::shared_ptr<info> lookup(const std::string& name);
void enter(const std::string& name, std::shared_ptr<info> entry);
};
struct writer
{
/**
* Writes data to the table and saves it under the given label.
*
* \param label Symbol name.
* \param data Data to be written.
* \param size Data size.
*
* \return New size of the table.
*/
virtual std::size_t sink(const std::string& label, const std::byte *data, std::size_t size) = 0;
/**
* Writes data and returns a label under that the data can be accessed.
*
* \param data Data to be written.
* \param size Data size.
*
* \return Label for the symbol.
*/
virtual std::string_view sink(const std::byte *data, std::size_t size) = 0;
/**
* Creates an external symbol.
*/
virtual void sink(const std::string& label) = 0;
/**
* \return Actual size of the text section.
*/
virtual std::size_t size() const = 0;
};
}