From d0461823a2359e0eb052dd10813bc6a3d66f7c74 Mon Sep 17 00:00:00 2001 From: "John Hodge (sonata)" Date: Thu, 1 Jan 2015 13:51:57 +0800 Subject: Name resolve framework coming along --- src/ast/ast.cpp | 92 ++++----------- src/ast/ast.hpp | 285 +++++---------------------------------------- src/ast/ast_expr.hpp | 302 ++++++++++++++++++++++++++++++++++++++++++++++++ src/ast/path.hpp | 64 +++++++++- src/common.hpp | 23 ++++ src/convert/resolve.cpp | 107 +++++++++++++++-- src/parse/expr.cpp | 11 +- src/types.hpp | 7 +- 8 files changed, 545 insertions(+), 346 deletions(-) create mode 100644 src/ast/ast_expr.hpp (limited to 'src') diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 29b551ed..e1e6e877 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -7,13 +7,6 @@ namespace AST { -Path::Path() -{ -} -Path::Path(Path::TagAbsolute) -{ -} - PathNode::PathNode(::std::string name, ::std::vector args): m_name(name), @@ -29,18 +22,29 @@ const ::std::vector& PathNode::args() const return m_params; } -Pattern::Pattern(TagMaybeBind, ::std::string name) -{ -} -Pattern::Pattern(TagValue, ::std::unique_ptr node) -{ -} -Pattern::Pattern(TagEnumVariant, Path path, ::std::vector sub_patterns) + +::std::ostream& operator<<(::std::ostream& os, const Pattern& pat) { + switch(pat.m_class) + { + case Pattern::MAYBE_BIND: + os << "Pattern(TagMaybeBind, '" << pat.m_path[0].name() << "')"; + break; + case Pattern::VALUE: + //os << "Pattern(TagValue, " << *pat.m_node << ")"; + os << "Pattern(TagValue, TODO:ExprNode)"; + break; + case Pattern::TUPLE: + os << "Pattern(TagTuple, " << pat.m_sub_patterns << ")"; + break; + case Pattern::TUPLE_STRUCT: + os << "Pattern(TagEnumVariant, " << pat.m_path << ", " << pat.m_sub_patterns << ")"; + break; + } + return os; } - Impl::Impl(TypeRef impl_type, TypeRef trait_type) { } @@ -90,6 +94,11 @@ void Expr::visit_nodes(NodeVisitor& v) { m_node->visit(v); } +::std::ostream& operator<<(::std::ostream& os, const Expr& pat) +{ + os << "Expr(TODO)"; + return os; +} ExprNode::~ExprNode() { } @@ -97,30 +106,18 @@ ExprNode::~ExprNode() { ExprNode_Block::~ExprNode_Block() { } void ExprNode_Block::visit(NodeVisitor& nv) { - for( auto& node : m_nodes ) { - if( node.get() ) - node->visit(nv); - } nv.visit(*this); } void ExprNode_Return::visit(NodeVisitor& nv) { - if( m_value.get() ) - m_value->visit(nv); nv.visit(*this); } void ExprNode_LetBinding::visit(NodeVisitor& nv) { - if( m_value.get() ) - m_value->visit(nv); nv.visit(*this); } void ExprNode_Assign::visit(NodeVisitor& nv) { - if( m_slot.get() ) - m_slot->visit(nv); - if( m_value.get() ) - m_value->visit(nv); nv.visit(*this); } @@ -160,50 +157,9 @@ void ExprNode_Cast::visit(NodeVisitor& nv) { nv.visit(*this); } void ExprNode_BinOp::visit(NodeVisitor& nv) { - m_left->visit(nv); - m_right->visit(nv); nv.visit(*this); } -#if 0 -ExprNode::ExprNode(TagLetBinding, Pattern pat, ExprNode value) -{ -} -ExprNode::ExprNode(TagReturn, ExprNode val) -{ -} -ExprNode::ExprNode(TagCast, ExprNode value, TypeRef dst_type) -{ -} -ExprNode::ExprNode(TagInteger, uint64_t value, enum eCoreType datatype) -{ -} -ExprNode::ExprNode(TagStructLiteral, Path path, ExprNode base_value, ::std::vector< ::std::pair< ::std::string,ExprNode> > values ) -{ -} -ExprNode::ExprNode(TagCallPath, Path path, ::std::vector args) -{ -} -ExprNode::ExprNode(TagCallObject, ExprNode val, ::std::vector args) -{ -} -ExprNode::ExprNode(TagMatch, ExprNode val, ::std::vector< ::std::pair > arms) -{ -} -ExprNode::ExprNode(TagIf, ExprNode cond, ExprNode true_code, ExprNode false_code) -{ -} -ExprNode::ExprNode(TagNamedValue, Path path) -{ -} -ExprNode::ExprNode(TagField, ::std::string name) -{ -} -ExprNode::ExprNode(TagBinOp, BinOpType type, ExprNode left, ExprNode right) -{ -} -#endif - TypeParam::TypeParam(bool is_lifetime, ::std::string name) { diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index 58f1e06c..6c3e726c 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -37,271 +37,48 @@ class ExprNode; class Pattern { + enum BindType { + MAYBE_BIND, + VALUE, + TUPLE, + TUPLE_STRUCT, + }; + BindType m_class; + Path m_path; + unique_ptr m_node; + ::std::vector m_sub_patterns; public: Pattern(); struct TagMaybeBind {}; - Pattern(TagMaybeBind, ::std::string name); + Pattern(TagMaybeBind, ::std::string name): + m_class(MAYBE_BIND), + m_path(Path::TagLocal(), name) + {} struct TagValue {}; - Pattern(TagValue, unique_ptr node); - - struct TagEnumVariant {}; - Pattern(TagEnumVariant, Path path, ::std::vector sub_patterns); -}; - -class NodeVisitor; - -class ExprNode -{ -public: - virtual ~ExprNode() = 0; - - virtual void visit(NodeVisitor& nv) = 0; -}; - -class ExprNode_Block: - public ExprNode -{ - ::std::vector< ::std::unique_ptr > m_nodes; -public: - ExprNode_Block(const ExprNode_Block& x) = delete; - ExprNode_Block(::std::vector< ::std::unique_ptr >&& nodes): - m_nodes( move(nodes) ) - { - } - virtual ~ExprNode_Block() override; - - virtual void visit(NodeVisitor& nv) override; -}; - -// Return a value -class ExprNode_Return: - public ExprNode -{ - unique_ptr m_value; -public: - ExprNode_Return(unique_ptr&& value): - m_value( move(value) ) - { - } - - virtual void visit(NodeVisitor& nv) override; -}; -class ExprNode_LetBinding: - public ExprNode -{ - Pattern m_pat; - unique_ptr m_value; -public: - ExprNode_LetBinding(Pattern pat, unique_ptr&& value): - m_pat( move(pat) ), - m_value( move(value) ) - { - } - - virtual void visit(NodeVisitor& nv) override; -}; -class ExprNode_Assign: - public ExprNode -{ - unique_ptr m_slot; - unique_ptr m_value; -public: - ExprNode_Assign(unique_ptr&& slot, unique_ptr&& value): - m_slot( move(slot) ), - m_value( move(value) ) - { - } - - virtual void visit(NodeVisitor& nv) override; -}; -class ExprNode_CallPath: - public ExprNode -{ - Path m_path; - ::std::vector> m_args; -public: - ExprNode_CallPath(Path&& path, ::std::vector>&& args): - m_path( move(path) ), - m_args( move(args) ) - { - } - - virtual void visit(NodeVisitor& nv) override; -}; -// Call an object (Fn/FnMut/FnOnce) -class ExprNode_CallObject: - public ExprNode -{ - unique_ptr m_val; - ::std::vector> m_args; -public: - ExprNode_CallObject(unique_ptr&& val, ::std::vector< unique_ptr >&& args): - m_val( move(val) ), - m_args( move(args) ) - { - } - virtual void visit(NodeVisitor& nv) override; -}; - -class ExprNode_Match: - public ExprNode -{ - typedef ::std::vector< ::std::pair > > arm_t; - unique_ptr m_val; - arm_t m_arms; -public: - ExprNode_Match(unique_ptr&& val, arm_t&& arms): - m_val( ::std::move(val) ), - m_arms( ::std::move(arms) ) - { - } - virtual void visit(NodeVisitor& nv) override; -}; - -class ExprNode_If: - public ExprNode -{ - unique_ptr m_cond; - unique_ptr m_true; - unique_ptr m_false; -public: - ExprNode_If(unique_ptr&& cond, unique_ptr&& true_code, unique_ptr&& false_code): - m_cond( ::std::move(cond) ), - m_true( ::std::move(true_code) ), - m_false( ::std::move(false_code) ) - { - } - virtual void visit(NodeVisitor& nv) override; -}; -// Literal integer -class ExprNode_Integer: - public ExprNode -{ - enum eCoreType m_datatype; - uint64_t m_value; -public: - ExprNode_Integer(uint64_t value, enum eCoreType datatype): - m_datatype(datatype), - m_value(value) - { - } - - virtual void visit(NodeVisitor& nv) override; -}; -// Literal structure -class ExprNode_StructLiteral: - public ExprNode -{ - typedef ::std::vector< ::std::pair< ::std::string, unique_ptr > > t_values; - Path m_path; - unique_ptr m_base_value; - t_values m_values; -public: - ExprNode_StructLiteral(Path path, unique_ptr&& base_value, t_values&& values ): - m_path( move(path) ), - m_base_value( move(base_value) ), - m_values( move(values) ) + Pattern(TagValue, unique_ptr node): + m_class(VALUE), + m_node( ::std::move(node) ) {} - - virtual void visit(NodeVisitor& nv) override; -}; -// Variable / Constant -class ExprNode_NamedValue: - public ExprNode -{ - Path m_path; -public: - ExprNode_NamedValue(Path&& path): - m_path( ::std::move(path) ) - { - } - virtual void visit(NodeVisitor& nv) override; -}; -// Field dereference -class ExprNode_Field: - public ExprNode -{ - ::std::unique_ptr m_obj; - ::std::string m_name; -public: - ExprNode_Field(::std::unique_ptr&& obj, ::std::string&& name): - m_obj( ::std::move(obj) ), - m_name( ::std::move(name) ) - { - } - virtual void visit(NodeVisitor& nv) override; -}; - -// Type cast ('as') -class ExprNode_Cast: - public ExprNode -{ - unique_ptr m_value; - TypeRef m_type; -public: - ExprNode_Cast(unique_ptr&& value, TypeRef&& dst_type): - m_value( move(value) ), - m_type( move(dst_type) ) - { - } - virtual void visit(NodeVisitor& nv) override; -}; -// Binary operation -class ExprNode_BinOp: - public ExprNode -{ -public: - enum Type { - CMPEQU, - CMPNEQU, + struct TagTuple {}; + Pattern(TagTuple, ::std::vector sub_patterns): + m_class(TUPLE), + m_sub_patterns( ::std::move(sub_patterns) ) + {} - BITAND, - BITOR, - BITXOR, + struct TagEnumVariant {}; + Pattern(TagEnumVariant, Path path, ::std::vector sub_patterns): + m_class(TUPLE_STRUCT), + m_path( ::std::move(path) ), + m_sub_patterns( ::std::move(sub_patterns) ) + {} - SHL, - SHR, - }; -private: - Type m_type; - ::std::unique_ptr m_left; - ::std::unique_ptr m_right; -public: - ExprNode_BinOp(const ExprNode_Block& x) = delete; - ExprNode_BinOp(Type type, ::std::unique_ptr left, ::std::unique_ptr right): - m_type(type), - m_left( ::std::move(left) ), - m_right( ::std::move(right) ) - { - } - virtual ~ExprNode_BinOp() override {} - - virtual void visit(NodeVisitor& nv) override; + friend ::std::ostream& operator<<(::std::ostream& os, const Pattern& pat); }; -class NodeVisitor -{ -public: - virtual void visit(ExprNode_Block& node) {} - virtual void visit(ExprNode_Return& node) {} - virtual void visit(ExprNode_LetBinding& node) {} - virtual void visit(ExprNode_Assign& node) {} - virtual void visit(ExprNode_CallPath& node) {} - virtual void visit(ExprNode_CallObject& node) {} - virtual void visit(ExprNode_Match& node) {} - virtual void visit(ExprNode_If& node) {} - - virtual void visit(ExprNode_Integer& node) {} - virtual void visit(ExprNode_StructLiteral& node) {} - virtual void visit(ExprNode_NamedValue& node) {} - - virtual void visit(ExprNode_Field& node) {} - virtual void visit(ExprNode_Cast& node) {} - virtual void visit(ExprNode_BinOp& node) {} -}; +#include "ast_expr.hpp" class Expr { @@ -317,6 +94,8 @@ public: } void visit_nodes(NodeVisitor& v); + + friend ::std::ostream& operator<<(::std::ostream& os, const Expr& pat); }; class Function diff --git a/src/ast/ast_expr.hpp b/src/ast/ast_expr.hpp new file mode 100644 index 00000000..223d7a4d --- /dev/null +++ b/src/ast/ast_expr.hpp @@ -0,0 +1,302 @@ +/* + */ +#ifndef AST_EXPR_INCLUDED +#define AST_EXPR_INCLUDED + +class NodeVisitor; + +class ExprNode +{ +public: + virtual ~ExprNode() = 0; + + virtual void visit(NodeVisitor& nv) = 0; +}; + +struct ExprNode_Block: + public ExprNode +{ + ::std::vector< ::std::unique_ptr > m_nodes; + + ExprNode_Block(const ExprNode_Block& x) = delete; + ExprNode_Block(::std::vector< ::std::unique_ptr >&& nodes): + m_nodes( move(nodes) ) + { + } + virtual ~ExprNode_Block() override; + + virtual void visit(NodeVisitor& nv) override; +}; + +// Return a value +struct ExprNode_Return: + public ExprNode +{ + unique_ptr m_value; + + ExprNode_Return(unique_ptr&& value): + m_value( move(value) ) + { + } + + virtual void visit(NodeVisitor& nv) override; +}; +struct ExprNode_LetBinding: + public ExprNode +{ + Pattern m_pat; + unique_ptr m_value; + + ExprNode_LetBinding(Pattern pat, unique_ptr&& value): + m_pat( move(pat) ), + m_value( move(value) ) + { + } + + virtual void visit(NodeVisitor& nv) override; +}; +struct ExprNode_Assign: + public ExprNode +{ + unique_ptr m_slot; + unique_ptr m_value; + + ExprNode_Assign(unique_ptr&& slot, unique_ptr&& value): + m_slot( move(slot) ), + m_value( move(value) ) + { + } + + virtual void visit(NodeVisitor& nv) override; +}; +struct ExprNode_CallPath: + public ExprNode +{ + Path m_path; + ::std::vector> m_args; + + ExprNode_CallPath(Path&& path, ::std::vector>&& args): + m_path( move(path) ), + m_args( move(args) ) + { + } + + virtual void visit(NodeVisitor& nv) override; +}; +// Call an object (Fn/FnMut/FnOnce) +struct ExprNode_CallObject: + public ExprNode +{ + unique_ptr m_val; + ::std::vector> m_args; + + ExprNode_CallObject(unique_ptr&& val, ::std::vector< unique_ptr >&& args): + m_val( move(val) ), + m_args( move(args) ) + { + } + virtual void visit(NodeVisitor& nv) override; +}; + +struct ExprNode_Match: + public ExprNode +{ + typedef ::std::vector< ::std::pair > > arm_t; + unique_ptr m_val; + arm_t m_arms; + + ExprNode_Match(unique_ptr&& val, arm_t&& arms): + m_val( ::std::move(val) ), + m_arms( ::std::move(arms) ) + { + } + virtual void visit(NodeVisitor& nv) override; +}; + +struct ExprNode_If: + public ExprNode +{ + unique_ptr m_cond; + unique_ptr m_true; + unique_ptr m_false; + + ExprNode_If(unique_ptr&& cond, unique_ptr&& true_code, unique_ptr&& false_code): + m_cond( ::std::move(cond) ), + m_true( ::std::move(true_code) ), + m_false( ::std::move(false_code) ) + { + } + virtual void visit(NodeVisitor& nv) override; +}; +// Literal integer +struct ExprNode_Integer: + public ExprNode +{ + enum eCoreType m_datatype; + uint64_t m_value; + + ExprNode_Integer(uint64_t value, enum eCoreType datatype): + m_datatype(datatype), + m_value(value) + { + } + + virtual void visit(NodeVisitor& nv) override; +}; +// Literal structure +struct ExprNode_StructLiteral: + public ExprNode +{ + typedef ::std::vector< ::std::pair< ::std::string, unique_ptr > > t_values; + Path m_path; + unique_ptr m_base_value; + t_values m_values; + + ExprNode_StructLiteral(Path path, unique_ptr&& base_value, t_values&& values ): + m_path( move(path) ), + m_base_value( move(base_value) ), + m_values( move(values) ) + {} + + virtual void visit(NodeVisitor& nv) override; +}; +// Variable / Constant +struct ExprNode_NamedValue: + public ExprNode +{ + Path m_path; + ExprNode_NamedValue(Path&& path): + m_path( ::std::move(path) ) + { + } + virtual void visit(NodeVisitor& nv) override; +}; +// Field dereference +struct ExprNode_Field: + public ExprNode +{ + ::std::unique_ptr m_obj; + ::std::string m_name; + + ExprNode_Field(::std::unique_ptr&& obj, ::std::string&& name): + m_obj( ::std::move(obj) ), + m_name( ::std::move(name) ) + { + } + virtual void visit(NodeVisitor& nv) override; +}; + +// Type cast ('as') +struct ExprNode_Cast: + public ExprNode +{ + unique_ptr m_value; + TypeRef m_type; + + ExprNode_Cast(unique_ptr&& value, TypeRef&& dst_type): + m_value( move(value) ), + m_type( move(dst_type) ) + { + } + virtual void visit(NodeVisitor& nv) override; +}; + +// Binary operation +struct ExprNode_BinOp: + public ExprNode +{ + enum Type { + CMPEQU, + CMPNEQU, + + BITAND, + BITOR, + BITXOR, + + SHL, + SHR, + }; + + Type m_type; + ::std::unique_ptr m_left; + ::std::unique_ptr m_right; + + ExprNode_BinOp(Type type, ::std::unique_ptr left, ::std::unique_ptr right): + m_type(type), + m_left( ::std::move(left) ), + m_right( ::std::move(right) ) + { + } + + virtual void visit(NodeVisitor& nv) override; +}; + +class NodeVisitor +{ +public: + void visit(const unique_ptr& cnode) { + if(cnode.get()) + cnode->visit(*this); + } + + virtual void visit(ExprNode_Block& node) { + for( auto& child : node.m_nodes ) + visit(child); + } + virtual void visit(ExprNode_Return& node) { + visit(node.m_value); + } + virtual void visit(ExprNode_LetBinding& node) { + // TODO: Handle recurse into Let pattern + visit(node.m_value); + } + virtual void visit(ExprNode_Assign& node) { + visit(node.m_slot); + visit(node.m_value); + } + virtual void visit(ExprNode_CallPath& node) { + for( auto& arg : node.m_args ) + visit(arg); + } + virtual void visit(ExprNode_CallObject& node) { + visit(node.m_val); + for( auto& arg : node.m_args ) + visit(arg); + } + virtual void visit(ExprNode_Match& node) { + visit(node.m_val); + for( auto& arm : node.m_arms ) + visit(arm.second); + } + virtual void visit(ExprNode_If& node) { + visit(node.m_cond); + visit(node.m_true); + visit(node.m_false); + } + + virtual void visit(ExprNode_Integer& node) { + // LEAF + } + virtual void visit(ExprNode_StructLiteral& node) { + visit(node.m_base_value); + for( auto& val : node.m_values ) + visit(val.second); + } + virtual void visit(ExprNode_NamedValue& node) { + // LEAF + } + + virtual void visit(ExprNode_Field& node) { + visit(node.m_obj); + } + virtual void visit(ExprNode_Cast& node) { + visit(node.m_value); + } + virtual void visit(ExprNode_BinOp& node) { + visit(node.m_left); + visit(node.m_right); + } +}; + +#endif + diff --git a/src/ast/path.hpp b/src/ast/path.hpp index 09e5d9ed..bc33c318 100644 --- a/src/ast/path.hpp +++ b/src/ast/path.hpp @@ -3,6 +3,7 @@ #ifndef AST_PATH_HPP_INCLUDED #define AST_PATH_HPP_INCLUDED +#include "../common.hpp" #include #include @@ -28,20 +29,71 @@ class PathNode public: PathNode(::std::string name, ::std::vector args); const ::std::string& name() const; + ::std::vector& args() { return m_params; } const ::std::vector& args() const; + + friend ::std::ostream& operator<<(::std::ostream& os, const PathNode& pn) { + os << pn.m_name; + if( pn.m_params.size() ) + { + os << "<"; + os << pn.m_params; + os << ">"; + } + return os; + } }; class Path { + enum Class { + RELATIVE, + ABSOLUTE, + LOCAL, + }; + Class m_class; + ::std::vector m_nodes; public: - Path(); + Path(): + m_class(RELATIVE) + {} struct TagAbsolute {}; - Path(TagAbsolute); + Path(TagAbsolute): + m_class(ABSOLUTE) + {} + struct TagLocal {}; + Path(TagLocal, ::std::string name): + m_class(LOCAL), + m_nodes({PathNode(name, {})}) + {} - void append(PathNode node) {} - size_t length() const {return 0;} - - PathNode& operator[](size_t idx) { throw ::std::out_of_range("Path []"); } + void append(PathNode node) { + m_nodes.push_back(node); + } + + bool is_relative() const { return m_class == RELATIVE; } + size_t size() const { return m_nodes.size(); } + ::std::vector& nodes() { return m_nodes; } + const ::std::vector& nodes() const { return m_nodes; } + + PathNode& operator[](size_t idx) { return m_nodes[idx]; } + const PathNode& operator[](size_t idx) const { return m_nodes[idx]; } + + friend ::std::ostream& operator<<(::std::ostream& os, const Path& path) { + switch(path.m_class) + { + case RELATIVE: + os << "Path({" << path.m_nodes << "})"; + break; + case ABSOLUTE: + os << "Path(TagAbsolute, {" << path.m_nodes << "})"; + break; + case LOCAL: + os << "Path(TagLocal, " << path.m_nodes[0].name() << ")"; + break; + } + return os; + } }; } // namespace AST diff --git a/src/common.hpp b/src/common.hpp index deaf4ed1..21f1663e 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -6,4 +6,27 @@ #define FOREACH(basetype, it, src) for(basetype::const_iterator it = src.begin(); it != src.end(); ++ it) #define FOREACH_M(basetype, it, src) for(basetype::iterator it = src.begin(); it != src.end(); ++ it) +#include +#include + +#define DEBUG(ss) do{ ::std::cerr << __func__ << ": " << ss << ::std::endl; } while(0) + +namespace AST { +template +inline ::std::ostream& operator<<(::std::ostream& os, const ::std::vector& v) { + if( v.size() > 0 ) + { + bool is_first = true; + for( const auto& i : v ) + { + if(!is_first) + os << ", "; + is_first = false; + os << i; + } + } + return os; +} +} + #endif diff --git a/src/convert/resolve.cpp b/src/convert/resolve.cpp index edc649cc..504fec93 100644 --- a/src/convert/resolve.cpp +++ b/src/convert/resolve.cpp @@ -8,13 +8,30 @@ class CPathResolver { const AST::Crate& m_crate; const AST::Module& m_module; + ::std::vector< ::std::string > m_locals; + // TODO: Maintain a stack of variable scopes public: CPathResolver(const AST::Crate& crate, const AST::Module& mod); - - void resolve_type(TypeRef& type); + + void resolve_path(AST::Path& path, bool allow_variables) const; + void resolve_type(TypeRef& type) const; void handle_function(AST::Function& fcn); + void handle_pattern(AST::Pattern& pat); + + void push_scope() { + m_locals.push_back( ::std::string() ); + } + void pop_scope() { + for( auto it = m_locals.end(); --it != m_locals.begin(); ) { + if( *it == "" ) { + m_locals.erase(it, m_locals.end()); + return ; + } + } + m_locals.clear(); + } }; // Path resolution checking @@ -23,16 +40,28 @@ void ResolvePaths(AST::Crate& crate); class CResolvePaths_NodeVisitor: public AST::NodeVisitor { - const CPathResolver& m_res; + CPathResolver& m_res; public: - CResolvePaths_NodeVisitor(const CPathResolver& res): + CResolvePaths_NodeVisitor(CPathResolver& res): m_res(res) { } void visit(AST::ExprNode_NamedValue& node) { - // TODO: Convert into a real absolute path - throw ParseError::Todo("CResolvePaths_NodeVisitor::visit(TagNamedValue)"); + m_res.resolve_path(node.m_path, true); + } + + void visit(AST::ExprNode_Match& node) { + + AST::NodeVisitor::visit(node.m_val); + + for( auto& arm : node.m_arms ) + { + m_res.push_scope(); + m_res.handle_pattern(arm.first); + AST::NodeVisitor::visit(arm.second); + m_res.pop_scope(); + } } }; @@ -42,24 +71,78 @@ CPathResolver::CPathResolver(const AST::Crate& crate, const AST::Module& mod): { } -void CPathResolver::resolve_type(TypeRef& type) +void CPathResolver::resolve_path(AST::Path& path, bool allow_variables) const +{ + // Handle generic components of the path + for( auto& ent : path.nodes() ) + { + for( auto& arg : ent.args() ) + { + resolve_type(arg); + } + } + + // Convert to absolute + if( !path.is_relative() ) + { + // Already absolute, our job is done + } + else + { + if( allow_variables && path.size() == 1 && path[0].args().size() == 0 ) + { + // One non-generic component, look in the current function for a variable + const ::std::string& var = path[0].name(); + DEBUG("varname = " << var); + auto varslot = m_locals.end(); + for(auto slot = m_locals.begin(); slot != m_locals.end(); ++slot) + { + if( *slot == var ) { + varslot = slot; + } + } + + if( varslot != m_locals.end() ) + { + DEBUG("Located slot"); + path = AST::Path(AST::Path::TagLocal(), var); + return ; + } + } + // Search relative to current module + throw ParseError::Todo("CPathResolver::resolve_path()"); + } +} + +void CPathResolver::resolve_type(TypeRef& type) const { // TODO: Convert type into absolute - throw ParseError::Todo("ResolvePaths_Type"); + throw ParseError::Todo("CPathResolver::resolve_type()"); +} + +void CPathResolver::handle_pattern(AST::Pattern& pat) +{ + DEBUG("pat = " << pat); + throw ParseError::Todo("CPathResolver::handle_pattern()"); } void CPathResolver::handle_function(AST::Function& fcn) { CResolvePaths_NodeVisitor node_visitor(*this); + for( auto& arg : fcn.args() ) + m_locals.push_back(arg.first); + fcn.code().visit_nodes( node_visitor ); resolve_type(fcn.rettype()); - FOREACH_M(AST::Function::Arglist, arg, fcn.args()) - { - resolve_type(arg->second); - } + for( auto& arg : fcn.args() ) + resolve_type(arg.second); + + pop_scope(); + if( m_locals.size() != 0 ) + throw ParseError::BugCheck("m_locals.size() != 0"); } void ResolvePaths_HandleFunction(const AST::Crate& crate, const AST::Module& mod, AST::Function& fcn) diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index 123ce1ec..c56c529d 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -47,7 +47,7 @@ AST::Pattern Parse_Pattern(TokenStream& lex) // - If the path resolves to a single node, either a local enum value, or a binding lex.putback(tok); path = Parse_Path(lex, false, PATH_GENERIC_EXPR); - if( path.length() == 1 && path[0].args().size() == 0 ) + if( path.size() == 1 && path[0].args().size() == 0 ) { // Could be a name binding, check the next token GET_TOK(tok, lex); @@ -70,11 +70,10 @@ AST::Pattern Parse_Pattern(TokenStream& lex) // A list of internal patterns ::std::vector child_pats; do { - AST::Pattern pat = Parse_Pattern(lex); - child_pats.push_back(pat); + child_pats.push_back( Parse_Pattern(lex) ); } while( GET_TOK(tok, lex) == TOK_COMMA ); CHECK_TOK(tok, TOK_PAREN_CLOSE); - return AST::Pattern(AST::Pattern::TagEnumVariant(), path, child_pats); + return AST::Pattern(AST::Pattern::TagEnumVariant(), ::std::move(path), ::std::move(child_pats)); } default: lex.putback(tok); @@ -138,7 +137,7 @@ ExprNodeP Parse_Stmt(TokenStream& lex, bool& opt_semicolon) GET_CHECK_TOK(tok, lex, TOK_EQUAL); ExprNodeP val = Parse_Expr1(lex); opt_semicolon = false; - return NEWNODE( AST::ExprNode_LetBinding, pat, ::std::move(val) ); + return NEWNODE( AST::ExprNode_LetBinding, ::std::move(pat), ::std::move(val) ); } case TOK_RWORD_RETURN: return NEWNODE( AST::ExprNode_Return, Parse_Expr1(lex) ); @@ -257,7 +256,7 @@ ExprNodeP Parse_ExprBlocks(TokenStream& lex) GET_CHECK_TOK(tok, lex, TOK_FATARROW); bool opt_semicolon = false; ExprNodeP val = Parse_Stmt(lex, opt_semicolon); - arms.push_back( ::std::make_pair(pat, ::std::move(val)) ); + arms.push_back( ::std::make_pair( ::std::move(pat), ::std::move(val) ) ); } while( GET_TOK(tok, lex) == TOK_COMMA ); CHECK_TOK(tok, TOK_BRACE_CLOSE); return NEWNODE( AST::ExprNode_Match, ::std::move(switch_val), ::std::move(arms) ); diff --git a/src/types.hpp b/src/types.hpp index 237d9ea6..f6a58d2a 100644 --- a/src/types.hpp +++ b/src/types.hpp @@ -1,7 +1,7 @@ #ifndef TYPES_HPP_INCLUDED #define TYPES_HPP_INCLUDED -#include +#include "common.hpp" #include "coretypes.hpp" #include "ast/path.hpp" @@ -32,6 +32,11 @@ public: struct TagPath {}; TypeRef(TagPath, AST::Path path) {} + + friend ::std::ostream& operator<<(::std::ostream& os, const TypeRef& tr) { + os << "TypeRef(TODO)"; + return os; + } }; #endif // TYPES_HPP_INCLUDED -- cgit v1.2.3