Prechádzať zdrojové kódy

Revert to handling Expression by const pointer (#616)

This reverts the bulk of #606, #607, and #611, as well as parts of #588, #605, and #614.
Geoff Romer 4 rokov pred
rodič
commit
047dfd692e

+ 1 - 1
executable_semantics/ast/declaration.cpp

@@ -22,7 +22,7 @@ void ChoiceDeclaration::Print() const {
   std::cout << "choice " << name << " {" << std::endl;
   for (const auto& [name, signature] : alternatives) {
     std::cout << "alt " << name << " ";
-    PrintExp(&signature);
+    PrintExp(signature);
     std::cout << ";" << std::endl;
   }
   std::cout << "}" << std::endl;

+ 4 - 3
executable_semantics/ast/declaration.h

@@ -137,10 +137,11 @@ struct StructDeclaration {
 struct ChoiceDeclaration {
   int line_num;
   std::string name;
-  std::list<std::pair<std::string, Expression>> alternatives;
+  std::list<std::pair<std::string, const Expression*>> alternatives;
 
-  ChoiceDeclaration(int line_num, std::string name,
-                    std::list<std::pair<std::string, Expression>> alternatives)
+  ChoiceDeclaration(
+      int line_num, std::string name,
+      std::list<std::pair<std::string, const Expression*>> alternatives)
       : line_num(line_num), name(name), alternatives(std::move(alternatives)) {}
 
   void Print() const;

+ 34 - 34
executable_semantics/ast/expression.cpp

@@ -84,12 +84,11 @@ auto Expression::MakeContinuationType(int line_num) -> const Expression* {
   return type;
 }
 
-auto Expression::MakeFunType(int line_num, Expression param, Expression ret)
-    -> const Expression* {
+auto Expression::MakeFunType(int line_num, const Expression* param,
+                             const Expression* ret) -> const Expression* {
   auto* t = new Expression();
   t->line_num = line_num;
-  t->value = FunctionType(
-      {.parameter = std::move(param), .return_type = std::move(ret)});
+  t->value = FunctionType({.parameter = param, .return_type = ret});
   return t;
 }
 
@@ -100,11 +99,11 @@ auto Expression::MakeVar(int line_num, std::string var) -> const Expression* {
   return v;
 }
 
-auto Expression::MakeVarPat(int line_num, std::string var, Expression type)
-    -> const Expression* {
+auto Expression::MakeVarPat(int line_num, std::string var,
+                            const Expression* type) -> const Expression* {
   auto* v = new Expression();
   v->line_num = line_num;
-  v->value = PatternVariable({.name = std::move(var), .type = std::move(type)});
+  v->value = PatternVariable({.name = std::move(var), .type = type});
   return v;
 }
 
@@ -123,35 +122,36 @@ auto Expression::MakeBool(int line_num, bool b) -> const Expression* {
 }
 
 auto Expression::MakeOp(int line_num, enum Operator op,
-                        std::vector<Expression> args) -> const Expression* {
+                        std::vector<const Expression*> args)
+    -> const Expression* {
   auto* e = new Expression();
   e->line_num = line_num;
   e->value = PrimitiveOperator({.op = op, .arguments = std::move(args)});
   return e;
 }
 
-auto Expression::MakeUnOp(int line_num, enum Operator op, Expression arg)
+auto Expression::MakeUnOp(int line_num, enum Operator op, const Expression* arg)
     -> const Expression* {
   auto* e = new Expression();
   e->line_num = line_num;
-  e->value = PrimitiveOperator({.op = op, .arguments = {std::move(arg)}});
+  e->value = PrimitiveOperator({.op = op, .arguments = {arg}});
   return e;
 }
 
-auto Expression::MakeBinOp(int line_num, enum Operator op, Expression arg1,
-                           Expression arg2) -> const Expression* {
+auto Expression::MakeBinOp(int line_num, enum Operator op,
+                           const Expression* arg1, const Expression* arg2)
+    -> const Expression* {
   auto* e = new Expression();
   e->line_num = line_num;
-  e->value = PrimitiveOperator(
-      {.op = op, .arguments = {std::move(arg1), std::move(arg2)}});
+  e->value = PrimitiveOperator({.op = op, .arguments = {arg1, arg2}});
   return e;
 }
 
-auto Expression::MakeCall(int line_num, Expression fun, Expression arg)
-    -> const Expression* {
+auto Expression::MakeCall(int line_num, const Expression* fun,
+                          const Expression* arg) -> const Expression* {
   auto* e = new Expression();
   e->line_num = line_num;
-  e->value = Call({.function = std::move(fun), .argument = std::move(arg)});
+  e->value = Call({.function = fun, .argument = arg});
   return e;
 }
 
@@ -159,7 +159,7 @@ auto Expression::MakeGetField(int line_num, const Expression* exp,
                               std::string field) -> const Expression* {
   auto* e = new Expression();
   e->line_num = line_num;
-  e->value = FieldAccess({.aggregate = *exp, .field = std::move(field)});
+  e->value = FieldAccess({.aggregate = exp, .field = std::move(field)});
   return e;
 }
 
@@ -187,11 +187,11 @@ auto Expression::MakeTuple(int line_num, std::vector<FieldInitializer> args)
   return e;
 }
 
-auto Expression::MakeIndex(int line_num, Expression exp, Expression i)
-    -> const Expression* {
+auto Expression::MakeIndex(int line_num, const Expression* exp,
+                           const Expression* i) -> const Expression* {
   auto* e = new Expression();
   e->line_num = line_num;
-  e->value = Index({.aggregate = std::move(exp), .offset = std::move(i)});
+  e->value = Index({.aggregate = exp, .offset = i});
   return e;
 }
 
@@ -231,20 +231,20 @@ static void PrintFields(const std::vector<FieldInitializer>& fields) {
       std::cout << ", ";
     }
     std::cout << iter->name << " = ";
-    PrintExp(iter->expression.GetPointer());
+    PrintExp(iter->expression);
   }
 }
 
 void PrintExp(const Expression* e) {
   switch (e->tag()) {
     case ExpressionKind::Index:
-      PrintExp(e->GetIndex().aggregate.GetPointer());
+      PrintExp(e->GetIndex().aggregate);
       std::cout << "[";
-      PrintExp(e->GetIndex().offset.GetPointer());
+      PrintExp(e->GetIndex().offset);
       std::cout << "]";
       break;
     case ExpressionKind::GetField:
-      PrintExp(e->GetFieldAccess().aggregate.GetPointer());
+      PrintExp(e->GetFieldAccess().aggregate);
       std::cout << ".";
       std::cout << e->GetFieldAccess().field;
       break;
@@ -269,15 +269,15 @@ void PrintExp(const Expression* e) {
         PrintOp(op.op);
         std::cout << " ";
         auto iter = op.arguments.begin();
-        PrintExp(&*iter);
+        PrintExp(*iter);
       } else if (op.arguments.size() == 2) {
         auto iter = op.arguments.begin();
-        PrintExp(&*iter);
+        PrintExp(*iter);
         std::cout << " ";
         PrintOp(op.op);
         std::cout << " ";
         ++iter;
-        PrintExp(&*iter);
+        PrintExp(*iter);
       }
       std::cout << ")";
       break;
@@ -286,17 +286,17 @@ void PrintExp(const Expression* e) {
       std::cout << e->GetVariable().name;
       break;
     case ExpressionKind::PatternVariable:
-      PrintExp(e->GetPatternVariable().type.GetPointer());
+      PrintExp(e->GetPatternVariable().type);
       std::cout << ": ";
       std::cout << e->GetPatternVariable().name;
       break;
     case ExpressionKind::Call:
-      PrintExp(e->GetCall().function.GetPointer());
+      PrintExp(e->GetCall().function);
       if (e->GetCall().argument->tag() == ExpressionKind::Tuple) {
-        PrintExp(e->GetCall().argument.GetPointer());
+        PrintExp(e->GetCall().argument);
       } else {
         std::cout << "(";
-        PrintExp(e->GetCall().argument.GetPointer());
+        PrintExp(e->GetCall().argument);
         std::cout << ")";
       }
       break;
@@ -317,9 +317,9 @@ void PrintExp(const Expression* e) {
       break;
     case ExpressionKind::FunctionT:
       std::cout << "fn ";
-      PrintExp(e->GetFunctionType().parameter.GetPointer());
+      PrintExp(e->GetFunctionType().parameter);
       std::cout << " -> ";
-      PrintExp(e->GetFunctionType().return_type.GetPointer());
+      PrintExp(e->GetFunctionType().return_type);
       break;
   }
 }

+ 22 - 24
executable_semantics/ast/expression.h

@@ -9,8 +9,6 @@
 #include <variant>
 #include <vector>
 
-#include "common/indirect_value.h"
-
 namespace Carbon {
 
 struct Expression;
@@ -21,7 +19,7 @@ struct FieldInitializer {
   std::string name;
 
   // The expression that initializes the field.
-  IndirectValue<Expression> expression;
+  const Expression* expression;
 };
 
 enum class ExpressionKind {
@@ -64,20 +62,20 @@ struct Variable {
 
 struct FieldAccess {
   static constexpr ExpressionKind Kind = ExpressionKind::GetField;
-  IndirectValue<Expression> aggregate;
+  const Expression* aggregate;
   std::string field;
 };
 
 struct Index {
   static constexpr ExpressionKind Kind = ExpressionKind::Index;
-  IndirectValue<Expression> aggregate;
-  IndirectValue<Expression> offset;
+  const Expression* aggregate;
+  const Expression* offset;
 };
 
 struct PatternVariable {
   static constexpr ExpressionKind Kind = ExpressionKind::PatternVariable;
   std::string name;
-  IndirectValue<Expression> type;
+  const Expression* type;
 };
 
 struct IntLiteral {
@@ -98,19 +96,19 @@ struct Tuple {
 struct PrimitiveOperator {
   static constexpr ExpressionKind Kind = ExpressionKind::PrimitiveOp;
   Operator op;
-  std::vector<Expression> arguments;
+  std::vector<const Expression*> arguments;
 };
 
 struct Call {
   static constexpr ExpressionKind Kind = ExpressionKind::Call;
-  IndirectValue<Expression> function;
-  IndirectValue<Expression> argument;
+  const Expression* function;
+  const Expression* argument;
 };
 
 struct FunctionType {
   static constexpr ExpressionKind Kind = ExpressionKind::FunctionT;
-  IndirectValue<Expression> parameter;
-  IndirectValue<Expression> return_type;
+  const Expression* parameter;
+  const Expression* return_type;
 };
 
 struct AutoT {
@@ -138,29 +136,29 @@ struct Expression {
   inline auto tag() const -> ExpressionKind;
 
   static auto MakeVar(int line_num, std::string var) -> const Expression*;
-  static auto MakeVarPat(int line_num, std::string var, Expression type)
+  static auto MakeVarPat(int line_num, std::string var, const Expression* type)
       -> const Expression*;
   static auto MakeInt(int line_num, int i) -> const Expression*;
   static auto MakeBool(int line_num, bool b) -> const Expression*;
-  static auto MakeOp(int line_num, Operator op, std::vector<Expression> args)
-      -> const Expression*;
-  static auto MakeUnOp(int line_num, enum Operator op, Expression arg)
-      -> const Expression*;
-  static auto MakeBinOp(int line_num, enum Operator op, Expression arg1,
-                        Expression arg2) -> const Expression*;
-  static auto MakeCall(int line_num, Expression fun, Expression arg)
+  static auto MakeOp(int line_num, Operator op,
+                     std::vector<const Expression*> args) -> const Expression*;
+  static auto MakeUnOp(int line_num, enum Operator op, const Expression* arg)
       -> const Expression*;
+  static auto MakeBinOp(int line_num, enum Operator op, const Expression* arg1,
+                        const Expression* arg2) -> const Expression*;
+  static auto MakeCall(int line_num, const Expression* fun,
+                       const Expression* arg) -> const Expression*;
   static auto MakeGetField(int line_num, const Expression* exp,
                            std::string field) -> const Expression*;
   static auto MakeTuple(int line_num, std::vector<FieldInitializer> args)
       -> const Expression*;
-  static auto MakeIndex(int line_num, Expression exp, Expression i)
-      -> const Expression*;
+  static auto MakeIndex(int line_num, const Expression* exp,
+                        const Expression* i) -> const Expression*;
   static auto MakeTypeType(int line_num) -> const Expression*;
   static auto MakeIntType(int line_num) -> const Expression*;
   static auto MakeBoolType(int line_num) -> const Expression*;
-  static auto MakeFunType(int line_num, Expression param, Expression ret)
-      -> const Expression*;
+  static auto MakeFunType(int line_num, const Expression* param,
+                          const Expression* ret) -> const Expression*;
   static auto MakeAutoType(int line_num) -> const Expression*;
   static auto MakeContinuationType(int line_num) -> const Expression*;
 

+ 6 - 6
executable_semantics/ast/function_definition.cpp

@@ -8,23 +8,23 @@
 
 namespace Carbon {
 
-auto MakeFunDef(int line_num, std::string name, Expression ret_type,
-                Expression param_pattern, const Statement* body)
+auto MakeFunDef(int line_num, std::string name, const Expression* ret_type,
+                const Expression* param_pattern, const Statement* body)
     -> FunctionDefinition {
   FunctionDefinition f;
   f.line_num = line_num;
   f.name = std::move(name);
-  f.return_type = std::move(ret_type);
-  f.param_pattern = std::move(param_pattern);
+  f.return_type = ret_type;
+  f.param_pattern = param_pattern;
   f.body = body;
   return f;
 }
 
 void PrintFunDefDepth(const FunctionDefinition& f, int depth) {
   std::cout << "fn " << f.name << " ";
-  PrintExp(&f.param_pattern);
+  PrintExp(f.param_pattern);
   std::cout << " -> ";
-  PrintExp(&f.return_type);
+  PrintExp(f.return_type);
   if (f.body) {
     std::cout << " {" << std::endl;
     PrintStatement(f.body, depth);

+ 5 - 4
executable_semantics/ast/function_definition.h

@@ -13,13 +13,14 @@ namespace Carbon {
 struct FunctionDefinition {
   int line_num;
   std::string name;
-  Expression param_pattern;
-  Expression return_type;
+  const Expression* param_pattern;
+  const Expression* return_type;
   const Statement* body;
 };
 
-auto MakeFunDef(int line_num, std::string name, Expression ret_type,
-                Expression param, const Statement* body) -> FunctionDefinition;
+auto MakeFunDef(int line_num, std::string name, const Expression* ret_type,
+                const Expression* param, const Statement* body)
+    -> FunctionDefinition;
 void PrintFunDef(const FunctionDefinition&);
 void PrintFunDefDepth(const FunctionDefinition&, int);
 

+ 24 - 21
executable_semantics/ast/statement.cpp

@@ -65,52 +65,53 @@ Run Statement::GetRun() const {
   return u.run;
 }
 
-auto Statement::MakeExpStmt(int line_num, Expression exp) -> const Statement* {
+auto Statement::MakeExpStmt(int line_num, const Expression* exp)
+    -> const Statement* {
   auto* s = new Statement();
   s->line_num = line_num;
   s->tag = StatementKind::ExpressionStatement;
-  s->u.exp = new Expression(std::move(exp));
+  s->u.exp = exp;
   return s;
 }
 
-auto Statement::MakeAssign(int line_num, Expression lhs, Expression rhs)
-    -> const Statement* {
+auto Statement::MakeAssign(int line_num, const Expression* lhs,
+                           const Expression* rhs) -> const Statement* {
   auto* s = new Statement();
   s->line_num = line_num;
   s->tag = StatementKind::Assign;
-  s->u.assign.lhs = new Expression(std::move(lhs));
-  s->u.assign.rhs = new Expression(std::move(rhs));
+  s->u.assign.lhs = lhs;
+  s->u.assign.rhs = rhs;
   return s;
 }
 
-auto Statement::MakeVarDef(int line_num, Expression pat, Expression init)
-    -> const Statement* {
+auto Statement::MakeVarDef(int line_num, const Expression* pat,
+                           const Expression* init) -> const Statement* {
   auto* s = new Statement();
   s->line_num = line_num;
   s->tag = StatementKind::VariableDefinition;
-  s->u.variable_definition.pat = new Expression(std::move(pat));
-  s->u.variable_definition.init = new Expression(std::move(init));
+  s->u.variable_definition.pat = pat;
+  s->u.variable_definition.init = init;
   return s;
 }
 
-auto Statement::MakeIf(int line_num, Expression cond,
+auto Statement::MakeIf(int line_num, const Expression* cond,
                        const Statement* then_stmt, const Statement* else_stmt)
     -> const Statement* {
   auto* s = new Statement();
   s->line_num = line_num;
   s->tag = StatementKind::If;
-  s->u.if_stmt.cond = new Expression(std::move(cond));
+  s->u.if_stmt.cond = cond;
   s->u.if_stmt.then_stmt = then_stmt;
   s->u.if_stmt.else_stmt = else_stmt;
   return s;
 }
 
-auto Statement::MakeWhile(int line_num, Expression cond, const Statement* body)
-    -> const Statement* {
+auto Statement::MakeWhile(int line_num, const Expression* cond,
+                          const Statement* body) -> const Statement* {
   auto* s = new Statement();
   s->line_num = line_num;
   s->tag = StatementKind::While;
-  s->u.while_stmt.cond = new Expression(std::move(cond));
+  s->u.while_stmt.cond = cond;
   s->u.while_stmt.body = body;
   return s;
 }
@@ -129,11 +130,12 @@ auto Statement::MakeContinue(int line_num) -> const Statement* {
   return s;
 }
 
-auto Statement::MakeReturn(int line_num, Expression e) -> const Statement* {
+auto Statement::MakeReturn(int line_num, const Expression* e)
+    -> const Statement* {
   auto* s = new Statement();
   s->line_num = line_num;
   s->tag = StatementKind::Return;
-  s->u.return_stmt = new Expression(std::move(e));
+  s->u.return_stmt = e;
   return s;
 }
 
@@ -157,13 +159,13 @@ auto Statement::MakeBlock(int line_num, const Statement* stmt)
 }
 
 auto Statement::MakeMatch(
-    int line_num, Expression exp,
+    int line_num, const Expression* exp,
     std::list<std::pair<const Expression*, const Statement*>>* clauses)
     -> const Statement* {
   auto* s = new Statement();
   s->line_num = line_num;
   s->tag = StatementKind::Match;
-  s->u.match_stmt.exp = new Expression(std::move(exp));
+  s->u.match_stmt.exp = exp;
   s->u.match_stmt.clauses = clauses;
   return s;
 }
@@ -183,11 +185,12 @@ auto Statement::MakeContinuation(int line_num,
 }
 
 // Returns an AST node for a run statement give its line number and argument.
-auto Statement::MakeRun(int line_num, Expression argument) -> const Statement* {
+auto Statement::MakeRun(int line_num, const Expression* argument)
+    -> const Statement* {
   auto* run = new Statement();
   run->line_num = line_num;
   run->tag = StatementKind::Run;
-  run->u.run.argument = new Expression(std::move(argument));
+  run->u.run.argument = argument;
   return run;
 }
 

+ 13 - 10
executable_semantics/ast/statement.h

@@ -80,23 +80,25 @@ struct Statement {
   StatementKind tag;
 
   // Constructors
-  static auto MakeExpStmt(int line_num, Expression exp) -> const Statement*;
-  static auto MakeAssign(int line_num, Expression lhs, Expression rhs)
+  static auto MakeExpStmt(int line_num, const Expression* exp)
       -> const Statement*;
-  static auto MakeVarDef(int line_num, Expression pat, Expression init)
+  static auto MakeAssign(int line_num, const Expression* lhs,
+                         const Expression* rhs) -> const Statement*;
+  static auto MakeVarDef(int line_num, const Expression* pat,
+                         const Expression* init) -> const Statement*;
+  static auto MakeIf(int line_num, const Expression* cond,
+                     const Statement* then_stmt, const Statement* else_stmt)
       -> const Statement*;
-  static auto MakeIf(int line_num, Expression cond, const Statement* then_stmt,
-                     const Statement* else_stmt) -> const Statement*;
-  static auto MakeReturn(int line_num, Expression e) -> const Statement*;
+  static auto MakeReturn(int line_num, const Expression* e) -> const Statement*;
   static auto MakeSeq(int line_num, const Statement* s1, const Statement* s2)
       -> const Statement*;
   static auto MakeBlock(int line_num, const Statement* s) -> const Statement*;
-  static auto MakeWhile(int line_num, Expression cond, const Statement* body)
-      -> const Statement*;
+  static auto MakeWhile(int line_num, const Expression* cond,
+                        const Statement* body) -> const Statement*;
   static auto MakeBreak(int line_num) -> const Statement*;
   static auto MakeContinue(int line_num) -> const Statement*;
   static auto MakeMatch(
-      int line_num, Expression exp,
+      int line_num, const Expression* exp,
       std::list<std::pair<const Expression*, const Statement*>>* clauses)
       -> const Statement*;
   // Returns an AST node for a continuation statement give its line number and
@@ -110,7 +112,8 @@ struct Statement {
   // Returns an AST node for a run statement give its line number and argument.
   //
   //     __run <argument>;
-  static auto MakeRun(int line_num, Expression argument) -> const Statement*;
+  static auto MakeRun(int line_num, const Expression* argument)
+      -> const Statement*;
   // Returns an AST node for an await statement give its line number.
   //
   //     __await;

+ 21 - 31
executable_semantics/interpreter/interpreter.cpp

@@ -315,7 +315,7 @@ void InitGlobals(std::list<Declaration>* fs) {
 auto ChoiceDeclaration::InitGlobals(Env& globals) const -> void {
   auto alts = new VarValues();
   for (const auto& [name, signature] : alternatives) {
-    auto t = InterpExp(Env(), &signature);
+    auto t = InterpExp(Env(), signature);
     alts->push_back(make_pair(name, t));
   }
   auto ct = Value::MakeChoiceTypeVal(name, alts);
@@ -342,7 +342,7 @@ auto StructDeclaration::InitGlobals(Env& globals) const -> void {
 }
 
 auto FunctionDeclaration::InitGlobals(Env& globals) const -> void {
-  auto pt = InterpExp(globals, &definition.param_pattern);
+  auto pt = InterpExp(globals, definition.param_pattern);
   auto f = Value::MakeFunVal(definition.name, pt, definition.body);
   Address a = state->heap.AllocateValue(f);
   globals.Set(definition.name, a);
@@ -640,8 +640,7 @@ void StepLvalue() {
       if (act->pos == 0) {
         //    { {e.f :: C, E, F} :: S, H}
         // -> { e :: [].f :: C, E, F} :: S, H}
-        frame->todo.Push(
-            MakeLvalAct(exp->GetFieldAccess().aggregate.GetPointer()));
+        frame->todo.Push(MakeLvalAct(exp->GetFieldAccess().aggregate));
         act->pos++;
       } else {
         //    { v :: [].f :: C, E, F} :: S, H}
@@ -658,10 +657,10 @@ void StepLvalue() {
       if (act->pos == 0) {
         //    { {e[i] :: C, E, F} :: S, H}
         // -> { e :: [][i] :: C, E, F} :: S, H}
-        frame->todo.Push(MakeExpAct(exp->GetIndex().aggregate.GetPointer()));
+        frame->todo.Push(MakeExpAct(exp->GetIndex().aggregate));
         act->pos++;
       } else if (act->pos == 1) {
-        frame->todo.Push(MakeExpAct(exp->GetIndex().offset.GetPointer()));
+        frame->todo.Push(MakeExpAct(exp->GetIndex().offset));
         act->pos++;
       } else if (act->pos == 2) {
         //    { v :: [][i] :: C, E, F} :: S, H}
@@ -684,8 +683,7 @@ void StepLvalue() {
       if (act->pos == 0) {
         //    { {(f1=e1,...) :: C, E, F} :: S, H}
         // -> { {e1 :: (f1=[],...) :: C, E, F} :: S, H}
-        const Expression* e1 =
-            exp->GetTuple().fields[0].expression.GetPointer();
+        const Expression* e1 = exp->GetTuple().fields[0].expression;
         frame->todo.Push(MakeLvalAct(e1));
         act->pos++;
       } else if (act->pos != static_cast<int>(exp->GetTuple().fields.size())) {
@@ -693,8 +691,7 @@ void StepLvalue() {
         //    H}
         // -> { { ek+1 :: (f1=v1,..., fk=vk, fk+1=[],...) :: C, E, F} :: S,
         // H}
-        const Expression* elt =
-            exp->GetTuple().fields[act->pos].expression.GetPointer();
+        const Expression* elt = exp->GetTuple().fields[act->pos].expression;
         frame->todo.Push(MakeLvalAct(elt));
         act->pos++;
       } else {
@@ -734,8 +731,7 @@ void StepExp() {
   switch (exp->tag()) {
     case ExpressionKind::PatternVariable: {
       if (act->pos == 0) {
-        frame->todo.Push(
-            MakeExpAct(exp->GetPatternVariable().type.GetPointer()));
+        frame->todo.Push(MakeExpAct(exp->GetPatternVariable().type));
         act->pos++;
       } else {
         auto v = Value::MakeVarPatVal(exp->GetPatternVariable().name,
@@ -749,10 +745,10 @@ void StepExp() {
       if (act->pos == 0) {
         //    { { e[i] :: C, E, F} :: S, H}
         // -> { { e :: [][i] :: C, E, F} :: S, H}
-        frame->todo.Push(MakeExpAct(exp->GetIndex().aggregate.GetPointer()));
+        frame->todo.Push(MakeExpAct(exp->GetIndex().aggregate));
         act->pos++;
       } else if (act->pos == 1) {
-        frame->todo.Push(MakeExpAct(exp->GetIndex().offset.GetPointer()));
+        frame->todo.Push(MakeExpAct(exp->GetIndex().offset));
         act->pos++;
       } else if (act->pos == 2) {
         auto tuple = act->results[0];
@@ -788,8 +784,7 @@ void StepExp() {
         if (exp->GetTuple().fields.size() > 0) {
           //    { {(f1=e1,...) :: C, E, F} :: S, H}
           // -> { {e1 :: (f1=[],...) :: C, E, F} :: S, H}
-          const Expression* e1 =
-              exp->GetTuple().fields[0].expression.GetPointer();
+          const Expression* e1 = exp->GetTuple().fields[0].expression;
           frame->todo.Push(MakeExpAct(e1));
           act->pos++;
         } else {
@@ -800,8 +795,7 @@ void StepExp() {
         //    H}
         // -> { { ek+1 :: (f1=v1,..., fk=vk, fk+1=[],...) :: C, E, F} :: S,
         // H}
-        const Expression* elt =
-            exp->GetTuple().fields[act->pos].expression.GetPointer();
+        const Expression* elt = exp->GetTuple().fields[act->pos].expression;
         frame->todo.Push(MakeExpAct(elt));
         act->pos++;
       } else {
@@ -813,8 +807,7 @@ void StepExp() {
       if (act->pos == 0) {
         //    { { e.f :: C, E, F} :: S, H}
         // -> { { e :: [].f :: C, E, F} :: S, H}
-        frame->todo.Push(
-            MakeLvalAct(exp->GetFieldAccess().aggregate.GetPointer()));
+        frame->todo.Push(MakeLvalAct(exp->GetFieldAccess().aggregate));
         act->pos++;
       } else {
         //    { { v :: [].f :: C, E, F} :: S, H}
@@ -859,8 +852,7 @@ void StepExp() {
           static_cast<int>(exp->GetPrimitiveOperator().arguments.size())) {
         //    { {v :: op(vs,[],e,es) :: C, E, F} :: S, H}
         // -> { {e :: op(vs,v,[],es) :: C, E, F} :: S, H}
-        const Expression* arg =
-            &(exp->GetPrimitiveOperator().arguments[act->pos]);
+        const Expression* arg = exp->GetPrimitiveOperator().arguments[act->pos];
         frame->todo.Push(MakeExpAct(arg));
         act->pos++;
       } else {
@@ -876,12 +868,12 @@ void StepExp() {
       if (act->pos == 0) {
         //    { {e1(e2) :: C, E, F} :: S, H}
         // -> { {e1 :: [](e2) :: C, E, F} :: S, H}
-        frame->todo.Push(MakeExpAct(exp->GetCall().function.GetPointer()));
+        frame->todo.Push(MakeExpAct(exp->GetCall().function));
         act->pos++;
       } else if (act->pos == 1) {
         //    { { v :: [](e) :: C, E, F} :: S, H}
         // -> { { e :: v([]) :: C, E, F} :: S, H}
-        frame->todo.Push(MakeExpAct(exp->GetCall().argument.GetPointer()));
+        frame->todo.Push(MakeExpAct(exp->GetCall().argument));
         act->pos++;
       } else if (act->pos == 2) {
         //    { { v2 :: v1([]) :: C, E, F} :: S, H}
@@ -923,14 +915,12 @@ void StepExp() {
     }
     case ExpressionKind::FunctionT: {
       if (act->pos == 0) {
-        frame->todo.Push(
-            MakeExpAct(exp->GetFunctionType().parameter.GetPointer()));
+        frame->todo.Push(MakeExpAct(exp->GetFunctionType().parameter));
         act->pos++;
       } else if (act->pos == 1) {
         //    { { pt :: fn [] -> e :: C, E, F} :: S, H}
         // -> { { e :: fn pt -> []) :: C, E, F} :: S, H}
-        frame->todo.Push(
-            MakeExpAct(exp->GetFunctionType().return_type.GetPointer()));
+        frame->todo.Push(MakeExpAct(exp->GetFunctionType().return_type));
         act->pos++;
       } else if (act->pos == 2) {
         //    { { rt :: fn pt -> [] :: C, E, F} :: S, H}
@@ -1233,7 +1223,7 @@ void StepStmt() {
       scopes.Push(scope);
       Stack<Action*> todo;
       todo.Push(MakeStmtAct(Statement::MakeReturn(
-          stmt->line_num, *Expression::MakeTuple(stmt->line_num, {}))));
+          stmt->line_num, Expression::MakeTuple(stmt->line_num, {}))));
       todo.Push(MakeStmtAct(stmt->GetContinuation().body));
       Frame* continuation_frame = new Frame("__continuation", scopes, todo);
       Address continuation_address = state->heap.AllocateValue(
@@ -1257,7 +1247,7 @@ void StepStmt() {
         // Push an expression statement action to ignore the result
         // value from the continuation.
         Action* ignore_result = MakeStmtAct(Statement::MakeExpStmt(
-            stmt->line_num, *Expression::MakeTuple(stmt->line_num, {})));
+            stmt->line_num, Expression::MakeTuple(stmt->line_num, {})));
         ignore_result->pos = 0;
         frame->todo.Push(ignore_result);
         // Push the continuation onto the current stack.
@@ -1402,7 +1392,7 @@ auto InterpProgram(std::list<Declaration>* fs) -> int {
 
   const Expression* arg = Expression::MakeTuple(0, {});
   const Expression* call_main =
-      Expression::MakeCall(0, *Expression::MakeVar(0, "main"), *arg);
+      Expression::MakeCall(0, Expression::MakeVar(0, "main"), arg);
   auto todo = Stack(MakeExpAct(call_main));
   auto* scope = new Scope(globals, std::list<std::string>());
   auto* frame = new Frame("top", Stack(scope), todo);

+ 55 - 61
executable_semantics/interpreter/typecheck.cpp

@@ -67,15 +67,15 @@ auto ReifyType(const Value* t, int line_num) -> const Expression* {
       return Expression::MakeContinuationType(0);
     case ValKind::FunctionTV:
       return Expression::MakeFunType(
-          0, *ReifyType(t->GetFunctionType().param, line_num),
-          *ReifyType(t->GetFunctionType().ret, line_num));
+          0, ReifyType(t->GetFunctionType().param, line_num),
+          ReifyType(t->GetFunctionType().ret, line_num));
     case ValKind::TupleV: {
       std::vector<FieldInitializer> args;
       for (const TupleElement& field : *t->GetTuple().elements) {
         args.push_back(
             {.name = field.name,
-             .expression = *ReifyType(state->heap.Read(field.address, line_num),
-                                      line_num)});
+             .expression = ReifyType(state->heap.Read(field.address, line_num),
+                                     line_num)});
       }
       return Expression::MakeTuple(0, args);
     }
@@ -85,7 +85,7 @@ auto ReifyType(const Value* t, int line_num) -> const Expression* {
       return Expression::MakeVar(0, *t->GetChoiceType().name);
     case ValKind::PointerTV:
       return Expression::MakeUnOp(
-          0, Operator::Ptr, *ReifyType(t->GetPointerType().type, line_num));
+          0, Operator::Ptr, ReifyType(t->GetPointerType().type, line_num));
     default:
       std::cerr << line_num << ": expected a type, not ";
       PrintValue(t, std::cerr);
@@ -144,7 +144,7 @@ auto TypeCheckExp(const Expression* e, TypeEnv types, Env values,
             << std::endl;
         exit(-1);
       }
-      auto t = InterpExp(values, e->GetPatternVariable().type.GetPointer());
+      auto t = InterpExp(values, e->GetPatternVariable().type);
       if (t->tag == ValKind::AutoTV) {
         if (expected == nullptr) {
           std::cerr << e->line_num
@@ -157,20 +157,18 @@ auto TypeCheckExp(const Expression* e, TypeEnv types, Env values,
       } else if (expected) {
         ExpectType(e->line_num, "pattern variable", t, expected);
       }
-      auto new_e =
-          Expression::MakeVarPat(e->line_num, e->GetPatternVariable().name,
-                                 *ReifyType(t, e->line_num));
+      auto new_e = Expression::MakeVarPat(
+          e->line_num, e->GetPatternVariable().name, ReifyType(t, e->line_num));
       types.Set(e->GetPatternVariable().name, t);
       return TCResult(new_e, t, types);
     }
     case ExpressionKind::Index: {
-      auto res = TypeCheckExp(e->GetIndex().aggregate.GetPointer(), types,
-                              values, nullptr, TCContext::ValueContext);
+      auto res = TypeCheckExp(e->GetIndex().aggregate, types, values, nullptr,
+                              TCContext::ValueContext);
       auto t = res.type;
       switch (t->tag) {
         case ValKind::TupleV: {
-          auto i =
-              ToInteger(InterpExp(values, e->GetIndex().offset.GetPointer()));
+          auto i = ToInteger(InterpExp(values, e->GetIndex().offset));
           std::string f = std::to_string(i);
           std::optional<Address> field_address = FindTupleField(f, t);
           if (field_address == std::nullopt) {
@@ -182,7 +180,7 @@ auto TypeCheckExp(const Expression* e, TypeEnv types, Env values,
           }
           auto field_t = state->heap.Read(*field_address, e->line_num);
           auto new_e = Expression::MakeIndex(
-              e->line_num, *res.exp, *Expression::MakeInt(e->line_num, i));
+              e->line_num, res.exp, Expression::MakeInt(e->line_num, i));
           return TCResult(new_e, field_t, res.types);
         }
         default:
@@ -222,10 +220,10 @@ auto TypeCheckExp(const Expression* e, TypeEnv types, Env values,
           arg_expected = state->heap.Read(
               (*expected->GetTuple().elements)[i].address, e->line_num);
         }
-        auto arg_res = TypeCheckExp(arg->expression.GetPointer(), new_types,
-                                    values, arg_expected, context);
+        auto arg_res = TypeCheckExp(arg->expression, new_types, values,
+                                    arg_expected, context);
         new_types = arg_res.types;
-        new_args.push_back({.name = arg->name, .expression = *arg_res.exp});
+        new_args.push_back({.name = arg->name, .expression = arg_res.exp});
         arg_types->push_back(
             {.name = arg->name,
              .address = state->heap.AllocateValue(arg_res.type)});
@@ -235,8 +233,8 @@ auto TypeCheckExp(const Expression* e, TypeEnv types, Env values,
       return TCResult(tuple_e, tuple_t, new_types);
     }
     case ExpressionKind::GetField: {
-      auto res = TypeCheckExp(e->GetFieldAccess().aggregate.GetPointer(), types,
-                              values, nullptr, TCContext::ValueContext);
+      auto res = TypeCheckExp(e->GetFieldAccess().aggregate, types, values,
+                              nullptr, TCContext::ValueContext);
       auto t = res.type;
       switch (t->tag) {
         case ValKind::StructTV:
@@ -316,14 +314,14 @@ auto TypeCheckExp(const Expression* e, TypeEnv types, Env values,
     case ExpressionKind::Boolean:
       return TCResult(e, Value::MakeBoolTypeVal(), types);
     case ExpressionKind::PrimitiveOp: {
-      std::vector<Expression> es;
+      std::vector<const Expression*> es;
       std::vector<const Value*> ts;
       auto new_types = types;
-      for (const Expression& argument : e->GetPrimitiveOperator().arguments) {
-        auto res = TypeCheckExp(&argument, types, values, nullptr,
+      for (const Expression* argument : e->GetPrimitiveOperator().arguments) {
+        auto res = TypeCheckExp(argument, types, values, nullptr,
                                 TCContext::ValueContext);
         new_types = res.types;
-        es.push_back(*res.exp);
+        es.push_back(res.exp);
         ts.push_back(res.type);
       }
       auto new_e =
@@ -374,18 +372,18 @@ auto TypeCheckExp(const Expression* e, TypeEnv types, Env values,
       break;
     }
     case ExpressionKind::Call: {
-      auto fun_res = TypeCheckExp(e->GetCall().function.GetPointer(), types,
-                                  values, nullptr, TCContext::ValueContext);
+      auto fun_res = TypeCheckExp(e->GetCall().function, types, values, nullptr,
+                                  TCContext::ValueContext);
       switch (fun_res.type->tag) {
         case ValKind::FunctionTV: {
           auto fun_t = fun_res.type;
           auto arg_res =
-              TypeCheckExp(e->GetCall().argument.GetPointer(), fun_res.types,
-                           values, fun_t->GetFunctionType().param, context);
+              TypeCheckExp(e->GetCall().argument, fun_res.types, values,
+                           fun_t->GetFunctionType().param, context);
           ExpectType(e->line_num, "call", fun_t->GetFunctionType().param,
                      arg_res.type);
           auto new_e =
-              Expression::MakeCall(e->line_num, *fun_res.exp, *arg_res.exp);
+              Expression::MakeCall(e->line_num, fun_res.exp, arg_res.exp);
           return TCResult(new_e, fun_t->GetFunctionType().ret, arg_res.types);
         }
         default: {
@@ -403,25 +401,22 @@ auto TypeCheckExp(const Expression* e, TypeEnv types, Env values,
       switch (context) {
         case TCContext::ValueContext:
         case TCContext::TypeContext: {
-          auto pt =
-              InterpExp(values, e->GetFunctionType().parameter.GetPointer());
-          auto rt =
-              InterpExp(values, e->GetFunctionType().return_type.GetPointer());
+          auto pt = InterpExp(values, e->GetFunctionType().parameter);
+          auto rt = InterpExp(values, e->GetFunctionType().return_type);
           auto new_e =
-              Expression::MakeFunType(e->line_num, *ReifyType(pt, e->line_num),
-                                      *ReifyType(rt, e->line_num));
+              Expression::MakeFunType(e->line_num, ReifyType(pt, e->line_num),
+                                      ReifyType(rt, e->line_num));
           return TCResult(new_e, Value::MakeTypeTypeVal(), types);
         }
         case TCContext::PatternContext: {
-          auto param_res =
-              TypeCheckExp(e->GetFunctionType().parameter.GetPointer(), types,
-                           values, nullptr, context);
+          auto param_res = TypeCheckExp(e->GetFunctionType().parameter, types,
+                                        values, nullptr, context);
           auto ret_res =
-              TypeCheckExp(e->GetFunctionType().return_type.GetPointer(),
-                           param_res.types, values, nullptr, context);
+              TypeCheckExp(e->GetFunctionType().return_type, param_res.types,
+                           values, nullptr, context);
           auto new_e = Expression::MakeFunType(
-              e->line_num, *ReifyType(param_res.type, e->line_num),
-              *ReifyType(ret_res.type, e->line_num));
+              e->line_num, ReifyType(param_res.type, e->line_num),
+              ReifyType(ret_res.type, e->line_num));
           return TCResult(new_e, Value::MakeTypeTypeVal(), ret_res.types);
         }
       }
@@ -473,7 +468,7 @@ auto TypeCheckStmt(const Statement* s, TypeEnv types, Env values,
             res_type, clause.first, clause.second, types, values, ret_type));
       }
       const Statement* new_s =
-          Statement::MakeMatch(s->line_num, *res.exp, new_clauses);
+          Statement::MakeMatch(s->line_num, res.exp, new_clauses);
       return TCStatement(new_s, types);
     }
     case StatementKind::While: {
@@ -484,7 +479,7 @@ auto TypeCheckStmt(const Statement* s, TypeEnv types, Env values,
       auto body_res =
           TypeCheckStmt(s->GetWhile().body, types, values, ret_type);
       auto new_s =
-          Statement::MakeWhile(s->line_num, *cnd_res.exp, body_res.stmt);
+          Statement::MakeWhile(s->line_num, cnd_res.exp, body_res.stmt);
       return TCStatement(new_s, types);
     }
     case StatementKind::Break:
@@ -503,7 +498,7 @@ auto TypeCheckStmt(const Statement* s, TypeEnv types, Env values,
       auto lhs_res = TypeCheckExp(s->GetVariableDefinition().pat, types, values,
                                   rhs_ty, TCContext::PatternContext);
       const Statement* new_s = Statement::MakeVarDef(
-          s->line_num, *s->GetVariableDefinition().pat, *res.exp);
+          s->line_num, s->GetVariableDefinition().pat, res.exp);
       return TCStatement(new_s, lhs_res.types);
     }
     case StatementKind::Sequence: {
@@ -525,14 +520,13 @@ auto TypeCheckStmt(const Statement* s, TypeEnv types, Env values,
                                   TCContext::ValueContext);
       auto lhs_t = lhs_res.type;
       ExpectType(s->line_num, "assign", lhs_t, rhs_t);
-      auto new_s =
-          Statement::MakeAssign(s->line_num, *lhs_res.exp, *rhs_res.exp);
+      auto new_s = Statement::MakeAssign(s->line_num, lhs_res.exp, rhs_res.exp);
       return TCStatement(new_s, lhs_res.types);
     }
     case StatementKind::ExpressionStatement: {
       auto res = TypeCheckExp(s->GetExpression(), types, values, nullptr,
                               TCContext::ValueContext);
-      auto new_s = Statement::MakeExpStmt(s->line_num, *res.exp);
+      auto new_s = Statement::MakeExpStmt(s->line_num, res.exp);
       return TCStatement(new_s, types);
     }
     case StatementKind::If: {
@@ -544,7 +538,7 @@ auto TypeCheckStmt(const Statement* s, TypeEnv types, Env values,
           TypeCheckStmt(s->GetIf().then_stmt, types, values, ret_type);
       auto els_res =
           TypeCheckStmt(s->GetIf().else_stmt, types, values, ret_type);
-      auto new_s = Statement::MakeIf(s->line_num, *cnd_res.exp, thn_res.stmt,
+      auto new_s = Statement::MakeIf(s->line_num, cnd_res.exp, thn_res.stmt,
                                      els_res.stmt);
       return TCStatement(new_s, types);
     }
@@ -559,7 +553,7 @@ auto TypeCheckStmt(const Statement* s, TypeEnv types, Env values,
       } else {
         ExpectType(s->line_num, "return", ret_type, res.type);
       }
-      return TCStatement(Statement::MakeReturn(s->line_num, *res.exp), types);
+      return TCStatement(Statement::MakeReturn(s->line_num, res.exp), types);
     }
     case StatementKind::Continuation: {
       TCStatement body_result =
@@ -578,7 +572,7 @@ auto TypeCheckStmt(const Statement* s, TypeEnv types, Env values,
       ExpectType(s->line_num, "argument of `run`",
                  Value::MakeContinuationTypeVal(), argument_result.type);
       const Statement* new_run =
-          Statement::MakeRun(s->line_num, *argument_result.exp);
+          Statement::MakeRun(s->line_num, argument_result.exp);
       return TCStatement(new_run, types);
     }
     case StatementKind::Await: {
@@ -593,7 +587,7 @@ auto CheckOrEnsureReturn(const Statement* stmt, bool void_return, int line_num)
   if (!stmt) {
     if (void_return) {
       return Statement::MakeReturn(line_num,
-                                   *Expression::MakeTuple(line_num, {}));
+                                   Expression::MakeTuple(line_num, {}));
     } else {
       std::cerr
           << "control-flow reaches end of non-void function without a return"
@@ -610,7 +604,7 @@ auto CheckOrEnsureReturn(const Statement* stmt, bool void_return, int line_num)
         auto s = CheckOrEnsureReturn(i->second, void_return, stmt->line_num);
         new_clauses->push_back(std::make_pair(i->first, s));
       }
-      return Statement::MakeMatch(stmt->line_num, *stmt->GetMatch().exp,
+      return Statement::MakeMatch(stmt->line_num, stmt->GetMatch().exp,
                                   new_clauses);
     }
     case StatementKind::Block:
@@ -619,7 +613,7 @@ auto CheckOrEnsureReturn(const Statement* stmt, bool void_return, int line_num)
                                               void_return, stmt->line_num));
     case StatementKind::If:
       return Statement::MakeIf(
-          stmt->line_num, *stmt->GetIf().cond,
+          stmt->line_num, stmt->GetIf().cond,
           CheckOrEnsureReturn(stmt->GetIf().then_stmt, void_return,
                               stmt->line_num),
           CheckOrEnsureReturn(stmt->GetIf().else_stmt, void_return,
@@ -650,7 +644,7 @@ auto CheckOrEnsureReturn(const Statement* stmt, bool void_return, int line_num)
         return Statement::MakeSeq(
             stmt->line_num, stmt,
             Statement::MakeReturn(stmt->line_num,
-                                  *Expression::MakeTuple(stmt->line_num, {})));
+                                  Expression::MakeTuple(stmt->line_num, {})));
       } else {
         std::cerr
             << stmt->line_num
@@ -664,9 +658,9 @@ auto CheckOrEnsureReturn(const Statement* stmt, bool void_return, int line_num)
 
 auto TypeCheckFunDef(const FunctionDefinition* f, TypeEnv types, Env values)
     -> struct FunctionDefinition* {
-  auto param_res = TypeCheckExp(&f->param_pattern, types, values, nullptr,
+  auto param_res = TypeCheckExp(f->param_pattern, types, values, nullptr,
                                 TCContext::PatternContext);
-  auto return_type = InterpExp(values, &f->return_type);
+  auto return_type = InterpExp(values, f->return_type);
   if (f->name == "main") {
     ExpectType(f->line_num, "return type of `main`", Value::MakeIntTypeVal(),
                return_type);
@@ -676,18 +670,18 @@ auto TypeCheckFunDef(const FunctionDefinition* f, TypeEnv types, Env values)
   bool void_return = TypeEqual(return_type, Value::MakeUnitTypeVal());
   auto body = CheckOrEnsureReturn(res.stmt, void_return, f->line_num);
   return new FunctionDefinition(MakeFunDef(f->line_num, f->name,
-                                           *ReifyType(return_type, f->line_num),
+                                           ReifyType(return_type, f->line_num),
                                            f->param_pattern, body));
 }
 
 auto TypeOfFunDef(TypeEnv types, Env values, const FunctionDefinition* fun_def)
     -> const Value* {
-  auto param_res = TypeCheckExp(&fun_def->param_pattern, types, values, nullptr,
+  auto param_res = TypeCheckExp(fun_def->param_pattern, types, values, nullptr,
                                 TCContext::PatternContext);
-  auto ret = InterpExp(values, &fun_def->return_type);
+  auto ret = InterpExp(values, fun_def->return_type);
   if (ret->tag == ValKind::AutoTV) {
     auto f = TypeCheckFunDef(fun_def, types, values);
-    ret = InterpExp(values, &f->return_type);
+    ret = InterpExp(values, f->return_type);
   }
   return Value::MakeFunTypeVal(param_res.type, ret);
 }
@@ -792,7 +786,7 @@ auto StructDeclaration::TopLevel(TypeCheckContext& tops) const -> void {
 auto ChoiceDeclaration::TopLevel(TypeCheckContext& tops) const -> void {
   auto alts = new VarValues();
   for (const auto& [name, signature] : alternatives) {
-    auto t = InterpExp(tops.values, &signature);
+    auto t = InterpExp(tops.values, signature);
     alts->push_back(std::make_pair(name, t));
   }
   auto ct = Value::MakeChoiceTypeVal(name, alts);

+ 8 - 8
executable_semantics/syntax/paren_contents_test.cpp

@@ -33,7 +33,7 @@ TEST(ParenContentsTest, UnaryNoCommaAsExpression) {
   // )
   // ```
   ParenContents contents(
-      {{.expression = *Expression::MakeInt(/*line_num=*/2, 42)}},
+      {{.expression = Expression::MakeInt(/*line_num=*/2, 42)}},
       ParenContents::HasTrailingComma::No);
 
   const Expression* expression = contents.AsExpression(/*line_num=*/1);
@@ -43,7 +43,7 @@ TEST(ParenContentsTest, UnaryNoCommaAsExpression) {
 
 TEST(ParenContentsTest, UnaryNoCommaAsTuple) {
   ParenContents contents(
-      {{.expression = *Expression::MakeInt(/*line_num=*/2, 42)}},
+      {{.expression = Expression::MakeInt(/*line_num=*/2, 42)}},
       ParenContents::HasTrailingComma::No);
 
   const Expression* tuple = contents.AsTuple(/*line_num=*/1);
@@ -56,7 +56,7 @@ TEST(ParenContentsTest, UnaryNoCommaAsTuple) {
 
 TEST(ParenContentsTest, UnaryWithCommaAsExpression) {
   ParenContents contents(
-      {{.expression = *Expression::MakeInt(/*line_num=*/2, 42)}},
+      {{.expression = Expression::MakeInt(/*line_num=*/2, 42)}},
       ParenContents::HasTrailingComma::Yes);
 
   const Expression* expression = contents.AsExpression(/*line_num=*/1);
@@ -69,7 +69,7 @@ TEST(ParenContentsTest, UnaryWithCommaAsExpression) {
 
 TEST(ParenContentsTest, UnaryWithCommaAsTuple) {
   ParenContents contents(
-      {{.expression = *Expression::MakeInt(/*line_num=*/2, 42)}},
+      {{.expression = Expression::MakeInt(/*line_num=*/2, 42)}},
       ParenContents::HasTrailingComma::Yes);
 
   const Expression* tuple = contents.AsTuple(/*line_num=*/1);
@@ -82,8 +82,8 @@ TEST(ParenContentsTest, UnaryWithCommaAsTuple) {
 
 TEST(ParenContentsTest, BinaryAsExpression) {
   ParenContents contents(
-      {{.expression = *Expression::MakeInt(/*line_num=*/2, 42)},
-       {.expression = *Expression::MakeInt(/*line_num=*/3, 42)}},
+      {{.expression = Expression::MakeInt(/*line_num=*/2, 42)},
+       {.expression = Expression::MakeInt(/*line_num=*/3, 42)}},
       ParenContents::HasTrailingComma::Yes);
 
   const Expression* expression = contents.AsExpression(/*line_num=*/1);
@@ -97,8 +97,8 @@ TEST(ParenContentsTest, BinaryAsExpression) {
 
 TEST(ParenContentsTest, BinaryAsTuple) {
   ParenContents contents(
-      {{.expression = *Expression::MakeInt(/*line_num=*/2, 42)},
-       {.expression = *Expression::MakeInt(/*line_num=*/3, 42)}},
+      {{.expression = Expression::MakeInt(/*line_num=*/2, 42)},
+       {.expression = Expression::MakeInt(/*line_num=*/3, 42)}},
       ParenContents::HasTrailingComma::Yes);
 
   const Expression* tuple = contents.AsTuple(/*line_num=*/1);

+ 38 - 38
executable_semantics/syntax/parser.ypp

@@ -110,8 +110,8 @@ void yy::parser::error(
 %type <Carbon::FieldInitializer> field_initializer
 %type <Carbon::ParenContents> paren_contents
 %type <std::vector<Carbon::FieldInitializer>> paren_contents_without_trailing_comma
-%type <std::pair<std::string, Carbon::Expression>> alternative
-%type <std::list<std::pair<std::string, Carbon::Expression>>> alternative_list
+%type <std::pair<std::string, const Carbon::Expression*>> alternative
+%type <std::list<std::pair<std::string, const Carbon::Expression*>>> alternative_list
 %type <std::pair<const Carbon::Expression*, const Carbon::Statement*>*> clause
 %type <std::list<std::pair<const Carbon::Expression*, const Carbon::Statement*>>*> clause_list
 %token END_OF_FILE 0
@@ -205,9 +205,9 @@ expression:
 | expression designator
     { $$ = Carbon::Expression::MakeGetField(yylineno, $1, $2); }
 | expression "[" expression "]"
-    { $$ = Carbon::Expression::MakeIndex(yylineno, *$1, *$3); }
+    { $$ = Carbon::Expression::MakeIndex(yylineno, $1, $3); }
 | identifier ":" expression
-    { $$ = Carbon::Expression::MakeVarPat(yylineno, $1, *$3); }
+    { $$ = Carbon::Expression::MakeVarPat(yylineno, $1, $3); }
 | integer_literal
     { $$ = Carbon::Expression::MakeInt(yylineno, $1); }
 | TRUE
@@ -226,33 +226,33 @@ expression:
     { $$ = Carbon::Expression::MakeContinuationType(yylineno); }
 | paren_expression { $$ = $1; }
 | expression EQUAL_EQUAL expression
-    { $$ = Carbon::Expression::MakeBinOp(yylineno, Carbon::Operator::Eq, *$1, *$3); }
+    { $$ = Carbon::Expression::MakeBinOp(yylineno, Carbon::Operator::Eq, $1, $3); }
 | expression "+" expression
-    { $$ = Carbon::Expression::MakeBinOp(yylineno, Carbon::Operator::Add, *$1, *$3); }
+    { $$ = Carbon::Expression::MakeBinOp(yylineno, Carbon::Operator::Add, $1, $3); }
 | expression "-" expression
-    { $$ = Carbon::Expression::MakeBinOp(yylineno, Carbon::Operator::Sub, *$1, *$3); }
+    { $$ = Carbon::Expression::MakeBinOp(yylineno, Carbon::Operator::Sub, $1, $3); }
 | expression BINARY_STAR expression
-    { $$ = Carbon::Expression::MakeBinOp(yylineno, Carbon::Operator::Mul, *$1, *$3); }
+    { $$ = Carbon::Expression::MakeBinOp(yylineno, Carbon::Operator::Mul, $1, $3); }
 | expression AND expression
-    { $$ = Carbon::Expression::MakeBinOp(yylineno, Carbon::Operator::And, *$1, *$3); }
+    { $$ = Carbon::Expression::MakeBinOp(yylineno, Carbon::Operator::And, $1, $3); }
 | expression OR expression
-    { $$ = Carbon::Expression::MakeBinOp(yylineno, Carbon::Operator::Or, *$1, *$3); }
+    { $$ = Carbon::Expression::MakeBinOp(yylineno, Carbon::Operator::Or, $1, $3); }
 | NOT expression
-    { $$ = Carbon::Expression::MakeUnOp(yylineno, Carbon::Operator::Not, *$2); }
+    { $$ = Carbon::Expression::MakeUnOp(yylineno, Carbon::Operator::Not, $2); }
 | "-" expression %prec UNARY_MINUS
-    { $$ = Carbon::Expression::MakeUnOp(yylineno, Carbon::Operator::Neg, *$2); }
+    { $$ = Carbon::Expression::MakeUnOp(yylineno, Carbon::Operator::Neg, $2); }
 | PREFIX_STAR expression
-    { $$ = Carbon::Expression::MakeUnOp(yylineno, Carbon::Operator::Deref, *$2); }
+    { $$ = Carbon::Expression::MakeUnOp(yylineno, Carbon::Operator::Deref, $2); }
 | UNARY_STAR expression %prec PREFIX_STAR
-    { $$ = Carbon::Expression::MakeUnOp(yylineno, Carbon::Operator::Deref, *$2); }
+    { $$ = Carbon::Expression::MakeUnOp(yylineno, Carbon::Operator::Deref, $2); }
 | expression tuple
-    { $$ = Carbon::Expression::MakeCall(yylineno, *$1, *$2); }
+    { $$ = Carbon::Expression::MakeCall(yylineno, $1, $2); }
 | expression POSTFIX_STAR
-    { $$ = Carbon::Expression::MakeUnOp(yylineno, Carbon::Operator::Ptr, *$1); }
+    { $$ = Carbon::Expression::MakeUnOp(yylineno, Carbon::Operator::Ptr, $1); }
 | expression UNARY_STAR
-    { $$ = Carbon::Expression::MakeUnOp(yylineno, Carbon::Operator::Ptr, *$1); }
+    { $$ = Carbon::Expression::MakeUnOp(yylineno, Carbon::Operator::Ptr, $1); }
 | FNTY tuple return_type
-    { $$ = Carbon::Expression::MakeFunType(yylineno, *$2, *$3); }
+    { $$ = Carbon::Expression::MakeFunType(yylineno, $2, $3); }
 ;
 designator: "." identifier { $$ = $2; }
 ;
@@ -264,9 +264,9 @@ tuple: "(" paren_contents ")"
 ;
 field_initializer:
   pattern
-    { $$ = Carbon::FieldInitializer({"", *$1}); }
+    { $$ = Carbon::FieldInitializer({"", $1}); }
 | designator "=" pattern
-    { $$ = Carbon::FieldInitializer({$1, *$3}); }
+    { $$ = Carbon::FieldInitializer({$1, $3}); }
 ;
 paren_contents:
   // Empty
@@ -297,7 +297,7 @@ clause:
 | DEFAULT DBLARROW statement
     {
       auto vp = Carbon::Expression::MakeVarPat(yylineno, "_",
-                                   *Carbon::Expression::MakeAutoType(yylineno));
+                                   Carbon::Expression::MakeAutoType(yylineno));
       $$ = new std::pair<const Carbon::Expression*, const Carbon::Statement*>(vp, $3);
     }
 ;
@@ -311,29 +311,29 @@ clause_list:
 ;
 statement:
   expression "=" expression ";"
-    { $$ = Carbon::Statement::MakeAssign(yylineno, *$1, *$3); }
+    { $$ = Carbon::Statement::MakeAssign(yylineno, $1, $3); }
 | VAR pattern "=" expression ";"
-    { $$ = Carbon::Statement::MakeVarDef(yylineno, *$2, *$4); }
+    { $$ = Carbon::Statement::MakeVarDef(yylineno, $2, $4); }
 | expression ";"
-    { $$ = Carbon::Statement::MakeExpStmt(yylineno, *$1); }
+    { $$ = Carbon::Statement::MakeExpStmt(yylineno, $1); }
 | IF "(" expression ")" statement optional_else
-    { $$ = Carbon::Statement::MakeIf(yylineno, *$3, $5, $6); }
+    { $$ = Carbon::Statement::MakeIf(yylineno, $3, $5, $6); }
 | WHILE "(" expression ")" statement
-    { $$ = Carbon::Statement::MakeWhile(yylineno, *$3, $5); }
+    { $$ = Carbon::Statement::MakeWhile(yylineno, $3, $5); }
 | BREAK ";"
     { $$ = Carbon::Statement::MakeBreak(yylineno); }
 | CONTINUE ";"
     { $$ = Carbon::Statement::MakeContinue(yylineno); }
 | RETURN expression ";"
-    { $$ = Carbon::Statement::MakeReturn(yylineno, *$2); }
+    { $$ = Carbon::Statement::MakeReturn(yylineno, $2); }
 | "{" statement_list "}"
     { $$ = Carbon::Statement::MakeBlock(yylineno, $2); }
 | MATCH "(" expression ")" "{" clause_list "}"
-    { $$ = Carbon::Statement::MakeMatch(yylineno, *$3, $6); }
+    { $$ = Carbon::Statement::MakeMatch(yylineno, $3, $6); }
 | CONTINUATION identifier statement
     { $$ = Carbon::Statement::MakeContinuation(yylineno, $2, $3); }
 | RUN expression ";"
-    { $$ = Carbon::Statement::MakeRun(yylineno, *$2); }
+    { $$ = Carbon::Statement::MakeRun(yylineno, $2); }
 | AWAIT ";"
     { $$ = Carbon::Statement::MakeAwait(yylineno); }
 ;
@@ -356,16 +356,16 @@ return_type:
 ;
 function_definition:
   FN identifier tuple return_type "{" statement_list "}"
-    { $$ = MakeFunDef(yylineno, $2, *$4, *$3, $6); }
+    { $$ = MakeFunDef(yylineno, $2, $4, $3, $6); }
 | FN identifier tuple DBLARROW expression ";"
     {
-      $$ = Carbon::MakeFunDef(yylineno, $2, *Carbon::Expression::MakeAutoType(yylineno), *$3,
-                              Carbon::Statement::MakeReturn(yylineno, *$5));
+      $$ = Carbon::MakeFunDef(yylineno, $2, Carbon::Expression::MakeAutoType(yylineno), $3,
+                              Carbon::Statement::MakeReturn(yylineno, $5));
     }
 ;
 function_declaration:
   FN identifier tuple return_type ";"
-    { $$ = MakeFunDef(yylineno, $2, *$4, *$3, 0); }
+    { $$ = MakeFunDef(yylineno, $2, $4, $3, 0); }
 ;
 variable_declaration: identifier ":" expression
     { $$ = MakeField(yylineno, $1, $3); }
@@ -381,19 +381,19 @@ member_list:
 ;
 alternative:
   identifier tuple
-    { $$ = std::pair<std::string, Carbon::Expression>($1, *$2); }
+    { $$ = std::pair<std::string, const Carbon::Expression*>($1, $2); }
 | identifier
     {
-      $$ = std::pair<std::string, Carbon::Expression>(
-          $1, *Carbon::Expression::MakeTuple(yylineno, {}));
+      $$ = std::pair<std::string, const Carbon::Expression*>(
+          $1, Carbon::Expression::MakeTuple(yylineno, {}));
     }
 ;
 alternative_list:
   // Empty
-    { $$ = std::list<std::pair<std::string, Carbon::Expression>>(); }
+    { $$ = std::list<std::pair<std::string, const Carbon::Expression*>>(); }
 | alternative
     {
-      $$ = std::list<std::pair<std::string, Carbon::Expression>>();
+      $$ = std::list<std::pair<std::string, const Carbon::Expression*>>();
       $$.push_front($1);
     }
 | alternative "," alternative_list