diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/analysis/rust-name-resolution.cc | 8 | ||||
-rw-r--r-- | gcc/rust/analysis/rust-name-resolution.h | 4 | ||||
-rw-r--r-- | gcc/rust/analysis/rust-scan.cc | 8 | ||||
-rw-r--r-- | gcc/rust/analysis/rust-scan.h | 4 | ||||
-rw-r--r-- | gcc/rust/analysis/rust-type-resolution.cc | 8 | ||||
-rw-r--r-- | gcc/rust/analysis/rust-type-resolution.h | 4 | ||||
-rw-r--r-- | gcc/rust/ast/rust-ast-full-decls.h | 7 | ||||
-rw-r--r-- | gcc/rust/ast/rust-ast-full-test.cc | 13 | ||||
-rw-r--r-- | gcc/rust/ast/rust-ast-visitor.h | 4 | ||||
-rw-r--r-- | gcc/rust/ast/rust-ast.h | 10 | ||||
-rw-r--r-- | gcc/rust/ast/rust-expr.h | 131 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile.cc | 8 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile.h | 4 | ||||
-rw-r--r-- | gcc/rust/parse/rust-parse-impl.h | 128 | ||||
-rw-r--r-- | gcc/rust/parse/rust-parse.h | 3 |
15 files changed, 231 insertions, 113 deletions
diff --git a/gcc/rust/analysis/rust-name-resolution.cc b/gcc/rust/analysis/rust-name-resolution.cc index 582f8ac..28a4af8 100644 --- a/gcc/rust/analysis/rust-name-resolution.cc +++ b/gcc/rust/analysis/rust-name-resolution.cc @@ -361,12 +361,12 @@ void NameResolution::visit (AST::IfLetExprConseqIfLet &expr) {} // void NameResolution::visit(MatchCase& match_case) {} -void +/*void NameResolution::visit (AST::MatchCaseBlockExpr &match_case) -{} -void +{}*/ +/*void NameResolution::visit (AST::MatchCaseExpr &match_case) -{} +{}*/ void NameResolution::visit (AST::MatchExpr &expr) {} diff --git a/gcc/rust/analysis/rust-name-resolution.h b/gcc/rust/analysis/rust-name-resolution.h index 51ef450..b3bc780 100644 --- a/gcc/rust/analysis/rust-name-resolution.h +++ b/gcc/rust/analysis/rust-name-resolution.h @@ -112,8 +112,8 @@ public: void visit (AST::IfLetExprConseqIf &expr) override; void visit (AST::IfLetExprConseqIfLet &expr) override; // void visit(MatchCase& match_case) override; - void visit (AST::MatchCaseBlockExpr &match_case) override; - void visit (AST::MatchCaseExpr &match_case) override; + // void visit (AST::MatchCaseBlockExpr &match_case) override; + // void visit (AST::MatchCaseExpr &match_case) override; void visit (AST::MatchExpr &expr) override; void visit (AST::AwaitExpr &expr) override; void visit (AST::AsyncBlockExpr &expr) override; diff --git a/gcc/rust/analysis/rust-scan.cc b/gcc/rust/analysis/rust-scan.cc index 4c032b0..402ac32 100644 --- a/gcc/rust/analysis/rust-scan.cc +++ b/gcc/rust/analysis/rust-scan.cc @@ -297,12 +297,12 @@ void TopLevelScan::visit (AST::IfLetExprConseqIfLet &expr) {} // void TopLevelScan::visit(MatchCase& match_case) {} -void +/*void TopLevelScan::visit (AST::MatchCaseBlockExpr &match_case) -{} -void +{}*/ +/*void TopLevelScan::visit (AST::MatchCaseExpr &match_case) -{} +{}*/ void TopLevelScan::visit (AST::MatchExpr &expr) {} diff --git a/gcc/rust/analysis/rust-scan.h b/gcc/rust/analysis/rust-scan.h index e898d41..77beeca 100644 --- a/gcc/rust/analysis/rust-scan.h +++ b/gcc/rust/analysis/rust-scan.h @@ -117,8 +117,8 @@ public: virtual void visit (AST::IfLetExprConseqIf &expr); virtual void visit (AST::IfLetExprConseqIfLet &expr); // virtual void visit(MatchCase& match_case); - virtual void visit (AST::MatchCaseBlockExpr &match_case); - virtual void visit (AST::MatchCaseExpr &match_case); + // virtual void visit (AST::MatchCaseBlockExpr &match_case); + // virtual void visit (AST::MatchCaseExpr &match_case); virtual void visit (AST::MatchExpr &expr); virtual void visit (AST::AwaitExpr &expr); virtual void visit (AST::AsyncBlockExpr &expr); diff --git a/gcc/rust/analysis/rust-type-resolution.cc b/gcc/rust/analysis/rust-type-resolution.cc index 8edebba..3503a83 100644 --- a/gcc/rust/analysis/rust-type-resolution.cc +++ b/gcc/rust/analysis/rust-type-resolution.cc @@ -704,12 +704,12 @@ void TypeResolution::visit (AST::IfLetExprConseqIfLet &expr) {} // void TypeResolution::visit(MatchCase& match_case) {} -void +/*void TypeResolution::visit (AST::MatchCaseBlockExpr &match_case) -{} -void +{}*/ +/*void TypeResolution::visit (AST::MatchCaseExpr &match_case) -{} +{}*/ void TypeResolution::visit (AST::MatchExpr &expr) {} diff --git a/gcc/rust/analysis/rust-type-resolution.h b/gcc/rust/analysis/rust-type-resolution.h index 6f74719..af4594e 100644 --- a/gcc/rust/analysis/rust-type-resolution.h +++ b/gcc/rust/analysis/rust-type-resolution.h @@ -188,8 +188,8 @@ public: void visit (AST::IfLetExprConseqIf &expr) override; void visit (AST::IfLetExprConseqIfLet &expr) override; // void visit(MatchCase& match_case) override; - void visit (AST::MatchCaseBlockExpr &match_case) override; - void visit (AST::MatchCaseExpr &match_case) override; + // void visit (AST::MatchCaseBlockExpr &match_case) override; + // void visit (AST::MatchCaseExpr &match_case) override; void visit (AST::MatchExpr &expr) override; void visit (AST::AwaitExpr &expr) override; void visit (AST::AsyncBlockExpr &expr) override; diff --git a/gcc/rust/ast/rust-ast-full-decls.h b/gcc/rust/ast/rust-ast-full-decls.h index a76a599..9b604a5 100644 --- a/gcc/rust/ast/rust-ast-full-decls.h +++ b/gcc/rust/ast/rust-ast-full-decls.h @@ -134,9 +134,10 @@ namespace Rust { class IfLetExprConseqIf; class IfLetExprConseqIfLet; struct MatchArm; - class MatchCase; - class MatchCaseBlockExpr; - class MatchCaseExpr; + // class MatchCase; + // class MatchCaseBlockExpr; + // class MatchCaseExpr; + struct MatchCase; class MatchExpr; class AwaitExpr; class AsyncBlockExpr; diff --git a/gcc/rust/ast/rust-ast-full-test.cc b/gcc/rust/ast/rust-ast-full-test.cc index 75ea74d..33d1736 100644 --- a/gcc/rust/ast/rust-ast-full-test.cc +++ b/gcc/rust/ast/rust-ast-full-test.cc @@ -2391,11 +2391,12 @@ MatchCase::as_string () const std::string str ("MatchCase: (match arm) "); str += "\n Match arm matcher: \n" + arm.as_string (); + str += "\n Expr: " + expr->as_string (); return str; } -std::string +/*std::string MatchCaseBlockExpr::as_string () const { std::string str = MatchCase::as_string (); @@ -2413,7 +2414,7 @@ MatchCaseExpr::as_string () const str += "\n Expr: " + expr->as_string (); return str; -} +}*/ std::string MatchExpr::as_string () const @@ -2447,9 +2448,7 @@ MatchExpr::as_string () const else { for (const auto &arm : match_arms) - { - str += "\n " + arm->as_string (); - } + str += "\n " + arm.as_string (); } return str; @@ -5759,7 +5758,7 @@ IfLetExprConseqIfLet::accept_vis (ASTVisitor &vis) vis.visit (*this); } -void +/*void MatchCaseBlockExpr::accept_vis (ASTVisitor &vis) { vis.visit (*this); @@ -5769,7 +5768,7 @@ void MatchCaseExpr::accept_vis (ASTVisitor &vis) { vis.visit (*this); -} +}*/ void MatchExpr::accept_vis (ASTVisitor &vis) diff --git a/gcc/rust/ast/rust-ast-visitor.h b/gcc/rust/ast/rust-ast-visitor.h index 0d89d51..b48e8f3 100644 --- a/gcc/rust/ast/rust-ast-visitor.h +++ b/gcc/rust/ast/rust-ast-visitor.h @@ -113,8 +113,8 @@ public: virtual void visit (IfLetExprConseqIf &expr) = 0; virtual void visit (IfLetExprConseqIfLet &expr) = 0; // virtual void visit(MatchCase& match_case) = 0; - virtual void visit (MatchCaseBlockExpr &match_case) = 0; - virtual void visit (MatchCaseExpr &match_case) = 0; + // virtual void visit (MatchCaseBlockExpr &match_case) = 0; + // virtual void visit (MatchCaseExpr &match_case) = 0; virtual void visit (MatchExpr &expr) = 0; virtual void visit (AwaitExpr &expr) = 0; virtual void visit (AsyncBlockExpr &expr) = 0; diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h index 4c115b2..f9fbc36 100644 --- a/gcc/rust/ast/rust-ast.h +++ b/gcc/rust/ast/rust-ast.h @@ -2,11 +2,6 @@ #define RUST_AST_BASE_H // Base for AST used in gccrs, basically required by all specific ast things -// GCC imports -#include "config.h" -#include "system.h" -#include "coretypes.h" // order: config, system, coretypes - #include "rust-system.h" // STL imports @@ -847,6 +842,9 @@ public: * methods. */ virtual Location get_locus_slow () const { return Location (); } + // HACK: strictly not needed, but faster than full downcast clone + virtual bool is_expr_without_block () const = 0; + virtual void accept_vis (ASTVisitor &vis) = 0; protected: @@ -887,6 +885,8 @@ protected: return clone_expr_without_block_impl (); } + bool is_expr_without_block () const final override { return true; }; + public: // Unique pointer custom clone function std::unique_ptr<ExprWithoutBlock> clone_expr_without_block () const diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h index 727cf3c..b989006 100644 --- a/gcc/rust/ast/rust-expr.h +++ b/gcc/rust/ast/rust-expr.h @@ -28,6 +28,8 @@ protected: return clone_expr_with_block_impl (); } + bool is_expr_without_block () const final override { return false; }; + public: // Unique pointer custom clone function std::unique_ptr<ExprWithBlock> clone_expr_with_block () const @@ -889,12 +891,12 @@ protected: // Value array elements class ArrayElemsValues : public ArrayElems { - std::vector<std::unique_ptr<Expr>> values; + std::vector<std::unique_ptr<Expr> > values; // TODO: should this store location data? public: - ArrayElemsValues (std::vector<std::unique_ptr<Expr>> elems) + ArrayElemsValues (std::vector<std::unique_ptr<Expr> > elems) : values (std::move (elems)) {} @@ -1117,7 +1119,7 @@ class TupleExpr : public ExprWithoutBlock { std::vector<Attribute> inner_attrs; - std::vector<std::unique_ptr<Expr>> tuple_elems; + std::vector<std::unique_ptr<Expr> > tuple_elems; // replaces (inlined version of) TupleElements Location locus; @@ -1127,7 +1129,7 @@ public: std::vector<Attribute> get_inner_attrs () const { return inner_attrs; } - TupleExpr (std::vector<std::unique_ptr<Expr>> tuple_elements, + TupleExpr (std::vector<std::unique_ptr<Expr> > tuple_elements, std::vector<Attribute> inner_attribs, std::vector<Attribute> outer_attribs, Location locus) : ExprWithoutBlock (std::move (outer_attribs)), @@ -1493,7 +1495,7 @@ class StructExprStructFields : public StructExprStruct { public: // std::vector<StructExprField> fields; - std::vector<std::unique_ptr<StructExprField>> fields; + std::vector<std::unique_ptr<StructExprField> > fields; // bool has_struct_base; StructBase struct_base; @@ -1513,7 +1515,7 @@ public: // Constructor for StructExprStructFields when no struct base is used StructExprStructFields ( PathInExpression struct_path, - std::vector<std::unique_ptr<StructExprField>> expr_fields, Location locus, + std::vector<std::unique_ptr<StructExprField> > expr_fields, Location locus, StructBase base_struct = StructBase::error (), std::vector<Attribute> inner_attribs = std::vector<Attribute> (), std::vector<Attribute> outer_attribs = std::vector<Attribute> ()) @@ -1608,7 +1610,7 @@ protected: class StructExprTuple : public StructExpr { std::vector<Attribute> inner_attrs; - std::vector<std::unique_ptr<Expr>> exprs; + std::vector<std::unique_ptr<Expr> > exprs; Location locus; @@ -1622,7 +1624,7 @@ public: }*/ StructExprTuple (PathInExpression struct_path, - std::vector<std::unique_ptr<Expr>> tuple_exprs, + std::vector<std::unique_ptr<Expr> > tuple_exprs, std::vector<Attribute> inner_attribs, std::vector<Attribute> outer_attribs, Location locus) : StructExpr (std::move (struct_path), std::move (outer_attribs)), @@ -1867,7 +1869,7 @@ protected: class EnumExprStruct : public EnumVariantExpr { // std::vector<EnumExprField> fields; - std::vector<std::unique_ptr<EnumExprField>> fields; + std::vector<std::unique_ptr<EnumExprField> > fields; Location locus; @@ -1879,7 +1881,7 @@ public: }*/ EnumExprStruct (PathInExpression enum_variant_path, - std::vector<std::unique_ptr<EnumExprField>> variant_fields, + std::vector<std::unique_ptr<EnumExprField> > variant_fields, std::vector<Attribute> outer_attribs, Location locus) : EnumVariantExpr (std::move (enum_variant_path), std::move (outer_attribs)), @@ -1936,7 +1938,7 @@ protected: // Tuple-like syntax enum variant instance creation AST node class EnumExprTuple : public EnumVariantExpr { - std::vector<std::unique_ptr<Expr>> values; + std::vector<std::unique_ptr<Expr> > values; Location locus; @@ -1948,7 +1950,7 @@ public: }*/ EnumExprTuple (PathInExpression enum_variant_path, - std::vector<std::unique_ptr<Expr>> variant_values, + std::vector<std::unique_ptr<Expr> > variant_values, std::vector<Attribute> outer_attribs, Location locus) : EnumVariantExpr (std::move (enum_variant_path), std::move (outer_attribs)), @@ -2051,7 +2053,7 @@ class CallExpr : public ExprWithoutBlock public: std::unique_ptr<Expr> function; // inlined form of CallParams - std::vector<std::unique_ptr<Expr>> params; + std::vector<std::unique_ptr<Expr> > params; Location locus; @@ -2064,7 +2066,7 @@ public: }*/ CallExpr (std::unique_ptr<Expr> function_expr, - std::vector<std::unique_ptr<Expr>> function_params, + std::vector<std::unique_ptr<Expr> > function_params, std::vector<Attribute> outer_attribs, Location locus) : ExprWithoutBlock (std::move (outer_attribs)), function (std::move (function_expr)), @@ -2128,7 +2130,7 @@ class MethodCallExpr : public ExprWithoutBlock std::unique_ptr<Expr> receiver; PathExprSegment method_name; // inlined form of CallParams - std::vector<std::unique_ptr<Expr>> params; + std::vector<std::unique_ptr<Expr> > params; Location locus; @@ -2141,7 +2143,7 @@ public: MethodCallExpr (std::unique_ptr<Expr> call_receiver, PathExprSegment method_path, - std::vector<std::unique_ptr<Expr>> method_params, + std::vector<std::unique_ptr<Expr> > method_params, std::vector<Attribute> outer_attribs, Location locus) : ExprWithoutBlock (std::move (outer_attribs)), receiver (std::move (call_receiver)), @@ -2407,7 +2409,7 @@ public: std::vector<Attribute> inner_attrs; // bool has_statements; - std::vector<std::unique_ptr<Stmt>> statements; + std::vector<std::unique_ptr<Stmt> > statements; // bool has_expr; std::unique_ptr<ExprWithoutBlock> expr; // inlined from Statements @@ -2421,7 +2423,7 @@ public: // Returns whether the block contains an expression bool has_expr () const { return expr != nullptr; } - BlockExpr (std::vector<std::unique_ptr<Stmt>> block_statements, + BlockExpr (std::vector<std::unique_ptr<Stmt> > block_statements, std::unique_ptr<ExprWithoutBlock> block_expr, std::vector<Attribute> inner_attribs, std::vector<Attribute> outer_attribs, Location locus) @@ -3278,14 +3280,14 @@ protected: class WhileLetLoopExpr : public BaseLoopExpr { // MatchArmPatterns patterns; - std::vector<std::unique_ptr<Pattern>> match_arm_patterns; // inlined + std::vector<std::unique_ptr<Pattern> > match_arm_patterns; // inlined std::unique_ptr<Expr> condition; public: std::string as_string () const override; // Constructor with a loop label - WhileLetLoopExpr (std::vector<std::unique_ptr<Pattern>> match_arm_patterns, + WhileLetLoopExpr (std::vector<std::unique_ptr<Pattern> > match_arm_patterns, std::unique_ptr<Expr> condition, std::unique_ptr<BlockExpr> loop_block, Location locus, LoopLabel loop_label = LoopLabel::error (), @@ -3622,7 +3624,7 @@ protected: class IfLetExpr : public ExprWithBlock { // MatchArmPatterns patterns; - std::vector<std::unique_ptr<Pattern>> match_arm_patterns; // inlined + std::vector<std::unique_ptr<Pattern> > match_arm_patterns; // inlined std::unique_ptr<Expr> value; std::unique_ptr<BlockExpr> if_block; @@ -3631,7 +3633,7 @@ class IfLetExpr : public ExprWithBlock public: std::string as_string () const override; - IfLetExpr (std::vector<std::unique_ptr<Pattern>> match_arm_patterns, + IfLetExpr (std::vector<std::unique_ptr<Pattern> > match_arm_patterns, std::unique_ptr<Expr> value, std::unique_ptr<BlockExpr> if_block, Location locus) : ExprWithBlock (std::vector<Attribute> ()), @@ -3774,7 +3776,7 @@ public: std::string as_string () const override; IfLetExprConseqElse ( - std::vector<std::unique_ptr<Pattern>> match_arm_patterns, + std::vector<std::unique_ptr<Pattern> > match_arm_patterns, std::unique_ptr<Expr> value, std::unique_ptr<BlockExpr> if_block, std::unique_ptr<BlockExpr> else_block, Location locus) : IfLetExpr (std::move (match_arm_patterns), std::move (value), @@ -3839,7 +3841,7 @@ class IfLetExprConseqIf : public IfLetExpr public: std::string as_string () const override; - IfLetExprConseqIf (std::vector<std::unique_ptr<Pattern>> match_arm_patterns, + IfLetExprConseqIf (std::vector<std::unique_ptr<Pattern> > match_arm_patterns, std::unique_ptr<Expr> value, std::unique_ptr<BlockExpr> if_block, std::unique_ptr<IfExpr> if_expr, Location locus) @@ -3905,7 +3907,7 @@ public: std::string as_string () const override; IfLetExprConseqIfLet ( - std::vector<std::unique_ptr<Pattern>> match_arm_patterns, + std::vector<std::unique_ptr<Pattern> > match_arm_patterns, std::unique_ptr<Expr> value, std::unique_ptr<BlockExpr> if_block, std::unique_ptr<IfLetExpr> if_let_expr, Location locus) : IfLetExpr (std::move (match_arm_patterns), std::move (value), @@ -3966,7 +3968,7 @@ struct MatchArm private: std::vector<Attribute> outer_attrs; // MatchArmPatterns patterns; - std::vector<std::unique_ptr<Pattern>> match_arm_patterns; // inlined + std::vector<std::unique_ptr<Pattern> > match_arm_patterns; // inlined // bool has_match_arm_guard; // inlined from MatchArmGuard @@ -3979,7 +3981,7 @@ public: bool has_match_arm_guard () const { return guard_expr != nullptr; } // Constructor for match arm with a guard expression - MatchArm (std::vector<std::unique_ptr<Pattern>> match_arm_patterns, + MatchArm (std::vector<std::unique_ptr<Pattern> > match_arm_patterns, std::unique_ptr<Expr> guard_expr = nullptr, std::vector<Attribute> outer_attrs = std::vector<Attribute> ()) : outer_attrs (std::move (outer_attrs)), @@ -3988,9 +3990,7 @@ public: {} // Copy constructor with clone - MatchArm (MatchArm const &other) - : /*match_arm_patterns(other.match_arm_patterns),*/ outer_attrs ( - other.outer_attrs) + MatchArm (MatchArm const &other) : outer_attrs (other.outer_attrs) { // guard to protect from null pointer dereference if (other.guard_expr != nullptr) @@ -4006,9 +4006,10 @@ public: // Overload assignment operator to clone MatchArm &operator= (MatchArm const &other) { - // match_arm_patterns = other.match_arm_patterns; outer_attrs = other.outer_attrs; - guard_expr = other.guard_expr->clone_expr (); + + if (other.guard_expr != nullptr) + guard_expr = other.guard_expr->clone_expr (); match_arm_patterns.reserve (other.match_arm_patterns.size ()); for (const auto &e : other.match_arm_patterns) @@ -4027,12 +4028,13 @@ public: // Creates a match arm in an error state. static MatchArm create_error () { - return MatchArm (std::vector<std::unique_ptr<Pattern>> ()); + return MatchArm (std::vector<std::unique_ptr<Pattern> > ()); } std::string as_string () const; }; +/* // Base "match case" for a match expression - abstract class MatchCase { @@ -4059,7 +4061,45 @@ public: virtual void accept_vis (ASTVisitor &vis) = 0; }; +*/ + +/* A "match case" - a correlated match arm and resulting expression. Not + * abstract. */ +struct MatchCase +{ +private: + MatchArm arm; + std::unique_ptr<Expr> expr; + + /* TODO: does whether trailing comma exists need to be stored? currently + * assuming it is only syntactical and has no effect on meaning. */ + +public: + MatchCase (MatchArm arm, std::unique_ptr<Expr> expr) + : arm (std::move (arm)), expr (std::move (expr)) + {} + + MatchCase (const MatchCase &other) + : arm (other.arm), expr (other.expr->clone_expr ()) + {} + MatchCase &operator= (const MatchCase &other) + { + arm = other.arm; + expr = other.expr->clone_expr (); + + return *this; + } + + MatchCase (MatchCase &&other) = default; + MatchCase &operator= (MatchCase &&other) = default; + + ~MatchCase () = default; + + std::string as_string () const; +}; + +#if 0 // Block expression match case class MatchCaseBlockExpr : public MatchCase { @@ -4147,6 +4187,7 @@ protected: return new MatchCaseExpr (*this); } }; +#endif // Match expression AST node class MatchExpr : public ExprWithBlock @@ -4156,7 +4197,9 @@ class MatchExpr : public ExprWithBlock // bool has_match_arms; // MatchArms match_arms; - std::vector<std::unique_ptr<MatchCase>> match_arms; // inlined from MatchArms + // std::vector<std::unique_ptr<MatchCase> > match_arms; // inlined from + // MatchArms + std::vector<MatchCase> match_arms; Location locus; @@ -4167,7 +4210,8 @@ public: bool has_match_arms () const { return !match_arms.empty (); } MatchExpr (std::unique_ptr<Expr> branch_value, - std::vector<std::unique_ptr<MatchCase>> match_arms, + // std::vector<std::unique_ptr<MatchCase> > match_arms, + std::vector<MatchCase> match_arms, std::vector<Attribute> inner_attrs, std::vector<Attribute> outer_attrs, Location locus) : ExprWithBlock (std::move (outer_attrs)), @@ -4178,14 +4222,13 @@ public: // Copy constructor requires clone due to unique_ptr MatchExpr (MatchExpr const &other) - : ExprWithBlock (other), - branch_value ( - other.branch_value->clone_expr ()), /*match_arms(other.match_arms),*/ - inner_attrs (other.inner_attrs), locus (other.locus) + : ExprWithBlock (other), branch_value (other.branch_value->clone_expr ()), + inner_attrs (other.inner_attrs), match_arms (other.match_arms), + locus (other.locus) { - match_arms.reserve (other.match_arms.size ()); + /*match_arms.reserve (other.match_arms.size ()); for (const auto &e : other.match_arms) - match_arms.push_back (e->clone_match_case ()); + match_arms.push_back (e->clone_match_case ());*/ } // Overloaded assignment operator to clone due to unique_ptr @@ -4193,14 +4236,14 @@ public: { ExprWithBlock::operator= (other); branch_value = other.branch_value->clone_expr (); - // match_arms = other.match_arms; inner_attrs = other.inner_attrs; + match_arms = other.match_arms; // outer_attrs = other.outer_attrs; locus = other.locus; - match_arms.reserve (other.match_arms.size ()); + /*match_arms.reserve (other.match_arms.size ()); for (const auto &e : other.match_arms) - match_arms.push_back (e->clone_match_case ()); + match_arms.push_back (e->clone_match_case ());*/ return *this; } diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc index 2b9b5bb..6374a45 100644 --- a/gcc/rust/backend/rust-compile.cc +++ b/gcc/rust/backend/rust-compile.cc @@ -889,12 +889,12 @@ Compilation::visit (AST::IfLetExprConseqIfLet &expr) } // void Compilation::visit(MatchCase& match_case) {} -void +/*void Compilation::visit (AST::MatchCaseBlockExpr &match_case) -{} -void +{}*/ +/*void Compilation::visit (AST::MatchCaseExpr &match_case) -{} +{}*/ void Compilation::visit (AST::MatchExpr &expr) {} diff --git a/gcc/rust/backend/rust-compile.h b/gcc/rust/backend/rust-compile.h index b28f0ee..ba03483 100644 --- a/gcc/rust/backend/rust-compile.h +++ b/gcc/rust/backend/rust-compile.h @@ -116,8 +116,8 @@ public: virtual void visit (AST::IfLetExprConseqIf &expr); virtual void visit (AST::IfLetExprConseqIfLet &expr); // virtual void visit(MatchCase& match_case); - virtual void visit (AST::MatchCaseBlockExpr &match_case); - virtual void visit (AST::MatchCaseExpr &match_case); + // virtual void visit (AST::MatchCaseBlockExpr &match_case); + // virtual void visit (AST::MatchCaseExpr &match_case); virtual void visit (AST::MatchExpr &expr); virtual void visit (AST::AwaitExpr &expr); virtual void visit (AST::AsyncBlockExpr &expr); diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h index 286d7a4..468312e 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -3895,7 +3895,8 @@ Parser<ManagedTokenSource>::parse_struct ( lexer.skip_token (); // parse struct fields, if any - std::vector<AST::StructField> struct_fields = parse_struct_fields (); + std::vector<AST::StructField> struct_fields + = parse_struct_fields ([] (TokenId id) { return id == RIGHT_CURLY; }); if (!skip_token (RIGHT_CURLY)) { @@ -3938,42 +3939,69 @@ Parser<ManagedTokenSource>::parse_struct_fields () // Return empty field list if no field there if (initial_field.is_error ()) - { - return fields; - } + return fields; fields.push_back (std::move (initial_field)); - // maybe think of a better control structure here - do-while with an initial - // error state? basically, loop through field list until can't find any more - // params - while (true) + while (lexer.peek_token ()->get_id () == COMMA) { - if (lexer.peek_token ()->get_id () != COMMA) + lexer.skip_token (); + + AST::StructField field = parse_struct_field (); + + if (field.is_error ()) { + // would occur with trailing comma, so allowed break; } - // skip comma if applies + fields.push_back (std::move (field)); + } + + fields.shrink_to_fit (); + return fields; + // TODO: template if possible (parse_non_ptr_seq) +} + +// Parses struct fields in struct declarations. +template <typename ManagedTokenSource> +template <typename EndTokenPred> +std::vector<AST::StructField> +Parser<ManagedTokenSource>::parse_struct_fields (EndTokenPred is_end_tok) +{ + std::vector<AST::StructField> fields; + + AST::StructField initial_field = parse_struct_field (); + + // Return empty field list if no field there + if (initial_field.is_error ()) + return fields; + + fields.push_back (std::move (initial_field)); + + while (lexer.peek_token ()->get_id () == COMMA) + { lexer.skip_token (); - AST::StructField field = parse_struct_field (); + if (is_end_tok (lexer.peek_token ()->get_id ())) + break; - if (!field.is_error ()) - { - fields.push_back (std::move (field)); - } - else + AST::StructField field = parse_struct_field (); + if (field.is_error ()) { - // this would occur with a trailing comma, which is allowed - break; + /* TODO: should every field be ditched just because one couldn't be + * parsed? */ + rust_error_at (lexer.peek_token ()->get_locus (), + "failed to parse struct field in struct fields"); + return {}; } + + fields.push_back (std::move (field)); } + fields.shrink_to_fit (); return fields; - - // TODO: this shares basically all code with function params and tuple fields - // - templates? + // TODO: template if possible (parse_non_ptr_seq) } // Parses a single struct field (in a struct definition). Does not parse commas. @@ -4257,7 +4285,8 @@ Parser<ManagedTokenSource>::parse_enum_item () // struct enum item lexer.skip_token (); - std::vector<AST::StructField> struct_fields = parse_struct_fields (); + std::vector<AST::StructField> struct_fields + = parse_struct_fields ([] (TokenId id) { return id == RIGHT_CURLY; }); if (!skip_token (RIGHT_CURLY)) { @@ -4326,7 +4355,8 @@ Parser<ManagedTokenSource>::parse_union ( /* parse union inner items as "struct fields" because hey, syntax reuse. Spec * said so. */ - std::vector<AST::StructField> union_fields = parse_struct_fields (); + std::vector<AST::StructField> union_fields + = parse_struct_fields ([] (TokenId id) { return id == RIGHT_CURLY; }); if (!skip_token (RIGHT_CURLY)) { @@ -8017,18 +8047,20 @@ Parser<ManagedTokenSource>::parse_match_expr ( std::vector<AST::Attribute> inner_attrs = parse_inner_attributes (); // parse match arms (if they exist) - std::vector<std::unique_ptr<AST::MatchCase> > match_arms; + // std::vector<std::unique_ptr<AST::MatchCase> > match_arms; + std::vector<AST::MatchCase> match_arms; - // FIXME: absolute worst control structure ever // parse match cases - while (true) + while (lexer.peek_token ()->get_id () != RIGHT_CURLY) { // parse match arm itself, which is required AST::MatchArm arm = parse_match_arm (); if (arm.is_error ()) { - // not necessarily an error - break; + // TODO is this worth throwing everything away? + rust_error_at (lexer.peek_token ()->get_locus (), + "failed to parse match arm in match arms"); + return nullptr; } if (!skip_token (MATCH_ARROW)) @@ -8038,6 +8070,45 @@ Parser<ManagedTokenSource>::parse_match_expr ( return nullptr; } + std::unique_ptr<AST::Expr> expr = parse_expr (); + if (expr == nullptr) + { + rust_error_at (lexer.peek_token ()->get_locus (), + "failed to parse expr in match arm in match expr"); + // skip somewhere? + return nullptr; + } + bool is_expr_without_block = expr->is_expr_without_block (); + + // construct match case expr and add to cases + match_arms.push_back (AST::MatchCase (std::move (arm), std::move (expr))); + + // handle comma presence + if (lexer.peek_token ()->get_id () != COMMA) + { + if (!is_expr_without_block) + { + // allowed even if not final case + continue; + } + else if (is_expr_without_block + && lexer.peek_token ()->get_id () != RIGHT_CURLY) + { + // not allowed if not final case + rust_error_at (lexer.peek_token ()->get_locus (), + "exprwithoutblock requires comma after match case " + "expression in match arm (if not final case)"); + return nullptr; + } + else + { + // otherwise, must be final case, so fine + break; + } + } + lexer.skip_token (); + +#if 0 // branch on next token - if '{', block expr, otherwise just expr if (lexer.peek_token ()->get_id () == LEFT_CURLY) { @@ -8089,6 +8160,7 @@ Parser<ManagedTokenSource>::parse_match_expr ( } lexer.skip_token (); } +#endif } if (!skip_token (RIGHT_CURLY)) diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h index b2de05e..e2f3a78 100644 --- a/gcc/rust/parse/rust-parse.h +++ b/gcc/rust/parse/rust-parse.h @@ -189,6 +189,8 @@ private: std::unique_ptr<AST::Struct> parse_struct (AST::Visibility vis, std::vector<AST::Attribute> outer_attrs); std::vector<AST::StructField> parse_struct_fields (); + template <typename EndTokenPred> + std::vector<AST::StructField> parse_struct_fields (EndTokenPred is_end_token); AST::StructField parse_struct_field (); std::vector<AST::TupleField> parse_tuple_fields (); AST::TupleField parse_tuple_field (); @@ -528,6 +530,7 @@ private: = std::vector<AST::Attribute> (), bool pratt_parse = false); std::unique_ptr<AST::StructExprField> parse_struct_expr_field (); + bool will_be_expr_with_block (); // Type-related std::unique_ptr<AST::Type> parse_type (); |