From 7e5f7f492d574fd92aec04258af5d27249f1edf1 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Wed, 20 Mar 2024 17:56:38 +0100 Subject: [PATCH] Implement first intrinsics for output --- backend/riscv.cpp | 190 +++++++++++++++------------ backend/target.cpp | 5 +- include/elna/backend/riscv.hpp | 11 +- include/elna/source/lexer.hpp | 4 +- include/elna/source/parser.hpp | 69 +++++----- include/elna/source/semantic.hpp | 2 +- source/lexer.cpp | 8 +- source/parser.cpp | 127 ++++++++---------- source/semantic.cpp | 2 +- tests/expectations/print_boolean.txt | 4 +- tests/print_boolean.eln | 4 +- tests/subtraction.eln | 2 +- tests/tester.cpp | 7 +- 13 files changed, 221 insertions(+), 214 deletions(-) diff --git a/backend/riscv.cpp b/backend/riscv.cpp index 604aa2b..2ce4b92 100644 --- a/backend/riscv.cpp +++ b/backend/riscv.cpp @@ -81,11 +81,112 @@ namespace elna::riscv { } + void visitor::generate_intrinsics() + { + this->writer->sink("printf"); + { + auto format_string = this->writer->sink(reinterpret_cast("%c\n\0"), 4); + + this->instructions.push_back(instruction(base_opcode::opImm) + .i(x_register::sp, funct3_t::addi, x_register::sp, -8)); + this->instructions.push_back(instruction(base_opcode::store) + .s(4, funct3_t::sw, x_register::sp, x_register::s0)); + this->instructions.push_back(instruction(base_opcode::store) + .s(0, funct3_t::sw, x_register::sp, x_register::ra)); + this->instructions.push_back(instruction(base_opcode::opImm) + .i(x_register::s0, funct3_t::addi, x_register::sp, -8)); + + this->instructions.push_back(instruction(base_opcode::opImm) + .i(x_register::a1, funct3_t::addi, x_register::zero, 't')); + this->instructions.push_back(instruction(base_opcode::branch) + .b(8, funct3_t::bne, x_register::zero, x_register::a0)); + this->instructions.push_back(instruction(base_opcode::opImm) + .i(x_register::a1, funct3_t::addi, x_register::zero, 'f')); + + relocate(format_string, address_t::high20); + this->instructions.push_back(instruction(base_opcode::lui).u(x_register::a5, 0)); + relocate(format_string, address_t::lower12i); + this->instructions.push_back(instruction(base_opcode::opImm) + .i(x_register::a0, funct3_t::addi, x_register::a5, 0)); + + relocate("printf", address_t::text); + this->instructions.push_back(instruction(base_opcode::auipc).u(x_register::ra, 0)); + this->instructions.push_back(instruction(base_opcode::jalr) + .i(x_register::ra, funct3_t::jalr, x_register::ra, 0)); + + this->instructions.push_back(instruction(base_opcode::load) + .i(x_register::s0, funct3_t::lw, x_register::sp, 4)); + this->instructions.push_back(instruction(base_opcode::load) + .i(x_register::ra, funct3_t::lw, x_register::sp, 0)); + this->instructions.push_back(instruction(base_opcode::opImm) + .i(x_register::sp, funct3_t::addi, x_register::sp, 8)); + this->instructions.push_back(instruction(base_opcode::jalr) + .i(x_register::zero, funct3_t::jalr, x_register::ra, 0)); + + this->writer->sink("writeb", reinterpret_cast(this->instructions.data()), + this->instructions.size() * sizeof(instruction)); + + this->instructions.clear(); + } + { + auto format_string = this->writer->sink(reinterpret_cast("%d\n\0"), 4); + + this->instructions.push_back(instruction(base_opcode::opImm) + .i(x_register::sp, funct3_t::addi, x_register::sp, -8)); + this->instructions.push_back(instruction(base_opcode::store) + .s(4, funct3_t::sw, x_register::sp, x_register::s0)); + this->instructions.push_back(instruction(base_opcode::store) + .s(0, funct3_t::sw, x_register::sp, x_register::ra)); + this->instructions.push_back(instruction(base_opcode::opImm) + .i(x_register::s0, funct3_t::addi, x_register::sp, -8)); + + this->instructions.push_back(instruction(base_opcode::opImm) + .i(x_register::a1, funct3_t::addi, x_register::a0, 0)); + + relocate(format_string, address_t::high20); + this->instructions.push_back(instruction(base_opcode::lui).u(x_register::a5, 0)); + relocate(format_string, address_t::lower12i); + this->instructions.push_back(instruction(base_opcode::opImm) + .i(x_register::a0, funct3_t::addi, x_register::a5, 0)); + + relocate("printf", address_t::text); + this->instructions.push_back(instruction(base_opcode::auipc).u(x_register::ra, 0)); + this->instructions.push_back(instruction(base_opcode::jalr) + .i(x_register::ra, funct3_t::jalr, x_register::ra, 0)); + + this->instructions.push_back(instruction(base_opcode::load) + .i(x_register::s0, funct3_t::lw, x_register::sp, 4)); + this->instructions.push_back(instruction(base_opcode::load) + .i(x_register::ra, funct3_t::lw, x_register::sp, 0)); + this->instructions.push_back(instruction(base_opcode::opImm) + .i(x_register::sp, funct3_t::addi, x_register::sp, 8)); + this->instructions.push_back(instruction(base_opcode::jalr) + .i(x_register::zero, funct3_t::jalr, x_register::ra, 0)); + + this->writer->sink("writei", reinterpret_cast(this->instructions.data()), + this->instructions.size() * sizeof(instruction)); + + this->instructions.clear(); + } + } + + void visitor::relocate(std::string_view name, address_t target) + { + this->references.push_back(reference()); + this->references.back().name = name; + this->references.back().offset = writer->size() + instructions.size() * 4; + this->references.back().target = target; + } + void visitor::visit(source::declaration *declaration) { } - void visitor::visit(source::definition *definition) + void visitor::visit(source::constant_definition *definition) + { + } + + void visitor::visit(source::procedure_definition *definition) { } @@ -126,51 +227,8 @@ namespace elna::riscv void visitor::visit(source::program *program) { - this->writer->sink("printf"); - auto format_string = this->writer->sink(reinterpret_cast("%d\n\0"), 4); + generate_intrinsics(); - this->instructions.push_back(instruction(base_opcode::opImm) - .i(x_register::sp, funct3_t::addi, x_register::sp, -8)); - this->instructions.push_back(instruction(base_opcode::store) - .s(4, funct3_t::sw, x_register::sp, x_register::s0)); - this->instructions.push_back(instruction(base_opcode::store) - .s(0, funct3_t::sw, x_register::sp, x_register::ra)); - this->instructions.push_back(instruction(base_opcode::opImm) - .i(x_register::s0, funct3_t::addi, x_register::sp, -8)); - - this->references.push_back(reference()); - this->references.back().name = format_string; - this->references.back().offset = writer->size() + instructions.size() * 4; - this->references.back().target = address_t::high20; - this->instructions.push_back(instruction(base_opcode::lui).u(x_register::a5, 0)); - this->references.push_back(reference()); - this->references.back().name = format_string; - this->references.back().offset = writer->size() + instructions.size() * 4; - this->references.back().target = address_t::lower12i; - this->instructions.push_back(instruction(base_opcode::opImm) - .i(x_register::a0, funct3_t::addi, x_register::a5, 0)); - - this->references.push_back(reference()); - this->references.back().name = "printf"; - this->references.back().offset = writer->size() + instructions.size() * 4; - this->references.back().target = address_t::text; - this->instructions.push_back(instruction(base_opcode::auipc).u(x_register::ra, 0)); - this->instructions.push_back(instruction(base_opcode::jalr) - .i(x_register::ra, funct3_t::jalr, x_register::ra, 0)); - - this->instructions.push_back(instruction(base_opcode::load) - .i(x_register::s0, funct3_t::lw, x_register::sp, 4)); - this->instructions.push_back(instruction(base_opcode::load) - .i(x_register::ra, funct3_t::lw, x_register::sp, 0)); - this->instructions.push_back(instruction(base_opcode::opImm) - .i(x_register::sp, funct3_t::addi, x_register::sp, 8)); - this->instructions.push_back(instruction(base_opcode::jalr) - .i(x_register::zero, funct3_t::jalr, x_register::ra, 0)); - - this->writer->sink("writei", reinterpret_cast(this->instructions.data()), - this->instructions.size() * sizeof(instruction)); - - this->instructions.clear(); visit(dynamic_cast(program)); this->writer->sink("main", reinterpret_cast(this->instructions.data()), this->instructions.size() * sizeof(instruction)); @@ -180,41 +238,7 @@ namespace elna::riscv { statement->arguments().accept(this); - // Print the result. - this->instructions.push_back(instruction(base_opcode::opImm) - .i(x_register::a1, funct3_t::addi, x_register::a0, 0)); - - this->instructions.push_back(instruction(base_opcode::auipc).u(x_register::ra, 0)); - this->instructions.push_back(instruction(base_opcode::jalr) - .i(x_register::ra, funct3_t::jalr, x_register::ra, -instructions.size() * 4 - 40)); - } - - void visitor::visit(source::question_mark_statement *statement) - { - statement->body().accept(this); - - // Print the result. - this->instructions.push_back(instruction(base_opcode::opImm) - .i(x_register::a1, funct3_t::addi, x_register::a0, 0)); - - auto format_string = this->writer->sink(reinterpret_cast("%d\n\0"), 4); - - this->references.push_back(reference()); - this->references.back().name = format_string; - this->references.back().offset = writer->size() + instructions.size() * 4; - this->references.back().target = address_t::high20; - this->instructions.push_back(instruction(base_opcode::lui).u(x_register::a5, 0)); - this->references.push_back(reference()); - this->references.back().name = format_string; - this->references.back().offset = writer->size() + instructions.size() * 4; - this->references.back().target = address_t::lower12i; - - this->instructions.push_back(instruction(base_opcode::opImm) - .i(x_register::a0, funct3_t::addi, x_register::a5, 0)); - this->references.push_back(reference()); - this->references.back().name = "printf"; - this->references.back().offset = writer->size() + instructions.size() * 4; - this->references.back().target = address_t::text; + relocate(statement->name(), address_t::text); this->instructions.push_back(instruction(base_opcode::auipc).u(x_register::ra, 0)); this->instructions.push_back(instruction(base_opcode::jalr) .i(x_register::ra, funct3_t::jalr, x_register::ra, 0)); @@ -242,15 +266,15 @@ namespace elna::riscv void visitor::visit(source::if_statement *statement) { - const auto free_register = this->register_in_use ? x_register::a0 : x_register::t0; - statement->prerequisite().accept(this); + const auto free_register = this->register_in_use ? x_register::a0 : x_register::t0; + auto before_branch = instructions.size(); instructions.push_back(instruction(base_opcode::branch)); statement->body().accept(this); instructions[before_branch] - .b((instructions.size() - before_branch) * 4, funct3_t::beq, x_register::zero, free_register); + .b((instructions.size() - before_branch) * 4 - 4, funct3_t::beq, x_register::zero, free_register); } void visitor::visit(source::while_statement *statement) diff --git a/backend/target.cpp b/backend/target.cpp index da9ddf1..cd5375d 100644 --- a/backend/target.cpp +++ b/backend/target.cpp @@ -204,22 +204,19 @@ namespace elna::riscv for (auto& reference : _visitor.references) { - ELFIO::Elf_Word relocated_symbol{ 0 }; + ELFIO::Elf_Word relocated_symbol = lookup(syma, reference.name); switch (reference.target) { case address_t::high20: - relocated_symbol = lookup(syma, reference.name); rela.add_entry(reference.offset, relocated_symbol, 26 /* ELFIO::R_RISCV_HI20 */); rela.add_entry(reference.offset, relocated_symbol, 51 /* ELFIO::R_RISCV_RELAX */); break; case address_t::lower12i: - relocated_symbol = lookup(syma, reference.name); rela.add_entry(reference.offset, relocated_symbol, 27 /* ELFIO::R_RISCV_LO12_I */); rela.add_entry(reference.offset, relocated_symbol, 51 /* ELFIO::R_RISCV_RELAX */); break; case address_t::text: - relocated_symbol = lookup(syma, "printf"); rela.add_entry(reference.offset, relocated_symbol, 18 /* ELFIO::R_RISCV_CALL */); rela.add_entry(reference.offset, relocated_symbol, 51 /* ELFIO::R_RISCV_RELAX */); break; diff --git a/include/elna/backend/riscv.hpp b/include/elna/backend/riscv.hpp index d67c3af..acb6ed8 100644 --- a/include/elna/backend/riscv.hpp +++ b/include/elna/backend/riscv.hpp @@ -160,10 +160,13 @@ namespace elna::riscv class visitor final : public source::parser_visitor { std::shared_ptr writer; - - public: std::vector instructions; bool register_in_use{ true }; + + void generate_intrinsics(); + void relocate(std::string_view name, address_t target); + + public: std::uint32_t variable_counter = 1; std::vector references; std::shared_ptr table; @@ -171,9 +174,9 @@ namespace elna::riscv visitor(std::shared_ptr writer); virtual void visit(source::declaration *declaration) override; - virtual void visit(source::definition *definition) override; + virtual void visit(source::constant_definition *definition) override; + virtual void visit(source::procedure_definition *definition) 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; virtual void visit(source::if_statement *statement) override; diff --git a/include/elna/source/lexer.hpp b/include/elna/source/lexer.hpp index e250f6e..0e3ca3e 100644 --- a/include/elna/source/lexer.hpp +++ b/include/elna/source/lexer.hpp @@ -70,11 +70,11 @@ namespace elna::source end, assignment, colon, - question_mark, when, then, _while, - _do + _do, + procedure }; /** diff --git a/include/elna/source/parser.hpp b/include/elna/source/parser.hpp index 615d52d..b3aef1e 100644 --- a/include/elna/source/parser.hpp +++ b/include/elna/source/parser.hpp @@ -15,9 +15,9 @@ namespace elna::source }; class declaration; - class definition; + class constant_definition; + class procedure_definition; class call_statement; - class question_mark_statement; class compound_statement; class assign_statement; class if_statement; @@ -32,9 +32,9 @@ namespace elna::source struct parser_visitor { virtual void visit(declaration *) = 0; - virtual void visit(definition *) = 0; + virtual void visit(constant_definition *) = 0; + virtual void visit(procedure_definition *) = 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; virtual void visit(if_statement *) = 0; @@ -50,9 +50,9 @@ namespace elna::source struct empty_visitor : parser_visitor { virtual void visit(declaration *declaration) override; - virtual void visit(definition *definition) override; + virtual void visit(constant_definition *definition) override; + virtual void visit(procedure_definition *definition) 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; virtual void visit(if_statement *) override; @@ -82,10 +82,6 @@ namespace elna::source { }; - class condition : public node - { - }; - /** * Variable declaration. */ @@ -106,16 +102,36 @@ namespace elna::source class definition : public node { std::string m_identifier; + + protected: + definition(const std::string& identifier); + + public: + std::string& identifier() noexcept; + }; + + class constant_definition : public definition + { std::unique_ptr m_body; public: - definition(const std::string& identifier, std::unique_ptr&& body); + constant_definition(const std::string& identifier, std::unique_ptr&& body); virtual void accept(parser_visitor *visitor) override; - std::string& identifier() noexcept; integer_literal& body(); }; + class procedure_definition : public definition + { + std::unique_ptr m_body; + + public: + procedure_definition(const std::string& identifier, std::unique_ptr&& body); + virtual void accept(parser_visitor *visitor) override; + + block& body(); + }; + class call_statement : public statement { std::string m_name; @@ -129,17 +145,6 @@ namespace elna::source expression& arguments(); }; - class question_mark_statement : public statement - { - std::unique_ptr m_body; - - public: - question_mark_statement(std::unique_ptr&& body); - virtual void accept(parser_visitor *visitor) override; - - condition& body(); - }; - class compound_statement : public statement { std::vector> m_statements; @@ -167,27 +172,27 @@ namespace elna::source class if_statement : public statement { - std::unique_ptr m_prerequisite; + std::unique_ptr m_prerequisite; std::unique_ptr m_body; public: - if_statement(std::unique_ptr&& prerequisite, std::unique_ptr&& body); + if_statement(std::unique_ptr&& prerequisite, std::unique_ptr&& body); virtual void accept(parser_visitor *visitor) override; - condition& prerequisite(); + expression& prerequisite(); statement& body(); }; class while_statement : public statement { - std::unique_ptr m_prerequisite; + std::unique_ptr m_prerequisite; std::unique_ptr m_body; public: - while_statement(std::unique_ptr&& prerequisite, std::unique_ptr&& body); + while_statement(std::unique_ptr&& prerequisite, std::unique_ptr&& body); virtual void accept(parser_visitor *visitor) override; - condition& prerequisite(); + expression& prerequisite(); statement& body(); }; @@ -230,7 +235,7 @@ namespace elna::source std::int32_t number() const noexcept; }; - class boolean_literal : public condition + class boolean_literal : public expression { bool m_boolean; @@ -273,12 +278,10 @@ namespace elna::source std::unique_ptr parse_factor(); std::unique_ptr parse_term(); std::unique_ptr parse_expression(); - std::unique_ptr parse_condition(); - std::unique_ptr parse_definition(); + std::unique_ptr parse_constant_definition(); std::unique_ptr parse_declaration(); std::unique_ptr parse_statement(); std::unique_ptr parse_call_statement(); - std::unique_ptr parse_question_mark_statement(); std::unique_ptr parse_compound_statement(); std::unique_ptr parse_assign_statement(); std::unique_ptr parse_if_statement(); diff --git a/include/elna/source/semantic.hpp b/include/elna/source/semantic.hpp index 6d2e311..5022814 100644 --- a/include/elna/source/semantic.hpp +++ b/include/elna/source/semantic.hpp @@ -9,7 +9,7 @@ namespace elna::source std::shared_ptr table; public: - void visit(definition *definition) override; + void visit(constant_definition *definition) override; void visit(declaration *declaration) override; void visit(block *block) override; }; diff --git a/source/lexer.cpp b/source/lexer.cpp index a1f7b6b..1382259 100644 --- a/source/lexer.cpp +++ b/source/lexer.cpp @@ -350,10 +350,6 @@ namespace elna::source { tokens.emplace_back(token::type::comma, iterator.position()); } - else if (*iterator == '?') - { - tokens.emplace_back(token::type::question_mark, iterator.position()); - } else if (*iterator == '.') { tokens.emplace_back(token::type::dot, iterator.position()); @@ -407,6 +403,10 @@ namespace elna::source { tokens.emplace_back(token::type::boolean, 0, iterator.position()); } + else if (word == "proc") + { + tokens.emplace_back(token::type::procedure, 0, iterator.position()); + } else { tokens.emplace_back(token::type::identifier, word.c_str(), iterator.position()); diff --git a/source/parser.cpp b/source/parser.cpp index fadf5e1..e0dc3c3 100644 --- a/source/parser.cpp +++ b/source/parser.cpp @@ -7,7 +7,12 @@ namespace elna::source { } - void empty_visitor::visit(definition *definition) + void empty_visitor::visit(constant_definition *definition) + { + definition->body().accept(this); + } + + void empty_visitor::visit(procedure_definition *definition) { definition->body().accept(this); } @@ -17,11 +22,6 @@ namespace elna::source statement->arguments().accept(this); } - void empty_visitor::visit(question_mark_statement *statement) - { - statement->body().accept(this); - } - void empty_visitor::visit(compound_statement *statement) { for (auto& nested_statement : statement->statements()) @@ -95,24 +95,19 @@ namespace elna::source { } - std::string& declaration::identifier() noexcept - { - return m_identifier; - } - - definition::definition(const std::string& identifier, std::unique_ptr&& body) - : m_identifier(std::move(identifier)), m_body(std::move(body)) - { - } - void declaration::accept(parser_visitor *visitor) { visitor->visit(this); } - void definition::accept(parser_visitor *visitor) + std::string& declaration::identifier() noexcept + { + return m_identifier; + } + + definition::definition(const std::string& identifier) + : m_identifier(identifier) { - visitor->visit(this); } std::string& definition::identifier() noexcept @@ -120,7 +115,32 @@ namespace elna::source return m_identifier; } - integer_literal& definition::body() + constant_definition::constant_definition(const std::string& identifier, std::unique_ptr&& body) + : definition(identifier), m_body(std::move(body)) + { + } + + void constant_definition::accept(parser_visitor *visitor) + { + visitor->visit(this); + } + + integer_literal& constant_definition::body() + { + return *m_body; + } + + procedure_definition::procedure_definition(const std::string& identifier, std::unique_ptr&& body) + : definition(identifier), m_body(std::move(body)) + { + } + + void procedure_definition::accept(parser_visitor *visitor) + { + visitor->visit(this); + } + + block& procedure_definition::body() { return *m_body; } @@ -279,21 +299,6 @@ namespace elna::source return *m_body; } - question_mark_statement::question_mark_statement(std::unique_ptr&& body) - : m_body(std::move(body)) - { - } - - void question_mark_statement::accept(parser_visitor *visitor) - { - visitor->visit(this); - } - - condition& question_mark_statement::body() - { - return *m_body; - } - compound_statement::compound_statement(std::vector>&& statements) : m_statements(std::move(statements)) { @@ -329,7 +334,7 @@ namespace elna::source return *m_rvalue; } - if_statement::if_statement(std::unique_ptr&& prerequisite, std::unique_ptr&& body) + if_statement::if_statement(std::unique_ptr&& prerequisite, std::unique_ptr&& body) : m_prerequisite(std::move(prerequisite)), m_body(std::move(body)) { } @@ -339,7 +344,7 @@ namespace elna::source visitor->visit(this); } - condition& if_statement::prerequisite() + expression& if_statement::prerequisite() { return *m_prerequisite; } @@ -349,7 +354,7 @@ namespace elna::source return *m_body; } - while_statement::while_statement(std::unique_ptr&& prerequisite, std::unique_ptr&& body) + while_statement::while_statement(std::unique_ptr&& prerequisite, std::unique_ptr&& body) : m_prerequisite(std::move(prerequisite)), m_body(std::move(body)) { } @@ -359,7 +364,7 @@ namespace elna::source visitor->visit(this); } - condition& while_statement::prerequisite() + expression& while_statement::prerequisite() { return *m_prerequisite; } @@ -407,6 +412,12 @@ namespace elna::source ++iterator; return result; } + else if (iterator->of() == source::token::token::type::boolean) + { + auto result = std::make_unique(iterator->number()); + ++iterator; + return result; + } else if (iterator->of() == source::token::type::left_paren) { ++iterator; @@ -458,18 +469,7 @@ namespace elna::source return term; } - std::unique_ptr parser::parse_condition() - { - if (iterator->of() == source::token::token::type::boolean) - { - auto result = std::make_unique(iterator->number()); - ++iterator; - return result; - } - return nullptr; - } - - std::unique_ptr parser::parse_definition() + std::unique_ptr parser::parse_constant_definition() { auto definition_identifier = iterator.advance(token::type::identifier); @@ -484,7 +484,7 @@ namespace elna::source if (iterator->of() == source::token::type::number) { - auto result = std::make_unique(definition_identifier.value().get().identifier(), + auto result = std::make_unique(definition_identifier.value().get().identifier(), std::make_unique(iterator->number())); ++iterator; return result; @@ -519,10 +519,6 @@ namespace elna::source { return parse_call_statement(); } - else if (iterator.current(token::type::question_mark)) - { - return parse_question_mark_statement(); - } else if (iterator.current(token::type::begin)) { return parse_compound_statement(); @@ -555,21 +551,6 @@ namespace elna::source return nullptr; } - std::unique_ptr parser::parse_question_mark_statement() - { - if (!iterator.advance(token::type::question_mark)) - { - return nullptr; - } - auto question_mark_body = parse_condition(); - - if (question_mark_body != nullptr) - { - return std::make_unique(std::move(question_mark_body)); - } - return nullptr; - } - std::unique_ptr parser::parse_compound_statement() { if (!iterator.advance(token::type::begin)) @@ -624,7 +605,7 @@ namespace elna::source { return nullptr; } - auto condition = parse_condition(); + auto condition = parse_expression(); if (condition == nullptr || !iterator.skip(token::type::then)) { @@ -645,7 +626,7 @@ namespace elna::source { return nullptr; } - auto condition = parse_condition(); + auto condition = parse_expression(); if (condition == nullptr || !iterator.skip(token::type::_do)) { @@ -671,7 +652,7 @@ namespace elna::source ++iterator; // Skip const. std::unique_ptr parsed_definition; - while ((parsed_definition = parse_definition()) != nullptr) + while ((parsed_definition = parse_constant_definition()) != nullptr) { definitions.push_back(std::move(parsed_definition)); diff --git a/source/semantic.cpp b/source/semantic.cpp index bd0eb94..7d3660a 100644 --- a/source/semantic.cpp +++ b/source/semantic.cpp @@ -3,7 +3,7 @@ namespace elna::source { - void name_analysis_visitor::visit(definition *definition) + void name_analysis_visitor::visit(constant_definition *definition) { this->table->enter(definition->identifier(), std::make_shared(constant_info(definition->body().number()))); diff --git a/tests/expectations/print_boolean.txt b/tests/expectations/print_boolean.txt index b261da1..532e7b0 100644 --- a/tests/expectations/print_boolean.txt +++ b/tests/expectations/print_boolean.txt @@ -1,2 +1,2 @@ -1 -0 +t +f diff --git a/tests/print_boolean.eln b/tests/print_boolean.eln index bc71153..7b24a1e 100644 --- a/tests/print_boolean.eln +++ b/tests/print_boolean.eln @@ -1,4 +1,4 @@ begin - ? True; - ? False + writeb(True); + writeb(False) end. diff --git a/tests/subtraction.eln b/tests/subtraction.eln index cfad17e..05c22fc 100644 --- a/tests/subtraction.eln +++ b/tests/subtraction.eln @@ -1,2 +1,2 @@ -write(5 - 4) +writei(5 - 4) . diff --git a/tests/tester.cpp b/tests/tester.cpp index 2c54ade..9538da4 100755 --- a/tests/tester.cpp +++ b/tests/tester.cpp @@ -114,9 +114,8 @@ namespace elna boost::asio::io_service io_service; std::future buffer; - boost::process::child spike( - "/opt/riscv/bin/spike", "--isa=RV32IMAC", - "/opt/riscv/riscv32-unknown-elf/bin/pk", + boost::process::child qemu( + boost::process::search_path("qemu-riscv32"), test_binary.string(), boost::process::std_out > buffer, boost::process::std_err > buffer, @@ -124,7 +123,7 @@ namespace elna ); io_service.run(); - return test_result{ test_status::successful, spike.exit_code(), buffer.get() }; + return test_result{ test_status::successful, qemu.exit_code(), buffer.get() }; } static test_results run_in_path(const std::filesystem::path test_directory)