summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-05-20 22:38:34 +0800
committerJohn Hodge <tpg@mutabah.net>2016-05-20 22:38:34 +0800
commitcca20d66c1f0933b12b4bfd82817aa2cf40b1730 (patch)
tree26ffdeb83d3b9e3f93f71adb44cf4d0dc50ecc5b
parentd2fcab19c6d8441f1b0610cb2147a43292893764 (diff)
downloadmrust-cca20d66c1f0933b12b4bfd82817aa2cf40b1730.tar.gz
Expand+HIR - `?` desugar, closures
-rw-r--r--src/expand/mod.cpp26
-rw-r--r--src/hir/expr.cpp2
-rw-r--r--src/hir/expr.hpp24
-rw-r--r--src/hir/from_ast_expr.cpp68
-rw-r--r--src/hir/path.hpp11
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;