mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 15:27:42 +00:00
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
4 changed files with 71 additions and 2 deletions
|
@ -1,6 +1,7 @@
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
AST/AST.cpp
|
AST/AST.cpp
|
||||||
AST/ASTPrinting.cpp
|
AST/ASTPrinting.cpp
|
||||||
|
Compiler/FunctionCallCanonicalizationPass.cpp
|
||||||
Compiler/GenericASTPass.cpp
|
Compiler/GenericASTPass.cpp
|
||||||
Parser/Lexer.cpp
|
Parser/Lexer.cpp
|
||||||
Parser/ParseError.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 <LibMain/Main.h>
|
||||||
#include <LibXML/Parser/Parser.h>
|
#include <LibXML/Parser/Parser.h>
|
||||||
|
|
||||||
|
#include "Compiler/FunctionCallCanonicalizationPass.h"
|
||||||
|
#include "Function.h"
|
||||||
#include "Parser/SpecParser.h"
|
#include "Parser/SpecParser.h"
|
||||||
|
|
||||||
ErrorOr<int> serenity_main(Main::Arguments)
|
ErrorOr<int> serenity_main(Main::Arguments)
|
||||||
{
|
{
|
||||||
using namespace JSSpecCompiler;
|
using namespace JSSpecCompiler;
|
||||||
|
|
||||||
|
ExecutionContext context;
|
||||||
|
|
||||||
auto input = TRY(TRY(Core::File::standard_input())->read_until_eof());
|
auto input = TRY(TRY(Core::File::standard_input())->read_until_eof());
|
||||||
XML::Parser parser { StringView(input.bytes()) };
|
XML::Parser parser { StringView(input.bytes()) };
|
||||||
|
|
||||||
|
@ -30,8 +34,12 @@ ErrorOr<int> serenity_main(Main::Arguments)
|
||||||
outln("{}", maybe_function.error()->to_string());
|
outln("{}", maybe_function.error()->to_string());
|
||||||
return 1;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue