diff options
| author | John Hodge <tpg@mutabah.net> | 2016-05-26 23:04:53 +0800 | 
|---|---|---|
| committer | John Hodge <tpg@mutabah.net> | 2016-05-26 23:04:53 +0800 | 
| commit | 46b2f9450a438a597492e0015b735e625ee0cd3a (patch) | |
| tree | ed9de85163e36c3dd5f6c0fbc38945ca941787a0 | |
| parent | 81d89041e8500d9f6dfab9c55aee76967a5233f1 (diff) | |
| download | mrust-46b2f9450a438a597492e0015b735e625ee0cd3a.tar.gz | |
HIR Const Eval - libcore types done, onwards to `const` items
| -rw-r--r-- | src/hir/expr.cpp | 5 | ||||
| -rw-r--r-- | src/hir/expr.hpp | 3 | ||||
| -rw-r--r-- | src/hir/expr_ptr.hpp | 5 | ||||
| -rw-r--r-- | src/hir/from_ast.cpp | 3 | ||||
| -rw-r--r-- | src/hir/type.hpp | 1 | ||||
| -rw-r--r-- | src/hir_conv/constant_evaluation.cpp | 176 | ||||
| -rw-r--r-- | src/include/tagged_union.hpp | 2 | 
7 files changed, 171 insertions, 24 deletions
| diff --git a/src/hir/expr.cpp b/src/hir/expr.cpp index bb3bf0eb..59651c57 100644 --- a/src/hir/expr.cpp +++ b/src/hir/expr.cpp @@ -5,6 +5,11 @@  ::HIR::ExprNode::~ExprNode()  {  } +const Span& ::HIR::ExprNode::span() const +{ +    static Span rv = Span(); +    return rv; +}  #define DEF_VISIT(nt, n, code)   void ::HIR::nt::visit(ExprVisitor& nv) { nv.visit(*this); } void ::HIR::ExprVisitorDef::visit(::HIR::nt& n) { code } diff --git a/src/hir/expr.hpp b/src/hir/expr.hpp index 6a40d669..1f13bea7 100644 --- a/src/hir/expr.hpp +++ b/src/hir/expr.hpp @@ -5,6 +5,7 @@  #include <memory>  #include <hir/pattern.hpp>  #include <hir/type.hpp> +#include <span.hpp>  namespace HIR { @@ -14,6 +15,8 @@ class ExprNode  {  public:      //::HIR::TypeRef    m_res_type; + +    const Span& span() const;      virtual void visit(ExprVisitor& v) = 0;      virtual ~ExprNode(); diff --git a/src/hir/expr_ptr.hpp b/src/hir/expr_ptr.hpp index 59663310..0dcc300a 100644 --- a/src/hir/expr_ptr.hpp +++ b/src/hir/expr_ptr.hpp @@ -21,7 +21,10 @@ public:      }      ~ExprPtr(); -    ::HIR::ExprNode& operator*() { return *node; } +          ::HIR::ExprNode& operator*()       { return *node; } +    const ::HIR::ExprNode& operator*() const { return *node; } +          ::HIR::ExprNode* operator->()       { return node; } +    const ::HIR::ExprNode* operator->() const { return node; }  };  }   // namespace HIR diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 41ee37fd..011fb6c4 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -466,7 +466,8 @@          if( e.size ) {              return ::HIR::TypeRef( ::HIR::TypeRef::Data::make_Array({                  box$( LowerHIR_Type(*e.inner) ), -                LowerHIR_Expr( e.size ) +                LowerHIR_Expr( e.size ), +                ~0u                  }) );          }          else { diff --git a/src/hir/type.hpp b/src/hir/type.hpp index ca79a0c1..4b3692c0 100644 --- a/src/hir/type.hpp +++ b/src/hir/type.hpp @@ -74,6 +74,7 @@ struct TypeRef      (Array, struct {          ::std::unique_ptr<TypeRef>  inner;          ::HIR::ExprPtr size; +        size_t  size_val;          }),      (Slice, struct {          ::std::unique_ptr<TypeRef>  inner; diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp index 7738861d..2544f85c 100644 --- a/src/hir_conv/constant_evaluation.cpp +++ b/src/hir_conv/constant_evaluation.cpp @@ -8,28 +8,49 @@  namespace { -    ::HIR::Literal evaluate_constant(const ::HIR::Crate& crate, ::HIR::ExprNode& expr) +    ::HIR::Function& get_function(const Span& sp, const ::HIR::Crate& crate, const ::HIR::Path& path) +    { +        TU_MATCH(::HIR::Path::Data, (path.m_data), (e), +        (Generic, +            TODO(sp, "get_function(path = " << path << ")"); +            ), +        (UfcsInherent, +            // Easy (ish) +            TODO(sp, "get_function(path = " << path << ")"); +            ), +        (UfcsKnown, +            TODO(sp, "get_function(path = " << path << ")"); +            ), +        (UfcsUnknown, +            // TODO - Since this isn't known, can it be searched properly? +            TODO(sp, "get_function(path = " << path << ")"); +            ) +        ) +        throw ""; +    } +     +    ::HIR::Literal evaluate_constant(const ::HIR::Crate& crate, const ::HIR::ExprNode& expr)      {          struct Visitor:              public ::HIR::ExprVisitor          { -            const ::HIR::Crate& crate; +            const ::HIR::Crate& m_crate;              ::HIR::Literal  m_rv;              Visitor(const ::HIR::Crate& crate): -                crate(crate) +                m_crate(crate)              {}              void badnode(const ::HIR::ExprNode& node) const { -                ERROR(Span(), E0000, "Node not allowed in constant expression"); +                ERROR(node.span(), E0000, "Node not allowed in constant expression");              }              void visit(::HIR::ExprNode_Block& node) override { -                TODO(Span(), "ExprNode_Block"); +                TODO(node.span(), "ExprNode_Block");              }              void visit(::HIR::ExprNode_Return& node) override { -                TODO(Span(), "ExprNode_Return"); +                TODO(node.span(), "ExprNode_Return");              }              void visit(::HIR::ExprNode_Let& node) override {                  badnode(node); @@ -51,13 +72,107 @@ namespace {                  badnode(node);              }              void visit(::HIR::ExprNode_BinOp& node) override { -                TODO(Span(), "ExprNode_BinOp"); +                node.m_left->visit(*this); +                auto left = mv$(m_rv); +                node.m_right->visit(*this); +                auto right = mv$(m_rv); +                 +                if( left.tag() != right.tag() ) { +                    ERROR(node.span(), E0000, "ExprNode_BinOp - Sides mismatched"); +                } +                 +                switch(node.m_op) +                { +                case ::HIR::ExprNode_BinOp::Op::CmpEqu: +                case ::HIR::ExprNode_BinOp::Op::CmpNEqu: +                case ::HIR::ExprNode_BinOp::Op::CmpLt: +                case ::HIR::ExprNode_BinOp::Op::CmpLtE: +                case ::HIR::ExprNode_BinOp::Op::CmpGt: +                case ::HIR::ExprNode_BinOp::Op::CmpGtE: +                    ERROR(node.span(), E0000, "ExprNode_BinOp - Comparisons"); +                    break; +                case ::HIR::ExprNode_BinOp::Op::BoolAnd: +                case ::HIR::ExprNode_BinOp::Op::BoolOr: +                    ERROR(node.span(), E0000, "ExprNode_BinOp - Logicals"); +                    break; + +                case ::HIR::ExprNode_BinOp::Op::Add: +                    TU_MATCH_DEF(::HIR::Literal, (left, right), (le, re), +                    ( throw ""; ), +                    (Integer,   m_rv = ::HIR::Literal(le + re); ), +                    (Float,     m_rv = ::HIR::Literal(le + re); ) +                    ) +                    break; +                case ::HIR::ExprNode_BinOp::Op::Sub: +                    TU_MATCH_DEF(::HIR::Literal, (left, right), (le, re), +                    ( throw ""; ), +                    (Integer,   m_rv = ::HIR::Literal(le - re); ), +                    (Float,     m_rv = ::HIR::Literal(le - re); ) +                    ) +                    break; +                case ::HIR::ExprNode_BinOp::Op::Mul: +                    TU_MATCH_DEF(::HIR::Literal, (left, right), (le, re), +                    ( throw ""; ), +                    (Integer,   m_rv = ::HIR::Literal(le * re); ), +                    (Float,     m_rv = ::HIR::Literal(le * re); ) +                    ) +                    break; +                case ::HIR::ExprNode_BinOp::Op::Div: +                    TU_MATCH_DEF(::HIR::Literal, (left, right), (le, re), +                    ( throw ""; ), +                    (Integer,   m_rv = ::HIR::Literal(le / re); ), +                    (Float,     m_rv = ::HIR::Literal(le / re); ) +                    ) +                    break; +                case ::HIR::ExprNode_BinOp::Op::Mod: +                    TU_MATCH_DEF(::HIR::Literal, (left, right), (le, re), +                    ( throw ""; ), +                    (Integer,   m_rv = ::HIR::Literal(le % re); ), +                    (Float,     ERROR(node.span(), E0000, "modulo operator on float in constant"); ) +                    ) +                    break; +                case ::HIR::ExprNode_BinOp::Op::And: +                    TU_MATCH_DEF(::HIR::Literal, (left, right), (le, re), +                    ( throw ""; ), +                    (Integer,   m_rv = ::HIR::Literal(le % re); ), +                    (Float,     ERROR(node.span(), E0000, "bitwise and operator on float in constant"); ) +                    ) +                    break; +                case ::HIR::ExprNode_BinOp::Op::Or: +                    TU_MATCH_DEF(::HIR::Literal, (left, right), (le, re), +                    ( throw ""; ), +                    (Integer,   m_rv = ::HIR::Literal(le | re); ), +                    (Float,     ERROR(node.span(), E0000, "bitwise or operator on float in constant"); ) +                    ) +                    break; +                case ::HIR::ExprNode_BinOp::Op::Xor: +                    TU_MATCH_DEF(::HIR::Literal, (left, right), (le, re), +                    ( throw ""; ), +                    (Integer,   m_rv = ::HIR::Literal(le ^ re); ), +                    (Float,     ERROR(node.span(), E0000, "bitwise xor operator on float in constant"); ) +                    ) +                    break; +                case ::HIR::ExprNode_BinOp::Op::Shr: +                    TU_MATCH_DEF(::HIR::Literal, (left, right), (le, re), +                    ( throw ""; ), +                    (Integer,   m_rv = ::HIR::Literal(le >> re); ), +                    (Float,     ERROR(node.span(), E0000, "bitwise shift right operator on float in constant"); ) +                    ) +                    break; +                case ::HIR::ExprNode_BinOp::Op::Shl: +                    TU_MATCH_DEF(::HIR::Literal, (left, right), (le, re), +                    ( throw ""; ), +                    (Integer,   m_rv = ::HIR::Literal(le << re); ), +                    (Float,     ERROR(node.span(), E0000, "bitwise shift left operator on float in constant"); ) +                    ) +                    break; +                }              }              void visit(::HIR::ExprNode_UniOp& node) override { -                TODO(Span(), "ExprNode_UniOp"); +                TODO(node.span(), "ExprNode_UniOp");              }              void visit(::HIR::ExprNode_Cast& node) override { -                TODO(Span(), "ExprNode_Cast"); +                TODO(node.span(), "ExprNode_Cast");              }              void visit(::HIR::ExprNode_Index& node) override {                  badnode(node); @@ -67,7 +182,17 @@ namespace {              }              void visit(::HIR::ExprNode_CallPath& node) override { -                TODO(Span(), "exec const fn"); +                ::std::vector<HIR::Literal> arg_vals; +                for(const auto& arg : node.m_args) { +                    arg->visit(*this); +                    arg_vals.push_back( mv$(m_rv) ); +                } +                 +                auto& fcn = get_function(node.span(), m_crate, node.m_path); +                if( ! fcn.m_const ) { +                    ERROR(node.span(), E0000, "Calling non-const function in const context"); +                } +                TODO(node.span(), "exec const fn - " << node.m_path);              }              void visit(::HIR::ExprNode_CallValue& node) override {                  badnode(node); @@ -95,29 +220,29 @@ namespace {                      m_rv = ::HIR::Literal(e);                      ),                  (ByteString, -                    TODO(Span(), "Byte literal in constant"); +                    TODO(node.span(), "Byte literal in constant");                      //m_rv = ::HIR::Literal::make_String(e);                      )                  )              }              void visit(::HIR::ExprNode_PathValue& node) override { -                TODO(Span(), "ExprNode_PathValue"); +                TODO(node.span(), "ExprNode_PathValue");              }              void visit(::HIR::ExprNode_Variable& node) override { -                TODO(Span(), "ExprNode_Variable"); +                TODO(node.span(), "ExprNode_Variable");              }              void visit(::HIR::ExprNode_StructLiteral& node) override { -                TODO(Span(), "ExprNode_StructLiteral"); +                TODO(node.span(), "ExprNode_StructLiteral");              }              void visit(::HIR::ExprNode_Tuple& node) override { -                TODO(Span(), "ExprNode_Tuple"); +                TODO(node.span(), "ExprNode_Tuple");              }              void visit(::HIR::ExprNode_ArrayList& node) override { -                TODO(Span(), "ExprNode_ArrayList"); +                TODO(node.span(), "ExprNode_ArrayList");              }              void visit(::HIR::ExprNode_ArraySized& node) override { -                TODO(Span(), "ExprNode_ArraySized"); +                TODO(node.span(), "ExprNode_ArraySized");              }              void visit(::HIR::ExprNode_Closure& node) override { @@ -126,7 +251,7 @@ namespace {          };          Visitor v { crate }; -        expr.visit(v); +        const_cast<::HIR::ExprNode&>(expr).visit(v);          if( v.m_rv.is_Invalid() ) {              BUG(Span(), "Expression did not yeild a literal"); @@ -150,13 +275,21 @@ namespace {              TU_IFLET(::HIR::TypeRef::Data, ty.m_data, Array, e,                  ::HIR::Visitor::visit_type(*e.inner);                  assert(&*e.size != nullptr); -                auto size = evaluate_constant(m_crate, *e.size); -                TODO(Span(), "visit_type - Set array size to " << size << ", ty = " << ty); +                auto val = evaluate_constant(m_crate, *e.size); +                if( !val.is_Integer() ) +                    ERROR(e.size->span(), E0000, "Array size isn't an integer"); +                e.size_val = val.as_Integer(); +                DEBUG("Array " << ty << " - size = " << e.size_val);              )              else {                  ::HIR::Visitor::visit_type(ty);              }          } +        void visit_constant(::HIR::Constant& item) override +        { +            item.m_value_res = evaluate_constant(m_crate, *item.m_value); +            DEBUG("constant = " << item.m_value_res); +        }          void visit_expr(::HIR::ExprPtr& expr) override          {              struct Visitor: @@ -171,8 +304,9 @@ namespace {                  void visit(::HIR::ExprNode_ArraySized& node) override {                      auto val = evaluate_constant(m_crate, *node.m_size);                      if( !val.is_Integer() ) -                        ERROR(Span(), E0000, "Array size isn't an integer"); +                        ERROR(node.span(), E0000, "Array size isn't an integer");                      node.m_size_val = val.as_Integer(); +                    DEBUG("Array literal [?; " << node.m_size_val << "]");                  }              }; diff --git a/src/include/tagged_union.hpp b/src/include/tagged_union.hpp index dd9ce056..213ebceb 100644 --- a/src/include/tagged_union.hpp +++ b/src/include/tagged_union.hpp @@ -109,7 +109,7 @@  */}  #define TU_MATCH_BIND1(TAG, VAR, NAME)  /*MATCH_BIND*/ auto& NAME = (VAR).as_##TAG(); (void)&NAME;  #define TU_MATCH_BIND2_(TAG, v1,v2, n1,n2)   TU_MATCH_BIND1(TAG, v1, n1) TU_MATCH_BIND1(TAG, v2, n2) -#define TU_MATCH_BIND2(...) TU_MATCH_BIND2_(__VA_ARGS__) +#define TU_MATCH_BIND2(...) TU_MATCH_BIND2_(__VA_ARGS__)    // << Exists to cause expansion of the vars  #define TU_MATCH_ARM(CLASS, VAR, NAME, TAG, ...)  case CLASS::TAG_##TAG: {/*  */    TU_GM(TU_MATCH_BIND, TU_EXP VAR)(TAG, TU_EXP VAR , TU_EXP NAME)/*  */    __VA_ARGS__/* | 
