| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587 |
- // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
- // Exceptions. See /LICENSE for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- #ifndef CARBON_EXPLORER_AST_STATEMENT_H_
- #define CARBON_EXPLORER_AST_STATEMENT_H_
- #include <utility>
- #include <vector>
- #include "common/ostream.h"
- #include "explorer/ast/ast_node.h"
- #include "explorer/ast/clone_context.h"
- #include "explorer/ast/expression.h"
- #include "explorer/ast/expression_category.h"
- #include "explorer/ast/pattern.h"
- #include "explorer/ast/return_term.h"
- #include "explorer/ast/value_node.h"
- #include "explorer/base/arena.h"
- #include "explorer/base/source_location.h"
- #include "llvm/ADT/ArrayRef.h"
- #include "llvm/Support/Compiler.h"
- namespace Carbon {
- class CallableDeclaration;
- class Statement : public AstNode {
- public:
- ~Statement() override = 0;
- void Print(llvm::raw_ostream& out) const override { PrintIndent(0, out); }
- void PrintID(llvm::raw_ostream& out) const override;
- void PrintIndent(int indent_num_spaces, llvm::raw_ostream& out) const;
- static auto classof(const AstNode* node) {
- return InheritsFromStatement(node->kind());
- }
- // Returns the enumerator corresponding to the most-derived type of this
- // object.
- auto kind() const -> StatementKind {
- return static_cast<StatementKind>(root_kind());
- }
- protected:
- explicit Statement(AstNodeKind kind, SourceLocation source_loc)
- : AstNode(kind, source_loc) {}
- explicit Statement(CloneContext& context, const Statement& other)
- : AstNode(context, other) {}
- };
- class Block : public Statement {
- public:
- Block(SourceLocation source_loc, std::vector<Nonnull<Statement*>> statements)
- : Statement(AstNodeKind::Block, source_loc),
- statements_(std::move(statements)) {}
- explicit Block(CloneContext& context, const Block& other)
- : Statement(context, other),
- statements_(context.Clone(other.statements_)) {}
- static auto classof(const AstNode* node) -> bool {
- return InheritsFromBlock(node->kind());
- }
- auto statements() const -> llvm::ArrayRef<Nonnull<const Statement*>> {
- return statements_;
- }
- auto statements() -> llvm::MutableArrayRef<Nonnull<Statement*>> {
- return statements_;
- }
- private:
- std::vector<Nonnull<Statement*>> statements_;
- };
- class ExpressionStatement : public Statement {
- public:
- ExpressionStatement(SourceLocation source_loc,
- Nonnull<Expression*> expression)
- : Statement(AstNodeKind::ExpressionStatement, source_loc),
- expression_(expression) {}
- explicit ExpressionStatement(CloneContext& context,
- const ExpressionStatement& other)
- : Statement(context, other),
- expression_(context.Clone(other.expression_)) {}
- static auto classof(const AstNode* node) -> bool {
- return InheritsFromExpressionStatement(node->kind());
- }
- auto expression() const -> const Expression& { return *expression_; }
- auto expression() -> Expression& { return *expression_; }
- private:
- Nonnull<Expression*> expression_;
- };
- enum class AssignOperator {
- Plain,
- Add,
- Div,
- Mul,
- Mod,
- Sub,
- And,
- Or,
- Xor,
- ShiftLeft,
- ShiftRight,
- };
- // Returns the spelling of this assignment operator token.
- auto AssignOperatorToString(AssignOperator op) -> std::string_view;
- class Assign : public Statement {
- public:
- Assign(SourceLocation source_loc, Nonnull<Expression*> lhs, AssignOperator op,
- Nonnull<Expression*> rhs)
- : Statement(AstNodeKind::Assign, source_loc),
- lhs_(lhs),
- rhs_(rhs),
- op_(op) {}
- explicit Assign(CloneContext& context, const Assign& other)
- : Statement(context, other),
- lhs_(context.Clone(other.lhs_)),
- rhs_(context.Clone(other.rhs_)),
- op_(other.op_),
- rewritten_form_(context.Clone(other.rewritten_form_)) {}
- static auto classof(const AstNode* node) -> bool {
- return InheritsFromAssign(node->kind());
- }
- auto lhs() const -> const Expression& { return *lhs_; }
- auto lhs() -> Expression& { return *lhs_; }
- auto rhs() const -> const Expression& { return *rhs_; }
- auto rhs() -> Expression& { return *rhs_; }
- auto op() const -> AssignOperator { return op_; }
- // Can only be called by type-checking, if a conversion was required.
- void set_rhs(Nonnull<Expression*> rhs) { rhs_ = rhs; }
- // Set the rewritten form of this statement. Can only be called during type
- // checking.
- auto set_rewritten_form(Nonnull<const Expression*> rewritten_form) -> void {
- CARBON_CHECK(!rewritten_form_.has_value(), "rewritten form set twice");
- rewritten_form_ = rewritten_form;
- }
- // Get the rewritten form of this statement. A rewritten form is used when
- // the statement is rewritten as a function call on an interface. A
- // rewritten form is not used when providing built-in operator semantics for
- // a plain assignment.
- auto rewritten_form() const -> std::optional<Nonnull<const Expression*>> {
- return rewritten_form_;
- }
- private:
- Nonnull<Expression*> lhs_;
- Nonnull<Expression*> rhs_;
- AssignOperator op_;
- std::optional<Nonnull<const Expression*>> rewritten_form_;
- };
- class IncrementDecrement : public Statement {
- public:
- IncrementDecrement(SourceLocation source_loc, Nonnull<Expression*> argument,
- bool is_increment)
- : Statement(AstNodeKind::IncrementDecrement, source_loc),
- argument_(argument),
- is_increment_(is_increment) {}
- explicit IncrementDecrement(CloneContext& context,
- const IncrementDecrement& other)
- : Statement(context, other),
- argument_(context.Clone(other.argument_)),
- is_increment_(other.is_increment_),
- rewritten_form_(context.Clone(other.rewritten_form_)) {}
- static auto classof(const AstNode* node) -> bool {
- return InheritsFromIncrementDecrement(node->kind());
- }
- auto argument() const -> const Expression& { return *argument_; }
- auto argument() -> Expression& { return *argument_; }
- auto is_increment() const -> bool { return is_increment_; }
- // Set the rewritten form of this statement. Can only be called during type
- // checking.
- auto set_rewritten_form(Nonnull<const Expression*> rewritten_form) -> void {
- CARBON_CHECK(!rewritten_form_.has_value(), "rewritten form set twice");
- rewritten_form_ = rewritten_form;
- }
- // Get the rewritten form of this statement.
- auto rewritten_form() const -> std::optional<Nonnull<const Expression*>> {
- return rewritten_form_;
- }
- private:
- Nonnull<Expression*> argument_;
- bool is_increment_;
- std::optional<Nonnull<const Expression*>> rewritten_form_;
- };
- class VariableDefinition : public Statement {
- public:
- enum DefinitionType {
- Var,
- Returned,
- };
- VariableDefinition(SourceLocation source_loc, Nonnull<Pattern*> pattern,
- std::optional<Nonnull<Expression*>> init,
- ExpressionCategory expression_category,
- DefinitionType def_type)
- : Statement(AstNodeKind::VariableDefinition, source_loc),
- pattern_(pattern),
- init_(init),
- expression_category_(expression_category),
- def_type_(def_type) {}
- explicit VariableDefinition(CloneContext& context,
- const VariableDefinition& other)
- : Statement(context, other),
- pattern_(context.Clone(other.pattern_)),
- init_(context.Clone(other.init_)),
- expression_category_(other.expression_category_),
- def_type_(other.def_type_) {}
- static auto classof(const AstNode* node) -> bool {
- return InheritsFromVariableDefinition(node->kind());
- }
- auto pattern() const -> const Pattern& { return *pattern_; }
- auto pattern() -> Pattern& { return *pattern_; }
- auto init() const -> const Expression& {
- CARBON_CHECK(has_init());
- return **init_;
- }
- auto init() -> Expression& {
- CARBON_CHECK(has_init());
- return **init_;
- }
- auto has_init() const -> bool { return init_.has_value(); }
- // Can only be called by type-checking, if a conversion was required.
- void set_init(Nonnull<Expression*> init) {
- CARBON_CHECK(has_init(), "should not add a new initializer");
- init_ = init;
- }
- auto expression_category() const -> ExpressionCategory {
- return expression_category_;
- }
- auto is_returned() const -> bool { return def_type_ == Returned; }
- private:
- Nonnull<Pattern*> pattern_;
- std::optional<Nonnull<Expression*>> init_;
- ExpressionCategory expression_category_;
- const DefinitionType def_type_;
- };
- class If : public Statement {
- public:
- If(SourceLocation source_loc, Nonnull<Expression*> condition,
- Nonnull<Block*> then_block, std::optional<Nonnull<Block*>> else_block)
- : Statement(AstNodeKind::If, source_loc),
- condition_(condition),
- then_block_(then_block),
- else_block_(else_block) {}
- explicit If(CloneContext& context, const If& other)
- : Statement(context, other),
- condition_(context.Clone(other.condition_)),
- then_block_(context.Clone(other.then_block_)),
- else_block_(context.Clone(other.else_block_)) {}
- static auto classof(const AstNode* node) -> bool {
- return InheritsFromIf(node->kind());
- }
- auto condition() const -> const Expression& { return *condition_; }
- auto condition() -> Expression& { return *condition_; }
- auto then_block() const -> const Block& { return *then_block_; }
- auto then_block() -> Block& { return *then_block_; }
- auto else_block() const -> std::optional<Nonnull<const Block*>> {
- return else_block_;
- }
- auto else_block() -> std::optional<Nonnull<Block*>> { return else_block_; }
- // Can only be called by type-checking, if a conversion was required.
- void set_condition(Nonnull<Expression*> condition) { condition_ = condition; }
- private:
- Nonnull<Expression*> condition_;
- Nonnull<Block*> then_block_;
- std::optional<Nonnull<Block*>> else_block_;
- };
- class Return : public Statement {
- public:
- static auto classof(const AstNode* node) -> bool {
- return InheritsFromReturn(node->kind());
- }
- // The AST node representing the function body this statement returns from.
- // Can only be called after ResolveControlFlow has visited this node.
- //
- // Note that this function does not represent an edge in the tree
- // structure of the AST: the return value is not a child of this node,
- // but an ancestor.
- auto function() const -> const CallableDeclaration& { return **function_; }
- auto function() -> CallableDeclaration& { return **function_; }
- // Can only be called once, by ResolveControlFlow.
- void set_function(Nonnull<CallableDeclaration*> function) {
- CARBON_CHECK(!function_.has_value());
- function_ = function;
- }
- protected:
- Return(AstNodeKind node_kind, SourceLocation source_loc)
- : Statement(node_kind, source_loc) {}
- explicit Return(CloneContext& context, const Return& other);
- private:
- std::optional<Nonnull<CallableDeclaration*>> function_;
- };
- class ReturnVar : public Return {
- public:
- explicit ReturnVar(SourceLocation source_loc)
- : Return(AstNodeKind::ReturnVar, source_loc) {}
- explicit ReturnVar(CloneContext& context, const ReturnVar& other)
- : Return(context, other), value_node_(context.Clone(other.value_node_)) {}
- static auto classof(const AstNode* node) -> bool {
- return InheritsFromReturnVar(node->kind());
- }
- // Returns the value node of the BindingPattern of the returned var
- // definition. Cannot be called before name resolution.
- auto value_node() const -> const ValueNodeView& { return *value_node_; }
- // Can only be called once, by ResolveNames.
- void set_value_node(ValueNodeView value_node) {
- CARBON_CHECK(!value_node_.has_value());
- value_node_ = value_node;
- }
- private:
- // The value node of the BindingPattern of the returned var definition.
- std::optional<ValueNodeView> value_node_;
- };
- class ReturnExpression : public Return {
- public:
- ReturnExpression(Nonnull<Arena*> arena, SourceLocation source_loc)
- : ReturnExpression(source_loc, arena->New<TupleLiteral>(source_loc),
- true) {}
- ReturnExpression(SourceLocation source_loc, Nonnull<Expression*> expression,
- bool is_omitted_expression)
- : Return(AstNodeKind::ReturnExpression, source_loc),
- expression_(expression),
- is_omitted_expression_(is_omitted_expression) {}
- explicit ReturnExpression(CloneContext& context,
- const ReturnExpression& other)
- : Return(context, other),
- expression_(context.Clone(other.expression_)),
- is_omitted_expression_(other.is_omitted_expression_) {}
- static auto classof(const AstNode* node) -> bool {
- return InheritsFromReturnExpression(node->kind());
- }
- auto expression() const -> const Expression& { return *expression_; }
- auto expression() -> Expression& { return *expression_; }
- auto is_omitted_expression() const -> bool { return is_omitted_expression_; }
- // Can only be called by type-checking, if a conversion was required.
- void set_expression(Nonnull<Expression*> expression) {
- expression_ = expression;
- }
- private:
- Nonnull<Expression*> expression_;
- bool is_omitted_expression_;
- };
- class While : public Statement {
- public:
- While(SourceLocation source_loc, Nonnull<Expression*> condition,
- Nonnull<Block*> body)
- : Statement(AstNodeKind::While, source_loc),
- condition_(condition),
- body_(body) {}
- explicit While(CloneContext& context, const While& other)
- : Statement(context, other),
- condition_(context.Clone(other.condition_)),
- body_(context.Clone(other.body_)) {}
- static auto classof(const AstNode* node) -> bool {
- return InheritsFromWhile(node->kind());
- }
- auto condition() const -> const Expression& { return *condition_; }
- auto condition() -> Expression& { return *condition_; }
- auto body() const -> const Block& { return *body_; }
- auto body() -> Block& { return *body_; }
- // Can only be called by type-checking, if a conversion was required.
- void set_condition(Nonnull<Expression*> condition) { condition_ = condition; }
- private:
- Nonnull<Expression*> condition_;
- Nonnull<Block*> body_;
- };
- class For : public Statement {
- public:
- For(SourceLocation source_loc, Nonnull<BindingPattern*> variable_declaration,
- Nonnull<Expression*> loop_target, Nonnull<Block*> body)
- : Statement(AstNodeKind::For, source_loc),
- variable_declaration_(variable_declaration),
- loop_target_(loop_target),
- body_(body) {}
- explicit For(CloneContext& context, const For& other)
- : Statement(context, other),
- variable_declaration_(context.Clone(other.variable_declaration_)),
- loop_target_(context.Clone(other.loop_target_)),
- body_(context.Clone(other.body_)) {}
- static auto classof(const AstNode* node) -> bool {
- return InheritsFromFor(node->kind());
- }
- auto variable_declaration() const -> const BindingPattern& {
- return *variable_declaration_;
- }
- auto variable_declaration() -> BindingPattern& {
- return *variable_declaration_;
- }
- auto loop_target() const -> const Expression& { return *loop_target_; }
- auto loop_target() -> Expression& { return *loop_target_; }
- auto body() const -> const Block& { return *body_; }
- auto body() -> Block& { return *body_; }
- private:
- Nonnull<BindingPattern*> variable_declaration_;
- Nonnull<Expression*> loop_target_;
- Nonnull<Block*> body_;
- };
- class Break : public Statement {
- public:
- explicit Break(SourceLocation source_loc)
- : Statement(AstNodeKind::Break, source_loc) {}
- explicit Break(CloneContext& context, const Break& other)
- : Statement(context, other), loop_(context.Clone(other.loop_)) {}
- static auto classof(const AstNode* node) -> bool {
- return InheritsFromBreak(node->kind());
- }
- // The AST node representing the loop this statement breaks out of.
- // Can only be called after ResolveControlFlow has visited this node.
- //
- // Note that this function does not represent an edge in the tree
- // structure of the AST: the return value is not a child of this node,
- // but an ancestor.
- auto loop() const -> const Statement& { return **loop_; }
- // Can only be called once, by ResolveControlFlow.
- void set_loop(Nonnull<const Statement*> loop) {
- CARBON_CHECK(!loop_.has_value());
- loop_ = loop;
- }
- private:
- std::optional<Nonnull<const Statement*>> loop_;
- };
- class Continue : public Statement {
- public:
- explicit Continue(SourceLocation source_loc)
- : Statement(AstNodeKind::Continue, source_loc) {}
- explicit Continue(CloneContext& context, const Continue& other)
- : Statement(context, other), loop_(context.Clone(other.loop_)) {}
- static auto classof(const AstNode* node) -> bool {
- return InheritsFromContinue(node->kind());
- }
- // The AST node representing the loop this statement continues.
- // Can only be called after ResolveControlFlow has visited this node.
- //
- // Note that this function does not represent an edge in the tree
- // structure of the AST: the return value is not a child of this node,
- // but an ancestor.
- auto loop() const -> const Statement& { return **loop_; }
- // Can only be called once, by ResolveControlFlow.
- void set_loop(Nonnull<const Statement*> loop) {
- CARBON_CHECK(!loop_.has_value());
- loop_ = loop;
- }
- private:
- std::optional<Nonnull<const Statement*>> loop_;
- };
- class Match : public Statement {
- public:
- class Clause {
- public:
- explicit Clause(Nonnull<Pattern*> pattern, Nonnull<Statement*> statement)
- : pattern_(pattern), statement_(statement) {}
- explicit Clause(CloneContext& context, const Clause& other)
- : pattern_(context.Clone(other.pattern_)),
- statement_(context.Clone(other.statement_)) {}
- auto pattern() const -> const Pattern& { return *pattern_; }
- auto pattern() -> Pattern& { return *pattern_; }
- auto statement() const -> const Statement& { return *statement_; }
- auto statement() -> Statement& { return *statement_; }
- private:
- Nonnull<Pattern*> pattern_;
- Nonnull<Statement*> statement_;
- };
- Match(SourceLocation source_loc, Nonnull<Expression*> expression,
- std::vector<Clause> clauses)
- : Statement(AstNodeKind::Match, source_loc),
- expression_(expression),
- clauses_(std::move(clauses)) {}
- explicit Match(CloneContext& context, const Match& other)
- : Statement(context, other),
- expression_(context.Clone(other.expression_)),
- clauses_(context.Clone(other.clauses_)) {}
- static auto classof(const AstNode* node) -> bool {
- return InheritsFromMatch(node->kind());
- }
- auto expression() const -> const Expression& { return *expression_; }
- auto expression() -> Expression& { return *expression_; }
- auto clauses() const -> llvm::ArrayRef<Clause> { return clauses_; }
- auto clauses() -> llvm::MutableArrayRef<Clause> { return clauses_; }
- // Can only be called by type-checking, if a conversion was required.
- void set_expression(Nonnull<Expression*> expression) {
- expression_ = expression;
- }
- private:
- Nonnull<Expression*> expression_;
- std::vector<Clause> clauses_;
- };
- } // namespace Carbon
- #endif // CARBON_EXPLORER_AST_STATEMENT_H_
|