1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-28 17:25:06 +00:00

Shell: Add support for functions

This implementation does not have support for 'return' yet.
This commit is contained in:
AnotherTest 2020-09-13 15:54:33 +04:30 committed by Andreas Kling
parent 519aa2048a
commit d1550ea64f
6 changed files with 264 additions and 5 deletions

View file

@ -167,7 +167,10 @@ RefPtr<AST::Node> Parser::parse_sequence()
break;
}
auto first = parse_or_logical_sequence();
auto first = parse_function_decl();
if (!first)
first = parse_or_logical_sequence();
if (!first)
return var_decls;
@ -259,6 +262,90 @@ RefPtr<AST::Node> Parser::parse_variable_decls()
return create<AST::VariableDeclarations>(move(variables));
}
RefPtr<AST::Node> Parser::parse_function_decl()
{
auto rule_start = push_start();
auto restore = [&] {
m_offset = rule_start->offset;
return nullptr;
};
consume_while(is_whitespace);
auto offset_before_name = m_offset;
auto function_name = consume_while(is_word_character);
auto offset_after_name = m_offset;
if (function_name.is_empty())
return restore();
if (!expect('('))
return restore();
Vector<AST::FunctionDeclaration::NameWithPosition> arguments;
for (;;) {
consume_while(is_whitespace);
if (expect(')'))
break;
auto name_offset = m_offset;
auto arg_name = consume_while(is_word_character);
if (arg_name.is_empty()) {
// FIXME: Should this be a syntax error, or just return?
return restore();
}
arguments.append({ arg_name, { name_offset, m_offset } });
}
consume_while(is_whitespace);
{
RefPtr<AST::Node> syntax_error;
{
auto obrace_error_start = push_start();
syntax_error = create<AST::SyntaxError>("Expected an open brace '{' to start a function body");
}
if (!expect('{')) {
return create<AST::FunctionDeclaration>(
AST::FunctionDeclaration::NameWithPosition {
move(function_name),
{ offset_before_name, offset_after_name } },
move(arguments),
move(syntax_error));
}
}
auto body = parse_toplevel();
{
RefPtr<AST::SyntaxError> syntax_error;
{
auto cbrace_error_start = push_start();
syntax_error = create<AST::SyntaxError>("Expected a close brace '}' to end a function body");
}
if (!expect('}')) {
if (body)
body->set_is_syntax_error(*syntax_error);
else
body = move(syntax_error);
return create<AST::FunctionDeclaration>(
AST::FunctionDeclaration::NameWithPosition {
move(function_name),
{ offset_before_name, offset_after_name } },
move(arguments),
move(body));
}
}
return create<AST::FunctionDeclaration>(
AST::FunctionDeclaration::NameWithPosition {
move(function_name),
{ offset_before_name, offset_after_name } },
move(arguments),
move(body));
}
RefPtr<AST::Node> Parser::parse_or_logical_sequence()
{
consume_while(is_whitespace);