diff --git a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/AST.h b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/AST.h index 4b72da89ab..879c3bab31 100644 --- a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/AST.h +++ b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/AST.h @@ -456,7 +456,12 @@ public: { } - Variant m_function; + FunctionPointer(FunctionDefinitionRef function_definition) + : m_function(function_definition) + { + } + + Variant m_function; protected: void dump_tree(StringBuilder& builder) override; diff --git a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/ASTPrinting.cpp b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/ASTPrinting.cpp index 2598522170..c7cd9e5729 100644 --- a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/ASTPrinting.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/ASTPrinting.cpp @@ -164,7 +164,7 @@ void FunctionPointer::dump_tree(StringBuilder& builder) [&](StringView name) { dump_node(builder, "Func external \"{}\"", name); }, - [&](FunctionRef function) { + [&](FunctionDefinitionRef function) { dump_node(builder, "Func local \"{}\"", function->m_name); }); } diff --git a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Compiler/CompilerPass.h b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Compiler/CompilerPass.h index 088f4393d3..b033a5b87c 100644 --- a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Compiler/CompilerPass.h +++ b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Compiler/CompilerPass.h @@ -15,7 +15,7 @@ namespace JSSpecCompiler { class CompilerPass { public: - CompilerPass(FunctionRef function) + CompilerPass(FunctionDefinitionRef function) : m_function(function) { } @@ -25,7 +25,7 @@ public: virtual void run() = 0; protected: - FunctionRef m_function; + FunctionDefinitionRef m_function; }; } diff --git a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Compiler/GenericASTPass.h b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Compiler/GenericASTPass.h index 8f00f91b79..28fd987525 100644 --- a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Compiler/GenericASTPass.h +++ b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Compiler/GenericASTPass.h @@ -36,7 +36,7 @@ class GenericASTPass : public CompilerPass , protected RecursiveASTVisitor { public: - GenericASTPass(FunctionRef function) + GenericASTPass(FunctionDefinitionRef function) : CompilerPass(function) { } diff --git a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Compiler/ReferenceResolvingPass.cpp b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Compiler/ReferenceResolvingPass.cpp index 7f6954b99e..f1abfe5108 100644 --- a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Compiler/ReferenceResolvingPass.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Compiler/ReferenceResolvingPass.cpp @@ -29,7 +29,7 @@ RecursionDecision ReferenceResolvingPass::on_entry(Tree tree) void ReferenceResolvingPass::on_leave(Tree tree) { - auto& functions = m_function->m_context->m_functions; + auto& functions = m_function->m_translation_unit->function_index; if (auto reference = as(tree); reference) { auto name = reference->m_name; diff --git a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Forward.h b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Forward.h index 1d7d582093..4268b60098 100644 --- a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Forward.h +++ b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Forward.h @@ -60,8 +60,8 @@ class Algorithm; class SpecFunction; // Function.h -class ExecutionContext; -class Function; -using FunctionRef = Function*; +struct TranslationUnit; +class FunctionDefinition; +using FunctionDefinitionRef = FunctionDefinition*; } diff --git a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Function.cpp b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Function.cpp index aed1882c2a..1566933aac 100644 --- a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Function.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Function.cpp @@ -9,9 +9,23 @@ namespace JSSpecCompiler { -Function::Function(ExecutionContext* context, StringView name, Tree ast) - : m_context(context) - , m_name(name) +FunctionDefinitionRef TranslationUnit::adopt_function(NonnullRefPtr&& function) +{ + function->m_translation_unit = this; + function_index.set(function->m_name, make_ref_counted(function)); + + FunctionDefinitionRef result = function.ptr(); + function_definitions.append(move(function)); + return result; +} + +FunctionDeclaration::FunctionDeclaration(StringView name) + : m_name(name) +{ +} + +FunctionDefinition::FunctionDefinition(StringView name, Tree ast) + : FunctionDeclaration(name) , m_ast(move(ast)) , m_return_value(make_ref_counted("$return"sv)) { diff --git a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Function.h b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Function.h index 85ee1cdd83..b363200a7a 100644 --- a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Function.h +++ b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Function.h @@ -15,17 +15,27 @@ namespace JSSpecCompiler { -class ExecutionContext { -public: - HashMap m_functions; +struct TranslationUnit { + FunctionDefinitionRef adopt_function(NonnullRefPtr&& function); + + Vector> function_definitions; + HashMap function_index; }; -class Function : public RefCounted { +class FunctionDeclaration : public RefCounted { public: - Function(ExecutionContext* context, StringView name, Tree ast); + FunctionDeclaration(StringView name); - ExecutionContext* m_context; + virtual ~FunctionDeclaration() = default; + + TranslationUnit* m_translation_unit = nullptr; StringView m_name; +}; + +class FunctionDefinition : public FunctionDeclaration { +public: + FunctionDefinition(StringView name, Tree ast); + Tree m_ast; VariableDeclarationRef m_return_value; HashMap m_local_variables; diff --git a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/main.cpp b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/main.cpp index d057bc9e15..400618bdc3 100644 --- a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/main.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/main.cpp @@ -19,12 +19,12 @@ ErrorOr serenity_main(Main::Arguments) { using namespace JSSpecCompiler; - ExecutionContext context; + TranslationUnit translation_unit; // Functions referenced in DifferenceISODate // TODO: This is here just for testing. In a long run, we need some place, which is not // `serenity_main`, to store built-in functions. - auto& functions = context.m_functions; + auto& functions = translation_unit.function_index; functions.set("CompareISODate"sv, make_ref_counted("CompareISODate"sv)); functions.set("CreateDateDurationRecord"sv, make_ref_counted("CreateDateDurationRecord"sv)); functions.set("AddISODate"sv, make_ref_counted("AddISODate"sv)); @@ -50,7 +50,8 @@ ErrorOr serenity_main(Main::Arguments) } auto spec_function = maybe_function.value(); - auto function = make_ref_counted(&context, spec_function.m_name, spec_function.m_algorithm.m_tree); + auto* function = translation_unit.adopt_function( + make_ref_counted(spec_function.m_name, spec_function.m_algorithm.m_tree)); for (auto const& argument : spec_function.m_arguments) function->m_local_variables.set(argument.name, make_ref_counted(argument.name));