summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge (sonata) <tpg@mutabah.net>2014-12-30 17:36:47 +0800
committerJohn Hodge (sonata) <tpg@mutabah.net>2014-12-30 17:36:47 +0800
commit90d17906a39d521e36ff9e4f6089a1fb67a0aab7 (patch)
tree3f1a75e92d94ad025ad613e868d055cb0e6fad2e
parent53321dbc3f9712b8823703202c8ea3af0630a1d9 (diff)
downloadmrust-90d17906a39d521e36ff9e4f6089a1fb67a0aab7.tar.gz
Rework expressions so they can be iterated (and actually save data)
-rw-r--r--.gitignore1
-rw-r--r--.lvimrc2
-rw-r--r--Makefile11
-rw-r--r--src/ast/ast.cpp102
-rw-r--r--src/ast/ast.hpp339
-rw-r--r--src/convert/flatten.cpp2
-rw-r--r--src/convert/resolve.cpp24
-rw-r--r--src/parse/expr.cpp147
-rw-r--r--src/parse/root.cpp2
-rw-r--r--src/types.cpp2
-rw-r--r--src/types.hpp2
11 files changed, 482 insertions, 152 deletions
diff --git a/.gitignore b/.gitignore
index ee0316da..e923f0c3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@
/mrustc.depend
/mrustc.layout
/.obj
+*.swp
diff --git a/.lvimrc b/.lvimrc
new file mode 100644
index 00000000..069917a3
--- /dev/null
+++ b/.lvimrc
@@ -0,0 +1,2 @@
+set expandtab
+set sts=4 ts=4 sw=4
diff --git a/Makefile b/Makefile
index bd10d95c..a5f030bf 100644
--- a/Makefile
+++ b/Makefile
@@ -17,6 +17,15 @@ OBJ += parse/parseerror.o parse/lex.o parse/preproc.o parse/root.o parse/expr.o
OBJ += convert/flatten.o convert/resolve.o convert/render.o
OBJ := $(addprefix $(OBJDIR),$(OBJ))
+
+all: $(BIN)
+
+clean:
+ $(RM) -r $(BIN) $(OBJ)
+
+test: $(BIN) samples/1.rs
+ time $(BIN) samples/1.rs
+
$(BIN): $(OBJ)
@mkdir -p $(dir $@)
$(CXX) -o $@ $(LINKFLAGS) $(OBJ) $(LIBS)
@@ -27,3 +36,5 @@ $(OBJDIR)%.o: src/%.cpp
-include $(OBJ:%=%.dep)
+# vim: noexpandtab ts=4
+
diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp
index a39bc0d4..29b551ed 100644
--- a/src/ast/ast.cpp
+++ b/src/ast/ast.cpp
@@ -32,7 +32,7 @@ const ::std::vector<TypeRef>& PathNode::args() const
Pattern::Pattern(TagMaybeBind, ::std::string name)
{
}
-Pattern::Pattern(TagValue, ExprNode node)
+Pattern::Pattern(TagValue, ::std::unique_ptr<ExprNode> node)
{
}
Pattern::Pattern(TagEnumVariant, Path path, ::std::vector<Pattern> sub_patterns)
@@ -40,9 +40,6 @@ Pattern::Pattern(TagEnumVariant, Path path, ::std::vector<Pattern> sub_patterns)
}
-Function::Function(::std::string name, TypeParams params, Class fcn_class, TypeRef ret_type, ::std::vector<StructItem> args, Expr code)
-{
-}
Impl::Impl(TypeRef impl_type, TypeRef trait_type)
{
@@ -51,8 +48,9 @@ void Impl::add_function(bool is_public, Function fcn)
{
}
-void Crate::iterate_functions(Crate::fcn_visitor_t* visitor)
+void Crate::iterate_functions(fcn_visitor_t* visitor)
{
+ m_root_module.iterate_functions(visitor, *this);
}
void Module::add_constant(bool is_public, ::std::string name, TypeRef type, Expr val)
@@ -68,23 +66,106 @@ void Module::add_struct(bool is_public, ::std::string name, TypeParams params, :
}
void Module::add_function(bool is_public, Function func)
{
+ for( const auto fcn_item : m_functions )
+ {
+ if( fcn_item.first.name() == func.name() ) {
+ throw ParseError::Todo("duplicate function definition");
+ }
+ }
+ m_functions.push_back( ::std::make_pair(func, is_public) );
}
void Module::add_impl(Impl impl)
{
}
-void Expr::visit_nodes(const NodeVisitor& v)
+void Module::iterate_functions(fcn_visitor_t *visitor, const Crate& crate)
{
- throw ParseError::Todo("Expr::visit_nodes");
+ for( auto fcn_item : this->m_functions )
+ {
+ visitor(crate, *this, fcn_item.first);
+ }
}
-ExprNode::ExprNode()
+void Expr::visit_nodes(NodeVisitor& v)
{
+ m_node->visit(v);
+}
+ExprNode::~ExprNode() {
}
-ExprNode::ExprNode(TagBlock, ::std::vector<ExprNode> nodes)
-{
+
+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);
+}
+
+void ExprNode_CallPath::visit(NodeVisitor& nv) {
+ nv.visit(*this);
+}
+
+void ExprNode_CallObject::visit(NodeVisitor& nv) {
+ nv.visit(*this);
}
+
+void ExprNode_Match::visit(NodeVisitor& nv) {
+ nv.visit(*this);
+}
+
+void ExprNode_If::visit(NodeVisitor& nv) {
+ nv.visit(*this);
+}
+
+void ExprNode_Integer::visit(NodeVisitor& nv) {
+ nv.visit(*this);
+}
+
+void ExprNode_StructLiteral::visit(NodeVisitor& nv) {
+ nv.visit(*this);
+}
+
+void ExprNode_NamedValue::visit(NodeVisitor& nv) {
+ nv.visit(*this);
+}
+
+void ExprNode_Field::visit(NodeVisitor& nv) {
+ nv.visit(*this);
+}
+
+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)
{
}
@@ -121,6 +202,7 @@ 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 ac153458..58f1e06c 100644
--- a/src/ast/ast.hpp
+++ b/src/ast/ast.hpp
@@ -11,6 +11,11 @@
namespace AST {
+using ::std::unique_ptr;
+using ::std::move;
+
+class Crate;
+
class MetaItem
{
::std::string m_name;
@@ -39,85 +44,279 @@ public:
Pattern(TagMaybeBind, ::std::string name);
struct TagValue {};
- Pattern(TagValue, ExprNode node);
+ Pattern(TagValue, unique_ptr<ExprNode> node);
struct TagEnumVariant {};
Pattern(TagEnumVariant, Path path, ::std::vector<Pattern> sub_patterns);
};
+class NodeVisitor;
+
class ExprNode
{
public:
- ExprNode();
-
- struct TagBlock {};
- ExprNode(TagBlock, ::std::vector<ExprNode> nodes);
-
- struct TagLetBinding {};
- ExprNode(TagLetBinding, Pattern pat, ExprNode value);
-
- struct TagReturn {};
- ExprNode(TagReturn, ExprNode val);
-
- struct TagAssign {};
- ExprNode(TagAssign, ExprNode slot, ExprNode value) {}
-
- struct TagCast {};
- ExprNode(TagCast, ExprNode value, TypeRef dst_type);
-
- struct TagInteger {};
- ExprNode(TagInteger, uint64_t value, enum eCoreType datatype);
-
- struct TagStructLiteral {};
- ExprNode(TagStructLiteral, Path path, ExprNode base_value, ::std::vector< ::std::pair< ::std::string,ExprNode> > values );
-
- struct TagCallPath {};
- ExprNode(TagCallPath, Path path, ::std::vector<ExprNode> args);
+ virtual ~ExprNode() = 0;
+
+ virtual void visit(NodeVisitor& nv) = 0;
+};
- struct TagCallObject {};
- ExprNode(TagCallObject, ExprNode val, ::std::vector<ExprNode> args);
+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;
+};
- struct TagMatch {};
- ExprNode(TagMatch, ExprNode val, ::std::vector< ::std::pair<Pattern,ExprNode> > arms);
+// 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;
+};
- struct TagIf {};
- ExprNode(TagIf, ExprNode cond, ExprNode true_code, ExprNode false_code);
+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;
+};
- struct TagNamedValue {};
- ExprNode(TagNamedValue, Path path);
+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) )
+ {}
+
+ 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;
+};
- struct TagField {};
- ExprNode(TagField, ::std::string name);
+// 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;
+};
- enum BinOpType {
- BINOP_CMPEQU,
- BINOP_CMPNEQU,
+// Binary operation
+class ExprNode_BinOp:
+ public ExprNode
+{
+public:
+ enum Type {
+ CMPEQU,
+ CMPNEQU,
- BINOP_BITAND,
- BINOP_BITOR,
- BINOP_BITXOR,
+ BITAND,
+ BITOR,
+ BITXOR,
- BINOP_SHL,
- BINOP_SHR,
+ SHL,
+ SHR,
};
- struct TagBinOp {};
- ExprNode(TagBinOp, BinOpType type, ExprNode left, ExprNode right);
+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;
};
class NodeVisitor
{
public:
- virtual void visit(ExprNode::TagBlock, ExprNode& node) {}
- virtual void visit(ExprNode::TagNamedValue, ExprNode& node) {}
+ 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) {}
};
class Expr
{
+ ::std::shared_ptr<ExprNode> m_node;
public:
- Expr() {}
- Expr(ExprNode node) {}
+ Expr(unique_ptr<ExprNode> node):
+ m_node(node.release())
+ {
+ }
+ Expr(ExprNode* node):
+ m_node(node)
+ {
+ }
- void visit_nodes(const NodeVisitor& v);
+ void visit_nodes(NodeVisitor& v);
};
class Function
@@ -133,23 +332,36 @@ public:
typedef ::std::vector<StructItem> Arglist;
private:
+ ::std::string m_name;
+ TypeParams m_generic_params;
+ Class m_fcn_class;
Expr m_code;
TypeRef m_rettype;
Arglist m_args;
public:
-
- Function(::std::string name, TypeParams params, Class fcn_class, TypeRef ret_type, Arglist args, Expr code);
+ Function(::std::string name, TypeParams params, Class fcn_class, TypeRef ret_type, Arglist args, Expr code):
+ m_name(name),
+ m_generic_params(params),
+ m_fcn_class(fcn_class),
+ m_code(code),
+ m_rettype(ret_type),
+ m_args(args)
+ {
+ }
+
+ const ::std::string& name() const { return m_name; }
+
+ TypeParams& generic_params() { return m_generic_params; }
+ const TypeParams& generic_params() const { return m_generic_params; }
Expr& code() { return m_code; }
- const Expr code() const { return m_code; }
+ const Expr& code() const { return m_code; }
const TypeRef& rettype() const { return m_rettype; }
TypeRef& rettype() { return m_rettype; }
const Arglist& args() const { return m_args; }
Arglist& args() { return m_args; }
-
- const char* name() const { return "TODO"; }
};
class Impl
@@ -160,9 +372,14 @@ public:
void add_function(bool is_public, Function fcn);
};
+
+class Module;
+
+typedef void fcn_visitor_t(const AST::Crate& crate, const AST::Module& mod, Function& fcn);
+
class Module
{
- ::std::vector<Function> m_functions;
+ ::std::vector< ::std::pair<Function,bool> > m_functions;
public:
void add_alias(bool is_public, Path path) {}
void add_constant(bool is_public, ::std::string name, TypeRef type, Expr val);
@@ -170,6 +387,8 @@ public:
void add_struct(bool is_public, ::std::string name, TypeParams params, ::std::vector<StructItem> items);
void add_function(bool is_public, Function func);
void add_impl(Impl impl);
+
+ void iterate_functions(fcn_visitor_t* visitor, const Crate& crate);
};
class Crate
@@ -181,8 +400,6 @@ public:
{
}
- typedef void fcn_visitor_t(const AST::Crate& crate, Function& fcn);
-
void iterate_functions( fcn_visitor_t* visitor );
};
@@ -201,8 +418,8 @@ class Flat
::std::vector<Function> m_functions;
public:
- const ::std::vector<Function>& functions() const;
- const ::std::vector<CStruct>& structs() const;
+ const ::std::vector<Function>& functions() const { return m_functions; }
+ const ::std::vector<CStruct>& structs() const { return m_structs; }
};
}
diff --git a/src/convert/flatten.cpp b/src/convert/flatten.cpp
index a040d154..bede5417 100644
--- a/src/convert/flatten.cpp
+++ b/src/convert/flatten.cpp
@@ -3,7 +3,7 @@
#include "../ast/ast.hpp"
#include "../parse/parseerror.hpp"
-AST::Flat Convert_Flattern(const AST::Crate& crate)
+AST::Flat Convert_Flatten(const AST::Crate& crate)
{
throw ParseError::Todo("Flatten");
}
diff --git a/src/convert/resolve.cpp b/src/convert/resolve.cpp
index d4d9c38b..edc649cc 100644
--- a/src/convert/resolve.cpp
+++ b/src/convert/resolve.cpp
@@ -6,8 +6,11 @@
class CPathResolver
{
+ const AST::Crate& m_crate;
+ const AST::Module& m_module;
+
public:
- CPathResolver(const AST::Crate& crate, AST::Function& fcn);
+ CPathResolver(const AST::Crate& crate, const AST::Module& mod);
void resolve_type(TypeRef& type);
@@ -16,7 +19,6 @@ public:
// Path resolution checking
void ResolvePaths(AST::Crate& crate);
-void ResolvePaths_HandleFunction(const AST::Crate& crate, AST::Function& fcn);
class CResolvePaths_NodeVisitor:
public AST::NodeVisitor
@@ -28,12 +30,18 @@ public:
{
}
- void visit(AST::ExprNode::TagNamedValue, AST::ExprNode& node) {
+ void visit(AST::ExprNode_NamedValue& node) {
// TODO: Convert into a real absolute path
throw ParseError::Todo("CResolvePaths_NodeVisitor::visit(TagNamedValue)");
}
};
+CPathResolver::CPathResolver(const AST::Crate& crate, const AST::Module& mod):
+ m_crate(crate),
+ m_module(mod)
+{
+}
+
void CPathResolver::resolve_type(TypeRef& type)
{
// TODO: Convert type into absolute
@@ -42,7 +50,9 @@ void CPathResolver::resolve_type(TypeRef& type)
void CPathResolver::handle_function(AST::Function& fcn)
{
- fcn.code().visit_nodes( CResolvePaths_NodeVisitor(*this) );
+ CResolvePaths_NodeVisitor node_visitor(*this);
+
+ fcn.code().visit_nodes( node_visitor );
resolve_type(fcn.rettype());
@@ -52,6 +62,12 @@ void CPathResolver::handle_function(AST::Function& fcn)
}
}
+void ResolvePaths_HandleFunction(const AST::Crate& crate, const AST::Module& mod, AST::Function& fcn)
+{
+ CPathResolver pr(crate, mod);
+ pr.handle_function(fcn);
+}
+
void ResolvePaths(AST::Crate& crate)
{
crate.iterate_functions(ResolvePaths_HandleFunction);
diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp
index e632d47f..123ce1ec 100644
--- a/src/parse/expr.cpp
+++ b/src/parse/expr.cpp
@@ -8,13 +8,15 @@
#include <iostream>
#include "tokentree.hpp"
+typedef ::std::unique_ptr<AST::ExprNode> ExprNodeP;
+#define NEWNODE(type, ...) ExprNodeP(new type(__VA_ARGS__))
using AST::ExprNode;
-AST::ExprNode Parse_ExprBlockNode(TokenStream& lex);
-AST::ExprNode Parse_Stmt(TokenStream& lex, bool& opt_semicolon);
-AST::ExprNode Parse_Expr0(TokenStream& lex);
-AST::ExprNode Parse_ExprBlocks(TokenStream& lex);
-AST::ExprNode Parse_Expr1(TokenStream& lex);
+ExprNodeP Parse_ExprBlockNode(TokenStream& lex);
+ExprNodeP Parse_Stmt(TokenStream& lex, bool& opt_semicolon);
+ExprNodeP Parse_Expr0(TokenStream& lex);
+ExprNodeP Parse_ExprBlocks(TokenStream& lex);
+ExprNodeP Parse_Expr1(TokenStream& lex);
AST::Expr Parse_Expr(TokenStream& lex, bool const_only)
{
@@ -76,11 +78,11 @@ AST::Pattern Parse_Pattern(TokenStream& lex)
}
default:
lex.putback(tok);
- return AST::Pattern(AST::Pattern::TagValue(), ExprNode(ExprNode::TagNamedValue(), path));
+ return AST::Pattern(AST::Pattern::TagValue(), NEWNODE(AST::ExprNode_NamedValue, ::std::move(path)));
}
break;
case TOK_INTEGER:
- return AST::Pattern( AST::Pattern::TagValue(), ExprNode(ExprNode::TagInteger(), tok.intval(), tok.datatype()) );
+ return AST::Pattern( AST::Pattern::TagValue(), NEWNODE(AST::ExprNode_Integer, tok.intval(), tok.datatype()) );
case TOK_PAREN_OPEN:
throw ParseError::Todo("tuple patterns");
default:
@@ -89,12 +91,12 @@ AST::Pattern Parse_Pattern(TokenStream& lex)
throw ParseError::BugCheck("Parse_TT_Stmt should early return");
}
-ExprNode Parse_ExprBlockNode(TokenStream& lex)
+ExprNodeP Parse_ExprBlockNode(TokenStream& lex)
{
TRACE_FUNCTION;
-
- ::std::vector<ExprNode> nodes;
Token tok;
+
+ ::std::vector<ExprNodeP> nodes;
GET_CHECK_TOK(tok, lex, TOK_BRACE_OPEN);
while( GET_TOK(tok, lex) != TOK_BRACE_CLOSE )
{
@@ -109,14 +111,14 @@ ExprNode Parse_ExprBlockNode(TokenStream& lex)
lex.putback(tok);
}
else {
- nodes.push_back(ExprNode());
+ nodes.push_back(nullptr);
break;
}
}
- return AST::ExprNode(ExprNode::TagBlock(), nodes);
+ return NEWNODE( AST::ExprNode_Block, ::std::move(nodes) );
}
-AST::ExprNode Parse_Stmt(TokenStream& lex, bool& opt_semicolon)
+ExprNodeP Parse_Stmt(TokenStream& lex, bool& opt_semicolon)
{
TRACE_FUNCTION;
@@ -134,12 +136,12 @@ AST::ExprNode Parse_Stmt(TokenStream& lex, bool& opt_semicolon)
//ret.append();
AST::Pattern pat = Parse_Pattern(lex);
GET_CHECK_TOK(tok, lex, TOK_EQUAL);
- AST::ExprNode val = Parse_Expr1(lex);
+ ExprNodeP val = Parse_Expr1(lex);
opt_semicolon = false;
- return ExprNode(ExprNode::TagLetBinding(), pat, val);
+ return NEWNODE( AST::ExprNode_LetBinding, pat, ::std::move(val) );
}
case TOK_RWORD_RETURN:
- return ExprNode(ExprNode::TagReturn(), Parse_Expr1(lex));
+ return NEWNODE( AST::ExprNode_Return, Parse_Expr1(lex) );
case TOK_RWORD_LOOP:
throw ParseError::Todo("loop");
break;
@@ -158,35 +160,35 @@ AST::ExprNode Parse_Stmt(TokenStream& lex, bool& opt_semicolon)
}
-::std::vector<AST::ExprNode> Parse_ParenList(TokenStream& lex)
+::std::vector<ExprNodeP> Parse_ParenList(TokenStream& lex)
{
TRACE_FUNCTION;
-
- ::std::vector<ExprNode> rv;
Token tok;
+
+ ::std::vector<ExprNodeP> rv;
GET_CHECK_TOK(tok, lex, TOK_PAREN_OPEN);
- if( (tok = lex.getToken()).type() != TOK_PAREN_CLOSE )
+ if( GET_TOK(tok, lex) != TOK_PAREN_CLOSE )
{
lex.putback(tok);
do {
rv.push_back( Parse_Expr1(lex) );
- } while( (tok = lex.getToken()).type() == TOK_COMMA );
+ } while( GET_TOK(tok, lex) == TOK_COMMA );
CHECK_TOK(tok, TOK_PAREN_CLOSE);
}
return rv;
}
// 0: Assign
-AST::ExprNode Parse_Expr0(TokenStream& lex)
+ExprNodeP Parse_Expr0(TokenStream& lex)
{
TRACE_FUNCTION;
+ Token tok;
- AST::ExprNode rv = Parse_ExprBlocks(lex);
- Token tok = lex.getToken();
- if( tok.type() == TOK_EQUAL )
+ ExprNodeP rv = Parse_ExprBlocks(lex);
+ if( GET_TOK(tok, lex) == TOK_EQUAL )
{
- ExprNode val = Parse_Expr1(lex);
- rv = ExprNode(ExprNode::TagAssign(), rv, val);
+ ExprNodeP val = Parse_Expr1(lex);
+ rv = NEWNODE( AST::ExprNode_Assign, ::std::move(rv), ::std::move(val) );
}
else
{
@@ -197,12 +199,12 @@ AST::ExprNode Parse_Expr0(TokenStream& lex)
/// Parse an 'if' statement
// Note: TOK_RWORD_IF has already been eaten
-AST::ExprNode Parse_IfStmt(TokenStream& lex)
+ExprNodeP Parse_IfStmt(TokenStream& lex)
{
TRACE_FUNCTION;
Token tok;
- ExprNode cond;
+ ExprNodeP cond;
if( GET_TOK(tok, lex) == TOK_RWORD_LET ) {
throw ParseError::Todo("if let");
}
@@ -212,10 +214,10 @@ AST::ExprNode Parse_IfStmt(TokenStream& lex)
}
// Contents
- ExprNode code = Parse_ExprBlockNode(lex);
+ ExprNodeP code = Parse_ExprBlockNode(lex);
// Handle else:
- ExprNode altcode;
+ ExprNodeP altcode;
if( GET_TOK(tok, lex) == TOK_RWORD_ELSE )
{
// Recurse for 'else if'
@@ -231,23 +233,22 @@ AST::ExprNode Parse_IfStmt(TokenStream& lex)
// - or nothing
else {
lex.putback(tok);
- altcode = ExprNode();
}
- return ExprNode(ExprNode::TagIf(), cond, code, altcode);
+ return NEWNODE( AST::ExprNode_If, ::std::move(cond), ::std::move(code), ::std::move(altcode) );
}
// 0.5: Blocks
-AST::ExprNode Parse_ExprBlocks(TokenStream& lex)
+ExprNodeP Parse_ExprBlocks(TokenStream& lex)
{
- Token tok = lex.getToken();
- switch( tok.type() )
+ Token tok;
+ switch( GET_TOK(tok, lex) )
{
case TOK_RWORD_MATCH: {
// 1. Get expression
- AST::ExprNode switch_val = Parse_Expr1(lex);
+ ExprNodeP switch_val = Parse_Expr1(lex);
GET_CHECK_TOK(tok, lex, TOK_BRACE_OPEN);
- ::std::vector< ::std::pair<AST::Pattern, ExprNode> > arms;
+ ::std::vector< ::std::pair<AST::Pattern, ::std::unique_ptr<ExprNode>> > arms;
do {
if( GET_TOK(tok, lex) == TOK_BRACE_CLOSE )
break;
@@ -255,11 +256,11 @@ AST::ExprNode Parse_ExprBlocks(TokenStream& lex)
AST::Pattern pat = Parse_Pattern(lex);
GET_CHECK_TOK(tok, lex, TOK_FATARROW);
bool opt_semicolon = false;
- AST::ExprNode val = Parse_Stmt(lex, opt_semicolon);
- arms.push_back( ::std::make_pair(pat, val) );
+ ExprNodeP val = Parse_Stmt(lex, opt_semicolon);
+ arms.push_back( ::std::make_pair(pat, ::std::move(val)) );
} while( GET_TOK(tok, lex) == TOK_COMMA );
CHECK_TOK(tok, TOK_BRACE_CLOSE);
- return AST::ExprNode(ExprNode::TagMatch(), switch_val, arms);
+ return NEWNODE( AST::ExprNode_Match, ::std::move(switch_val), ::std::move(arms) );
}
case TOK_RWORD_IF:
// TODO: if let
@@ -272,11 +273,11 @@ AST::ExprNode Parse_ExprBlocks(TokenStream& lex)
#define LEFTASSOC(cur, _next, cases) \
-AST::ExprNode _next(TokenStream& lex); \
-AST::ExprNode cur(TokenStream& lex) \
+ExprNodeP _next(TokenStream& lex); \
+ExprNodeP cur(TokenStream& lex) \
{ \
- AST::ExprNode (*next)(TokenStream&) = _next;\
- AST::ExprNode rv = next(lex); \
+ ExprNodeP (*next)(TokenStream&) = _next;\
+ ExprNodeP rv = next(lex); \
while(true) \
{ \
Token tok; \
@@ -303,10 +304,10 @@ LEFTASSOC(Parse_Expr2, Parse_Expr3,
// 3: (In)Equality
LEFTASSOC(Parse_Expr3, Parse_Expr4,
case TOK_DOUBLE_EQUAL:
- rv = ExprNode(ExprNode::TagBinOp(), ExprNode::BINOP_CMPEQU, rv, next(lex));
+ rv = NEWNODE( AST::ExprNode_BinOp, AST::ExprNode_BinOp::CMPEQU, ::std::move(rv), next(lex));
break;
case TOK_EXCLAM_EQUAL:
- rv = ExprNode(ExprNode::TagBinOp(), ExprNode::BINOP_CMPNEQU, rv, next(lex));
+ rv = NEWNODE( AST::ExprNode_BinOp, AST::ExprNode_BinOp::CMPNEQU, ::std::move(rv), next(lex));
break;
)
// 4: Comparisons
@@ -323,28 +324,28 @@ LEFTASSOC(Parse_Expr4, Parse_Expr5,
// 5: Bit OR
LEFTASSOC(Parse_Expr5, Parse_Expr6,
case TOK_PIPE:
- rv = ExprNode(ExprNode::TagBinOp(), ExprNode::BINOP_BITOR, rv, next(lex));
+ rv = NEWNODE( AST::ExprNode_BinOp, AST::ExprNode_BinOp::BITOR, ::std::move(rv), next(lex));
break;
)
// 6: Bit XOR
LEFTASSOC(Parse_Expr6, Parse_Expr7,
case TOK_CARET:
- rv = ExprNode(ExprNode::TagBinOp(), ExprNode::BINOP_BITXOR, rv, next(lex));
+ rv = NEWNODE( AST::ExprNode_BinOp, AST::ExprNode_BinOp::BITXOR, ::std::move(rv), next(lex));
break;
)
// 7: Bit AND
LEFTASSOC(Parse_Expr7, Parse_Expr8,
case TOK_AMP:
- rv = ExprNode(ExprNode::TagBinOp(), ExprNode::BINOP_BITAND, rv, next(lex));
+ rv = NEWNODE( AST::ExprNode_BinOp, AST::ExprNode_BinOp::BITAND, ::std::move(rv), next(lex));
break;
)
// 8: Bit Shifts
LEFTASSOC(Parse_Expr8, Parse_Expr9,
case TOK_DOUBLE_LT:
- rv = ExprNode(ExprNode::TagBinOp(), ExprNode::BINOP_SHL, rv, next(lex));
+ rv = NEWNODE( AST::ExprNode_BinOp, AST::ExprNode_BinOp::SHL, ::std::move(rv), next(lex));
break;
case TOK_DOUBLE_GT:
- rv = ExprNode(ExprNode::TagBinOp(), ExprNode::BINOP_SHR, rv, next(lex));
+ rv = NEWNODE( AST::ExprNode_BinOp, AST::ExprNode_BinOp::SHR, ::std::move(rv), next(lex));
break;
)
// 9: Add / Subtract
@@ -357,7 +358,7 @@ LEFTASSOC(Parse_Expr9, Parse_Expr10,
// 10: Cast
LEFTASSOC(Parse_Expr10, Parse_Expr11,
case TOK_RWORD_AS:
- rv = ExprNode(ExprNode::TagCast(), rv, Parse_Type(lex));
+ rv = NEWNODE( AST::ExprNode_Cast, ::std::move(rv), Parse_Type(lex) );
break;
)
// 11: Times / Divide / Modulo
@@ -370,8 +371,8 @@ LEFTASSOC(Parse_Expr11, Parse_Expr12,
throw ParseError::Todo("expr - modulo");
)
// 12: Unaries
-AST::ExprNode Parse_ExprFC(TokenStream& lex);
-AST::ExprNode Parse_Expr12(TokenStream& lex)
+ExprNodeP Parse_ExprFC(TokenStream& lex);
+ExprNodeP Parse_Expr12(TokenStream& lex)
{
Token tok;
switch((tok = lex.getToken()).type())
@@ -392,10 +393,10 @@ AST::ExprNode Parse_Expr12(TokenStream& lex)
}
}
-AST::ExprNode Parse_ExprVal(TokenStream& lex);
-AST::ExprNode Parse_ExprFC(TokenStream& lex)
+ExprNodeP Parse_ExprVal(TokenStream& lex);
+ExprNodeP Parse_ExprFC(TokenStream& lex)
{
- AST::ExprNode val = Parse_ExprVal(lex);
+ ExprNodeP val = Parse_ExprVal(lex);
while(true)
{
Token tok;
@@ -404,13 +405,13 @@ AST::ExprNode Parse_ExprFC(TokenStream& lex)
case TOK_PAREN_OPEN:
// Function call
lex.putback(tok);
- val = AST::ExprNode(AST::ExprNode::TagCallObject(), val, Parse_ParenList(lex));
+ val = NEWNODE( AST::ExprNode_CallObject, ::std::move(val), Parse_ParenList(lex) );
break;
case TOK_DOT:
// Field access
// TODO: What about tuple indexing?
GET_CHECK_TOK(tok, lex, TOK_IDENT);
- val = AST::ExprNode(AST::ExprNode::TagField(), tok.str());
+ val = NEWNODE( AST::ExprNode_Field, ::std::move(val), ::std::string(tok.str()) );
break;
default:
lex.putback(tok);
@@ -419,11 +420,11 @@ AST::ExprNode Parse_ExprFC(TokenStream& lex)
}
}
-AST::ExprNode Parse_ExprVal(TokenStream& lex)
+ExprNodeP Parse_ExprVal(TokenStream& lex)
{
Token tok;
AST::Path path;
- switch((tok = lex.getToken()).type())
+ switch( GET_TOK(tok, lex) )
{
case TOK_IDENT:
// Get path
@@ -438,18 +439,18 @@ AST::ExprNode Parse_ExprVal(TokenStream& lex)
// Braced structure literal
// - A series of 0 or more pairs of <ident>: <expr>,
// - '..' <expr>
- ::std::vector< ::std::pair< ::std::string, AST::ExprNode> > items;
+ ::std::vector< ::std::pair< ::std::string, ::std::unique_ptr<AST::ExprNode>> > items;
while( GET_TOK(tok, lex) == TOK_IDENT )
{
::std::string name = tok.str();
GET_CHECK_TOK(tok, lex, TOK_COLON);
- AST::ExprNode val = Parse_Expr0(lex);
- items.push_back( ::std::make_pair(name, val) );
+ ExprNodeP val = Parse_Expr0(lex);
+ items.push_back( ::std::make_pair(::std::move(name), ::std::move(val)) );
if( GET_TOK(tok,lex) == TOK_BRACE_CLOSE )
break;
CHECK_TOK(tok, TOK_COMMA);
}
- AST::ExprNode base_val;
+ ExprNodeP base_val;
if( tok.type() == TOK_DOUBLE_DOT )
{
// default
@@ -457,30 +458,30 @@ AST::ExprNode Parse_ExprVal(TokenStream& lex)
GET_TOK(tok, lex);
}
CHECK_TOK(tok, TOK_BRACE_CLOSE);
- return ExprNode(ExprNode::TagStructLiteral(), path, base_val, items);
+ return NEWNODE( AST::ExprNode_StructLiteral, path, ::std::move(base_val), ::std::move(items) );
}
case TOK_PAREN_OPEN: {
lex.putback(tok);
// Function call
- ::std::vector<AST::ExprNode> args = Parse_ParenList(lex);
- return ExprNode(ExprNode::TagCallPath(), path, args);
+ ::std::vector<ExprNodeP> args = Parse_ParenList(lex);
+ return NEWNODE( AST::ExprNode_CallPath, ::std::move(path), ::std::move(args) );
}
default:
// Value
lex.putback(tok);
- return ExprNode(ExprNode::TagNamedValue(), path);
+ return NEWNODE( AST::ExprNode_NamedValue, ::std::move(path) );
}
case TOK_INTEGER:
- return ExprNode(ExprNode::TagInteger(), tok.intval(), tok.datatype());
+ return NEWNODE( AST::ExprNode_Integer, tok.intval(), tok.datatype() );
case TOK_FLOAT:
throw ParseError::Todo("Float");
case TOK_RWORD_SELF: {
AST::Path path;
path.append( AST::PathNode("self", ::std::vector<TypeRef>()) );
- return ExprNode(ExprNode::TagNamedValue(), path);
+ return NEWNODE( AST::ExprNode_NamedValue, ::std::move(path) );
}
case TOK_PAREN_OPEN: {
- ExprNode rv = Parse_Expr0(lex);
+ ExprNodeP rv = Parse_Expr0(lex);
GET_CHECK_TOK(tok, lex, TOK_PAREN_CLOSE);
return rv; }
case TOK_MACRO: {
diff --git a/src/parse/root.cpp b/src/parse/root.cpp
index c9fc0401..4f2a5084 100644
--- a/src/parse/root.cpp
+++ b/src/parse/root.cpp
@@ -156,7 +156,7 @@ TypeRef Parse_Type(TokenStream& lex)
GET_CHECK_TOK(tok, lex, TOK_DOUBLE_DOT);
AST::Expr array_size = Parse_Expr(lex, true);
GET_CHECK_TOK(tok, lex, TOK_SQUARE_CLOSE);
- return TypeRef(TypeRef::TagSizedArray(), inner, array_size);
+ return TypeRef(TypeRef::TagSizedArray(), inner, ::std::move(array_size));
}
else {
GET_CHECK_TOK(tok, lex, TOK_SQUARE_CLOSE);
diff --git a/src/types.cpp b/src/types.cpp
index 4bfb448f..a5edb5b8 100644
--- a/src/types.cpp
+++ b/src/types.cpp
@@ -3,6 +3,6 @@
#include "types.hpp"
#include "ast/ast.hpp"
-TypeRef::TypeRef(TypeRef::TagSizedArray, TypeRef inner, AST::Expr size_expr)
+TypeRef::TypeRef(TypeRef::TagSizedArray, TypeRef inner, AST::Expr&& size_expr)
{
}
diff --git a/src/types.hpp b/src/types.hpp
index 18972143..237d9ea6 100644
--- a/src/types.hpp
+++ b/src/types.hpp
@@ -26,7 +26,7 @@ public:
struct TagPointer {};
TypeRef(TagPointer _, bool is_mut, TypeRef inner_type) {}
struct TagSizedArray {};
- TypeRef(TagSizedArray _, TypeRef inner_type, AST::Expr size);
+ TypeRef(TagSizedArray _, TypeRef inner_type, AST::Expr&& size);
struct TagUnsizedArray {};
TypeRef(TagUnsizedArray _, TypeRef inner_type) {}