Replace ! with a function call writei
This commit is contained in:
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
Reference in New Issue
Block a user