summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/hir/expr.cpp5
-rw-r--r--src/hir/expr.hpp3
-rw-r--r--src/hir/expr_ptr.hpp5
-rw-r--r--src/hir/from_ast.cpp3
-rw-r--r--src/hir/type.hpp1
-rw-r--r--src/hir_conv/constant_evaluation.cpp176
-rw-r--r--src/include/tagged_union.hpp2
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__/*