From 035afdccff2ad2bb76d9dc3ddd6eacd85e84af11 Mon Sep 17 00:00:00 2001 From: pk19604014 <95385881+pk19604014@users.noreply.github.com> Date: Thu, 2 Jun 2022 16:16:51 -0400 Subject: [PATCH] Added EnumKindName() for rtti enums + sample usage to print node kind names during type checking (#1305) Sample trace output: ``` checking tuple pattern (v1: T1, v2: T2), expecting (T1:! ImplicitAs(U1), T2:! ImplicitAs(U2)) checking binding pattern v1: T1, expecting T1:! ImplicitAs(U1) checking expression pattern T1 checking identifier expression T1 ``` --- explorer/ast/BUILD | 8 +++-- explorer/gen_rtti.py | 36 +++++++++++++++++++++ explorer/interpreter/type_checker.cpp | 11 +++++-- explorer/testdata/basic_syntax/trace.carbon | 2 +- 4 files changed, 50 insertions(+), 7 deletions(-) diff --git a/explorer/ast/BUILD b/explorer/ast/BUILD index 89f785c37883..279775eedb36 100644 --- a/explorer/ast/BUILD +++ b/explorer/ast/BUILD @@ -16,7 +16,7 @@ cc_library( cc_library( name = "ast_node", - srcs = ["ast_node.cpp"], + srcs = ["ast_node.cpp", "ast_rtti.cpp",], hdrs = [ "ast_node.h", "ast_rtti.h", @@ -30,9 +30,11 @@ cc_library( genrule( name = "ast_rtti", srcs = ["ast_rtti.txt"], - outs = ["ast_rtti.h"], + outs = ["ast_rtti.h", "ast_rtti.cpp"], cmd = "./$(location //explorer:gen_rtti)" + - " $(location ast_rtti.txt) > \"$@\"", + " $(location ast_rtti.txt)" + + " $(location ast_rtti.h) $(location ast_rtti.cpp)" + + " $(rootpath ast_rtti.h)", tools = ["//explorer:gen_rtti"], ) diff --git a/explorer/gen_rtti.py b/explorer/gen_rtti.py index 2368cbb91d13..4356df74ff68 100755 --- a/explorer/gen_rtti.py +++ b/explorer/gen_rtti.py @@ -181,6 +181,10 @@ _LINE_PATTERN = r"""(?P \w*) \s* def main() -> None: input_filename = sys.argv[1] + header_filename = sys.argv[2] + cpp_filename = sys.argv[3] + relative_header = sys.argv[4] + with open(input_filename) as file: lines = file.readlines() @@ -226,11 +230,15 @@ def main() -> None: if node.kind == Class.Kind.ROOT: node.Finalize() + header_file = open(header_filename, "w") + sys.stdout = header_file + print(f"// Generated from {input_filename} by explorer/gen_rtti.py\n") trans_table = str.maketrans({"/": "_", ".": "_"}) guard_macro = input_filename.upper().translate(trans_table) + "_" print(f"#ifndef {guard_macro}") print(f"#define {guard_macro}") + print("\n#include ") print("\nnamespace Carbon {\n") for node in classes.values(): @@ -242,6 +250,8 @@ def main() -> None: print(f" {node.Root().leaves[id].name} = {id},") print("};\n") + print(f"std::string_view {node.name}KindName({node.name}Kind k);\n") + if node.kind in [Class.Kind.ABSTRACT, Class.Kind.CONCRETE]: print( f"inline bool InheritsFrom{node.name}({node.Root().name}Kind" @@ -273,6 +283,32 @@ def main() -> None: print("} // namespace Carbon\n") print(f"#endif // {guard_macro}") + header_file.close() + + cpp_file = open(cpp_filename, "w") + sys.stdout = cpp_file + + print(f"// Generated from {input_filename} by explorer/gen_rtti.py\n") + print(f'#include "{relative_header}"') + print("\nnamespace Carbon {\n") + for node in classes.values(): + if node.kind != Class.Kind.CONCRETE: + assert node.id_range is not None + ids = range(node.id_range[0], node.id_range[1]) + print(f"std::string_view {node.name}KindName({node.name}Kind k) {{") + print(" switch(k) {") + for id in ids: + name = node.Root().leaves[id].name + desc = " ".join( + w.lower() for w in re.sub(r"([A-Z])", r" \1", name).split() + ) + print(f' case {node.name}Kind::{name}: return "{desc}";') + print(" }") + print("}\n") + + print("} // namespace Carbon\n") + cpp_file.close() + if __name__ == "__main__": main() diff --git a/explorer/interpreter/type_checker.cpp b/explorer/interpreter/type_checker.cpp index d8f15136ac34..1962f461b26d 100644 --- a/explorer/interpreter/type_checker.cpp +++ b/explorer/interpreter/type_checker.cpp @@ -994,7 +994,8 @@ auto TypeChecker::TypeCheckExp(Nonnull e, const ImplScope& impl_scope) -> ErrorOr { if (trace_stream_) { - **trace_stream_ << "checking expression " << *e; + **trace_stream_ << "checking " << ExpressionKindName(e->kind()) << " " + << *e; **trace_stream_ << "\nconstants: "; PrintConstants(**trace_stream_); **trace_stream_ << "\n"; @@ -1793,7 +1794,7 @@ auto TypeChecker::TypeCheckPattern( ImplScope& impl_scope, ValueCategory enclosing_value_category) -> ErrorOr { if (trace_stream_) { - **trace_stream_ << "checking pattern " << *p; + **trace_stream_ << "checking " << PatternKindName(p->kind()) << " " << *p; if (expected) { **trace_stream_ << ", expecting " << **expected; } @@ -1986,7 +1987,8 @@ auto TypeChecker::TypeCheckStmt(Nonnull s, const ImplScope& impl_scope) -> ErrorOr { if (trace_stream_) { - **trace_stream_ << "checking statement " << *s << "\n"; + **trace_stream_ << "checking " << StatementKindName(s->kind()) << " " << *s + << "\n"; } switch (s->kind()) { case StatementKind::Match: { @@ -2723,6 +2725,9 @@ auto TypeChecker::TypeCheck(AST& ast) -> ErrorOr { auto TypeChecker::TypeCheckDeclaration(Nonnull d, const ImplScope& impl_scope) -> ErrorOr { + if (trace_stream_) { + **trace_stream_ << "checking " << DeclarationKindName(d->kind()) << "\n"; + } switch (d->kind()) { case DeclarationKind::InterfaceDeclaration: { CARBON_RETURN_IF_ERROR(TypeCheckInterfaceDeclaration( diff --git a/explorer/testdata/basic_syntax/trace.carbon b/explorer/testdata/basic_syntax/trace.carbon index d6cf3b4f32ab..88266965665a 100644 --- a/explorer/testdata/basic_syntax/trace.carbon +++ b/explorer/testdata/basic_syntax/trace.carbon @@ -12,7 +12,7 @@ // CHECK: ********** source program ********** // CHECK: fn Print (format_str: String) { // CHECK: ********** type checking ********** -// CHECK: checking pattern (format_str: String) +// CHECK: checking tuple pattern (format_str: String) // CHECK: ********** type checking complete ********** // CHECK: fn Print (format_str: String) { // CHECK: ********** starting execution **********