From 90d17906a39d521e36ff9e4f6089a1fb67a0aab7 Mon Sep 17 00:00:00 2001 From: "John Hodge (sonata)" Date: Tue, 30 Dec 2014 17:36:47 +0800 Subject: Rework expressions so they can be iterated (and actually save data) --- src/ast/ast.cpp | 102 +++++++++++++-- src/ast/ast.hpp | 339 +++++++++++++++++++++++++++++++++++++++--------- src/convert/flatten.cpp | 2 +- src/convert/resolve.cpp | 24 +++- src/parse/expr.cpp | 147 ++++++++++----------- src/parse/root.cpp | 2 +- src/types.cpp | 2 +- src/types.hpp | 2 +- 8 files changed, 468 insertions(+), 152 deletions(-) (limited to 'src') 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& PathNode::args() const Pattern::Pattern(TagMaybeBind, ::std::string name) { } -Pattern::Pattern(TagValue, ExprNode node) +Pattern::Pattern(TagValue, ::std::unique_ptr node) { } Pattern::Pattern(TagEnumVariant, Path path, ::std::vector sub_patterns) @@ -40,9 +40,6 @@ Pattern::Pattern(TagEnumVariant, Path path, ::std::vector sub_patterns) } -Function::Function(::std::string name, TypeParams params, Class fcn_class, TypeRef ret_type, ::std::vector 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 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 node); struct TagEnumVariant {}; Pattern(TagEnumVariant, Path path, ::std::vector sub_patterns); }; +class NodeVisitor; + class ExprNode { public: - ExprNode(); - - struct TagBlock {}; - ExprNode(TagBlock, ::std::vector 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 args); + virtual ~ExprNode() = 0; + + virtual void visit(NodeVisitor& nv) = 0; +}; - struct TagCallObject {}; - ExprNode(TagCallObject, ExprNode val, ::std::vector args); +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; +}; - struct TagMatch {}; - ExprNode(TagMatch, ExprNode val, ::std::vector< ::std::pair > arms); +// 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; +}; - struct TagIf {}; - ExprNode(TagIf, ExprNode cond, ExprNode true_code, ExprNode false_code); +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; +}; - struct TagNamedValue {}; - ExprNode(TagNamedValue, Path path); +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) ) + {} + + 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; +}; - struct TagField {}; - ExprNode(TagField, ::std::string name); +// 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; +}; - 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 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; }; 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 m_node; public: - Expr() {} - Expr(ExprNode node) {} + Expr(unique_ptr 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 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 m_functions; + ::std::vector< ::std::pair > 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 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 m_functions; public: - const ::std::vector& functions() const; - const ::std::vector& structs() const; + const ::std::vector& functions() const { return m_functions; } + const ::std::vector& 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 #include "tokentree.hpp" +typedef ::std::unique_ptr 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 nodes; Token tok; + + ::std::vector 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 Parse_ParenList(TokenStream& lex) +::std::vector Parse_ParenList(TokenStream& lex) { TRACE_FUNCTION; - - ::std::vector rv; Token tok; + + ::std::vector 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 > arms; + ::std::vector< ::std::pair> > 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 : , // - '..' - ::std::vector< ::std::pair< ::std::string, AST::ExprNode> > items; + ::std::vector< ::std::pair< ::std::string, ::std::unique_ptr> > 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 args = Parse_ParenList(lex); - return ExprNode(ExprNode::TagCallPath(), path, args); + ::std::vector 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()) ); - 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) {} -- cgit v1.2.3