summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge (sonata) <tpg@mutabah.net>2015-01-01 13:51:57 +0800
committerJohn Hodge (sonata) <tpg@mutabah.net>2015-01-01 13:51:57 +0800
commitd0461823a2359e0eb052dd10813bc6a3d66f7c74 (patch)
tree7173e4f9c0c2acc98db0d29d5bc10822a15d9237 /src
parent90d17906a39d521e36ff9e4f6089a1fb67a0aab7 (diff)
downloadmrust-d0461823a2359e0eb052dd10813bc6a3d66f7c74.tar.gz
Name resolve framework coming along
Diffstat (limited to 'src')
-rw-r--r--src/ast/ast.cpp92
-rw-r--r--src/ast/ast.hpp285
-rw-r--r--src/ast/ast_expr.hpp302
-rw-r--r--src/ast/path.hpp64
-rw-r--r--src/common.hpp23
-rw-r--r--src/convert/resolve.cpp107
-rw-r--r--src/parse/expr.cpp11
-rw-r--r--src/types.hpp7
8 files changed, 545 insertions, 346 deletions
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<TypeRef> args):
m_name(name),
@@ -29,18 +22,29 @@ const ::std::vector<TypeRef>& PathNode::args() const
return m_params;
}
-Pattern::Pattern(TagMaybeBind, ::std::string name)
-{
-}
-Pattern::Pattern(TagValue, ::std::unique_ptr<ExprNode> node)
-{
-}
-Pattern::Pattern(TagEnumVariant, Path path, ::std::vector<Pattern> 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<ExprNode> args)
-{
-}
-ExprNode::ExprNode(TagCallObject, ExprNode val, ::std::vector<ExprNode> args)
-{
-}
-ExprNode::ExprNode(TagMatch, ExprNode val, ::std::vector< ::std::pair<Pattern,ExprNode> > 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<ExprNode> m_node;
+ ::std::vector<Pattern> 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<ExprNode> node);
-
- struct TagEnumVariant {};
- Pattern(TagEnumVariant, Path path, ::std::vector<Pattern> 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<ExprNode> > m_nodes;
-public:
- ExprNode_Block(const ExprNode_Block& x) = delete;
- ExprNode_Block(::std::vector< ::std::unique_ptr<ExprNode> >&& 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<ExprNode> m_value;
-public:
- ExprNode_Return(unique_ptr<ExprNode>&& value):
- m_value( move(value) )
- {
- }
-
- virtual void visit(NodeVisitor& nv) override;
-};
-class ExprNode_LetBinding:
- public ExprNode
-{
- Pattern m_pat;
- unique_ptr<ExprNode> m_value;
-public:
- ExprNode_LetBinding(Pattern pat, unique_ptr<ExprNode>&& value):
- m_pat( move(pat) ),
- m_value( move(value) )
- {
- }
-
- virtual void visit(NodeVisitor& nv) override;
-};
-class ExprNode_Assign:
- public ExprNode
-{
- unique_ptr<ExprNode> m_slot;
- unique_ptr<ExprNode> m_value;
-public:
- ExprNode_Assign(unique_ptr<ExprNode>&& slot, unique_ptr<ExprNode>&& 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<unique_ptr<ExprNode>> m_args;
-public:
- ExprNode_CallPath(Path&& path, ::std::vector<unique_ptr<ExprNode>>&& 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<ExprNode> m_val;
- ::std::vector<unique_ptr<ExprNode>> m_args;
-public:
- ExprNode_CallObject(unique_ptr<ExprNode>&& val, ::std::vector< unique_ptr<ExprNode> >&& 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<Pattern,unique_ptr<ExprNode> > > arm_t;
- unique_ptr<ExprNode> m_val;
- arm_t m_arms;
-public:
- ExprNode_Match(unique_ptr<ExprNode>&& 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<ExprNode> m_cond;
- unique_ptr<ExprNode> m_true;
- unique_ptr<ExprNode> m_false;
-public:
- ExprNode_If(unique_ptr<ExprNode>&& cond, unique_ptr<ExprNode>&& true_code, unique_ptr<ExprNode>&& 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<ExprNode> > > t_values;
- Path m_path;
- unique_ptr<ExprNode> m_base_value;
- t_values m_values;
-public:
- ExprNode_StructLiteral(Path path, unique_ptr<ExprNode>&& base_value, t_values&& values ):
- m_path( move(path) ),
- m_base_value( move(base_value) ),
- m_values( move(values) )
+ Pattern(TagValue, unique_ptr<ExprNode> 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<ExprNode> m_obj;
- ::std::string m_name;
-public:
- ExprNode_Field(::std::unique_ptr<ExprNode>&& 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<ExprNode> m_value;
- TypeRef m_type;
-public:
- ExprNode_Cast(unique_ptr<ExprNode>&& 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<Pattern> sub_patterns):
+ m_class(TUPLE),
+ m_sub_patterns( ::std::move(sub_patterns) )
+ {}
- BITAND,
- BITOR,
- BITXOR,
+ struct TagEnumVariant {};
+ Pattern(TagEnumVariant, Path path, ::std::vector<Pattern> 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<ExprNode> m_left;
- ::std::unique_ptr<ExprNode> m_right;
-public:
- ExprNode_BinOp(const ExprNode_Block& x) = delete;
- ExprNode_BinOp(Type type, ::std::unique_ptr<ExprNode> left, ::std::unique_ptr<ExprNode> 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<ExprNode> > m_nodes;
+
+ ExprNode_Block(const ExprNode_Block& x) = delete;
+ ExprNode_Block(::std::vector< ::std::unique_ptr<ExprNode> >&& 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<ExprNode> m_value;
+
+ ExprNode_Return(unique_ptr<ExprNode>&& value):
+ m_value( move(value) )
+ {
+ }
+
+ virtual void visit(NodeVisitor& nv) override;
+};
+struct ExprNode_LetBinding:
+ public ExprNode
+{
+ Pattern m_pat;
+ unique_ptr<ExprNode> m_value;
+
+ ExprNode_LetBinding(Pattern pat, unique_ptr<ExprNode>&& value):
+ m_pat( move(pat) ),
+ m_value( move(value) )
+ {
+ }
+
+ virtual void visit(NodeVisitor& nv) override;
+};
+struct ExprNode_Assign:
+ public ExprNode
+{
+ unique_ptr<ExprNode> m_slot;
+ unique_ptr<ExprNode> m_value;
+
+ ExprNode_Assign(unique_ptr<ExprNode>&& slot, unique_ptr<ExprNode>&& 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<unique_ptr<ExprNode>> m_args;
+
+ ExprNode_CallPath(Path&& path, ::std::vector<unique_ptr<ExprNode>>&& 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<ExprNode> m_val;
+ ::std::vector<unique_ptr<ExprNode>> m_args;
+
+ ExprNode_CallObject(unique_ptr<ExprNode>&& val, ::std::vector< unique_ptr<ExprNode> >&& 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<Pattern,unique_ptr<ExprNode> > > arm_t;
+ unique_ptr<ExprNode> m_val;
+ arm_t m_arms;
+
+ ExprNode_Match(unique_ptr<ExprNode>&& 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<ExprNode> m_cond;
+ unique_ptr<ExprNode> m_true;
+ unique_ptr<ExprNode> m_false;
+
+ ExprNode_If(unique_ptr<ExprNode>&& cond, unique_ptr<ExprNode>&& true_code, unique_ptr<ExprNode>&& 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<ExprNode> > > t_values;
+ Path m_path;
+ unique_ptr<ExprNode> m_base_value;
+ t_values m_values;
+
+ ExprNode_StructLiteral(Path path, unique_ptr<ExprNode>&& 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<ExprNode> m_obj;
+ ::std::string m_name;
+
+ ExprNode_Field(::std::unique_ptr<ExprNode>&& 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<ExprNode> m_value;
+ TypeRef m_type;
+
+ ExprNode_Cast(unique_ptr<ExprNode>&& 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<ExprNode> m_left;
+ ::std::unique_ptr<ExprNode> m_right;
+
+ ExprNode_BinOp(Type type, ::std::unique_ptr<ExprNode> left, ::std::unique_ptr<ExprNode> 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<ExprNode>& 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 <string>
#include <stdexcept>
@@ -28,20 +29,71 @@ class PathNode
public:
PathNode(::std::string name, ::std::vector<TypeRef> args);
const ::std::string& name() const;
+ ::std::vector<TypeRef>& args() { return m_params; }
const ::std::vector<TypeRef>& 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<PathNode> 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<PathNode>& nodes() { return m_nodes; }
+ const ::std::vector<PathNode>& 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 <iostream>
+#include <vector>
+
+#define DEBUG(ss) do{ ::std::cerr << __func__ << ": " << ss << ::std::endl; } while(0)
+
+namespace AST {
+template <typename T>
+inline ::std::ostream& operator<<(::std::ostream& os, const ::std::vector<T>& 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<AST::Pattern> 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 <vector>
+#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