diff --git a/executable_semantics/ast/ast.h b/executable_semantics/ast/ast.h index ab599b2eb43f..7d761e046368 100644 --- a/executable_semantics/ast/ast.h +++ b/executable_semantics/ast/ast.h @@ -22,7 +22,7 @@ struct AST { // Import directives. std::vector imports; // The file's ordered declarations. - std::vector> declarations; + std::vector> declarations; }; } // namespace Carbon diff --git a/executable_semantics/ast/declaration.h b/executable_semantics/ast/declaration.h index 9290b708ba9f..2c3a0d7451e7 100644 --- a/executable_semantics/ast/declaration.h +++ b/executable_semantics/ast/declaration.h @@ -15,6 +15,7 @@ #include "executable_semantics/ast/pattern.h" #include "executable_semantics/ast/source_location.h" #include "executable_semantics/common/nonnull.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/Support/Compiler.h" namespace Carbon { @@ -60,7 +61,7 @@ class Declaration { class FunctionDeclaration : public Declaration { public: - FunctionDeclaration(Nonnull definition) + FunctionDeclaration(Nonnull definition) : Declaration(Kind::FunctionDeclaration, definition->source_loc()), definition(definition) {} @@ -69,9 +70,10 @@ class FunctionDeclaration : public Declaration { } auto Definition() const -> const FunctionDefinition& { return *definition; } + auto Definition() -> FunctionDefinition& { return *definition; } private: - Nonnull definition; + Nonnull definition; }; class ClassDeclaration : public Declaration { @@ -88,6 +90,7 @@ class ClassDeclaration : public Declaration { } auto Definition() const -> const ClassDefinition& { return definition; } + auto Definition() -> ClassDefinition& { return definition; } private: ClassDefinition definition; @@ -97,7 +100,7 @@ class ChoiceDeclaration : public Declaration { public: class Alternative { public: - Alternative(std::string name, Nonnull signature) + Alternative(std::string name, Nonnull signature) : name_(name), signature_(signature) {} auto name() const -> const std::string& { return name_; } @@ -105,7 +108,7 @@ class ChoiceDeclaration : public Declaration { private: std::string name_; - Nonnull signature_; + Nonnull signature_; }; ChoiceDeclaration(SourceLocation loc, std::string name, @@ -131,9 +134,8 @@ class ChoiceDeclaration : public Declaration { // Global variable definition implements the Declaration concept. class VariableDeclaration : public Declaration { public: - VariableDeclaration(SourceLocation loc, - Nonnull binding, - Nonnull initializer) + VariableDeclaration(SourceLocation loc, Nonnull binding, + Nonnull initializer) : Declaration(Kind::VariableDeclaration, loc), binding(binding), initializer(initializer) {} @@ -143,14 +145,16 @@ class VariableDeclaration : public Declaration { } auto Binding() const -> Nonnull { return binding; } + auto Binding() -> Nonnull { return binding; } auto Initializer() const -> Nonnull { return initializer; } + auto Initializer() -> Nonnull { return initializer; } private: // TODO: split this into a non-optional name and a type, initialized by // a constructor that takes a BindingPattern and handles errors like a // missing name. - Nonnull binding; - Nonnull initializer; + Nonnull binding; + Nonnull initializer; }; } // namespace Carbon diff --git a/executable_semantics/ast/expression.cpp b/executable_semantics/ast/expression.cpp index 39490d9d4a48..2d2d57837d18 100644 --- a/executable_semantics/ast/expression.cpp +++ b/executable_semantics/ast/expression.cpp @@ -18,10 +18,8 @@ using llvm::cast; auto ExpressionFromParenContents( Nonnull arena, SourceLocation loc, - const ParenContents& paren_contents) - -> Nonnull { - std::optional> single_term = - paren_contents.SingleTerm(); + const ParenContents& paren_contents) -> Nonnull { + std::optional> single_term = paren_contents.SingleTerm(); if (single_term.has_value()) { return *single_term; } else { @@ -31,8 +29,7 @@ auto ExpressionFromParenContents( auto TupleExpressionFromParenContents( Nonnull arena, SourceLocation loc, - const ParenContents& paren_contents) - -> Nonnull { + const ParenContents& paren_contents) -> Nonnull { return arena->New( loc, paren_contents.TupleElements(loc)); } diff --git a/executable_semantics/ast/expression.h b/executable_semantics/ast/expression.h index 76582d2418f5..701c18b94745 100644 --- a/executable_semantics/ast/expression.h +++ b/executable_semantics/ast/expression.h @@ -14,6 +14,7 @@ #include "executable_semantics/ast/paren_contents.h" #include "executable_semantics/ast/source_location.h" #include "executable_semantics/common/arena.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/Support/Compiler.h" namespace Carbon { @@ -64,26 +65,24 @@ class Expression { // tuple otherwise. auto ExpressionFromParenContents( Nonnull arena, SourceLocation loc, - const ParenContents& paren_contents) - -> Nonnull; + const ParenContents& paren_contents) -> Nonnull; // Converts paren_contents to an Expression, interpreting the parentheses as // forming a tuple. auto TupleExpressionFromParenContents( Nonnull arena, SourceLocation loc, - const ParenContents& paren_contents) - -> Nonnull; + const ParenContents& paren_contents) -> Nonnull; // A FieldInitializer represents the initialization of a single tuple field. struct FieldInitializer { - FieldInitializer(std::string name, Nonnull expression) + FieldInitializer(std::string name, Nonnull expression) : name(std::move(name)), expression(expression) {} // The field name. Cannot be empty. std::string name; // The expression that initializes the field. - Nonnull expression; + Nonnull expression; }; enum class Operator { @@ -117,7 +116,7 @@ class IdentifierExpression : public Expression { class FieldAccessExpression : public Expression { public: explicit FieldAccessExpression(SourceLocation loc, - Nonnull aggregate, + Nonnull aggregate, std::string field) : Expression(Kind::FieldAccessExpression, loc), aggregate(aggregate), @@ -128,18 +127,18 @@ class FieldAccessExpression : public Expression { } auto Aggregate() const -> Nonnull { return aggregate; } + auto Aggregate() -> Nonnull { return aggregate; } auto Field() const -> const std::string& { return field; } private: - Nonnull aggregate; + Nonnull aggregate; std::string field; }; class IndexExpression : public Expression { public: - explicit IndexExpression(SourceLocation loc, - Nonnull aggregate, - Nonnull offset) + explicit IndexExpression(SourceLocation loc, Nonnull aggregate, + Nonnull offset) : Expression(Kind::IndexExpression, loc), aggregate(aggregate), offset(offset) {} @@ -149,11 +148,13 @@ class IndexExpression : public Expression { } auto Aggregate() const -> Nonnull { return aggregate; } + auto Aggregate() -> Nonnull { return aggregate; } auto Offset() const -> Nonnull { return offset; } + auto Offset() -> Nonnull { return offset; } private: - Nonnull aggregate; - Nonnull offset; + Nonnull aggregate; + Nonnull offset; }; class IntLiteral : public Expression { @@ -233,7 +234,7 @@ class PrimitiveOperatorExpression : public Expression { public: explicit PrimitiveOperatorExpression( SourceLocation loc, Operator op, - std::vector> arguments) + std::vector> arguments) : Expression(Kind::PrimitiveOperatorExpression, loc), op(op), arguments(std::move(arguments)) {} @@ -243,20 +244,22 @@ class PrimitiveOperatorExpression : public Expression { } auto Op() const -> Operator { return op; } - auto Arguments() const -> const std::vector>& { + auto Arguments() const -> llvm::ArrayRef> { + return arguments; + } + auto Arguments() -> llvm::MutableArrayRef> { return arguments; } private: Operator op; - std::vector> arguments; + std::vector> arguments; }; class CallExpression : public Expression { public: - explicit CallExpression(SourceLocation loc, - Nonnull function, - Nonnull argument) + explicit CallExpression(SourceLocation loc, Nonnull function, + Nonnull argument) : Expression(Kind::CallExpression, loc), function(function), argument(argument) {} @@ -266,18 +269,20 @@ class CallExpression : public Expression { } auto Function() const -> Nonnull { return function; } + auto Function() -> Nonnull { return function; } auto Argument() const -> Nonnull { return argument; } + auto Argument() -> Nonnull { return argument; } private: - Nonnull function; - Nonnull argument; + Nonnull function; + Nonnull argument; }; class FunctionTypeLiteral : public Expression { public: explicit FunctionTypeLiteral(SourceLocation loc, - Nonnull parameter, - Nonnull return_type, + Nonnull parameter, + Nonnull return_type, bool is_omitted_return_type) : Expression(Kind::FunctionTypeLiteral, loc), parameter(parameter), @@ -289,12 +294,14 @@ class FunctionTypeLiteral : public Expression { } auto Parameter() const -> Nonnull { return parameter; } + auto Parameter() -> Nonnull { return parameter; } auto ReturnType() const -> Nonnull { return return_type; } + auto ReturnType() -> Nonnull { return return_type; } auto IsOmittedReturnType() const -> bool { return is_omitted_return_type; } private: - Nonnull parameter; - Nonnull return_type; + Nonnull parameter; + Nonnull return_type; bool is_omitted_return_type; }; diff --git a/executable_semantics/ast/function_definition.h b/executable_semantics/ast/function_definition.h index 00de202e27ff..cd57588c16ec 100644 --- a/executable_semantics/ast/function_definition.h +++ b/executable_semantics/ast/function_definition.h @@ -26,13 +26,12 @@ class FunctionDefinition { public: FunctionDefinition(SourceLocation source_loc, std::string name, std::vector deduced_params, - Nonnull param_pattern, - Nonnull return_type, - bool is_omitted_return_type, - std::optional> body) + Nonnull param_pattern, + Nonnull return_type, bool is_omitted_return_type, + std::optional> body) : source_loc_(source_loc), name_(std::move(name)), - deduced_parameters_(deduced_params), + deduced_parameters_(std::move(deduced_params)), param_pattern_(param_pattern), return_type_(return_type), is_omitted_return_type_(is_omitted_return_type), @@ -48,6 +47,7 @@ class FunctionDefinition { return deduced_parameters_; } auto param_pattern() const -> const TuplePattern& { return *param_pattern_; } + auto param_pattern() -> TuplePattern& { return *param_pattern_; } auto return_type() const -> const Pattern& { return *return_type_; } auto is_omitted_return_type() const -> bool { return is_omitted_return_type_; @@ -55,15 +55,16 @@ class FunctionDefinition { auto body() const -> std::optional> { return body_; } + auto body() -> std::optional> { return body_; } private: SourceLocation source_loc_; std::string name_; std::vector deduced_parameters_; - Nonnull param_pattern_; - Nonnull return_type_; + Nonnull param_pattern_; + Nonnull return_type_; bool is_omitted_return_type_; - std::optional> body_; + std::optional> body_; }; } // namespace Carbon diff --git a/executable_semantics/ast/paren_contents.h b/executable_semantics/ast/paren_contents.h index df2888cd1bb2..2a5e64eef4a0 100644 --- a/executable_semantics/ast/paren_contents.h +++ b/executable_semantics/ast/paren_contents.h @@ -28,16 +28,16 @@ template struct ParenContents { struct Element { std::optional name; - Nonnull term; + Nonnull term; }; // If this object represents a single term, with no name and no trailing // comma, this method returns that term. This typically means the parentheses // can be interpreted as grouping. - auto SingleTerm() const -> std::optional>; + auto SingleTerm() const -> std::optional>; // Converts `elements` to std::vector. TupleElement must - // have a constructor that takes a std::string and a Nonnull. + // have a constructor that takes a std::string and a Nonnull. // // TODO: Find a way to deduce TupleElement from Term. template @@ -50,8 +50,7 @@ struct ParenContents { // Implementation details only below here. template -auto ParenContents::SingleTerm() const - -> std::optional> { +auto ParenContents::SingleTerm() const -> std::optional> { if (elements.size() == 1 && !elements.front().name.has_value() && !has_trailing_comma) { return elements.front().term; diff --git a/executable_semantics/ast/pattern.cpp b/executable_semantics/ast/pattern.cpp index 2f6a5b7a547c..455915ffc803 100644 --- a/executable_semantics/ast/pattern.cpp +++ b/executable_semantics/ast/pattern.cpp @@ -55,7 +55,7 @@ void Pattern::Print(llvm::raw_ostream& out) const { } TuplePattern::TuplePattern(Nonnull arena, - Nonnull tuple_literal) + Nonnull tuple_literal) : Pattern(Kind::TuplePattern, tuple_literal->SourceLoc()) { const auto& tuple = cast(*tuple_literal); for (const FieldInitializer& init : tuple.Fields()) { @@ -66,9 +66,8 @@ TuplePattern::TuplePattern(Nonnull arena, auto PatternFromParenContents(Nonnull arena, SourceLocation loc, const ParenContents& paren_contents) - -> Nonnull { - std::optional> single_term = - paren_contents.SingleTerm(); + -> Nonnull { + std::optional> single_term = paren_contents.SingleTerm(); if (single_term.has_value()) { return *single_term; } else { @@ -78,7 +77,7 @@ auto PatternFromParenContents(Nonnull arena, SourceLocation loc, auto TuplePatternFromParenContents(Nonnull arena, SourceLocation loc, const ParenContents& paren_contents) - -> Nonnull { + -> Nonnull { return arena->New( loc, paren_contents.TupleElements(loc)); } @@ -86,8 +85,8 @@ auto TuplePatternFromParenContents(Nonnull arena, SourceLocation loc, // Used by AlternativePattern for constructor initialization. Produces a helpful // error for incorrect expressions, rather than letting a default cast error // apply. -static const FieldAccessExpression& RequireFieldAccess( - Nonnull alternative) { +static auto RequireFieldAccess(Nonnull alternative) + -> FieldAccessExpression& { if (alternative->Tag() != Expression::Kind::FieldAccessExpression) { FATAL_PROGRAM_ERROR(alternative->SourceLoc()) << "Alternative pattern must have the form of a field access."; @@ -96,8 +95,8 @@ static const FieldAccessExpression& RequireFieldAccess( } AlternativePattern::AlternativePattern(SourceLocation loc, - Nonnull alternative, - Nonnull arguments) + Nonnull alternative, + Nonnull arguments) : Pattern(Kind::AlternativePattern, loc), choice_type(RequireFieldAccess(alternative).Aggregate()), alternative_name(RequireFieldAccess(alternative).Field()), diff --git a/executable_semantics/ast/pattern.h b/executable_semantics/ast/pattern.h index f895ef00244d..1bb702890d96 100644 --- a/executable_semantics/ast/pattern.h +++ b/executable_semantics/ast/pattern.h @@ -12,6 +12,7 @@ #include "common/ostream.h" #include "executable_semantics/ast/expression.h" #include "executable_semantics/ast/source_location.h" +#include "llvm/ADT/ArrayRef.h" namespace Carbon { @@ -71,7 +72,7 @@ class AutoPattern : public Pattern { class BindingPattern : public Pattern { public: BindingPattern(SourceLocation loc, std::optional name, - Nonnull type) + Nonnull type) : Pattern(Kind::BindingPattern, loc), name(std::move(name)), type(type) {} static auto classof(const Pattern* pattern) -> bool { @@ -83,10 +84,11 @@ class BindingPattern : public Pattern { // The pattern specifying the type of values that this pattern matches. auto Type() const -> Nonnull { return type; } + auto Type() -> Nonnull { return type; } private: std::optional name; - Nonnull type; + Nonnull type; }; // A pattern that matches a tuple value field-wise. @@ -94,14 +96,14 @@ class TuplePattern : public Pattern { public: // Represents a portion of a tuple pattern corresponding to a single field. struct Field { - Field(std::string name, Nonnull pattern) + Field(std::string name, Nonnull pattern) : name(std::move(name)), pattern(pattern) {} // The field name. Cannot be empty std::string name; // The pattern the field must match. - Nonnull pattern; + Nonnull pattern; }; TuplePattern(SourceLocation loc, std::vector fields) @@ -111,13 +113,14 @@ class TuplePattern : public Pattern { // ExpressionPattern. // // REQUIRES: tuple_literal->Tag() == Expression::Kind::TupleLiteral - TuplePattern(Nonnull arena, Nonnull tuple_literal); + TuplePattern(Nonnull arena, Nonnull tuple_literal); static auto classof(const Pattern* pattern) -> bool { return pattern->Tag() == Kind::TuplePattern; } - auto Fields() const -> const std::vector& { return fields; } + auto Fields() const -> llvm::ArrayRef { return fields; } + auto Fields() -> llvm::MutableArrayRef { return fields; } private: std::vector fields; @@ -128,13 +131,13 @@ class TuplePattern : public Pattern { // tuple otherwise. auto PatternFromParenContents(Nonnull arena, SourceLocation loc, const ParenContents& paren_contents) - -> Nonnull; + -> Nonnull; // Converts paren_contents to a TuplePattern, interpreting the parentheses as // forming a tuple. auto TuplePatternFromParenContents(Nonnull arena, SourceLocation loc, const ParenContents& paren_contents) - -> Nonnull; + -> Nonnull; // Converts `contents` to ParenContents by replacing each Expression // with an ExpressionPattern. @@ -148,9 +151,9 @@ class AlternativePattern : public Pattern { // Constructs an AlternativePattern that matches a value of the type // specified by choice_type if it represents an alternative named // alternative_name, and its arguments match `arguments`. - AlternativePattern(SourceLocation loc, Nonnull choice_type, + AlternativePattern(SourceLocation loc, Nonnull choice_type, std::string alternative_name, - Nonnull arguments) + Nonnull arguments) : Pattern(Kind::AlternativePattern, loc), choice_type(choice_type), alternative_name(std::move(alternative_name)), @@ -158,30 +161,32 @@ class AlternativePattern : public Pattern { // Constructs an AlternativePattern that matches the alternative specified // by `alternative`, if its arguments match `arguments`. - AlternativePattern(SourceLocation loc, Nonnull alternative, - Nonnull arguments); + AlternativePattern(SourceLocation loc, Nonnull alternative, + Nonnull arguments); static auto classof(const Pattern* pattern) -> bool { return pattern->Tag() == Kind::AlternativePattern; } auto ChoiceType() const -> Nonnull { return choice_type; } + auto ChoiceType() -> Nonnull { return choice_type; } auto AlternativeName() const -> const std::string& { return alternative_name; } auto Arguments() const -> Nonnull { return arguments; } + auto Arguments() -> Nonnull { return arguments; } private: - Nonnull choice_type; + Nonnull choice_type; std::string alternative_name; - Nonnull arguments; + Nonnull arguments; }; // A pattern that matches a value if it is equal to the value of a given // expression. class ExpressionPattern : public Pattern { public: - ExpressionPattern(Nonnull expression) + ExpressionPattern(Nonnull expression) : Pattern(Kind::ExpressionPattern, expression->SourceLoc()), expression(expression) {} @@ -190,9 +195,10 @@ class ExpressionPattern : public Pattern { } auto Expression() const -> Nonnull { return expression; } + auto Expression() -> Nonnull { return expression; } private: - Nonnull expression; + Nonnull expression; }; } // namespace Carbon diff --git a/executable_semantics/ast/statement.h b/executable_semantics/ast/statement.h index af5980432255..2544d7a3ce2f 100644 --- a/executable_semantics/ast/statement.h +++ b/executable_semantics/ast/statement.h @@ -12,6 +12,7 @@ #include "executable_semantics/ast/pattern.h" #include "executable_semantics/ast/source_location.h" #include "executable_semantics/common/arena.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/Support/Compiler.h" namespace Carbon { @@ -58,7 +59,7 @@ class Statement { class ExpressionStatement : public Statement { public: - ExpressionStatement(SourceLocation loc, Nonnull exp) + ExpressionStatement(SourceLocation loc, Nonnull exp) : Statement(Kind::ExpressionStatement, loc), exp(exp) {} static auto classof(const Statement* stmt) -> bool { @@ -66,15 +67,15 @@ class ExpressionStatement : public Statement { } auto Exp() const -> Nonnull { return exp; } + auto Exp() -> Nonnull { return exp; } private: - Nonnull exp; + Nonnull exp; }; class Assign : public Statement { public: - Assign(SourceLocation loc, Nonnull lhs, - Nonnull rhs) + Assign(SourceLocation loc, Nonnull lhs, Nonnull rhs) : Statement(Kind::Assign, loc), lhs(lhs), rhs(rhs) {} static auto classof(const Statement* stmt) -> bool { @@ -82,17 +83,19 @@ class Assign : public Statement { } auto Lhs() const -> Nonnull { return lhs; } + auto Lhs() -> Nonnull { return lhs; } auto Rhs() const -> Nonnull { return rhs; } + auto Rhs() -> Nonnull { return rhs; } private: - Nonnull lhs; - Nonnull rhs; + Nonnull lhs; + Nonnull rhs; }; class VariableDefinition : public Statement { public: - VariableDefinition(SourceLocation loc, Nonnull pat, - Nonnull init) + VariableDefinition(SourceLocation loc, Nonnull pat, + Nonnull init) : Statement(Kind::VariableDefinition, loc), pat(pat), init(init) {} static auto classof(const Statement* stmt) -> bool { @@ -100,18 +103,20 @@ class VariableDefinition : public Statement { } auto Pat() const -> Nonnull { return pat; } + auto Pat() -> Nonnull { return pat; } auto Init() const -> Nonnull { return init; } + auto Init() -> Nonnull { return init; } private: - Nonnull pat; - Nonnull init; + Nonnull pat; + Nonnull init; }; class If : public Statement { public: - If(SourceLocation loc, Nonnull cond, - Nonnull then_stmt, - std::optional> else_stmt) + If(SourceLocation loc, Nonnull cond, + Nonnull then_stmt, + std::optional> else_stmt) : Statement(Kind::If, loc), cond(cond), then_stmt(then_stmt), @@ -122,23 +127,25 @@ class If : public Statement { } auto Cond() const -> Nonnull { return cond; } + auto Cond() -> Nonnull { return cond; } auto ThenStmt() const -> Nonnull { return then_stmt; } + auto ThenStmt() -> Nonnull { return then_stmt; } auto ElseStmt() const -> std::optional> { return else_stmt; } + auto ElseStmt() -> std::optional> { return else_stmt; } private: - Nonnull cond; - Nonnull then_stmt; - std::optional> else_stmt; + Nonnull cond; + Nonnull then_stmt; + std::optional> else_stmt; }; class Return : public Statement { public: Return(Nonnull arena, SourceLocation loc) : Return(loc, arena->New(loc), true) {} - Return(SourceLocation loc, Nonnull exp, - bool is_omitted_exp) + Return(SourceLocation loc, Nonnull exp, bool is_omitted_exp) : Statement(Kind::Return, loc), exp(exp), is_omitted_exp(is_omitted_exp) {} @@ -148,17 +155,18 @@ class Return : public Statement { } auto Exp() const -> Nonnull { return exp; } + auto Exp() -> Nonnull { return exp; } auto IsOmittedExp() const -> bool { return is_omitted_exp; } private: - Nonnull exp; + Nonnull exp; bool is_omitted_exp; }; class Sequence : public Statement { public: - Sequence(SourceLocation loc, Nonnull stmt, - std::optional> next) + Sequence(SourceLocation loc, Nonnull stmt, + std::optional> next) : Statement(Kind::Sequence, loc), stmt(stmt), next(next) {} static auto classof(const Statement* stmt) -> bool { @@ -166,16 +174,18 @@ class Sequence : public Statement { } auto Stmt() const -> Nonnull { return stmt; } + auto Stmt() -> Nonnull { return stmt; } auto Next() const -> std::optional> { return next; } + auto Next() -> std::optional> { return next; } private: - Nonnull stmt; - std::optional> next; + Nonnull stmt; + std::optional> next; }; class Block : public Statement { public: - Block(SourceLocation loc, std::optional> stmt) + Block(SourceLocation loc, std::optional> stmt) : Statement(Kind::Block, loc), stmt(stmt) {} static auto classof(const Statement* stmt) -> bool { @@ -183,15 +193,15 @@ class Block : public Statement { } auto Stmt() const -> std::optional> { return stmt; } + auto Stmt() -> std::optional> { return stmt; } private: - std::optional> stmt; + std::optional> stmt; }; class While : public Statement { public: - While(SourceLocation loc, Nonnull cond, - Nonnull body) + While(SourceLocation loc, Nonnull cond, Nonnull body) : Statement(Kind::While, loc), cond(cond), body(body) {} static auto classof(const Statement* stmt) -> bool { @@ -199,11 +209,13 @@ class While : public Statement { } auto Cond() const -> Nonnull { return cond; } + auto Cond() -> Nonnull { return cond; } auto Body() const -> Nonnull { return body; } + auto Body() -> Nonnull { return body; } private: - Nonnull cond; - Nonnull body; + Nonnull cond; + Nonnull body; }; class Break : public Statement { @@ -226,10 +238,8 @@ class Continue : public Statement { class Match : public Statement { public: - Match( - SourceLocation loc, Nonnull exp, - std::vector, Nonnull>> - clauses) + Match(SourceLocation loc, Nonnull exp, + std::vector, Nonnull>> clauses) : Statement(Kind::Match, loc), exp(exp), clauses(std::move(clauses)) {} static auto classof(const Statement* stmt) -> bool { @@ -237,15 +247,15 @@ class Match : public Statement { } auto Exp() const -> Nonnull { return exp; } - auto Clauses() const -> const std::vector< - std::pair, Nonnull>>& { + auto Exp() -> Nonnull { return exp; } + auto Clauses() const + -> llvm::ArrayRef, Nonnull>> { return clauses; } private: - Nonnull exp; - std::vector, Nonnull>> - clauses; + Nonnull exp; + std::vector, Nonnull>> clauses; }; // A continuation statement. @@ -256,7 +266,7 @@ class Match : public Statement { class Continuation : public Statement { public: Continuation(SourceLocation loc, std::string continuation_variable, - Nonnull body) + Nonnull body) : Statement(Kind::Continuation, loc), continuation_variable(std::move(continuation_variable)), body(body) {} @@ -269,10 +279,11 @@ class Continuation : public Statement { return continuation_variable; } auto Body() const -> Nonnull { return body; } + auto Body() -> Nonnull { return body; } private: std::string continuation_variable; - Nonnull body; + Nonnull body; }; // A run statement. @@ -280,7 +291,7 @@ class Continuation : public Statement { // __run ; class Run : public Statement { public: - Run(SourceLocation loc, Nonnull argument) + Run(SourceLocation loc, Nonnull argument) : Statement(Kind::Run, loc), argument(argument) {} static auto classof(const Statement* stmt) -> bool { @@ -288,9 +299,10 @@ class Run : public Statement { } auto Argument() const -> Nonnull { return argument; } + auto Argument() -> Nonnull { return argument; } private: - Nonnull argument; + Nonnull argument; }; // An await statement. diff --git a/executable_semantics/interpreter/exec_program.cpp b/executable_semantics/interpreter/exec_program.cpp index 1c03d62fc361..86d8fb9bf166 100644 --- a/executable_semantics/interpreter/exec_program.cpp +++ b/executable_semantics/interpreter/exec_program.cpp @@ -15,9 +15,8 @@ namespace Carbon { // Adds builtins, currently only Print(). Note Print() is experimental, not // standardized, but is made available for printing state in tests. -static void AddIntrinsics( - Nonnull arena, - std::vector>* declarations) { +static void AddIntrinsics(Nonnull arena, + std::vector>* declarations) { SourceLocation loc("", 0); std::vector print_fields = {TuplePattern::Field( "0", @@ -47,7 +46,7 @@ void ExecProgram(Nonnull arena, AST ast) { llvm::outs() << "********** type checking **********\n"; } TypeChecker type_checker(arena); - TypeChecker::TypeCheckContext p = type_checker.TopLevel(ast.declarations); + TypeChecker::TypeCheckContext p = type_checker.TopLevel(&ast.declarations); TypeEnv top = p.types; Env ct_top = p.values; std::vector> new_decls; @@ -62,7 +61,12 @@ void ExecProgram(Nonnull arena, AST ast) { } llvm::outs() << "********** starting execution **********\n"; } - int result = Interpreter(arena).InterpProgram(new_decls); + + SourceLocation loc("", 0); + Nonnull call_main = arena->New( + loc, arena->New(loc, "main"), + arena->New(loc)); + int result = Interpreter(arena).InterpProgram(new_decls, call_main); llvm::outs() << "result: " << result << "\n"; } diff --git a/executable_semantics/interpreter/interpreter.cpp b/executable_semantics/interpreter/interpreter.cpp index 7ffca6716c4d..e12b83394497 100644 --- a/executable_semantics/interpreter/interpreter.cpp +++ b/executable_semantics/interpreter/interpreter.cpp @@ -1133,7 +1133,8 @@ void Interpreter::Step() { } auto Interpreter::InterpProgram( - const std::vector>& fs) -> int { + const std::vector>& fs, + Nonnull call_main) -> int { // Check that the interpreter is in a clean state. CHECK(globals.IsEmpty()); CHECK(stack.IsEmpty()); @@ -1144,11 +1145,6 @@ auto Interpreter::InterpProgram( } InitGlobals(fs); - SourceLocation loc("", 0); - - Nonnull arg = arena->New(loc); - Nonnull call_main = arena->New( - loc, arena->New(loc, "main"), arg); auto todo = Stack>(arena->New(call_main)); auto scopes = Stack>(arena->New(globals)); stack = Stack>(arena->New("top", scopes, todo)); diff --git a/executable_semantics/interpreter/interpreter.h b/executable_semantics/interpreter/interpreter.h index 6735b6d17f6d..a47f84238cf6 100644 --- a/executable_semantics/interpreter/interpreter.h +++ b/executable_semantics/interpreter/interpreter.h @@ -28,7 +28,8 @@ class Interpreter { : arena(arena), globals(arena), heap(arena) {} // Interpret the whole program. - auto InterpProgram(const std::vector>& fs) -> int; + auto InterpProgram(const std::vector>& fs, + Nonnull call_main) -> int; // Interpret an expression at compile-time. auto InterpExp(Env values, Nonnull e) diff --git a/executable_semantics/interpreter/type_checker.cpp b/executable_semantics/interpreter/type_checker.cpp index 82df4448bb05..c4601cf945e2 100644 --- a/executable_semantics/interpreter/type_checker.cpp +++ b/executable_semantics/interpreter/type_checker.cpp @@ -52,7 +52,7 @@ static void ExpectPointerType(SourceLocation loc, const std::string& context, } auto TypeChecker::ReifyType(Nonnull t, SourceLocation loc) - -> Nonnull { + -> Nonnull { switch (t->Tag()) { case Value::Kind::IntType: return arena->New(loc); @@ -83,7 +83,7 @@ auto TypeChecker::ReifyType(Nonnull t, SourceLocation loc) case Value::Kind::PointerType: return arena->New( loc, Operator::Ptr, - std::vector>( + std::vector>( {ReifyType(cast(*t).Type(), loc)})); case Value::Kind::VariableType: return arena->New(loc, @@ -248,7 +248,7 @@ auto TypeChecker::Substitute(TypeEnv dict, Nonnull type) } } -auto TypeChecker::TypeCheckExp(Nonnull e, TypeEnv types, +auto TypeChecker::TypeCheckExp(Nonnull e, TypeEnv types, Env values) -> TCExpression { if (tracing_output) { llvm::outs() << "checking expression " << *e << "\ntypes: "; @@ -259,7 +259,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, TypeEnv types, } switch (e->Tag()) { case Expression::Kind::IndexExpression: { - const auto& index = cast(*e); + auto& index = cast(*e); auto res = TypeCheckExp(index.Aggregate(), types, values); auto t = res.type; switch (t->Tag()) { @@ -298,7 +298,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, TypeEnv types, return TCExpression(tuple_e, tuple_t, new_types); } case Expression::Kind::FieldAccessExpression: { - const auto& access = cast(*e); + auto& access = cast(*e); auto res = TypeCheckExp(access.Aggregate(), types, values); auto t = res.type; switch (t->Tag()) { @@ -307,18 +307,16 @@ auto TypeChecker::TypeCheckExp(Nonnull e, TypeEnv types, // Search for a field for (auto& field : t_class.Fields()) { if (access.Field() == field.first) { - Nonnull new_e = - arena->New(e->SourceLoc(), res.exp, - access.Field()); + Nonnull new_e = arena->New( + e->SourceLoc(), res.exp, access.Field()); return TCExpression(new_e, field.second, res.types); } } // Search for a method for (auto& method : t_class.Methods()) { if (access.Field() == method.first) { - Nonnull new_e = - arena->New(e->SourceLoc(), res.exp, - access.Field()); + Nonnull new_e = arena->New( + e->SourceLoc(), res.exp, access.Field()); return TCExpression(new_e, method.second, res.types); } } @@ -343,9 +341,8 @@ auto TypeChecker::TypeCheckExp(Nonnull e, TypeEnv types, const auto& choice = cast(*t); for (const auto& vt : choice.Alternatives()) { if (access.Field() == vt.first) { - Nonnull new_e = - arena->New(e->SourceLoc(), res.exp, - access.Field()); + Nonnull new_e = arena->New( + e->SourceLoc(), res.exp, access.Field()); auto fun_ty = arena->New( std::vector(), vt.second, t); return TCExpression(new_e, fun_ty, res.types); @@ -377,10 +374,10 @@ auto TypeChecker::TypeCheckExp(Nonnull e, TypeEnv types, return TCExpression(e, arena->New(), types); case Expression::Kind::PrimitiveOperatorExpression: { const auto& op = cast(*e); - std::vector> es; + std::vector> es; std::vector> ts; auto new_types = types; - for (Nonnull argument : op.Arguments()) { + for (Nonnull argument : op.Arguments()) { auto res = TypeCheckExp(argument, types, values); new_types = res.types; es.push_back(res.exp); @@ -435,7 +432,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, TypeEnv types, break; } case Expression::Kind::CallExpression: { - const auto& call = cast(*e); + auto& call = cast(*e); auto fun_res = TypeCheckExp(call.Function(), types, values); switch (fun_res.type->Tag()) { case Value::Kind::FunctionType: { @@ -499,7 +496,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, TypeEnv types, } auto TypeChecker::TypeCheckPattern( - Nonnull p, TypeEnv types, Env values, + Nonnull p, TypeEnv types, Env values, std::optional> expected) -> TCPattern { if (tracing_output) { llvm::outs() << "checking pattern " << *p; @@ -517,7 +514,7 @@ auto TypeChecker::TypeCheckPattern( return {.pattern = p, .type = arena->New(), .types = types}; } case Pattern::Kind::BindingPattern: { - const auto& binding = cast(*p); + auto& binding = cast(*p); TCPattern binding_type_result = TypeCheckPattern(binding.Type(), types, values, std::nullopt); Nonnull type = @@ -543,7 +540,7 @@ auto TypeChecker::TypeCheckPattern( return {.pattern = new_p, .type = type, .types = types}; } case Pattern::Kind::TuplePattern: { - const auto& tuple = cast(*p); + auto& tuple = cast(*p); std::vector new_fields; std::vector field_types; auto new_types = types; @@ -556,7 +553,7 @@ auto TypeChecker::TypeCheckPattern( << "tuples of different length"; } for (size_t i = 0; i < tuple.Fields().size(); ++i) { - const TuplePattern::Field& field = tuple.Fields()[i]; + TuplePattern::Field& field = tuple.Fields()[i]; std::optional> expected_field_type; if (expected) { const TupleElement& expected_element = @@ -580,7 +577,7 @@ auto TypeChecker::TypeCheckPattern( return {.pattern = new_tuple, .type = tuple_t, .types = new_types}; } case Pattern::Kind::AlternativePattern: { - const auto& alternative = cast(*p); + auto& alternative = cast(*p); Nonnull choice_type = interpreter.InterpExp(values, alternative.ChoiceType()); if (choice_type->Tag() != Value::Kind::ChoiceType) { @@ -603,8 +600,8 @@ auto TypeChecker::TypeCheckPattern( values, *parameter_types); // TODO: Think about a cleaner way to cast between Ptr types. // (multiple TODOs) - auto arguments = Nonnull( - cast(arg_results.pattern)); + auto arguments = + Nonnull(cast(arg_results.pattern)); return {.pattern = arena->New( alternative.SourceLoc(), ReifyType(choice_type, alternative.SourceLoc()), @@ -623,26 +620,26 @@ auto TypeChecker::TypeCheckPattern( } auto TypeChecker::TypeCheckCase(Nonnull expected, - Nonnull pat, - Nonnull body, TypeEnv types, - Env values, Nonnull& ret_type, + Nonnull pat, Nonnull body, + TypeEnv types, Env values, + Nonnull& ret_type, bool is_omitted_ret_type) - -> std::pair, Nonnull> { + -> std::pair, Nonnull> { auto pat_res = TypeCheckPattern(pat, types, values, expected); auto res = TypeCheckStmt(body, pat_res.types, values, ret_type, is_omitted_ret_type); return std::make_pair(pat, res.stmt); } -auto TypeChecker::TypeCheckStmt(Nonnull s, TypeEnv types, +auto TypeChecker::TypeCheckStmt(Nonnull s, TypeEnv types, Env values, Nonnull& ret_type, bool is_omitted_ret_type) -> TCStatement { switch (s->Tag()) { case Statement::Kind::Match: { - const auto& match = cast(*s); + auto& match = cast(*s); auto res = TypeCheckExp(match.Exp(), types, values); auto res_type = res.type; - std::vector, Nonnull>> + std::vector, Nonnull>> new_clauses; for (auto& clause : match.Clauses()) { new_clauses.push_back(TypeCheckCase(res_type, clause.first, @@ -653,7 +650,7 @@ auto TypeChecker::TypeCheckStmt(Nonnull s, TypeEnv types, return TCStatement(new_s, types); } case Statement::Kind::While: { - const auto& while_stmt = cast(*s); + auto& while_stmt = cast(*s); auto cnd_res = TypeCheckExp(while_stmt.Cond(), types, values); ExpectType(s->SourceLoc(), "condition of `while`", arena->New(), cnd_res.type); @@ -667,7 +664,7 @@ auto TypeChecker::TypeCheckStmt(Nonnull s, TypeEnv types, case Statement::Kind::Continue: return TCStatement(s, types); case Statement::Kind::Block: { - const auto& block = cast(*s); + auto& block = cast(*s); if (block.Stmt()) { auto stmt_res = TypeCheckStmt(*block.Stmt(), types, values, ret_type, is_omitted_ret_type); @@ -678,7 +675,7 @@ auto TypeChecker::TypeCheckStmt(Nonnull s, TypeEnv types, } } case Statement::Kind::VariableDefinition: { - const auto& var = cast(*s); + auto& var = cast(*s); auto res = TypeCheckExp(var.Init(), types, values); Nonnull rhs_ty = res.type; auto lhs_res = TypeCheckPattern(var.Pat(), types, values, rhs_ty); @@ -687,11 +684,11 @@ auto TypeChecker::TypeCheckStmt(Nonnull s, TypeEnv types, return TCStatement(new_s, lhs_res.types); } case Statement::Kind::Sequence: { - const auto& seq = cast(*s); + auto& seq = cast(*s); auto stmt_res = TypeCheckStmt(seq.Stmt(), types, values, ret_type, is_omitted_ret_type); auto checked_types = stmt_res.types; - std::optional> next_stmt; + std::optional> next_stmt; if (seq.Next()) { auto next_res = TypeCheckStmt(*seq.Next(), checked_types, values, ret_type, is_omitted_ret_type); @@ -703,7 +700,7 @@ auto TypeChecker::TypeCheckStmt(Nonnull s, TypeEnv types, checked_types); } case Statement::Kind::Assign: { - const auto& assign = cast(*s); + auto& assign = cast(*s); auto rhs_res = TypeCheckExp(assign.Rhs(), types, values); auto rhs_t = rhs_res.type; auto lhs_res = TypeCheckExp(assign.Lhs(), types, values); @@ -719,13 +716,13 @@ auto TypeChecker::TypeCheckStmt(Nonnull s, TypeEnv types, return TCStatement(new_s, types); } case Statement::Kind::If: { - const auto& if_stmt = cast(*s); + auto& if_stmt = cast(*s); auto cnd_res = TypeCheckExp(if_stmt.Cond(), types, values); ExpectType(s->SourceLoc(), "condition of `if`", arena->New(), cnd_res.type); auto then_res = TypeCheckStmt(if_stmt.ThenStmt(), types, values, ret_type, is_omitted_ret_type); - std::optional> else_stmt; + std::optional> else_stmt; if (if_stmt.ElseStmt()) { auto else_res = TypeCheckStmt(*if_stmt.ElseStmt(), types, values, ret_type, is_omitted_ret_type); @@ -736,7 +733,7 @@ auto TypeChecker::TypeCheckStmt(Nonnull s, TypeEnv types, return TCStatement(new_s, types); } case Statement::Kind::Return: { - const auto& ret = cast(*s); + auto& ret = cast(*s); auto res = TypeCheckExp(ret.Exp(), types, values); if (ret_type->Tag() == Value::Kind::AutoType) { // The following infers the return type from the first 'return' @@ -756,7 +753,7 @@ auto TypeChecker::TypeCheckStmt(Nonnull s, TypeEnv types, types); } case Statement::Kind::Continuation: { - const auto& cont = cast(*s); + auto& cont = cast(*s); TCStatement body_result = TypeCheckStmt(cont.Body(), types, values, ret_type, is_omitted_ret_type); auto new_continuation = arena->New( @@ -780,8 +777,8 @@ auto TypeChecker::TypeCheckStmt(Nonnull s, TypeEnv types, } auto TypeChecker::CheckOrEnsureReturn( - std::optional> opt_stmt, bool omitted_ret_type, - SourceLocation loc) -> Nonnull { + std::optional> opt_stmt, bool omitted_ret_type, + SourceLocation loc) -> Nonnull { if (!opt_stmt) { if (omitted_ret_type) { return arena->New(arena, loc); @@ -791,11 +788,11 @@ auto TypeChecker::CheckOrEnsureReturn( "type without reaching a return statement"; } } - Nonnull stmt = *opt_stmt; + Nonnull stmt = *opt_stmt; switch (stmt->Tag()) { case Statement::Kind::Match: { - const auto& match = cast(*stmt); - std::vector, Nonnull>> + auto& match = cast(*stmt); + std::vector, Nonnull>> new_clauses; for (const auto& clause : match.Clauses()) { auto s = CheckOrEnsureReturn(clause.second, omitted_ret_type, @@ -810,7 +807,7 @@ auto TypeChecker::CheckOrEnsureReturn( CheckOrEnsureReturn(cast(*stmt).Stmt(), omitted_ret_type, stmt->SourceLoc())); case Statement::Kind::If: { - const auto& if_stmt = cast(*stmt); + auto& if_stmt = cast(*stmt); return arena->New( stmt->SourceLoc(), if_stmt.Cond(), CheckOrEnsureReturn(if_stmt.ThenStmt(), omitted_ret_type, @@ -821,7 +818,7 @@ auto TypeChecker::CheckOrEnsureReturn( case Statement::Kind::Return: return stmt; case Statement::Kind::Sequence: { - const auto& seq = cast(*stmt); + auto& seq = cast(*stmt); if (seq.Next()) { return arena->New( stmt->SourceLoc(), seq.Stmt(), @@ -857,9 +854,8 @@ auto TypeChecker::CheckOrEnsureReturn( // a function. // TODO: Add checking to function definitions to ensure that // all deduced type parameters will be deduced. -auto TypeChecker::TypeCheckFunDef(const FunctionDefinition* f, TypeEnv types, - Env values) - -> Nonnull { +auto TypeChecker::TypeCheckFunDef(FunctionDefinition* f, TypeEnv types, + Env values) -> Nonnull { // Bring the deduced parameters into scope for (const auto& deduced : f->deduced_parameters()) { // auto t = interpreter.InterpExp(values, deduced.type); @@ -877,7 +873,7 @@ auto TypeChecker::TypeCheckFunDef(const FunctionDefinition* f, TypeEnv types, return_type); // TODO: Check that main doesn't have any parameters. } - std::optional> body_stmt; + std::optional> body_stmt; if (f->body()) { auto res = TypeCheckStmt(*f->body(), param_res.types, values, return_type, f->is_omitted_return_type()); @@ -892,7 +888,7 @@ auto TypeChecker::TypeCheckFunDef(const FunctionDefinition* f, TypeEnv types, } auto TypeChecker::TypeOfFunDef(TypeEnv types, Env values, - const FunctionDefinition* fun_def) + FunctionDefinition* fun_def) -> Nonnull { // Bring the deduced parameters into scope for (const auto& deduced : fun_def->deduced_parameters()) { @@ -961,9 +957,8 @@ static auto GetName(const Declaration& d) -> const std::string& { } } -auto TypeChecker::MakeTypeChecked(const Nonnull d, - const TypeEnv& types, const Env& values) - -> Nonnull { +auto TypeChecker::MakeTypeChecked(Nonnull d, const TypeEnv& types, + const Env& values) -> Nonnull { switch (d->Tag()) { case Declaration::Kind::FunctionDeclaration: return arena->New(TypeCheckFunDef( @@ -990,7 +985,7 @@ auto TypeChecker::MakeTypeChecked(const Nonnull d, return d; case Declaration::Kind::VariableDeclaration: { - const auto& var = cast(*d); + auto& var = cast(*d); // Signals a type error if the initializing expression does not have // the declared type of the variable, otherwise returns this // declaration with annotated types. @@ -1012,19 +1007,19 @@ auto TypeChecker::MakeTypeChecked(const Nonnull d, } } -void TypeChecker::TopLevel(const Declaration& d, TypeCheckContext* tops) { - switch (d.Tag()) { +void TypeChecker::TopLevel(Nonnull d, TypeCheckContext* tops) { + switch (d->Tag()) { case Declaration::Kind::FunctionDeclaration: { - const FunctionDefinition& func_def = - cast(d).Definition(); + FunctionDefinition& func_def = cast(*d).Definition(); auto t = TypeOfFunDef(tops->types, tops->values, &func_def); tops->types.Set(func_def.name(), t); - interpreter.InitEnv(d, &tops->values); + interpreter.InitEnv(*d, &tops->values); break; } case Declaration::Kind::ClassDeclaration: { - const ClassDefinition& class_def = cast(d).Definition(); + const ClassDefinition& class_def = + cast(*d).Definition(); auto st = TypeOfClassDef(&class_def, tops->types, tops->values); Address a = interpreter.AllocateValue(st); tops->values.Set(class_def.name, a); // Is this obsolete? @@ -1041,7 +1036,7 @@ void TypeChecker::TopLevel(const Declaration& d, TypeCheckContext* tops) { } case Declaration::Kind::ChoiceDeclaration: { - const auto& choice = cast(d); + const auto& choice = cast(*d); VarValues alts; for (const auto& alternative : choice.Alternatives()) { auto t = interpreter.InterpExp(tops->values, &alternative.signature()); @@ -1055,10 +1050,10 @@ void TypeChecker::TopLevel(const Declaration& d, TypeCheckContext* tops) { } case Declaration::Kind::VariableDeclaration: { - const auto& var = cast(d); + auto& var = cast(*d); // Associate the variable name with it's declared type in the // compile-time symbol table. - Nonnull type = + Nonnull type = cast(*var.Binding()->Type()).Expression(); Nonnull declared_type = interpreter.InterpExp(tops->values, type); @@ -1068,16 +1063,16 @@ void TypeChecker::TopLevel(const Declaration& d, TypeCheckContext* tops) { } } -auto TypeChecker::TopLevel(const std::vector>& fs) +auto TypeChecker::TopLevel(std::vector>* fs) -> TypeCheckContext { TypeCheckContext tops(arena); bool found_main = false; - for (auto const& d : fs) { + for (auto const& d : *fs) { if (GetName(*d) == "main") { found_main = true; } - TopLevel(*d, &tops); + TopLevel(d, &tops); } if (found_main == false) { diff --git a/executable_semantics/interpreter/type_checker.h b/executable_semantics/interpreter/type_checker.h index bfa70ef99807..8831e2ccfc34 100644 --- a/executable_semantics/interpreter/type_checker.h +++ b/executable_semantics/interpreter/type_checker.h @@ -32,35 +32,31 @@ class TypeChecker { Env values; }; - auto MakeTypeChecked(const Nonnull d, - const TypeEnv& types, const Env& values) - -> Nonnull; + auto MakeTypeChecked(Nonnull d, const TypeEnv& types, + const Env& values) -> Nonnull; - auto TopLevel(const std::vector>& fs) - -> TypeCheckContext; + auto TopLevel(std::vector>* fs) -> TypeCheckContext; private: struct TCExpression { - TCExpression(Nonnull e, Nonnull t, - TypeEnv types) + TCExpression(Nonnull e, Nonnull t, TypeEnv types) : exp(e), type(t), types(types) {} - Nonnull exp; + Nonnull exp; Nonnull type; TypeEnv types; }; struct TCPattern { - Nonnull pattern; + Nonnull pattern; Nonnull type; TypeEnv types; }; struct TCStatement { - TCStatement(Nonnull s, TypeEnv types) - : stmt(s), types(types) {} + TCStatement(Nonnull s, TypeEnv types) : stmt(s), types(types) {} - Nonnull stmt; + Nonnull stmt; TypeEnv types; }; @@ -75,14 +71,14 @@ class TypeChecker { // types maps variable names to the type of their run-time value. // values maps variable names to their compile-time values. It is not // directly used in this function but is passed to InterExp. - auto TypeCheckExp(Nonnull e, TypeEnv types, Env values) + auto TypeCheckExp(Nonnull e, TypeEnv types, Env values) -> TCExpression; // Equivalent to TypeCheckExp, but operates on Patterns instead of // Expressions. `expected` is the type that this pattern is expected to have, // if the surrounding context gives us that information. Otherwise, it is // nullopt. - auto TypeCheckPattern(Nonnull p, TypeEnv types, Env values, + auto TypeCheckPattern(Nonnull p, TypeEnv types, Env values, std::optional> expected) -> TCPattern; @@ -93,33 +89,32 @@ class TypeChecker { // declared return type of the enclosing function definition. If the return // type is "auto", then the return type is inferred from the first return // statement. - auto TypeCheckStmt(Nonnull s, TypeEnv types, Env values, + auto TypeCheckStmt(Nonnull s, TypeEnv types, Env values, Nonnull& ret_type, bool is_omitted_ret_type) -> TCStatement; - auto TypeCheckFunDef(const FunctionDefinition* f, TypeEnv types, Env values) - -> Nonnull; + auto TypeCheckFunDef(FunctionDefinition* f, TypeEnv types, Env values) + -> Nonnull; - auto TypeCheckCase(Nonnull expected, - Nonnull pat, - Nonnull body, TypeEnv types, Env values, + auto TypeCheckCase(Nonnull expected, Nonnull pat, + Nonnull body, TypeEnv types, Env values, Nonnull& ret_type, bool is_omitted_ret_type) - -> std::pair, Nonnull>; + -> std::pair, Nonnull>; - auto TypeOfFunDef(TypeEnv types, Env values, - const FunctionDefinition* fun_def) -> Nonnull; + auto TypeOfFunDef(TypeEnv types, Env values, FunctionDefinition* fun_def) + -> Nonnull; auto TypeOfClassDef(const ClassDefinition* sd, TypeEnv /*types*/, Env ct_top) -> Nonnull; - void TopLevel(const Declaration& d, TypeCheckContext* tops); + void TopLevel(Nonnull d, TypeCheckContext* tops); - auto CheckOrEnsureReturn(std::optional> opt_stmt, + auto CheckOrEnsureReturn(std::optional> opt_stmt, bool omitted_ret_type, SourceLocation loc) - -> Nonnull; + -> Nonnull; // Reify type to type expression. auto ReifyType(Nonnull t, SourceLocation loc) - -> Nonnull; + -> Nonnull; auto Substitute(TypeEnv dict, Nonnull type) -> Nonnull; diff --git a/executable_semantics/syntax/parser.ypp b/executable_semantics/syntax/parser.ypp index 5f19bb6f64a2..052632b45191 100644 --- a/executable_semantics/syntax/parser.ypp +++ b/executable_semantics/syntax/parser.ypp @@ -98,43 +98,43 @@ %type > import_directives %type optional_library_path %type api_or_impl -%type > declaration -%type > function_declaration -%type > function_definition -%type >> declaration_list -%type > statement -%type > if_statement -%type >> optional_else -%type , bool>> return_expression -%type > block -%type >> statement_list -%type > expression +%type > declaration +%type > function_declaration +%type > function_definition +%type >> declaration_list +%type > statement +%type > if_statement +%type >> optional_else +%type , bool>> return_expression +%type > block +%type >> statement_list +%type > expression %type generic_binding %type > deduced_params %type > deduced_param_list -%type > pattern -%type > non_expression_pattern -%type , bool>> return_type -%type > paren_expression -%type > tuple +%type > pattern +%type > non_expression_pattern +%type , bool>> return_type +%type > paren_expression +%type > tuple %type > binding_lhs -%type > variable_declaration +%type > variable_declaration %type > member %type >> member_list %type ::Element> paren_expression_element %type > paren_expression_base %type > paren_expression_contents -%type > paren_pattern -%type > tuple_pattern -%type > maybe_empty_tuple_pattern +%type > paren_pattern +%type > tuple_pattern +%type > maybe_empty_tuple_pattern %type > paren_pattern_base %type ::Element> paren_pattern_element %type > paren_pattern_contents %type > alternative %type > alternative_list %type > alternative_list_contents -%type , Nonnull>> clause -%type , Nonnull>>> clause_list +%type , Nonnull>> clause +%type , Nonnull>>> clause_list %token // Most tokens have their spelling defined in lexer.lpp. @@ -303,61 +303,61 @@ expression: { $$ = arena->New( context.SourceLoc(), Operator::Eq, - std::vector>({$1, $3})); + std::vector>({$1, $3})); } | expression PLUS expression { $$ = arena->New( context.SourceLoc(), Operator::Add, - std::vector>({$1, $3})); + std::vector>({$1, $3})); } | expression MINUS expression { $$ = arena->New( context.SourceLoc(), Operator::Sub, - std::vector>({$1, $3})); + std::vector>({$1, $3})); } | expression BINARY_STAR expression { $$ = arena->New( context.SourceLoc(), Operator::Mul, - std::vector>({$1, $3})); + std::vector>({$1, $3})); } | expression AND expression { $$ = arena->New( context.SourceLoc(), Operator::And, - std::vector>({$1, $3})); + std::vector>({$1, $3})); } | expression OR expression { $$ = arena->New( context.SourceLoc(), Operator::Or, - std::vector>({$1, $3})); + std::vector>({$1, $3})); } | NOT expression { $$ = arena->New( context.SourceLoc(), Operator::Not, - std::vector>({$2})); + std::vector>({$2})); } | MINUS expression %prec UNARY_MINUS { $$ = arena->New( context.SourceLoc(), Operator::Neg, - std::vector>({$2})); + std::vector>({$2})); } | PREFIX_STAR expression { $$ = arena->New( context.SourceLoc(), Operator::Deref, - std::vector>({$2})); + std::vector>({$2})); } | UNARY_STAR expression %prec PREFIX_STAR { $$ = arena->New( context.SourceLoc(), Operator::Deref, - std::vector>({$2})); + std::vector>({$2})); } | expression tuple { $$ = arena->New(context.SourceLoc(), $1, $2); } @@ -365,13 +365,13 @@ expression: { $$ = arena->New( context.SourceLoc(), Operator::Ptr, - std::vector>({$1})); + std::vector>({$1})); } | expression UNARY_STAR { $$ = arena->New( context.SourceLoc(), Operator::Ptr, - std::vector>({$1})); + std::vector>({$1})); } | FNTY tuple return_type { @@ -501,17 +501,13 @@ maybe_empty_tuple_pattern: ; clause: CASE pattern DOUBLE_ARROW statement - { - $$ = - std::pair, Nonnull>($2, $4); - } + { $$ = std::pair, Nonnull>($2, $4); } | DEFAULT DOUBLE_ARROW statement { auto vp = arena -> New( context.SourceLoc(), std::nullopt, arena->New(context.SourceLoc())); - $$ = - std::pair, Nonnull>(vp, $3); + $$ = std::pair, Nonnull>(vp, $3); } ; clause_list: @@ -701,7 +697,7 @@ declaration_list: | declaration_list declaration { $$ = $1; - $$.push_back(Nonnull($2)); + $$.push_back(Nonnull($2)); } ; %%