Parse parameter list
This commit is contained in:
parent
44e32760ca
commit
07521f2b58
@ -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));
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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()
|
||||||
|
2
tests/expectations/procedure_2_statements.txt
Normal file
2
tests/expectations/procedure_2_statements.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
5
|
||||||
|
3
|
1
tests/expectations/procedure_print_argument.txt
Normal file
1
tests/expectations/procedure_print_argument.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
5
|
9
tests/procedure_2_statements.eln
Normal file
9
tests/procedure_2_statements.eln
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
proc g()
|
||||||
|
begin
|
||||||
|
writei(5);
|
||||||
|
writei(3)
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
g()
|
||||||
|
end.
|
@ -1,4 +1,4 @@
|
|||||||
proc f; writei(5);
|
proc f() writei(5);
|
||||||
|
|
||||||
begin
|
begin
|
||||||
f()
|
f()
|
||||||
|
5
tests/procedure_print_argument.eln
Normal file
5
tests/procedure_print_argument.eln
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
proc f(a: Int) writei(a);
|
||||||
|
|
||||||
|
begin
|
||||||
|
f(5)
|
||||||
|
end.
|
@ -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() });
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user