Skip to content

Commit

Permalink
Add unimplemented impl to the ast.
Browse files Browse the repository at this point in the history
#1277

PiperOrigin-RevId: 679721290
  • Loading branch information
erinzmoore authored and copybara-github committed Sep 27, 2024
1 parent bb041f3 commit 1af3c8c
Show file tree
Hide file tree
Showing 15 changed files with 133 additions and 1 deletion.
8 changes: 8 additions & 0 deletions xls/dslx/fmt/ast_fmt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2262,6 +2262,13 @@ static DocRef Fmt(const StructDef& n, const Comments& comments,
return JoinWithAttr(attr, ConcatNGroup(arena, pieces), arena);
}

// TODO: https://github.com/google/xls/issues/1277 - Support impl.
static DocRef Fmt(const Impl& n, const Comments& comments, DocArena& arena) {
std::vector<DocRef> pieces;
std::optional<DocRef> attr;
return JoinWithAttr(attr, ConcatNGroup(arena, pieces), arena);
}

static DocRef FmtEnumMember(const EnumMember& n, const Comments& comments,
DocArena& arena) {
return ConcatNGroup(
Expand Down Expand Up @@ -2396,6 +2403,7 @@ static DocRef Fmt(const ModuleMember& n, const Comments& comments,
return arena.MakeConcat(Fmt(*n, comments, arena), arena.semi());
},
[&](const StructDef* n) { return Fmt(*n, comments, arena); },
[&](const Impl* n) { return Fmt(*n, comments, arena); },
[&](const ConstantDef* n) { return Fmt(*n, comments, arena); },
[&](const EnumDef* n) { return Fmt(*n, comments, arena); },
[&](const Import* n) { return Fmt(*n, comments, arena); },
Expand Down
7 changes: 7 additions & 0 deletions xls/dslx/fmt/ast_fmt_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1410,6 +1410,13 @@ TEST_F(ModuleFmtTest, StructDefTwoParametrics) {
Run(kProgram, kWantMultiline, 35);
}

// TODO: https://github.com/google/xls/issues/1277 - Support impl.
TEST_F(ModuleFmtTest, DISABLED_ImplSimple) {
const std::string kInput = "pub impl {} \n";

Run(kInput);
}

TEST_F(ModuleFmtTest, SimpleTestFunction) {
Run(
R"(fn id(x: u32) -> u32 { x }
Expand Down
17 changes: 17 additions & 0 deletions xls/dslx/frontend/ast.cc
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@ std::string_view AstNodeKindToString(AstNodeKind kind) {
return "type reference";
case AstNodeKind::kImport:
return "import";
case AstNodeKind::kImpl:
return "impl";
case AstNodeKind::kUnop:
return "unary op";
case AstNodeKind::kBinop:
Expand Down Expand Up @@ -1294,6 +1296,21 @@ std::vector<std::string> StructDef::GetMemberNames() const {
return names;
}

// -- class Impl

Impl::Impl(Module* owner, Span span, TypeAnnotation* struct_ref, bool is_public)
: AstNode(owner),
span_(span),
struct_ref_(struct_ref),
public_(is_public) {}

Impl::~Impl() = default;

std::string Impl::ToString() const {
std::string type_name = ToAstNode(struct_ref_)->ToString();
return absl::StrFormat("%simpl %s {}", public_ ? "pub " : "", type_name);
}

// -- class StructInstance

StructInstance::StructInstance(
Expand Down
32 changes: 32 additions & 0 deletions xls/dslx/frontend/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
X(EnumDef) \
X(Function) \
X(Import) \
X(Impl) \
X(MatchArm) \
X(Module) \
X(NameDef) \
Expand Down Expand Up @@ -2310,6 +2311,37 @@ class StructDef : public AstNode {
std::optional<std::string> extern_type_name_;
};

// Represents an impl for a struct.
class Impl : public AstNode {
public:
Impl(Module* owner, Span span, TypeAnnotation* struct_ref, bool is_public);

~Impl() override;

AstNodeKind kind() const override { return AstNodeKind::kImpl; }

absl::Status Accept(AstNodeVisitor* v) const override {
return absl::UnimplementedError("impl not yet implemented");
}

std::string_view GetNodeTypeName() const override { return "Impl"; }

std::string ToString() const override;

std::vector<AstNode*> GetChildren(bool want_types) const override {
return {};
};

bool is_public() const { return public_; }
const Span& span() const { return span_; }
std::optional<Span> GetSpan() const override { return span_; }

private:
Span span_;
TypeAnnotation* struct_ref_;
bool public_;
};

// Represents instantiation of a struct via member expressions.
//
// TODO(leary): 2020-09-08 Break out a StructInstanceMember type in lieu of the
Expand Down
7 changes: 7 additions & 0 deletions xls/dslx/frontend/ast_cloner.cc
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,10 @@ class AstCloner : public AstNodeVisitor {
return absl::OkStatus();
}

absl::Status HandleImpl(const Impl* n) override {
return absl::UnimplementedError("impl not yet implemented");
}

absl::Status HandleStructInstance(const StructInstance* n) override {
XLS_RETURN_IF_ERROR(VisitChildren(n));

Expand Down Expand Up @@ -984,6 +988,9 @@ absl::StatusOr<std::unique_ptr<Module>> CloneModule(Module* module,
new_member = down_cast<StructDef*>(cloner.old_to_new().at(sd));
return absl::OkStatus();
},
[&](Impl* _) -> absl::Status {
return absl::UnimplementedError("impl not yet implemented");
},
[&](ConstantDef* cd) -> absl::Status {
XLS_RETURN_IF_ERROR(cd->Accept(&cloner));
new_member = down_cast<ConstantDef*>(cloner.old_to_new().at(cd));
Expand Down
1 change: 1 addition & 0 deletions xls/dslx/frontend/ast_node.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ enum class AstNodeKind : uint8_t {
kFor,
kFormatMacro,
kFunction,
kImpl,
kImport,
kIndex,
kInstantiation,
Expand Down
37 changes: 37 additions & 0 deletions xls/dslx/frontend/ast_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <cstdint>
#include <optional>
#include <string>
#include <vector>

#include "gmock/gmock.h"
#include "gtest/gtest.h"
Expand Down Expand Up @@ -49,6 +50,42 @@ TEST(AstTest, ModuleWithConstant) {
EXPECT_EQ(m.ToString(), "const MOL = 42;");
}

TEST(AstTest, ModuleWithStructAndImpl) {
FileTable file_table;
Module m("test", /*fs_path=*/std::nullopt, file_table);
const Span fake_span;
const std::vector<ParametricBinding*> empty_binding;

// One member var: `member_var: bool`.
BuiltinType bool_type = BuiltinTypeFromString("bool").value();
TypeAnnotation* bool_type_annot = m.Make<BuiltinTypeAnnotation>(
Span::Fake(), bool_type, m.GetOrCreateBuiltinNameDef(bool_type));
std::vector<StructMember> members{
StructMember(fake_span, "member_var", bool_type_annot)};

// Struct definition.
NameDef* name_def =
m.Make<NameDef>(fake_span, std::string("MyStruct"), nullptr);
StructDef* struct_def =
m.Make<StructDef>(fake_span, name_def, empty_binding, members, false);
name_def->set_definer(struct_def);
XLS_ASSERT_OK(m.AddTop(struct_def, /*make_collision_error=*/nullptr));

// Impl definition.
TypeRef* type_ref = m.Make<TypeRef>(fake_span, TypeDefinition(struct_def));
TypeAnnotation* type_annot = m.Make<TypeRefTypeAnnotation>(
fake_span, type_ref, /*parametrics=*/std::vector<ExprOrType>{});
Impl* impl = m.Make<Impl>(fake_span, type_annot, /*is_public=*/false);
XLS_ASSERT_OK(m.AddTop(impl, /*make_collision_error=*/nullptr));

constexpr std::string_view kExpected = R"(struct MyStruct {
member_var: bool,
}
impl MyStruct {})";

EXPECT_EQ(m.ToString(), kExpected);
}

TEST(AstTest, GetNumberAsInt64) {
struct Example {
std::string text;
Expand Down
4 changes: 4 additions & 0 deletions xls/dslx/frontend/module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ absl::Status Module::AddTop(ModuleMember member,
[](QuickCheck* qc) { return std::make_optional(qc->identifier()); },
[](TypeAlias* td) { return std::make_optional(td->identifier()); },
[](StructDef* sd) { return std::make_optional(sd->identifier()); },
[](Impl* id) -> std::optional<std::string> { return std::nullopt; },
[](ConstantDef* cd) { return std::make_optional(cd->identifier()); },
[](EnumDef* ed) { return std::make_optional(ed->identifier()); },
[](Import* i) { return std::make_optional(i->identifier()); },
Expand Down Expand Up @@ -378,6 +379,7 @@ std::string_view GetModuleMemberTypeName(const ModuleMember& module_member) {
[](QuickCheck*) { return "quick-check"; },
[](TypeAlias*) { return "type-alias"; },
[](StructDef*) { return "struct-definition"; },
[](Impl*) { return "impl"; },
[](ConstantDef*) { return "constant-definition"; },
[](EnumDef*) { return "enum-definition"; },
[](Import*) { return "import"; },
Expand All @@ -392,6 +394,7 @@ bool IsPublic(const ModuleMember& member) {
[](const Proc* m) { return m->is_public(); },
[](const TypeAlias* m) { return m->is_public(); },
[](const StructDef* m) { return m->is_public(); },
[](const Impl* m) { return m->is_public(); },
[](const ConstantDef* m) { return m->is_public(); },
[](const EnumDef* m) { return m->is_public(); },
[](const TestFunction* m) { return false; },
Expand Down Expand Up @@ -420,6 +423,7 @@ NameDef* ModuleMemberGetNameDef(const ModuleMember& mm) {
[](QuickCheck* n) -> NameDef* { return n->name_def(); },
[](TypeAlias* n) -> NameDef* { return &n->name_def(); },
[](StructDef* n) -> NameDef* { return n->name_def(); },
[](Impl* n) -> NameDef* { return nullptr; },
[](ConstantDef* n) -> NameDef* { return n->name_def(); },
[](EnumDef* n) -> NameDef* { return n->name_def(); },
[](Import* n) -> NameDef* { return &n->name_def(); },
Expand Down
2 changes: 1 addition & 1 deletion xls/dslx/frontend/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ namespace xls::dslx {
using ModuleMember =
std::variant<Function*, Proc*, TestFunction*, TestProc*, QuickCheck*,
TypeAlias*, StructDef*, ConstantDef*, EnumDef*, Import*,
ConstAssert*>;
ConstAssert*, Impl*>;

// Note: this returns nullptr for constructs that do not define a name, e.g.
// `ConstAssert`.
Expand Down
3 changes: 3 additions & 0 deletions xls/dslx/ir_convert/extract_conversion_order.cc
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,9 @@ absl::StatusOr<std::vector<ConversionRecord>> GetOrder(Module* module,
},
[](TypeAlias*) { return absl::OkStatus(); },
[](StructDef*) { return absl::OkStatus(); },
[](Impl*) {
return absl::UnimplementedError("impl not yet implemented");
},
[](EnumDef*) { return absl::OkStatus(); },
[](Import*) { return absl::OkStatus(); },
[](ConstAssert*) { return absl::OkStatus(); },
Expand Down
1 change: 1 addition & 0 deletions xls/dslx/ir_convert/function_converter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,7 @@ class FunctionConverterVisitor : public AstNodeVisitor {
INVALID(QuickCheck)
INVALID(Spawn)
INVALID(StructDef)
INVALID(Impl)
INVALID(ProcMember)

private:
Expand Down
4 changes: 4 additions & 0 deletions xls/dslx/lsp/document_symbols.cc
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ std::vector<verible::lsp::DocumentSymbol> ToDocumentSymbols(const Module& m) {
return std::vector<verible::lsp::DocumentSymbol>{};
},
[](StructDef* s) { return ToDocumentSymbols(*s); },
[](Impl*) {
// TODO(google/xls#1080): Complete the set of symbols.
return std::vector<verible::lsp::DocumentSymbol>{};
},
[](ConstantDef* c) { return ToDocumentSymbols(*c); },
[](EnumDef* e) { return ToDocumentSymbols(*e); },
[](Import*) {
Expand Down
6 changes: 6 additions & 0 deletions xls/dslx/type_system/deduce.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2115,6 +2115,11 @@ absl::StatusOr<std::unique_ptr<Type>> DeduceConstRef(const ConstRef* node,
return type;
}

absl::StatusOr<std::unique_ptr<Type>> DeduceImpl(const Impl* node,
DeduceCtx* ctx) {
return absl::UnimplementedError("impl not yet implemented");
}

class DeduceVisitor : public AstNodeVisitor {
public:
explicit DeduceVisitor(DeduceCtx* ctx) : ctx_(ctx) {}
Expand Down Expand Up @@ -2142,6 +2147,7 @@ class DeduceVisitor : public AstNodeVisitor {
DEDUCE_DISPATCH(Cast, DeduceCast)
DEDUCE_DISPATCH(ConstAssert, DeduceConstAssert)
DEDUCE_DISPATCH(StructDef, DeduceStructDef)
DEDUCE_DISPATCH(Impl, DeduceImpl)
DEDUCE_DISPATCH(Array, DeduceArray)
DEDUCE_DISPATCH(Attr, DeduceAttr)
DEDUCE_DISPATCH(StatementBlock, DeduceStatementBlock)
Expand Down
1 change: 1 addition & 0 deletions xls/dslx/type_system/type_info.proto
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ enum AstNodeKindProto {
AST_NODE_KIND_PROC_MEMBER = 60;
AST_NODE_KIND_ALL_ONES_MACRO = 61;
AST_NODE_KIND_REST_OF_TUPLE = 62;
AST_NODE_KIND_IMPL = 63;
}

message BitsValueProto {
Expand Down
4 changes: 4 additions & 0 deletions xls/dslx/type_system/type_info_to_proto.cc
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ AstNodeKindProto ToProto(AstNodeKind kind) {
return AST_NODE_KIND_PROC_MEMBER;
case AstNodeKind::kRestOfTuple:
return AST_NODE_KIND_REST_OF_TUPLE;
case AstNodeKind::kImpl:
return AST_NODE_KIND_IMPL;
}
// Fatal since enum class values should not be out of range.
LOG(FATAL) << "Out of range AstNodeKind: " << static_cast<int64_t>(kind);
Expand Down Expand Up @@ -766,6 +768,8 @@ absl::StatusOr<AstNodeKind> FromProto(AstNodeKindProto p) {
return AstNodeKind::kProcMember;
case AST_NODE_KIND_REST_OF_TUPLE:
return AstNodeKind::kRestOfTuple;
case AST_NODE_KIND_IMPL:
return AstNodeKind::kImpl;
// Note: since this is a proto enum there are sentinel values defined in
// addition to the "real" above. Return an invalid argument error.
case AST_NODE_KIND_INVALID:
Expand Down

0 comments on commit 1af3c8c

Please sign in to comment.