Skip to content

Commit 72794e7

Browse files
DanShadersADKaster
authored andcommitted
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))))`.
1 parent 1c4cd34 commit 72794e7

File tree

4 files changed

+71
-2
lines changed

4 files changed

+71
-2
lines changed

Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
set(SOURCES
22
AST/AST.cpp
33
AST/ASTPrinting.cpp
4+
Compiler/FunctionCallCanonicalizationPass.cpp
45
Compiler/GenericASTPass.cpp
56
Parser/Lexer.cpp
67
Parser/ParseError.cpp
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright (c) 2023, Dan Klishch <danilklishch@gmail.com>
3+
*
4+
* SPDX-License-Identifier: BSD-2-Clause
5+
*/
6+
7+
#include "Compiler/FunctionCallCanonicalizationPass.h"
8+
#include "AST/AST.h"
9+
10+
namespace JSSpecCompiler {
11+
12+
RecursionDecision FunctionCallCanonicalizationPass::on_entry(Tree tree)
13+
{
14+
if (auto binary_operation = as<BinaryOperation>(tree); binary_operation) {
15+
if (binary_operation->m_operation == BinaryOperator::FunctionCall) {
16+
Vector<Tree> arguments;
17+
18+
auto current_tree = binary_operation->m_right;
19+
while (true) {
20+
auto argument_tree = as<BinaryOperation>(current_tree);
21+
if (!argument_tree || argument_tree->m_operation != BinaryOperator::Comma)
22+
break;
23+
arguments.append(argument_tree->m_left);
24+
current_tree = argument_tree->m_right;
25+
}
26+
arguments.append(current_tree);
27+
28+
replace_current_node_with(make_ref_counted<FunctionCall>(binary_operation->m_left, move(arguments)));
29+
}
30+
}
31+
return RecursionDecision::Recurse;
32+
}
33+
34+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright (c) 2023, Dan Klishch <danilklishch@gmail.com>
3+
*
4+
* SPDX-License-Identifier: BSD-2-Clause
5+
*/
6+
7+
#pragma once
8+
9+
#include "Compiler/GenericASTPass.h"
10+
11+
namespace JSSpecCompiler {
12+
13+
// FunctionCallCanonicalizationPass simplifies ladders of BinaryOperators nodes in the function call
14+
// arguments into nice and neat FunctionCall nodes.
15+
//
16+
// Ladders initially appear since I do not want to complicate expression parser, so it interprets
17+
// `f(a, b, c, d)` as `f "function_call_operator" (a, (b, (c, d))))`.
18+
class FunctionCallCanonicalizationPass : public GenericASTPass {
19+
public:
20+
using GenericASTPass::GenericASTPass;
21+
22+
protected:
23+
RecursionDecision on_entry(Tree tree) override;
24+
};
25+
26+
}

Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/main.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,16 @@
99
#include <LibMain/Main.h>
1010
#include <LibXML/Parser/Parser.h>
1111

12+
#include "Compiler/FunctionCallCanonicalizationPass.h"
13+
#include "Function.h"
1214
#include "Parser/SpecParser.h"
1315

1416
ErrorOr<int> serenity_main(Main::Arguments)
1517
{
1618
using namespace JSSpecCompiler;
1719

20+
ExecutionContext context;
21+
1822
auto input = TRY(TRY(Core::File::standard_input())->read_until_eof());
1923
XML::Parser parser { StringView(input.bytes()) };
2024

@@ -30,8 +34,12 @@ ErrorOr<int> serenity_main(Main::Arguments)
3034
outln("{}", maybe_function.error()->to_string());
3135
return 1;
3236
}
33-
auto function = maybe_function.value();
37+
auto spec_function = maybe_function.value();
38+
39+
auto function = make_ref_counted<JSSpecCompiler::Function>(&context, spec_function.m_name, spec_function.m_algorithm.m_tree);
40+
41+
FunctionCallCanonicalizationPass(function).run();
3442

35-
out("{}", function.m_algorithm.m_tree);
43+
out("{}", function->m_ast);
3644
return 0;
3745
}

0 commit comments

Comments
 (0)