diff options
author | John Hodge <tpg@mutabah.net> | 2016-05-26 11:04:04 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-05-26 11:04:04 +0800 |
commit | 81d89041e8500d9f6dfab9c55aee76967a5233f1 (patch) | |
tree | 26452d9973421d917921548e1b2b63950a6ca52b | |
parent | dd7680bc0d53f02e4b96b2b3896ebea16742c9bb (diff) | |
download | mrust-81d89041e8500d9f6dfab9c55aee76967a5233f1.tar.gz |
HIR Cosnt Eval - Initial work, hits TODOs
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | src/hir/expr.hpp | 4 | ||||
-rw-r--r-- | src/hir/from_ast.cpp | 15 | ||||
-rw-r--r-- | src/hir/hir.cpp | 30 | ||||
-rw-r--r-- | src/hir/hir.hpp | 3 | ||||
-rw-r--r-- | src/hir/type.cpp | 8 | ||||
-rw-r--r-- | src/hir/type.hpp | 3 | ||||
-rw-r--r-- | src/hir/visitor.cpp | 3 | ||||
-rw-r--r-- | src/hir_conv/constant_evaluation.cpp | 184 | ||||
-rw-r--r-- | src/main.cpp | 6 | ||||
-rw-r--r-- | src/parse/lex.cpp | 4 |
11 files changed, 252 insertions, 9 deletions
@@ -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()), |