diff options
-rw-r--r-- | src/ast/expr.hpp | 4 | ||||
-rw-r--r-- | src/ast/path.cpp | 2 | ||||
-rw-r--r-- | src/ast/path.hpp | 7 | ||||
-rw-r--r-- | src/convert/resolve.cpp | 40 | ||||
-rw-r--r-- | src/parse/expr.cpp | 3 |
5 files changed, 40 insertions, 16 deletions
diff --git a/src/ast/expr.hpp b/src/ast/expr.hpp index d455f3cb..663beae0 100644 --- a/src/ast/expr.hpp +++ b/src/ast/expr.hpp @@ -21,6 +21,7 @@ class ExprNode: public Serialisable { TypeRef m_res_type; + Position m_pos; public: virtual ~ExprNode() = 0; @@ -28,6 +29,9 @@ public: //virtual void visit(NodeVisitor& nv) const = 0; virtual void print(::std::ostream& os) const = 0; + void set_pos(Position p) { m_pos = ::std::move(p); } + const Position& get_pos() const { return m_pos; } + TypeRef& get_res_type() { return m_res_type; } friend ::std::ostream& operator<<(::std::ostream& os, const ExprNode& node); diff --git a/src/ast/path.cpp b/src/ast/path.cpp index 686647a5..c06a63a4 100644 --- a/src/ast/path.cpp +++ b/src/ast/path.cpp @@ -386,7 +386,7 @@ void Path::print_pretty(::std::ostream& os) const ::std::ostream& operator<<(::std::ostream& os, const Path& path) { - if( path.m_nodes.size() == 0 ) + if( path.m_nodes.size() == 0 && path.m_class == Path::RELATIVE ) { os << "/* null path */"; return os; diff --git a/src/ast/path.hpp b/src/ast/path.hpp index 027f8f35..1e70389d 100644 --- a/src/ast/path.hpp +++ b/src/ast/path.hpp @@ -215,7 +215,12 @@ public: } /// Grab the args from the first node of b, and add the rest to the end of the path void add_tailing(const Path& b) { - m_nodes.back().args() = b[0].args(); + if( m_nodes.size() > 0 ) + m_nodes.back().args() = b[0].args(); + else if( b[0].args().size() > 0 ) + throw ::std::runtime_error("add_tail to empty path, but generics in source"); + else + ; for(unsigned int i = 1; i < b.m_nodes.size(); i ++) m_nodes.push_back(b.m_nodes[i]); m_binding = PathBinding(); diff --git a/src/convert/resolve.cpp b/src/convert/resolve.cpp index 86c56578..411d1ae4 100644 --- a/src/convert/resolve.cpp +++ b/src/convert/resolve.cpp @@ -36,7 +36,7 @@ class CPathResolver: friend ::std::ostream& operator<<(::std::ostream& os, const LocalItem& x) {
//return os << "'" << x.name << "' = " << x.path;
- return os << "'" << x.name << "'";
+ return os << (x.type == TYPE ? "type" : "var") << " '" << x.name << "'";
}
};
const AST::Crate& m_crate;
@@ -67,7 +67,7 @@ public: }
virtual void end_scope() override;
- ::rust::option<const AST::Path&> lookup_local(LocalItem::Type type, const ::std::string& name) const;
+ ::rust::option<const LocalItem&> lookup_local(LocalItem::Type type, const ::std::string& name) const;
// TODO: Handle a block and obtain the local module (if any)
};
@@ -99,7 +99,7 @@ public: m_res.handle_path(node.m_path, CASTIterator::MODE_EXPR);
}
void visit(AST::ExprNode_CallPath& node) {
- DEBUG("ExprNode_CallPath - " << node);
+ DEBUG(node.get_pos() << " ExprNode_CallPath - " << node);
AST::NodeVisitorDef::visit(node);
m_res.handle_path(node.m_path, CASTIterator::MODE_EXPR);
}
@@ -252,16 +252,16 @@ void CPathResolver::end_scope() m_locals.clear();
}
// Returns the bound path for the local item
-::rust::option<const AST::Path&> CPathResolver::lookup_local(LocalItem::Type type, const ::std::string& name) const
+::rust::option<const CPathResolver::LocalItem&> CPathResolver::lookup_local(LocalItem::Type type, const ::std::string& name) const
{
DEBUG("m_locals = [" << m_locals << "]");
for( auto it = m_locals.end(); it -- != m_locals.begin(); )
{
if( it->type == type && it->name == name ) {
- return ::rust::option<const AST::Path&>(it->path);
+ return ::rust::option<const LocalItem&>(*it);
}
}
- return ::rust::option<const AST::Path&>();
+ return ::rust::option<const LocalItem&>();
}
// Search relative to current module
@@ -377,24 +377,38 @@ void CPathResolver::handle_path(AST::Path& path, CASTIterator::PathMode mode) bool is_trivial_path = (path.size() == 1 && path[0].args().size() == 0);
LocalItem::Type search_type = (is_trivial_path && mode == MODE_EXPR ? LocalItem::VAR : LocalItem::TYPE);
- auto local = lookup_local( search_type, path[0].name() );
- if( local.is_some() )
+ auto local_o = lookup_local( search_type, path[0].name() );
+ if( local_o.is_some() )
{
- auto rpath = local.unwrap();
- DEBUG("Local hit: " << path[0].name() << " = " << rpath);
+ auto local = local_o.unwrap();
+ DEBUG("Local hit: " << path[0].name() << " = " << local);
switch(mode)
{
// Local variable?
// - TODO: What would happen if MODE_EXPR but path isn't a single ident?
case MODE_EXPR:
- if( is_trivial_path )
+ if( local.type == LocalItem::VAR )
{
+ if( !is_trivial_path )
+ throw ParseError::Todo("TODO: MODE_EXPR, but not a single identifer, what do?");
DEBUG("Local variable " << path[0].name());
path = AST::Path(AST::Path::TagLocal(), path[0].name());
- return ;
}
- throw ParseError::Todo("TODO: MODE_EXPR, but not a single identifer, what do?");
+ else
+ {
+ if( is_trivial_path )
+ throw ParseError::Generic("Type used in expression context?");
+ // Convert to a UFCS path
+ DEBUG("Local type");
+ auto np = AST::Path(AST::Path::TagUfcs(), TypeRef(TypeRef::TagArg(), path[0].name()), TypeRef());
+ DEBUG("np = " << np);
+ np.add_tailing(path);
+ DEBUG("np = " << np);
+ path = ::std::move(np);
+ DEBUG("path = " << path);
+ }
+ return ;
// Type parameter
case MODE_TYPE:
DEBUG("Local type " << path);
diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index 7f4e73a1..cd449670 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -18,7 +18,8 @@ #include "tokentree.hpp"
typedef ::std::unique_ptr<AST::ExprNode> ExprNodeP;
-#define NEWNODE(type, ...) ExprNodeP(new type(__VA_ARGS__))
+static inline ExprNodeP mk_exprnodep(const TokenStream& lex, AST::ExprNode* en){en->set_pos(lex.getPosition()); return ExprNodeP(en); }
+#define NEWNODE(type, ...) mk_exprnodep(lex, new type(__VA_ARGS__))
using AST::ExprNode;
ExprNodeP Parse_ExprBlockNode(TokenStream& lex);
|