JSSpecCompiler: Add function call canonicalization pass
It simplifies ladders of BinaryOperators nodes in the function call arguments into nice and neat FunctionCall node. Ladders initially appear since I do not want to complicate expression parser, so it interprets `f(a, b, c, d)` as `f "function_call_operator" (a, (b, (c, d))))`.
This commit is contained in:
parent
1c4cd34320
commit
72794e7843
Notes:
sideshowbarker
2024-07-17 01:04:03 +09:00
Author: https://github.com/DanShaders Commit: https://github.com/SerenityOS/serenity/commit/72794e7843 Pull-request: https://github.com/SerenityOS/serenity/pull/20917
4 changed files with 71 additions and 2 deletions
|
@ -1,6 +1,7 @@
|
|||
set(SOURCES
|
||||
AST/AST.cpp
|
||||
AST/ASTPrinting.cpp
|
||||
Compiler/FunctionCallCanonicalizationPass.cpp
|
||||
Compiler/GenericASTPass.cpp
|
||||
Parser/Lexer.cpp
|
||||
Parser/ParseError.cpp
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Dan Klishch <danilklishch@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "Compiler/FunctionCallCanonicalizationPass.h"
|
||||
#include "AST/AST.h"
|
||||
|
||||
namespace JSSpecCompiler {
|
||||
|
||||
RecursionDecision FunctionCallCanonicalizationPass::on_entry(Tree tree)
|
||||
{
|
||||
if (auto binary_operation = as<BinaryOperation>(tree); binary_operation) {
|
||||
if (binary_operation->m_operation == BinaryOperator::FunctionCall) {
|
||||
Vector<Tree> arguments;
|
||||
|
||||
auto current_tree = binary_operation->m_right;
|
||||
while (true) {
|
||||
auto argument_tree = as<BinaryOperation>(current_tree);
|
||||
if (!argument_tree || argument_tree->m_operation != BinaryOperator::Comma)
|
||||
break;
|
||||
arguments.append(argument_tree->m_left);
|
||||
current_tree = argument_tree->m_right;
|
||||
}
|
||||
arguments.append(current_tree);
|
||||
|
||||
replace_current_node_with(make_ref_counted<FunctionCall>(binary_operation->m_left, move(arguments)));
|
||||
}
|
||||
}
|
||||
return RecursionDecision::Recurse;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Dan Klishch <danilklishch@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Compiler/GenericASTPass.h"
|
||||
|
||||
namespace JSSpecCompiler {
|
||||
|
||||
// FunctionCallCanonicalizationPass simplifies ladders of BinaryOperators nodes in the function call
|
||||
// arguments into nice and neat FunctionCall nodes.
|
||||
//
|
||||
// Ladders initially appear since I do not want to complicate expression parser, so it interprets
|
||||
// `f(a, b, c, d)` as `f "function_call_operator" (a, (b, (c, d))))`.
|
||||
class FunctionCallCanonicalizationPass : public GenericASTPass {
|
||||
public:
|
||||
using GenericASTPass::GenericASTPass;
|
||||
|
||||
protected:
|
||||
RecursionDecision on_entry(Tree tree) override;
|
||||
};
|
||||
|
||||
}
|
|
@ -9,12 +9,16 @@
|
|||
#include <LibMain/Main.h>
|
||||
#include <LibXML/Parser/Parser.h>
|
||||
|
||||
#include "Compiler/FunctionCallCanonicalizationPass.h"
|
||||
#include "Function.h"
|
||||
#include "Parser/SpecParser.h"
|
||||
|
||||
ErrorOr<int> serenity_main(Main::Arguments)
|
||||
{
|
||||
using namespace JSSpecCompiler;
|
||||
|
||||
ExecutionContext context;
|
||||
|
||||
auto input = TRY(TRY(Core::File::standard_input())->read_until_eof());
|
||||
XML::Parser parser { StringView(input.bytes()) };
|
||||
|
||||
|
@ -30,8 +34,12 @@ ErrorOr<int> serenity_main(Main::Arguments)
|
|||
outln("{}", maybe_function.error()->to_string());
|
||||
return 1;
|
||||
}
|
||||
auto function = maybe_function.value();
|
||||
auto spec_function = maybe_function.value();
|
||||
|
||||
out("{}", function.m_algorithm.m_tree);
|
||||
auto function = make_ref_counted<JSSpecCompiler::Function>(&context, spec_function.m_name, spec_function.m_algorithm.m_tree);
|
||||
|
||||
FunctionCallCanonicalizationPass(function).run();
|
||||
|
||||
out("{}", function->m_ast);
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue