summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/hir/deserialise.cpp4
-rw-r--r--src/hir/hir.cpp6
-rw-r--r--src/hir/hir.hpp6
-rw-r--r--src/hir/serialise.cpp4
-rw-r--r--src/hir_conv/constant_evaluation.cpp40
5 files changed, 56 insertions, 4 deletions
diff --git a/src/hir/deserialise.cpp b/src/hir/deserialise.cpp
index 4161cd09..fcfaeda1 100644
--- a/src/hir/deserialise.cpp
+++ b/src/hir/deserialise.cpp
@@ -910,6 +910,10 @@ namespace {
{
#define _(x, ...) case ::HIR::Literal::TAG_##x: return ::HIR::Literal::make_##x(__VA_ARGS__);
_(List, deserialise_vec< ::HIR::Literal>() )
+ _(Variant, {
+ static_cast<unsigned int>(read_count()),
+ deserialise_vec< ::HIR::Literal>()
+ })
_(Integer, read_u64() )
_(Float, read_double() )
_(BorrowOf, deserialise_path() )
diff --git a/src/hir/hir.cpp b/src/hir/hir.cpp
index c2ad4d00..aa3344eb 100644
--- a/src/hir/hir.cpp
+++ b/src/hir/hir.cpp
@@ -15,6 +15,12 @@ namespace HIR {
os << " " << val << ",";
os << " ]";
),
+ (Variant,
+ os << "#" << e.idx << ":[";
+ for(const auto& val : e.vals)
+ os << " " << val << ",";
+ os << " ]";
+ ),
(Integer,
os << e;
),
diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp
index b1f18fcf..5c7f5a30 100644
--- a/src/hir/hir.hpp
+++ b/src/hir/hir.hpp
@@ -49,6 +49,12 @@ TAGGED_UNION(Literal, Invalid,
(Invalid, struct {}),
// List = Array, Tuple, struct literal
(List, ::std::vector<Literal>), // TODO: Have a variant for repetition lists
+ // Variant = Enum variant
+ (Variant, struct {
+ unsigned int idx;
+ ::std::vector<Literal> vals;
+ }),
+ // Literal values
(Integer, uint64_t),
(Float, double),
(BorrowOf, ::HIR::Path),
diff --git a/src/hir/serialise.cpp b/src/hir/serialise.cpp
index 6a74d348..0b581a27 100644
--- a/src/hir/serialise.cpp
+++ b/src/hir/serialise.cpp
@@ -466,6 +466,10 @@ namespace {
(List,
serialise_vec(e);
),
+ (Variant,
+ write_count(e.idx);
+ serialise_vec(e.vals);
+ ),
(Integer,
write_u64(e);
),
diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp
index 967f209c..56cd2058 100644
--- a/src/hir_conv/constant_evaluation.cpp
+++ b/src/hir_conv/constant_evaluation.cpp
@@ -41,6 +41,13 @@ namespace {
}
return ::HIR::Literal( mv$(vals) );
),
+ (Variant,
+ ::std::vector< ::HIR::Literal> vals;
+ for(const auto& val : e.vals) {
+ vals.push_back( clone_literal(val) );
+ }
+ return ::HIR::Literal::make_Variant({ e.idx, mv$(vals) });
+ ),
(Integer,
return ::HIR::Literal(e);
),
@@ -411,16 +418,37 @@ namespace {
}
void visit(::HIR::ExprNode_TupleVariant& node) override {
- if( ! node.m_is_struct ) {
- TODO(node.span(), "_TupleVariant - Enum");
- }
+
::std::vector< ::HIR::Literal> vals;
for(const auto& vn : node.m_args ) {
vn->visit(*this);
assert( !m_rv.is_Invalid() );
vals.push_back( mv$(m_rv) );
}
- m_rv = ::HIR::Literal::make_List(mv$(vals));
+
+ if( node.m_is_struct )
+ {
+ const auto& ent = m_crate.get_typeitem_by_path(node.span(), node.m_path.m_path);
+ ASSERT_BUG(node.span(), ent.is_Struct(), "_TupleVariant with m_is_struct set pointing to " << ent.tag_str());
+ //const auto& str = ent.as_Struct();
+
+ m_rv = ::HIR::Literal::make_List(mv$(vals));
+ }
+ else
+ {
+ const auto& varname = node.m_path.m_path.m_components.back();
+ auto tmp_path = node.m_path.m_path;
+ tmp_path.m_components.pop_back();
+ const auto& ent = m_crate.get_typeitem_by_path(node.span(), tmp_path);
+ ASSERT_BUG(node.span(), ent.is_Enum(), "_TupleVariant with m_is_struct clear pointing to " << ent.tag_str());
+ const auto& enm = ent.as_Enum();
+
+ auto it = ::std::find_if( enm.m_variants.begin(), enm.m_variants.end(), [&](const auto&x){ return x.first == varname; } );
+ ASSERT_BUG(node.span(), it != enm.m_variants.end(), "_TupleVariant points to unknown variant - " << node.m_path);
+ unsigned int var_idx = it - enm.m_variants.begin();
+
+ m_rv = ::HIR::Literal::make_Variant({var_idx, mv$(vals)});
+ }
}
void visit(::HIR::ExprNode_CallPath& node) override {
TRACE_FUNCTION_FR("_CallPath - " << node.m_path, m_rv);
@@ -488,9 +516,11 @@ namespace {
const auto& rv = m_crate.get_typeitem_by_path(node.span(), node.m_path.m_path);
TU_IFLET( ::HIR::TypeItem, rv, Struct, e,
+ ASSERT_BUG(node.span(), node.m_is_struct, "_UnitLiteral with m_is_struct clear pointing to a struct");
m_rv = ::HIR::Literal::make_List({});
)
else TU_IFLET( ::HIR::TypeItem, rv, Enum, e,
+ ASSERT_BUG(node.span(), !node.m_is_struct, "_UnitLiteral with m_is_struct set pointing to an enum");
TODO(node.span(), "Handle Enum _UnitVairant - " << node.m_path);
)
else {
@@ -544,6 +574,7 @@ namespace {
const auto& ent = m_crate.get_typeitem_by_path(node.span(), node.m_path.m_path);
TU_IFLET( ::HIR::TypeItem, ent, Struct, str,
+ ASSERT_BUG(node.span(), node.m_is_struct, "_StructLiteral with m_is_struct clear pointing to a struct");
const auto& fields = str.m_data.as_Named();
::std::vector< ::HIR::Literal> vals;
@@ -576,6 +607,7 @@ namespace {
m_rv = ::HIR::Literal::make_List(mv$(vals));
)
else TU_IFLET( ::HIR::TypeItem, ent, Enum, enm,
+ ASSERT_BUG(node.span(), !node.m_is_struct, "_StructLiteral with m_is_struct set pointing to an enum");
TODO(node.span(), "Handle Enum _UnitVariant - " << node.m_path);
)
else {