summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-05-26 11:04:04 +0800
committerJohn Hodge <tpg@mutabah.net>2016-05-26 11:04:04 +0800
commit81d89041e8500d9f6dfab9c55aee76967a5233f1 (patch)
tree26452d9973421d917921548e1b2b63950a6ca52b
parentdd7680bc0d53f02e4b96b2b3896ebea16742c9bb (diff)
downloadmrust-81d89041e8500d9f6dfab9c55aee76967a5233f1.tar.gz
HIR Cosnt Eval - Initial work, hits TODOs
-rw-r--r--Makefile1
-rw-r--r--src/hir/expr.hpp4
-rw-r--r--src/hir/from_ast.cpp15
-rw-r--r--src/hir/hir.cpp30
-rw-r--r--src/hir/hir.hpp3
-rw-r--r--src/hir/type.cpp8
-rw-r--r--src/hir/type.hpp3
-rw-r--r--src/hir/visitor.cpp3
-rw-r--r--src/hir_conv/constant_evaluation.cpp184
-rw-r--r--src/main.cpp6
-rw-r--r--src/parse/lex.cpp4
11 files changed, 252 insertions, 9 deletions
diff --git a/Makefile b/Makefile
index d05acaab..029853ca 100644
--- a/Makefile
+++ b/Makefile
@@ -42,6 +42,7 @@ OBJ += expand/std_prelude.o
OBJ += macro_rules/mod.o macro_rules/eval.o macro_rules/parse.o
OBJ += resolve/use.o resolve/index.o resolve/absolute.o
OBJ += hir/from_ast.o hir/from_ast_expr.o
+OBJ += hir/hir.o
OBJ += hir/crate_ptr.o hir/type_ptr.o hir/expr_ptr.o
OBJ += hir/type.o hir/path.o hir/expr.o
OBJ += hir/visitor.o
diff --git a/src/hir/expr.hpp b/src/hir/expr.hpp
index 910dac8b..6a40d669 100644
--- a/src/hir/expr.hpp
+++ b/src/hir/expr.hpp
@@ -399,10 +399,12 @@ struct ExprNode_ArraySized:
{
::HIR::ExprNodeP m_val;
::HIR::ExprNodeP m_size; // TODO: Has to be constant
+ size_t m_size_val;
ExprNode_ArraySized(::HIR::ExprNodeP val, ::HIR::ExprNodeP size):
m_val( mv$(val) ),
- m_size( mv$(size) )
+ m_size( mv$(size) ),
+ m_size_val( ~0u )
{}
NODE_METHODS();
diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp
index df73d4ec..41ee37fd 100644
--- a/src/hir/from_ast.cpp
+++ b/src/hir/from_ast.cpp
@@ -463,10 +463,17 @@
return ::HIR::TypeRef( ::HIR::TypeRef::Data::make_Pointer({e.is_mut, box$(LowerHIR_Type(*e.inner))}) );
),
(Array,
- return ::HIR::TypeRef( ::HIR::TypeRef::Data::make_Array({
- box$( LowerHIR_Type(*e.inner) ),
- LowerHIR_Expr( e.size )
- }) );
+ if( e.size ) {
+ return ::HIR::TypeRef( ::HIR::TypeRef::Data::make_Array({
+ box$( LowerHIR_Type(*e.inner) ),
+ LowerHIR_Expr( e.size )
+ }) );
+ }
+ else {
+ return ::HIR::TypeRef( ::HIR::TypeRef::Data::make_Slice({
+ box$( LowerHIR_Type(*e.inner) )
+ }) );
+ }
),
(Path,
diff --git a/src/hir/hir.cpp b/src/hir/hir.cpp
new file mode 100644
index 00000000..5b9401f5
--- /dev/null
+++ b/src/hir/hir.cpp
@@ -0,0 +1,30 @@
+/*
+ */
+#include "hir.hpp"
+
+namespace HIR {
+ ::std::ostream& operator<<(::std::ostream& os, const ::HIR::Literal& v)
+ {
+ TU_MATCH(::HIR::Literal, (v), (e),
+ (Invalid,
+ os << "!";
+ ),
+ (List,
+ os << "[";
+ for(const auto& val : e)
+ os << " " << val << ",";
+ os << " ]";
+ ),
+ (Integer,
+ os << e;
+ ),
+ (Float,
+ os << e;
+ ),
+ (String,
+ os << "\"" << e << "\"";
+ )
+ )
+ return os;
+ }
+}
diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp
index f77c2a14..2887fd13 100644
--- a/src/hir/hir.hpp
+++ b/src/hir/hir.hpp
@@ -43,12 +43,13 @@ struct VisEnt
TAGGED_UNION(Literal, Invalid,
(Invalid, struct {}),
// List = Array, Tuple, struct literal
- (List, ::std::vector<Literal>),
+ (List, ::std::vector<Literal>), // TODO: Have a variant for repetition lists
(Integer, uint64_t),
(Float, double),
// String = &'static str or &[u8; N]
(String, ::std::string)
);
+extern ::std::ostream& operator<<(::std::ostream& os, const Literal& v);
// --------------------------------------------------------------------
// Type structures
diff --git a/src/hir/type.cpp b/src/hir/type.cpp
index 2bbfafa8..6863cd12 100644
--- a/src/hir/type.cpp
+++ b/src/hir/type.cpp
@@ -65,6 +65,9 @@ void ::HIR::TypeRef::fmt(::std::ostream& os) const
(Array,
os << "[" << *e.inner << "; " << "/*sz*/" << "]";
),
+ (Slice,
+ os << "[" << *e.inner << "]";
+ ),
(Tuple,
os << "(";
for(const auto& t : e)
@@ -131,6 +134,11 @@ void ::HIR::TypeRef::fmt(::std::ostream& os) const
// /* huh */
// }) );
),
+ (Slice,
+ return ::HIR::TypeRef( Data::make_Slice({
+ box$( e.inner->clone() )
+ }) );
+ ),
(Tuple,
::std::vector< ::HIR::TypeRef> types;
for(const auto& t : e)
diff --git a/src/hir/type.hpp b/src/hir/type.hpp
index 06535dfb..ca79a0c1 100644
--- a/src/hir/type.hpp
+++ b/src/hir/type.hpp
@@ -75,6 +75,9 @@ struct TypeRef
::std::unique_ptr<TypeRef> inner;
::HIR::ExprPtr size;
}),
+ (Slice, struct {
+ ::std::unique_ptr<TypeRef> inner;
+ }),
(Tuple, ::std::vector<TypeRef>),
(Borrow, struct {
::HIR::BorrowType type;
diff --git a/src/hir/visitor.cpp b/src/hir/visitor.cpp
index 76bfda9c..9a38aa20 100644
--- a/src/hir/visitor.cpp
+++ b/src/hir/visitor.cpp
@@ -254,6 +254,9 @@ void ::HIR::Visitor::visit_type(::HIR::TypeRef& ty)
this->visit_type( *e.inner );
this->visit_expr( e.size );
),
+ (Slice,
+ this->visit_type( *e.inner );
+ ),
(Tuple,
for(auto& t : e) {
this->visit_type(t);
diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp
index 0c8fe8fd..7738861d 100644
--- a/src/hir_conv/constant_evaluation.cpp
+++ b/src/hir_conv/constant_evaluation.cpp
@@ -4,7 +4,189 @@
#include "main_bindings.hpp"
#include <hir/hir.hpp>
#include <hir/expr.hpp>
+#include <hir/visitor.hpp>
-void ConvertHIR_ConstantEvaluate(::HIR::Crate& hir_crate)
+
+namespace {
+ ::HIR::Literal evaluate_constant(const ::HIR::Crate& crate, ::HIR::ExprNode& expr)
+ {
+ struct Visitor:
+ public ::HIR::ExprVisitor
+ {
+ const ::HIR::Crate& crate;
+
+ ::HIR::Literal m_rv;
+
+ Visitor(const ::HIR::Crate& crate):
+ crate(crate)
+ {}
+
+ void badnode(const ::HIR::ExprNode& node) const {
+ ERROR(Span(), E0000, "Node not allowed in constant expression");
+ }
+
+ void visit(::HIR::ExprNode_Block& node) override {
+ TODO(Span(), "ExprNode_Block");
+ }
+ void visit(::HIR::ExprNode_Return& node) override {
+ TODO(Span(), "ExprNode_Return");
+ }
+ void visit(::HIR::ExprNode_Let& node) override {
+ badnode(node);
+ }
+ void visit(::HIR::ExprNode_Loop& node) override {
+ badnode(node);
+ }
+ void visit(::HIR::ExprNode_LoopControl& node) override {
+ badnode(node);
+ }
+ void visit(::HIR::ExprNode_Match& node) override {
+ badnode(node);
+ }
+ void visit(::HIR::ExprNode_If& node) override {
+ badnode(node);
+ }
+
+ void visit(::HIR::ExprNode_Assign& node) override {
+ badnode(node);
+ }
+ void visit(::HIR::ExprNode_BinOp& node) override {
+ TODO(Span(), "ExprNode_BinOp");
+ }
+ void visit(::HIR::ExprNode_UniOp& node) override {
+ TODO(Span(), "ExprNode_UniOp");
+ }
+ void visit(::HIR::ExprNode_Cast& node) override {
+ TODO(Span(), "ExprNode_Cast");
+ }
+ void visit(::HIR::ExprNode_Index& node) override {
+ badnode(node);
+ }
+ void visit(::HIR::ExprNode_Deref& node) override {
+ badnode(node);
+ }
+
+ void visit(::HIR::ExprNode_CallPath& node) override {
+ TODO(Span(), "exec const fn");
+ }
+ void visit(::HIR::ExprNode_CallValue& node) override {
+ badnode(node);
+ }
+ void visit(::HIR::ExprNode_CallMethod& node) override {
+ // TODO: const methods
+ badnode(node);
+ }
+ void visit(::HIR::ExprNode_Field& node) override {
+ badnode(node);
+ }
+
+ void visit(::HIR::ExprNode_Literal& node) override {
+ TU_MATCH(::HIR::ExprNode_Literal::Data, (node.m_data), (e),
+ (Integer,
+ m_rv = ::HIR::Literal(e.m_value);
+ ),
+ (Float,
+ m_rv = ::HIR::Literal(e.m_value);
+ ),
+ (Boolean,
+ m_rv = ::HIR::Literal(static_cast<uint64_t>(e));
+ ),
+ (String,
+ m_rv = ::HIR::Literal(e);
+ ),
+ (ByteString,
+ TODO(Span(), "Byte literal in constant");
+ //m_rv = ::HIR::Literal::make_String(e);
+ )
+ )
+ }
+ void visit(::HIR::ExprNode_PathValue& node) override {
+ TODO(Span(), "ExprNode_PathValue");
+ }
+ void visit(::HIR::ExprNode_Variable& node) override {
+ TODO(Span(), "ExprNode_Variable");
+ }
+
+ void visit(::HIR::ExprNode_StructLiteral& node) override {
+ TODO(Span(), "ExprNode_StructLiteral");
+ }
+ void visit(::HIR::ExprNode_Tuple& node) override {
+ TODO(Span(), "ExprNode_Tuple");
+ }
+ void visit(::HIR::ExprNode_ArrayList& node) override {
+ TODO(Span(), "ExprNode_ArrayList");
+ }
+ void visit(::HIR::ExprNode_ArraySized& node) override {
+ TODO(Span(), "ExprNode_ArraySized");
+ }
+
+ void visit(::HIR::ExprNode_Closure& node) override {
+ badnode(node);
+ }
+ };
+
+ Visitor v { crate };
+ expr.visit(v);
+
+ if( v.m_rv.is_Invalid() ) {
+ BUG(Span(), "Expression did not yeild a literal");
+ }
+
+ return mv$(v.m_rv);
+ }
+
+ class Expander:
+ public ::HIR::Visitor
+ {
+ const ::HIR::Crate& m_crate;
+
+ public:
+ Expander(const ::HIR::Crate& crate):
+ m_crate(crate)
+ {}
+
+ void visit_type(::HIR::TypeRef& ty)
+ {
+ 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);
+ )
+ else {
+ ::HIR::Visitor::visit_type(ty);
+ }
+ }
+ void visit_expr(::HIR::ExprPtr& expr) override
+ {
+ struct Visitor:
+ public ::HIR::ExprVisitorDef
+ {
+ const ::HIR::Crate& m_crate;
+
+ Visitor(const ::HIR::Crate& crate):
+ m_crate(crate)
+ {}
+
+ 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");
+ node.m_size_val = val.as_Integer();
+ }
+ };
+
+ if( &*expr != nullptr )
+ {
+ Visitor v { this->m_crate };
+ (*expr).visit(v);
+ }
+ }
+ };
+} // namespace
+
+void ConvertHIR_ConstantEvaluate(::HIR::Crate& crate)
{
+ Expander exp { crate };
+ exp.visit_crate( crate );
}
diff --git a/src/main.cpp b/src/main.cpp
index 6be8b2ca..f163e736 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -77,13 +77,19 @@ int main(int argc, char *argv[])
ProgramParams params(argc, argv);
// Set up cfg values
+ // TODO: Target spec
Cfg_SetFlag("linux");
Cfg_SetValue("target_pointer_width", "64");
+ Cfg_SetValue("target_endian", "little");
+ Cfg_SetValue("target_arch", "x86-noasm"); // TODO: asm! macro
Cfg_SetValueCb("target_has_atomic", [](const ::std::string& s) {
if(s == "8") return true; // Has an atomic byte
if(s == "ptr") return true; // Has an atomic pointer-sized value
return false;
});
+ Cfg_SetValueCb("target_feature", [](const ::std::string& s) {
+ return false;
+ });
try
diff --git a/src/parse/lex.cpp b/src/parse/lex.cpp
index 395eee48..5530f0b5 100644
--- a/src/parse/lex.cpp
+++ b/src/parse/lex.cpp
@@ -20,8 +20,8 @@
#include <typeinfo>
#include <algorithm> // std::count
-//const bool DEBUG_PRINT_TOKENS = false;
-const bool DEBUG_PRINT_TOKENS = true;
+const bool DEBUG_PRINT_TOKENS = false;
+//const bool DEBUG_PRINT_TOKENS = true;
Lexer::Lexer(const ::std::string& filename):
m_path(filename.c_str()),