diff options
-rw-r--r-- | src/expand/mod.cpp | 26 | ||||
-rw-r--r-- | src/hir/expr.cpp | 2 | ||||
-rw-r--r-- | src/hir/expr.hpp | 24 | ||||
-rw-r--r-- | src/hir/from_ast_expr.cpp | 68 | ||||
-rw-r--r-- | src/hir/path.hpp | 11 |
5 files changed, 117 insertions, 14 deletions
diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp index 7474ce21..f0508698 100644 --- a/src/expand/mod.cpp +++ b/src/expand/mod.cpp @@ -482,6 +482,32 @@ struct CExpandExpr: } void visit(::AST::ExprNode_UniOp& node) override { this->visit_nodelete(node, node.m_value); + if( node.m_type == ::AST::ExprNode_UniOp::QMARK ) { + auto path_Ok = ::AST::Path("", {::AST::PathNode("result"), ::AST::PathNode("Result"), ::AST::PathNode("Ok")}); + auto path_Err = ::AST::Path("", {::AST::PathNode("result"), ::AST::PathNode("Result"), ::AST::PathNode("Err")}); + auto path_From = ::AST::Path("", {::AST::PathNode("convert"), ::AST::PathNode("From")}); + + ::std::vector< ::AST::ExprNode_Match_Arm> arms; + arms.push_back(::AST::ExprNode_Match_Arm( + ::make_vec1( ::AST::Pattern(::AST::Pattern::TagEnumVariant(), path_Ok, ::make_vec1( ::AST::Pattern(::AST::Pattern::TagBind(), "v") )) ), + nullptr, + ::AST::ExprNodeP( new ::AST::ExprNode_NamedValue( ::AST::Path(::AST::Path::TagLocal(), "v") ) ) + )); + arms.push_back(::AST::ExprNode_Match_Arm( + ::make_vec1( ::AST::Pattern(::AST::Pattern::TagEnumVariant(), path_Err, ::make_vec1( ::AST::Pattern(::AST::Pattern::TagBind(), "e") )) ), + nullptr, + ::AST::ExprNodeP(new ::AST::ExprNode_Flow( + ::AST::ExprNode_Flow::RETURN, + "", + ::AST::ExprNodeP(new ::AST::ExprNode_CallPath( + ::AST::Path(::AST::Path::TagUfcs(), ::TypeRef(), mv$(path_From), { ::AST::PathNode("from") }), + ::make_vec1( ::AST::ExprNodeP( new ::AST::ExprNode_NamedValue( ::AST::Path(::AST::Path::TagLocal(), "e") ) ) ) + )) + )) + )); + + replacement.reset(new ::AST::ExprNode_Match( mv$(node.m_value), mv$(arms) )); + } } }; diff --git a/src/hir/expr.cpp b/src/hir/expr.cpp index c80d5f61..d42c2678 100644 --- a/src/hir/expr.cpp +++ b/src/hir/expr.cpp @@ -36,5 +36,7 @@ DEF_VISIT(ExprNode_Tuple) DEF_VISIT(ExprNode_ArrayList) DEF_VISIT(ExprNode_ArraySized) +DEF_VISIT(ExprNode_Closure); + #undef DEF_VISIT diff --git a/src/hir/expr.hpp b/src/hir/expr.hpp index a1ea043b..6b9482fb 100644 --- a/src/hir/expr.hpp +++ b/src/hir/expr.hpp @@ -44,8 +44,8 @@ struct ExprNode_Return: { ::HIR::ExprNodeP m_value; - ExprNode_Return(::HIR::ExprNodeP v): - m_value( mv$(m_value) ) + ExprNode_Return(::HIR::ExprNodeP value): + m_value( mv$(value) ) {} NODE_METHODS(); @@ -406,6 +406,24 @@ struct ExprNode_ArraySized: NODE_METHODS(); }; +struct ExprNode_Closure: + public ExprNode +{ + typedef ::std::vector< ::std::pair< ::HIR::Pattern, ::HIR::TypeRef> > args_t; + + args_t m_args; + ::HIR::TypeRef m_return; + ::HIR::ExprNodeP m_code; + + ExprNode_Closure(args_t args, ::HIR::TypeRef rv, ::HIR::ExprNodeP code): + m_args( ::std::move(args) ), + m_return( ::std::move(rv) ), + m_code( ::std::move(code) ) + {} + + NODE_METHODS(); +}; + #undef NODE_METHODS class ExprVisitor @@ -441,6 +459,8 @@ public: NV(ExprNode_Tuple); NV(ExprNode_ArrayList); NV(ExprNode_ArraySized); + + NV(ExprNode_Closure); }; } diff --git a/src/hir/from_ast_expr.cpp b/src/hir/from_ast_expr.cpp index 690d31cb..e52e9194 100644 --- a/src/hir/from_ast_expr.cpp +++ b/src/hir/from_ast_expr.cpp @@ -94,11 +94,38 @@ struct LowerHIR_ExprNode_Visitor: ::HIR::ExprNode_BinOp::Op op; switch(v.m_type) { - case ::AST::ExprNode_BinOp::RANGE: - TODO(v.get_pos(), "Desugar range"); - break; + case ::AST::ExprNode_BinOp::RANGE: { + // TODO: Lang items + auto path_Range = ::HIR::GenericPath( ::HIR::SimplePath("", {"ops", "Range"}) ); + auto path_RangeFrom = ::HIR::GenericPath( ::HIR::SimplePath("", {"ops", "RangeFrom"}) ); + auto path_RangeTo = ::HIR::GenericPath( ::HIR::SimplePath("", {"ops", "RangeTo"}) ); + auto path_RangeFull = ::HIR::GenericPath( ::HIR::SimplePath("", {"ops", "RangeFull"}) ); + + ::HIR::ExprNode_StructLiteral::t_values values; + if( v.m_left ) + values.push_back( ::std::make_pair( ::std::string("start"), LowerHIR_ExprNode_Inner( *v.m_left ) ) ); + if( v.m_right ) + values.push_back( ::std::make_pair( ::std::string("end") , LowerHIR_ExprNode_Inner( *v.m_right ) ) ); + + if( v.m_left ) { + if( v.m_right ) { + m_rv.reset( new ::HIR::ExprNode_StructLiteral(mv$(path_Range), nullptr, mv$(values)) ); + } + else { + m_rv.reset( new ::HIR::ExprNode_StructLiteral(mv$(path_RangeFrom), nullptr, mv$(values)) ); + } + } + else { + if( v.m_right ) { + m_rv.reset( new ::HIR::ExprNode_StructLiteral(mv$(path_RangeTo), nullptr, mv$(values)) ); + } + else { + m_rv.reset( new ::HIR::ExprNode_PathValue(mv$(path_RangeFull)) ); + } + } + break; } case ::AST::ExprNode_BinOp::RANGE_INC: - TODO(v.get_pos(), "Desugar range"); + TODO(v.get_pos(), "Desugar range (inclusive)"); break; case ::AST::ExprNode_BinOp::PLACE_IN: TODO(v.get_pos(), "Desugar placement syntax"); @@ -141,6 +168,7 @@ struct LowerHIR_ExprNode_Visitor: break; case ::AST::ExprNode_UniOp::QMARK: TODO(v.get_pos(), "Desugar question mark operator"); + // NOTE: This operator doesn't use language items, ergo it's a basic desugar and is done in expand break; case ::AST::ExprNode_UniOp::REF: op = ::HIR::ExprNode_UniOp::Op::Ref ; if(0) @@ -165,10 +193,20 @@ struct LowerHIR_ExprNode_Visitor: ::std::vector< ::HIR::ExprNodeP> args; for(const auto& arg : v.m_args) args.push_back( LowerHIR_ExprNode_Inner(*arg) ); - m_rv.reset( new ::HIR::ExprNode_CallPath( - LowerHIR_Path(v.m_path), - mv$( args ) - ) ); + + TU_IFLET(::AST::Path::Class, v.m_path.m_class, Local, e, + m_rv.reset( new ::HIR::ExprNode_CallValue( + ::HIR::ExprNodeP(new ::HIR::ExprNode_Variable( e.name, v.m_path.binding().as_Variable().slot )), + mv$(args) + ) ); + ) + else + { + m_rv.reset( new ::HIR::ExprNode_CallPath( + LowerHIR_Path(v.m_path), + mv$( args ) + ) ); + } } virtual void visit(::AST::ExprNode_CallMethod& v) override { ::std::vector< ::HIR::ExprNodeP> args; @@ -239,7 +277,7 @@ struct LowerHIR_ExprNode_Visitor: break; } case ::AST::ExprNode_Loop::FOR: // NOTE: This should already be desugared (as a pass before resolve) - TODO(v.get_pos(), "Desugar for loop"); + BUG(v.get_pos(), "Encountered still-sugared for loop"); break; } } @@ -344,6 +382,18 @@ struct LowerHIR_ExprNode_Visitor: m_rv.reset( new ::HIR::ExprNode_Literal( ::HIR::ExprNode_Literal::Data::make_String( v.m_value ) ) ); } virtual void visit(::AST::ExprNode_Closure& v) override { + ::HIR::ExprNode_Closure::args_t args; + for(const auto& arg : v.m_args) { + args.push_back( ::std::make_pair( + LowerHIR_Pattern( arg.first ), + LowerHIR_Type( arg.second ) + ) ); + } + m_rv.reset( new ::HIR::ExprNode_Closure( + mv$(args), + LowerHIR_Type(v.m_return), + LowerHIR_ExprNode_Inner(*v.m_code) + ) ); } virtual void visit(::AST::ExprNode_StructLiteral& v) override { ::HIR::ExprNode_StructLiteral::t_values values; diff --git a/src/hir/path.hpp b/src/hir/path.hpp index 05ceab3d..9d66b135 100644 --- a/src/hir/path.hpp +++ b/src/hir/path.hpp @@ -12,6 +12,9 @@ namespace HIR { /// Simple path - Absolute with no generic parameters struct SimplePath { + ::std::string m_crate_name; + ::std::vector< ::std::string> m_components; + SimplePath(): m_crate_name("") { @@ -20,9 +23,11 @@ struct SimplePath m_crate_name( mv$(crate) ) { } - - ::std::string m_crate_name; - ::std::vector< ::std::string> m_components; + SimplePath(::std::string crate, ::std::vector< ::std::string> components): + m_crate_name( mv$(crate) ), + m_components( mv$(components) ) + { + } SimplePath operator+(const ::std::string& s) const; |