diff options
author | John Hodge (sonata) <tpg@mutabah.net> | 2015-01-01 13:51:57 +0800 |
---|---|---|
committer | John Hodge (sonata) <tpg@mutabah.net> | 2015-01-01 13:51:57 +0800 |
commit | d0461823a2359e0eb052dd10813bc6a3d66f7c74 (patch) | |
tree | 7173e4f9c0c2acc98db0d29d5bc10822a15d9237 /src | |
parent | 90d17906a39d521e36ff9e4f6089a1fb67a0aab7 (diff) | |
download | mrust-d0461823a2359e0eb052dd10813bc6a3d66f7c74.tar.gz |
Name resolve framework coming along
Diffstat (limited to 'src')
-rw-r--r-- | src/ast/ast.cpp | 92 | ||||
-rw-r--r-- | src/ast/ast.hpp | 285 | ||||
-rw-r--r-- | src/ast/ast_expr.hpp | 302 | ||||
-rw-r--r-- | src/ast/path.hpp | 64 | ||||
-rw-r--r-- | src/common.hpp | 23 | ||||
-rw-r--r-- | src/convert/resolve.cpp | 107 | ||||
-rw-r--r-- | src/parse/expr.cpp | 11 | ||||
-rw-r--r-- | src/types.hpp | 7 |
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
|