Parse parameter list

This commit is contained in:
Eugen Wissner 2024-03-28 00:55:13 +01:00
parent 44e32760ca
commit 07521f2b58
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
10 changed files with 76 additions and 14 deletions

View File

@ -157,6 +157,8 @@ namespace elna::riscv
void visitor::prologue() void visitor::prologue()
{ {
this->variable_counter = 1;
this->instructions.push_back(instruction(base_opcode::opImm)); this->instructions.push_back(instruction(base_opcode::opImm));
this->instructions.push_back(instruction(base_opcode::store)); this->instructions.push_back(instruction(base_opcode::store));
this->instructions.push_back(instruction(base_opcode::store)); this->instructions.push_back(instruction(base_opcode::store));
@ -195,7 +197,7 @@ namespace elna::riscv
this->instructions.push_back(instruction(base_opcode::op) this->instructions.push_back(instruction(base_opcode::op)
.r(x_register::a0, funct3_t::_and, x_register::zero, x_register::zero)); .r(x_register::a0, funct3_t::_and, x_register::zero, x_register::zero));
epilogue(static_cast<std::uint32_t>(variable_counter * 4 + 8 + main_symbol->stack_size())); epilogue(static_cast<std::uint32_t>(this->variable_counter * 4 + 8 + main_symbol->stack_size()));
this->writer->sink(definition->identifier(), this->writer->sink(definition->identifier(),
reinterpret_cast<const std::byte *>(this->instructions.data()), reinterpret_cast<const std::byte *>(this->instructions.data()),
this->instructions.size() * sizeof(instruction)); this->instructions.size() * sizeof(instruction));
@ -224,7 +226,7 @@ namespace elna::riscv
this->instructions.push_back(instruction(base_opcode::op) this->instructions.push_back(instruction(base_opcode::op)
.r(x_register::a0, funct3_t::_and, x_register::zero, x_register::zero)); .r(x_register::a0, funct3_t::_and, x_register::zero, x_register::zero));
epilogue(static_cast<std::uint32_t>(variable_counter * 4 + 8 + main_symbol->stack_size())); epilogue(static_cast<std::uint32_t>(this->variable_counter * 4 + 8 + main_symbol->stack_size()));
this->writer->sink("main", reinterpret_cast<const std::byte *>(this->instructions.data()), this->writer->sink("main", reinterpret_cast<const std::byte *>(this->instructions.data()),
this->instructions.size() * sizeof(instruction)); this->instructions.size() * sizeof(instruction));
} }

View File

@ -38,7 +38,7 @@ namespace elna::cli
{ {
for (const auto& compile_error : lex_result.errors()) for (const auto& compile_error : lex_result.errors())
{ {
std::cout << compile_error->line() << ':' << compile_error->column() std::cerr << compile_error->line() << ':' << compile_error->column()
<< ": " << compile_error->what() << std::endl; << ": " << compile_error->what() << std::endl;
} }
return 1; return 1;
@ -49,7 +49,7 @@ namespace elna::cli
{ {
for (const auto& compile_error : parser.errors()) for (const auto& compile_error : parser.errors())
{ {
std::cout << compile_error->line() << ':' << compile_error->column() std::cerr << compile_error->line() << ':' << compile_error->column()
<< ": " << compile_error->what() << std::endl; << ": " << compile_error->what() << std::endl;
} }
return 2; return 2;

View File

@ -44,8 +44,10 @@ namespace elna
void add_exit_code(const test_status result) noexcept; void add_exit_code(const test_status result) noexcept;
}; };
test_result run_for_output(boost::asio::io_context& context, const std::filesystem::path& binary, boost::process::v2::process_stdio get_output_streams(const std::uint8_t stream_number,
std::initializer_list<boost::string_view> arguments); boost::asio::readable_pipe& read_pipe);
test_result run_for_output(boost::asio::io_context& context, const std::uint8_t stream_number,
const std::filesystem::path& binary, std::initializer_list<boost::string_view> arguments);
test_result build_test(boost::asio::io_context& context, const std::filesystem::directory_entry& test_entry); test_result build_test(boost::asio::io_context& context, const std::filesystem::directory_entry& test_entry);
test_result run_test(boost::asio::io_context& context, const std::filesystem::directory_entry& test_entry); test_result run_test(boost::asio::io_context& context, const std::filesystem::directory_entry& test_entry);
void print_result(const std::filesystem::directory_entry& test_entry, const test_result& result); void print_result(const std::filesystem::directory_entry& test_entry, const test_result& result);

View File

@ -516,18 +516,43 @@ namespace elna::source
} }
auto definition_identifier = iterator.advance(token::type::identifier); auto definition_identifier = iterator.advance(token::type::identifier);
if (!definition_identifier.has_value() || !iterator.skip(token::type::semicolon)) if (!definition_identifier.has_value() || !iterator.skip(token::type::left_paren))
{ {
return nullptr; return nullptr;
} }
std::vector<std::unique_ptr<declaration>> declarations;
while (!iterator.current(token::type::right_paren))
{
std::unique_ptr<declaration> parsed_declaration = parse_declaration();
if (parsed_declaration == nullptr)
{
return nullptr;
}
declarations.push_back(std::move(parsed_declaration));
if (iterator->of() == token::type::comma)
{
++iterator;
continue;
}
else if (iterator->of() != token::type::right_paren)
{
iterator.add_error(*iterator);
return nullptr;
}
}
iterator.skip(token::type::right_paren);
auto definition_body = parse_block(); auto definition_body = parse_block();
if (definition_body == nullptr || !iterator.skip(token::type::semicolon)) if (definition_body == nullptr || !iterator.skip(token::type::semicolon))
{ {
return nullptr; return nullptr;
} }
return std::make_unique<procedure_definition>(definition_identifier->get().identifier(), auto procedure = std::make_unique<procedure_definition>(definition_identifier->get().identifier(),
std::move(definition_body)); std::move(definition_body));
procedure->parameters() = std::move(declarations);
return procedure;
} }
std::unique_ptr<declaration> parser::parse_declaration() std::unique_ptr<declaration> parser::parse_declaration()

View File

@ -0,0 +1,2 @@
5
3

View File

@ -0,0 +1 @@
5

View File

@ -0,0 +1,9 @@
proc g()
begin
writei(5);
writei(3)
end;
begin
g()
end.

View File

@ -1,4 +1,4 @@
proc f; writei(5); proc f() writei(5);
begin begin
f() f()

View File

@ -0,0 +1,5 @@
proc f(a: Int) writei(a);
begin
f(5)
end.

View File

@ -43,17 +43,33 @@ namespace elna
return in_build_directory() / path; return in_build_directory() / path;
} }
test_result run_for_output(boost::asio::io_context& context, const std::filesystem::path& binary, boost::process::v2::process_stdio get_output_streams(const std::uint8_t stream_number,
std::initializer_list<boost::string_view> arguments) boost::asio::readable_pipe& read_pipe)
{
if (stream_number == 1)
{
return boost::process::v2::process_stdio{ nullptr, read_pipe };
}
if (stream_number == 2)
{
return boost::process::v2::process_stdio{ nullptr, {}, read_pipe };
}
return boost::process::v2::process_stdio{ nullptr, read_pipe, read_pipe };
}
test_result run_for_output(boost::asio::io_context& context, const std::uint8_t stream_number,
const std::filesystem::path& binary, std::initializer_list<boost::string_view> arguments)
{ {
boost::asio::readable_pipe read_pipe{ context }; boost::asio::readable_pipe read_pipe{ context };
test_result result{}; test_result result{};
std::string output; std::string output;
boost::asio::dynamic_string_buffer buffer = boost::asio::dynamic_buffer(output); boost::asio::dynamic_string_buffer buffer = boost::asio::dynamic_buffer(output);
boost::system::error_code ec; boost::system::error_code ec;
boost::process::v2::process_stdio process_stdio;
boost::process::v2::process elna_child(context, boost::process::v2::process elna_child(context,
binary, arguments, binary, arguments,
boost::process::v2::process_stdio{ nullptr, read_pipe, read_pipe }); get_output_streams(stream_number, read_pipe));
do do
{ {
std::size_t transferred = read_pipe.read_some(buffer.prepare(512), ec); std::size_t transferred = read_pipe.read_some(buffer.prepare(512), ec);
@ -84,7 +100,7 @@ namespace elna
std::filesystem::remove(test_binary); std::filesystem::remove(test_binary);
std::filesystem::remove(test_object); std::filesystem::remove(test_object);
test_result result = run_for_output(context, "./build/bin/elna", test_result result = run_for_output(context, 2, "./build/bin/elna",
{ "-o", test_object.string(), test_entry.path().string() }); { "-o", test_object.string(), test_entry.path().string() });
if (result.code != 0) if (result.code != 0)
@ -157,7 +173,7 @@ namespace elna
std::filesystem::path test_binary = in_build_directory(test_filename); std::filesystem::path test_binary = in_build_directory(test_filename);
test_binary.replace_extension(); test_binary.replace_extension();
return run_for_output(context, return run_for_output(context, 1,
boost::process::search_path("qemu-riscv32"), boost::process::search_path("qemu-riscv32"),
{ test_binary.string() }); { test_binary.string() });
} }