diff options
-rw-r--r-- | src/expand/mod.cpp | 147 |
1 files changed, 129 insertions, 18 deletions
diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp index 27de20ed..928151a6 100644 --- a/src/expand/mod.cpp +++ b/src/expand/mod.cpp @@ -15,6 +15,7 @@ void Expand_Attrs(const ::AST::MetaItems& attrs, AttrStage stage, ::std::function<void(const ExpandDecorator& d,const ::AST::MetaItem& a)> f); void Expand_Mod(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST::Path modpath, ::AST::Module& mod); +void Expand_Expr(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> modstack, AST::Expr& node); void Register_Synext_Decorator(::std::string name, ::std::unique_ptr<ExpandDecorator> handler) { g_decorators[name] = mv$(handler); @@ -115,6 +116,95 @@ void Expand_Attrs(const ::AST::MetaItems& attrs, AttrStage stage, ::AST::Crate& // Leave valid and return an empty expression return ::std::unique_ptr<TokenStream>(); } +::std::unique_ptr<TokenStream> Expand_Macro(bool is_early, const ::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST::Module& mod, const ::AST::MacroInvocation& mi) +{ + return Expand_Macro(is_early, crate, modstack, mod, mi.span(), mi.name(), mi.input_ident(), mi.input_tt()); +} + +void Expand_Pattern(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST::Module& mod, ::AST::Pattern& pat) +{ + TU_MATCH(::AST::Pattern::Data, (pat.data()), (e), + (MaybeBind, + ), + (Macro, + auto tt = Expand_Macro(is_early, crate, modstack, mod, *e.inv); + TODO(e.inv->span(), "Expand macro invocation in pattern"); + ), + (Any, + ), + (Box, + Expand_Pattern(is_early, crate, modstack, mod, *e.sub); + ), + (Ref, + Expand_Pattern(is_early, crate, modstack, mod, *e.sub); + ), + (Value, + Expand_Expr(is_early, crate, modstack, e.start); + Expand_Expr(is_early, crate, modstack, e.end); + ), + (Tuple, + for(auto& sp : e.sub_patterns) + Expand_Pattern(is_early, crate, modstack, mod, sp); + ), + (StructTuple, + for(auto& sp : e.sub_patterns) + Expand_Pattern(is_early, crate, modstack, mod, sp); + ), + (Struct, + for(auto& sp : e.sub_patterns) + Expand_Pattern(is_early, crate, modstack, mod, sp.second); + ), + (Slice, + for(auto& sp : e.leading) + Expand_Pattern(is_early, crate, modstack, mod, sp); + for(auto& sp : e.trailing) + Expand_Pattern(is_early, crate, modstack, mod, sp); + ) + ) +} + +void Expand_Type(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST::Module& mod, ::TypeRef& ty) +{ + TU_MATCH(::TypeData, (ty.m_data), (e), + (None, + ), + (Any, + ), + (Unit, + ), + (Macro, + auto tt = Expand_Macro(is_early, crate, modstack, mod, e.inv); + TODO(e.inv.span(), "Expand macro invocation in type"); + ), + (Primitive, + ), + (Function, + TODO(ty.span(), "Expand function type"); + ), + (Tuple, + for(auto& st : e.inner_types) + Expand_Type(is_early, crate, modstack, mod, st); + ), + (Borrow, + Expand_Type(is_early, crate, modstack, mod, *e.inner); + ), + (Pointer, + Expand_Type(is_early, crate, modstack, mod, *e.inner); + ), + (Array, + Expand_Type(is_early, crate, modstack, mod, *e.inner); + // TODO: Array size expression + //Expand_Expr(is_early, crate, modstack, e.size); + ), + (Generic, + ), + (Path, + ), + (TraitObject, + ) + ) +} + struct CExpandExpr: public ::AST::NodeVisitor { @@ -130,6 +220,10 @@ struct CExpandExpr: { } + ::AST::Module& cur_mod() { + return *(::AST::Module*)(modstack.m_item); + } + void visit(::std::unique_ptr<AST::ExprNode>& cnode) { if(cnode.get()) Expand_Attrs(cnode->attrs(), stage_pre(is_early), [&](const auto& d, const auto& a){ d.handle(a, this->crate, cnode); }); @@ -173,7 +267,7 @@ struct CExpandExpr: } void visit(::AST::ExprNode_Macro& node) override { - auto& mod = *(::AST::Module*)(modstack.m_item); + auto& mod = this->cur_mod(); auto ttl = Expand_Macro( is_early, crate, modstack, mod, Span(node.get_pos()), @@ -208,7 +302,8 @@ struct CExpandExpr: this->visit_nodelete(node, node.m_value); } void visit(::AST::ExprNode_LetBinding& node) override { - // TODO: Pattern and type + Expand_Type(is_early, crate, modstack, this->cur_mod(), node.m_type); + Expand_Pattern(is_early, crate, modstack, this->cur_mod(), node.m_pat); this->visit_nodelete(node, node.m_value); } void visit(::AST::ExprNode_Assign& node) override { @@ -216,7 +311,6 @@ struct CExpandExpr: this->visit_nodelete(node, node.m_value); } void visit(::AST::ExprNode_CallPath& node) override { - // TODO: path? this->visit_vector(node.m_args); } void visit(::AST::ExprNode_CallMethod& node) override { @@ -233,7 +327,15 @@ struct CExpandExpr: } void visit(::AST::ExprNode_Match& node) override { this->visit_nodelete(node, node.m_val); - // TODO: Arms + for(auto& arm : node.m_arms) + { + // TODO: Attributes on match arms (is it only #[cfg] that's allowed?) + for(auto& pat : arm.m_patterns) { + Expand_Pattern(is_early, crate, modstack, this->cur_mod(), pat); + } + this->visit_nodelete(node, arm.m_cond); + this->visit_nodelete(node, arm.m_code); + } } void visit(::AST::ExprNode_If& node) override { this->visit_nodelete(node, node.m_cond); @@ -241,7 +343,7 @@ struct CExpandExpr: this->visit_nodelete(node, node.m_false); } void visit(::AST::ExprNode_IfLet& node) override { - // TODO: Pattern + Expand_Pattern(is_early, crate, modstack, this->cur_mod(), node.m_pattern); this->visit_nodelete(node, node.m_value); this->visit_nodelete(node, node.m_true); this->visit_nodelete(node, node.m_false); @@ -251,13 +353,20 @@ struct CExpandExpr: void visit(::AST::ExprNode_Bool& node) override { } void visit(::AST::ExprNode_String& node) override { } void visit(::AST::ExprNode_Closure& node) override { - // TODO: Arg patterns and types - // TODO: Return type + for(auto& arg : node.m_args) { + Expand_Pattern(is_early, crate, modstack, this->cur_mod(), arg.first); + Expand_Type(is_early, crate, modstack, this->cur_mod(), arg.second); + } + Expand_Type(is_early, crate, modstack, this->cur_mod(), node.m_return); this->visit_nodelete(node, node.m_code); } void visit(::AST::ExprNode_StructLiteral& node) override { this->visit_nodelete(node, node.m_base_value); - // TODO: Values (with #[cfg] support) + for(auto& val : node.m_values) + { + // TODO: Attributes on struct literal items (#[cfg] only?) + this->visit_nodelete(node, val.second); + } } void visit(::AST::ExprNode_Array& node) override { this->visit_nodelete(node, node.m_size); @@ -279,7 +388,7 @@ struct CExpandExpr: } void visit(::AST::ExprNode_Cast& node) override { this->visit_nodelete(node, node.m_value); - // TODO: Type + Expand_Type(is_early, crate, modstack, this->cur_mod(), node.m_type); } void visit(::AST::ExprNode_BinOp& node) override { this->visit_nodelete(node, node.m_left); @@ -294,7 +403,7 @@ void Expand_Expr(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> m auto visitor = CExpandExpr(is_early, crate, modstack); visitor.visit(node); } -void Expand_Expr(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST::Path item_path, AST::Expr& node) +void Expand_Expr(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> modstack, AST::Expr& node) { auto visitor = CExpandExpr(is_early, crate, modstack); node.visit_nodes(visitor); @@ -321,8 +430,7 @@ void Expand_Mod(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> mo // Move out of the module to avoid invalidation if a new macro invocation is added auto mi_owned = mv$(mi); - auto ttl = Expand_Macro(is_early, crate, modstack, mod, - mi_owned.span(), mi_owned.name(), mi_owned.input_ident(), mi_owned.input_tt()); + auto ttl = Expand_Macro(is_early, crate, modstack, mod, mi_owned); if( ! ttl.get() ) { @@ -357,7 +465,7 @@ void Expand_Mod(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> mo Expand_Mod(is_early, crate, sub_modstack, path, e.e); ), (Crate, - // Skip, no recursion + // Can't recurse into an `extern crate` ), (Struct, @@ -370,16 +478,19 @@ void Expand_Mod(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> mo // TODO: Trait definition ), (Type, - // TODO: Do type aliases require recursion? + Expand_Type(is_early, crate, modstack, mod, e.e.type()); ), (Function, - // TODO: Recurse into argument patterns + types - Expand_Expr(is_early, crate, modstack, path, e.e.code()); + for(auto& arg : e.e.args()) { + Expand_Pattern(is_early, crate, modstack, mod, arg.first); + Expand_Type(is_early, crate, modstack, mod, arg.second); + } + Expand_Type(is_early, crate, modstack, mod, e.e.rettype()); + Expand_Expr(is_early, crate, modstack, e.e.code()); ), (Static, - // Recurse into static values - Expand_Expr(is_early, crate, modstack, path, e.e.value()); + Expand_Expr(is_early, crate, modstack, e.e.value()); ) ) |