mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-21 20:15:17 +00:00
JSSpecCompiler: Let FunctionDeclaration know its name and category
This is achieved by moving ClauseHeader::{AbstractOperation,Accessor, Method} to Function.h itself and storing them in FunctionDeclaration. This commit also introduces QualifiedName class that is used to store function's name split by '.' (just like it appear in the spec).
This commit is contained in:
parent
70cfa60f56
commit
0e7c33b1be
Notes:
sideshowbarker
2024-07-17 01:46:43 +09:00
Author: https://github.com/DanShaders Commit: https://github.com/SerenityOS/serenity/commit/0e7c33b1be Pull-request: https://github.com/SerenityOS/serenity/pull/23647 Reviewed-by: https://github.com/ADKaster ✅
12 changed files with 170 additions and 96 deletions
|
@ -185,7 +185,7 @@ void Enumerator::dump_tree(StringBuilder& builder)
|
|||
|
||||
void FunctionPointer::dump_tree(StringBuilder& builder)
|
||||
{
|
||||
dump_node(builder, "Func \"{}\"", m_declaration->m_name);
|
||||
dump_node(builder, "Func \"{}\"", m_declaration->name());
|
||||
}
|
||||
|
||||
void List::dump_tree(StringBuilder& builder)
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace JSSpecCompiler {
|
|||
|
||||
void ReferenceResolvingPass::process_function()
|
||||
{
|
||||
for (auto argument : m_function->m_arguments)
|
||||
for (auto argument : m_function->arguments())
|
||||
m_function->m_local_variables.set(argument.name, make_ref_counted<NamedVariableDeclaration>(argument.name));
|
||||
GenericASTPass::process_function();
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ void ReferenceResolvingPass::on_leave(Tree tree)
|
|||
return;
|
||||
}
|
||||
|
||||
if (auto function = m_translation_unit->find_declaration_by_name(name)) {
|
||||
if (auto function = m_translation_unit->find_abstract_operation_by_name(name)) {
|
||||
replace_current_node_with(make_ref_counted<FunctionPointer>(function));
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/Enumerate.h>
|
||||
#include <AK/Queue.h>
|
||||
|
||||
#include "AST/AST.h"
|
||||
|
@ -430,9 +431,9 @@ void SSABuildingPass::rename_variables(Vertex u, Vertex from)
|
|||
void SSABuildingPass::rename_variables()
|
||||
{
|
||||
HashMap<StringView, size_t> argument_index_by_name;
|
||||
for (size_t i = 0; i < m_function->m_arguments.size(); ++i)
|
||||
argument_index_by_name.set(m_function->m_arguments[i].name, i);
|
||||
m_function->m_ssa_arguments.resize(m_function->m_arguments.size());
|
||||
for (auto [i, argument] : enumerate(m_function->arguments()))
|
||||
argument_index_by_name.set(argument.name, i);
|
||||
m_function->m_ssa_arguments.resize(m_function->arguments().size());
|
||||
|
||||
for (auto const& [name, var_decl] : m_function->m_local_variables) {
|
||||
make_new_ssa_variable_for(var_decl);
|
||||
|
|
|
@ -19,23 +19,21 @@ TranslationUnit::~TranslationUnit() = default;
|
|||
|
||||
void TranslationUnit::adopt_declaration(NonnullRefPtr<FunctionDeclaration>&& declaration)
|
||||
{
|
||||
declaration->m_translation_unit = this;
|
||||
m_function_index.set(declaration->m_name, declaration.ptr());
|
||||
if (auto decl_name = declaration->declaration(); decl_name.has<AbstractOperationDeclaration>())
|
||||
m_abstract_operation_index.set(decl_name.get<AbstractOperationDeclaration>().name, declaration.ptr());
|
||||
m_declarations_owner.append(move(declaration));
|
||||
}
|
||||
|
||||
FunctionDefinitionRef TranslationUnit::adopt_function(NonnullRefPtr<FunctionDefinition>&& definition)
|
||||
void TranslationUnit::adopt_function(NonnullRefPtr<FunctionDefinition>&& definition)
|
||||
{
|
||||
FunctionDefinitionRef result = definition.ptr();
|
||||
m_functions_to_compile.append(result);
|
||||
m_functions_to_compile.append(definition);
|
||||
adopt_declaration(definition);
|
||||
return result;
|
||||
}
|
||||
|
||||
FunctionDeclarationRef TranslationUnit::find_declaration_by_name(StringView name) const
|
||||
FunctionDeclarationRef TranslationUnit::find_abstract_operation_by_name(StringView name) const
|
||||
{
|
||||
auto it = m_function_index.find(name);
|
||||
if (it == m_function_index.end())
|
||||
auto it = m_abstract_operation_index.find(name);
|
||||
if (it == m_abstract_operation_index.end())
|
||||
return nullptr;
|
||||
return it->value;
|
||||
}
|
||||
|
@ -50,14 +48,39 @@ EnumeratorRef TranslationUnit::get_node_for_enumerator_value(StringView value)
|
|||
return enumerator;
|
||||
}
|
||||
|
||||
FunctionDeclaration::FunctionDeclaration(StringView name, Vector<FunctionArgument>&& arguments)
|
||||
: m_name(name)
|
||||
, m_arguments(arguments)
|
||||
FunctionDeclaration::FunctionDeclaration(Declaration&& declaration, Location location)
|
||||
: m_declaration(move(declaration))
|
||||
, m_location(location)
|
||||
{
|
||||
}
|
||||
|
||||
FunctionDefinition::FunctionDefinition(StringView name, Tree ast, Vector<FunctionArgument>&& arguments)
|
||||
: FunctionDeclaration(name, move(arguments))
|
||||
String FunctionDeclaration::name() const
|
||||
{
|
||||
return m_declaration.visit(
|
||||
[&](AbstractOperationDeclaration const& abstract_operation) {
|
||||
return abstract_operation.name.to_string();
|
||||
},
|
||||
[&](MethodDeclaration const& method) {
|
||||
return MUST(String::formatted("%{}%", method.name.to_string()));
|
||||
},
|
||||
[&](AccessorDeclaration const& accessor) {
|
||||
return MUST(String::formatted("%get {}%", accessor.name.to_string()));
|
||||
});
|
||||
}
|
||||
|
||||
ReadonlySpan<FunctionArgument> FunctionDeclaration::arguments() const
|
||||
{
|
||||
return m_declaration.visit(
|
||||
[&](AccessorDeclaration const&) {
|
||||
return ReadonlySpan<FunctionArgument> {};
|
||||
},
|
||||
[&](auto const& declaration) {
|
||||
return declaration.arguments.span();
|
||||
});
|
||||
}
|
||||
|
||||
FunctionDefinition::FunctionDefinition(Declaration&& declaration, Location location, Tree ast)
|
||||
: FunctionDeclaration(move(declaration), location)
|
||||
, m_ast(move(ast))
|
||||
, m_named_return_value(make_ref_counted<NamedVariableDeclaration>("$return"sv))
|
||||
{
|
||||
|
|
|
@ -22,9 +22,8 @@ public:
|
|||
~TranslationUnit();
|
||||
|
||||
void adopt_declaration(NonnullRefPtr<FunctionDeclaration>&& declaration);
|
||||
FunctionDefinitionRef adopt_function(NonnullRefPtr<FunctionDefinition>&& definition);
|
||||
|
||||
FunctionDeclarationRef find_declaration_by_name(StringView name) const;
|
||||
void adopt_function(NonnullRefPtr<FunctionDefinition>&& definition);
|
||||
FunctionDeclarationRef find_abstract_operation_by_name(StringView name) const;
|
||||
|
||||
StringView filename() const { return m_filename; }
|
||||
DiagnosticEngine& diag() { return m_diagnostic_engine; }
|
||||
|
@ -37,7 +36,7 @@ private:
|
|||
DiagnosticEngine m_diagnostic_engine;
|
||||
Vector<FunctionDefinitionRef> m_functions_to_compile;
|
||||
Vector<NonnullRefPtr<FunctionDeclaration>> m_declarations_owner;
|
||||
HashMap<StringView, FunctionDeclarationRef> m_function_index;
|
||||
HashMap<FlyString, FunctionDeclarationRef> m_abstract_operation_index;
|
||||
HashMap<StringView, EnumeratorRef> m_enumerator_nodes;
|
||||
};
|
||||
|
||||
|
@ -46,20 +45,95 @@ struct FunctionArgument {
|
|||
size_t optional_arguments_group;
|
||||
};
|
||||
|
||||
class QualifiedName {
|
||||
public:
|
||||
QualifiedName() { }
|
||||
|
||||
QualifiedName(ReadonlySpan<StringView> parsed_name)
|
||||
{
|
||||
m_components.ensure_capacity(parsed_name.size());
|
||||
for (auto component : parsed_name)
|
||||
m_components.unchecked_append(MUST(FlyString::from_utf8(component)));
|
||||
}
|
||||
|
||||
QualifiedName(ReadonlySpan<FlyString> parsed_name)
|
||||
{
|
||||
m_components.ensure_capacity(parsed_name.size());
|
||||
for (auto component : parsed_name)
|
||||
m_components.unchecked_append(component);
|
||||
}
|
||||
|
||||
String to_string() const
|
||||
{
|
||||
return MUST(String::join("."sv, m_components));
|
||||
}
|
||||
|
||||
Vector<FlyString> const& components() const
|
||||
{
|
||||
return m_components;
|
||||
}
|
||||
|
||||
FlyString last_component() const
|
||||
{
|
||||
return m_components.last();
|
||||
}
|
||||
|
||||
ReadonlySpan<FlyString> without_last_component() const
|
||||
{
|
||||
return components().span().slice(0, components().size() - 1);
|
||||
}
|
||||
|
||||
QualifiedName slice(size_t start, size_t length) const
|
||||
{
|
||||
return { m_components.span().slice(start, length) };
|
||||
}
|
||||
|
||||
QualifiedName with_appended(FlyString component) const
|
||||
{
|
||||
auto new_components = m_components;
|
||||
new_components.append(component);
|
||||
return { new_components };
|
||||
}
|
||||
|
||||
private:
|
||||
Vector<FlyString> m_components;
|
||||
};
|
||||
|
||||
struct AbstractOperationDeclaration {
|
||||
FlyString name;
|
||||
Vector<FunctionArgument> arguments;
|
||||
};
|
||||
|
||||
struct AccessorDeclaration {
|
||||
QualifiedName name;
|
||||
};
|
||||
|
||||
struct MethodDeclaration {
|
||||
QualifiedName name;
|
||||
Vector<FunctionArgument> arguments;
|
||||
};
|
||||
|
||||
using Declaration = Variant<AbstractOperationDeclaration, AccessorDeclaration, MethodDeclaration>;
|
||||
|
||||
class FunctionDeclaration : public RefCounted<FunctionDeclaration> {
|
||||
public:
|
||||
FunctionDeclaration(StringView name, Vector<FunctionArgument>&& arguments);
|
||||
FunctionDeclaration(Declaration&& declaration, Location location);
|
||||
|
||||
virtual ~FunctionDeclaration() = default;
|
||||
|
||||
TranslationUnitRef m_translation_unit = nullptr;
|
||||
StringView m_name;
|
||||
Vector<FunctionArgument> m_arguments;
|
||||
Declaration const& declaration() const { return m_declaration; }
|
||||
Location location() const { return m_location; }
|
||||
String name() const;
|
||||
ReadonlySpan<FunctionArgument> arguments() const;
|
||||
|
||||
private:
|
||||
Declaration m_declaration;
|
||||
Location m_location;
|
||||
};
|
||||
|
||||
class FunctionDefinition : public FunctionDeclaration {
|
||||
public:
|
||||
FunctionDefinition(StringView name, Tree ast, Vector<FunctionArgument>&& arguments);
|
||||
FunctionDefinition(Declaration&& declaration, Location location, Tree ast);
|
||||
|
||||
void reindex_ssa_variables();
|
||||
|
||||
|
|
|
@ -28,7 +28,13 @@ NonnullRefPtr<FunctionDefinition> CppASTConverter::convert()
|
|||
for (auto const& parameter : m_function->parameters())
|
||||
arguments.append({ .name = parameter->full_name() });
|
||||
|
||||
return make_ref_counted<FunctionDefinition>(name, tree, move(arguments));
|
||||
return make_ref_counted<FunctionDefinition>(
|
||||
AbstractOperationDeclaration {
|
||||
.name = MUST(FlyString::from_utf8(name)),
|
||||
.arguments = move(arguments),
|
||||
},
|
||||
Location {},
|
||||
tree);
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
|
@ -24,7 +24,7 @@ NonnullOwnPtr<SpecificationClause> SpecificationClause::create(SpecificationPars
|
|||
[&](AK::Empty const&) {
|
||||
result = make<SpecificationClause>(move(specification_clause));
|
||||
},
|
||||
[&](OneOf<ClauseHeader::AbstractOperation, ClauseHeader::Accessor, ClauseHeader::Method> auto const&) {
|
||||
[&](OneOf<AbstractOperationDeclaration, AccessorDeclaration, MethodDeclaration> auto const&) {
|
||||
result = make<SpecificationFunction>(move(specification_clause));
|
||||
});
|
||||
|
||||
|
|
|
@ -15,35 +15,29 @@ bool SpecificationFunction::post_initialize(XML::Node const* element)
|
|||
VERIFY(element->as_element().name == tag_emu_clause);
|
||||
|
||||
auto& ctx = context();
|
||||
m_location = ctx.location_from_xml_offset(element->offset);
|
||||
|
||||
auto maybe_id = get_attribute_by_name(element, attribute_id);
|
||||
if (!maybe_id.has_value()) {
|
||||
ctx.diag().error(ctx.location_from_xml_offset(element->offset),
|
||||
ctx.diag().error(m_location,
|
||||
"no id attribute");
|
||||
} else {
|
||||
m_id = maybe_id.value();
|
||||
}
|
||||
|
||||
m_header.header.visit(
|
||||
[&](ClauseHeader::AbstractOperation const& abstract_operation) {
|
||||
auto maybe_abstract_operation_id = get_attribute_by_name(element, attribute_aoid);
|
||||
if (maybe_abstract_operation_id.has_value())
|
||||
m_name = MUST(String::from_utf8(maybe_abstract_operation_id.value()));
|
||||
[&](AbstractOperationDeclaration const& abstract_operation) {
|
||||
m_declaration = abstract_operation;
|
||||
|
||||
auto const& [function_name, arguments] = abstract_operation;
|
||||
m_arguments = arguments;
|
||||
auto abstract_operation_id = get_attribute_by_name(element, attribute_aoid).value();
|
||||
|
||||
if (m_name != function_name) {
|
||||
ctx.diag().warn(ctx.location_from_xml_offset(element->offset),
|
||||
if (abstract_operation.name != abstract_operation_id) {
|
||||
ctx.diag().warn(m_location,
|
||||
"function name in header and <emu-clause>[aoid] do not match");
|
||||
}
|
||||
},
|
||||
[&](ClauseHeader::Accessor const& accessor) {
|
||||
m_name = MUST(String::formatted("%get {}%", MUST(String::join("."sv, accessor.qualified_name))));
|
||||
},
|
||||
[&](ClauseHeader::Method const& method) {
|
||||
m_name = MUST(String::formatted("%{}%", MUST(String::join("."sv, method.qualified_name))));
|
||||
m_arguments = method.arguments;
|
||||
[&](OneOf<AccessorDeclaration, MethodDeclaration> auto const& declaration) {
|
||||
m_declaration = declaration;
|
||||
},
|
||||
[&](auto const&) {
|
||||
VERIFY_NOT_REACHED();
|
||||
|
@ -70,7 +64,7 @@ bool SpecificationFunction::post_initialize(XML::Node const* element)
|
|||
}
|
||||
|
||||
if (algorithm_nodes.size() != 1) {
|
||||
ctx.diag().error(ctx.location_from_xml_offset(element->offset),
|
||||
ctx.diag().error(m_location,
|
||||
"<emu-clause> specifing function should have exactly one <emu-alg> child"sv);
|
||||
return false;
|
||||
}
|
||||
|
@ -86,7 +80,7 @@ bool SpecificationFunction::post_initialize(XML::Node const* element)
|
|||
|
||||
void SpecificationFunction::do_collect(TranslationUnitRef translation_unit)
|
||||
{
|
||||
translation_unit->adopt_function(make_ref_counted<FunctionDefinition>(m_name, m_algorithm.tree(), move(m_arguments)));
|
||||
translation_unit->adopt_function(make_ref_counted<FunctionDefinition>(m_declaration.release_value(), m_location, m_algorithm.tree()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -145,9 +145,8 @@ protected:
|
|||
|
||||
private:
|
||||
StringView m_id;
|
||||
String m_name;
|
||||
|
||||
Vector<FunctionArgument> m_arguments;
|
||||
Optional<Declaration> m_declaration;
|
||||
Location m_location;
|
||||
Algorithm m_algorithm;
|
||||
};
|
||||
|
||||
|
|
|
@ -644,14 +644,14 @@ TextParseErrorOr<Tree> TextParser::parse_step_with_substeps(Tree substeps)
|
|||
}
|
||||
|
||||
// <qualified_name> :== <word> (. <word>)*
|
||||
TextParseErrorOr<Vector<StringView>> TextParser::parse_qualified_name()
|
||||
TextParseErrorOr<QualifiedName> TextParser::parse_qualified_name()
|
||||
{
|
||||
Vector<StringView> qualified_name;
|
||||
qualified_name.append(TRY(consume_token_with_type(TokenType::Word)).data);
|
||||
while (true) {
|
||||
auto token_or_error = consume_token_with_type(TokenType::MemberAccess);
|
||||
if (token_or_error.is_error())
|
||||
return qualified_name;
|
||||
return QualifiedName { qualified_name };
|
||||
qualified_name.append(TRY(consume_token_with_type(TokenType::Word)).data);
|
||||
}
|
||||
}
|
||||
|
@ -702,12 +702,14 @@ TextParseErrorOr<Vector<FunctionArgument>> TextParser::parse_function_arguments_
|
|||
}
|
||||
|
||||
// <ao_declaration> :== <word> <function_arguments> $
|
||||
TextParseErrorOr<ClauseHeader::AbstractOperation> TextParser::parse_abstract_operation_declaration()
|
||||
TextParseErrorOr<AbstractOperationDeclaration> TextParser::parse_abstract_operation_declaration()
|
||||
{
|
||||
auto rollback = rollback_point();
|
||||
|
||||
ClauseHeader::AbstractOperation function_definition;
|
||||
function_definition.name = TRY(consume_token_with_type(TokenType::Word)).data;
|
||||
auto name = TRY(consume_token_with_type(TokenType::Word)).data;
|
||||
|
||||
AbstractOperationDeclaration function_definition;
|
||||
function_definition.name = MUST(FlyString::from_utf8(name));
|
||||
function_definition.arguments = TRY(parse_function_arguments_in_declaration());
|
||||
TRY(expect_eof());
|
||||
|
||||
|
@ -716,25 +718,25 @@ TextParseErrorOr<ClauseHeader::AbstractOperation> TextParser::parse_abstract_ope
|
|||
}
|
||||
|
||||
// <accessor_declaration> :== get <qualified_name> $
|
||||
TextParseErrorOr<ClauseHeader::Accessor> TextParser::parse_accessor_declaration()
|
||||
TextParseErrorOr<AccessorDeclaration> TextParser::parse_accessor_declaration()
|
||||
{
|
||||
auto rollback = rollback_point();
|
||||
|
||||
TRY(consume_word("get"sv));
|
||||
ClauseHeader::Accessor accessor;
|
||||
accessor.qualified_name = TRY(parse_qualified_name());
|
||||
AccessorDeclaration accessor;
|
||||
accessor.name = TRY(parse_qualified_name());
|
||||
TRY(expect_eof());
|
||||
|
||||
rollback.disarm();
|
||||
return accessor;
|
||||
}
|
||||
|
||||
TextParseErrorOr<ClauseHeader::Method> TextParser::parse_method_declaration()
|
||||
TextParseErrorOr<MethodDeclaration> TextParser::parse_method_declaration()
|
||||
{
|
||||
auto rollback = rollback_point();
|
||||
|
||||
ClauseHeader::Method method;
|
||||
method.qualified_name = TRY(parse_qualified_name());
|
||||
MethodDeclaration method;
|
||||
method.name = TRY(parse_qualified_name());
|
||||
method.arguments = TRY(parse_function_arguments_in_declaration());
|
||||
TRY(expect_eof());
|
||||
|
||||
|
|
|
@ -13,22 +13,8 @@
|
|||
namespace JSSpecCompiler {
|
||||
|
||||
struct ClauseHeader {
|
||||
struct AbstractOperation {
|
||||
StringView name;
|
||||
Vector<FunctionArgument> arguments;
|
||||
};
|
||||
|
||||
struct Accessor {
|
||||
Vector<StringView> qualified_name;
|
||||
};
|
||||
|
||||
struct Method {
|
||||
Vector<StringView> qualified_name;
|
||||
Vector<FunctionArgument> arguments;
|
||||
};
|
||||
|
||||
StringView section_number;
|
||||
Variant<AK::Empty, AbstractOperation, Accessor, Method> header;
|
||||
Variant<AK::Empty, AbstractOperationDeclaration, AccessorDeclaration, MethodDeclaration> header;
|
||||
};
|
||||
|
||||
struct TextParseError { };
|
||||
|
@ -102,11 +88,11 @@ private:
|
|||
TextParseErrorOr<Tree> parse_if(Tree then_branch);
|
||||
TextParseErrorOr<Tree> parse_else(Tree else_branch);
|
||||
|
||||
TextParseErrorOr<Vector<StringView>> parse_qualified_name();
|
||||
TextParseErrorOr<QualifiedName> parse_qualified_name();
|
||||
TextParseErrorOr<Vector<FunctionArgument>> parse_function_arguments_in_declaration();
|
||||
TextParseErrorOr<ClauseHeader::AbstractOperation> parse_abstract_operation_declaration();
|
||||
TextParseErrorOr<ClauseHeader::Method> parse_method_declaration();
|
||||
TextParseErrorOr<ClauseHeader::Accessor> parse_accessor_declaration();
|
||||
TextParseErrorOr<AbstractOperationDeclaration> parse_abstract_operation_declaration();
|
||||
TextParseErrorOr<MethodDeclaration> parse_method_declaration();
|
||||
TextParseErrorOr<AccessorDeclaration> parse_accessor_declaration();
|
||||
|
||||
SpecificationParsingContext& m_ctx;
|
||||
Vector<Token> const& m_tokens;
|
||||
|
|
|
@ -71,8 +71,8 @@ private:
|
|||
};
|
||||
|
||||
template<>
|
||||
struct AK::Formatter<Vector<FunctionArgument>> : AK::Formatter<StringView> {
|
||||
ErrorOr<void> format(FormatBuilder& builder, Vector<FunctionArgument> const& arguments)
|
||||
struct AK::Formatter<ReadonlySpan<FunctionArgument>> : AK::Formatter<StringView> {
|
||||
ErrorOr<void> format(FormatBuilder& builder, ReadonlySpan<FunctionArgument> const& arguments)
|
||||
{
|
||||
size_t previous_optional_group = 0;
|
||||
for (size_t i = 0; i < arguments.size(); ++i) {
|
||||
|
@ -139,17 +139,6 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
|
||||
TranslationUnit translation_unit(filename);
|
||||
|
||||
// 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.
|
||||
translation_unit.adopt_declaration(make_ref_counted<FunctionDeclaration>("CompareISODate"sv, Vector<FunctionArgument> {}));
|
||||
translation_unit.adopt_declaration(make_ref_counted<FunctionDeclaration>("CreateDateDurationRecord"sv, Vector<FunctionArgument> {}));
|
||||
translation_unit.adopt_declaration(make_ref_counted<FunctionDeclaration>("AddISODate"sv, Vector<FunctionArgument> {}));
|
||||
translation_unit.adopt_declaration(make_ref_counted<FunctionDeclaration>("ISODaysInMonth"sv, Vector<FunctionArgument> {}));
|
||||
translation_unit.adopt_declaration(make_ref_counted<FunctionDeclaration>("ISODateToEpochDays"sv, Vector<FunctionArgument> {}));
|
||||
translation_unit.adopt_declaration(make_ref_counted<FunctionDeclaration>("truncate"sv, Vector<FunctionArgument> {}));
|
||||
translation_unit.adopt_declaration(make_ref_counted<FunctionDeclaration>("remainder"sv, Vector<FunctionArgument> {}));
|
||||
|
||||
for (auto const& step : pipeline.pipeline()) {
|
||||
step.step->run(&translation_unit);
|
||||
|
||||
|
@ -161,14 +150,14 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
if (step.dump_ast) {
|
||||
outln(stderr, "===== AST after {} =====", step.step->name());
|
||||
for (auto const& function : translation_unit.functions_to_compile()) {
|
||||
outln(stderr, "{}({}):", function->m_name, function->m_arguments);
|
||||
outln(stderr, "{}({}):", function->name(), function->arguments());
|
||||
outln(stderr, "{}", function->m_ast);
|
||||
}
|
||||
}
|
||||
if (step.dump_cfg && translation_unit.functions_to_compile().size() && translation_unit.functions_to_compile()[0]->m_cfg != nullptr) {
|
||||
outln(stderr, "===== CFG after {} =====", step.step->name());
|
||||
for (auto const& function : translation_unit.functions_to_compile()) {
|
||||
outln(stderr, "{}({}):", function->m_name, function->m_arguments);
|
||||
outln(stderr, "{}({}):", function->name(), function->arguments());
|
||||
outln(stderr, "{}", *function->m_cfg);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue