summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-08-20 09:39:00 +0800
committerJohn Hodge <tpg@mutabah.net>2016-08-20 09:39:00 +0800
commit05c54c5496a3790061f3a2e5b5483ce8380d5b1b (patch)
treeba225391a320b6f2faeb8b3e826dcb34ee627782
parentf66c6970e3b9a5704254ea946a984982e11856b2 (diff)
downloadmrust-05c54c5496a3790061f3a2e5b5483ce8380d5b1b.tar.gz
HIR - Support &[...] in constant evaluation (hacky)
-rw-r--r--src/hir/hir.cpp3
-rw-r--r--src/hir/hir.hpp4
-rw-r--r--src/hir_conv/constant_evaluation.cpp70
3 files changed, 68 insertions, 9 deletions
diff --git a/src/hir/hir.cpp b/src/hir/hir.cpp
index 4ff909aa..3b69e7c2 100644
--- a/src/hir/hir.cpp
+++ b/src/hir/hir.cpp
@@ -21,6 +21,9 @@ namespace HIR {
(Float,
os << e;
),
+ (BorrowOf,
+ os << "&" << e;
+ ),
(String,
os << "\"" << e << "\"";
)
diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp
index d7650c7e..2eaf508d 100644
--- a/src/hir/hir.hpp
+++ b/src/hir/hir.hpp
@@ -46,6 +46,7 @@ TAGGED_UNION(Literal, Invalid,
(List, ::std::vector<Literal>), // TODO: Have a variant for repetition lists
(Integer, uint64_t),
(Float, double),
+ (BorrowOf, ::HIR::SimplePath),
// String = &'static str or &[u8; N]
(String, ::std::string)
);
@@ -369,6 +370,9 @@ public:
return ::HIR::SimplePath();
}
}
+ const char* get_name() const {
+ return name ? name : "";
+ }
ItemPath operator+(const ::std::string& name) const {
return ItemPath(*this, name.c_str());
diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp
index 53997e20..3ed54209 100644
--- a/src/hir_conv/constant_evaluation.cpp
+++ b/src/hir_conv/constant_evaluation.cpp
@@ -10,6 +10,8 @@
#include <algorithm>
namespace {
+ typedef ::std::vector< ::std::pair< ::std::string, ::HIR::Static> > t_new_values;
+
::HIR::Literal clone_literal(const ::HIR::Literal& v)
{
TU_MATCH(::HIR::Literal, (v), (e),
@@ -29,6 +31,9 @@ namespace {
(Float,
return ::HIR::Literal(e);
),
+ (BorrowOf,
+ return ::HIR::Literal(e);
+ ),
(String,
return ::HIR::Literal(e);
)
@@ -172,18 +177,26 @@ namespace {
return *rv_p;
}
- ::HIR::Literal evaluate_constant(const ::HIR::Crate& crate, const ::HIR::ExprNode& expr)
+ ::HIR::Literal evaluate_constant(const ::HIR::Crate& crate, t_new_values& newval_output, const ::HIR::ItemPath& mod_path, ::std::string prefix, const ::HIR::ExprNode& expr)
{
struct Visitor:
public ::HIR::ExprVisitor
{
const ::HIR::Crate& m_crate;
+ t_new_values& m_newval_output;
+ const ::HIR::ItemPath& m_mod_path;
+ ::std::string m_name_prefix;
+
::std::vector< ::std::pair< ::std::string, ::HIR::Literal > > m_values;
+ ::HIR::TypeRef m_exp_type;
::HIR::Literal m_rv;
- Visitor(const ::HIR::Crate& crate):
- m_crate(crate)
+ Visitor(const ::HIR::Crate& crate, t_new_values& newval_output, const ::HIR::ItemPath& mod_path, ::std::string prefix):
+ m_crate(crate),
+ m_newval_output(newval_output),
+ m_mod_path(mod_path),
+ m_name_prefix(prefix)
{}
void badnode(const ::HIR::ExprNode& node) const {
@@ -192,8 +205,11 @@ namespace {
void visit(::HIR::ExprNode_Block& node) override {
TRACE_FUNCTION_F("_Block");
+
for(const auto& e : node.m_nodes)
+ {
e->visit(*this);
+ }
}
void visit(::HIR::ExprNode_Return& node) override {
TODO(node.span(), "ExprNode_Return");
@@ -339,7 +355,24 @@ namespace {
}
}
void visit(::HIR::ExprNode_Borrow& node) override {
- TODO(node.span(), "&/&mut in constant");
+ //auto ty = m_exp_type;
+
+ node.m_value->visit(*this);
+ auto val = mv$(m_rv);
+
+ if( node.m_type != ::HIR::BorrowType::Shared ) {
+ ERROR(node.span(), E0000, "Only shared borrows are allowed in constants");
+ }
+
+ // Create new static containing borrowed data
+ auto name = FMT(m_name_prefix << &node);
+ m_newval_output.push_back(::std::make_pair( name, ::HIR::Static {
+ false,
+ ::HIR::TypeRef(),
+ ::HIR::ExprNodeP(),
+ mv$(val)
+ } ));
+ m_rv = ::HIR::Literal::make_BorrowOf( (m_mod_path + name).get_simple_path() );
}
void visit(::HIR::ExprNode_Cast& node) override {
TRACE_FUNCTION_F("_Cast");
@@ -525,7 +558,7 @@ namespace {
}
};
- Visitor v { crate };
+ Visitor v { crate, newval_output, mod_path, prefix };
const_cast<::HIR::ExprNode&>(expr).visit(v);
if( v.m_rv.is_Invalid() ) {
@@ -539,18 +572,37 @@ namespace {
public ::HIR::Visitor
{
const ::HIR::Crate& m_crate;
+ const ::HIR::ItemPath* m_mod_path;
+ t_new_values m_new_values;
public:
Expander(const ::HIR::Crate& crate):
m_crate(crate)
{}
+ void visit_module(::HIR::ItemPath p, ::HIR::Module& mod) override
+ {
+ auto saved_mp = m_mod_path;
+ m_mod_path = &p;
+ auto saved = mv$( m_new_values );
+
+ ::HIR::Visitor::visit_module(p, mod);
+
+ //auto items = mv$( m_new_values );
+ //for( auto item : items )
+ //{
+ //
+ //}
+ m_new_values = mv$(saved);
+ m_mod_path = saved_mp;
+ }
+
void visit_type(::HIR::TypeRef& ty) override
{
TU_IFLET(::HIR::TypeRef::Data, ty.m_data, Array, e,
::HIR::Visitor::visit_type(*e.inner);
assert(e.size.get() != nullptr);
- auto val = evaluate_constant(m_crate, *e.size);
+ auto val = evaluate_constant(m_crate, m_new_values, *m_mod_path, FMT("ty_" << &ty << "$"), *e.size);
if( !val.is_Integer() )
ERROR(e.size->span(), E0000, "Array size isn't an integer");
e.size_val = val.as_Integer();
@@ -563,13 +615,13 @@ namespace {
void visit_constant(::HIR::ItemPath p, ::HIR::Constant& item) override
{
visit_type(item.m_type);
- item.m_value_res = evaluate_constant(m_crate, *item.m_value);
+ item.m_value_res = evaluate_constant(m_crate, m_new_values, *m_mod_path, FMT(p.get_name() << "$"), *item.m_value);
DEBUG("constant: " << item.m_type << " = " << item.m_value_res);
}
void visit_static(::HIR::ItemPath p, ::HIR::Static& item) override
{
visit_type(item.m_type);
- item.m_value_res = evaluate_constant(m_crate, *item.m_value);
+ item.m_value_res = evaluate_constant(m_crate, m_new_values, *m_mod_path, FMT(p.get_name() << "$"), *item.m_value);
DEBUG("static: " << item.m_type << " = " << item.m_value_res);
}
void visit_expr(::HIR::ExprPtr& expr) override
@@ -604,7 +656,7 @@ namespace {
}
void visit(::HIR::ExprNode_ArraySized& node) override {
- auto val = evaluate_constant(m_exp.m_crate, *node.m_size);
+ auto val = evaluate_constant(m_exp.m_crate, m_exp.m_new_values, *m_exp.m_mod_path, FMT("array_" << &node << "$"), *node.m_size);
if( !val.is_Integer() )
ERROR(node.span(), E0000, "Array size isn't an integer");
node.m_size_val = val.as_Integer();