Просмотр исходного кода

rename env and ct_env (#419)

* change env to types, ct_env to values in type checker, change env to values in interpreter

* fix bazeliskrc, change to use latest (#420)
Jeremy G. Siek 5 лет назад
Родитель
Сommit
3d02412f2f

+ 43 - 42
executable_semantics/interpreter/interpreter.cpp

@@ -154,8 +154,8 @@ void KillObject(Address address) {
   }
 }
 
-void PrintEnv(Env env, std::ostream& out) {
-  for (const auto& [name, value] : env) {
+void PrintEnv(Env values, std::ostream& out) {
+  for (const auto& [name, value] : values) {
     out << name << ": ";
     PrintValue(state->heap[value], out);
     out << ", ";
@@ -196,7 +196,7 @@ void PrintHeap(const std::vector<const Value*>& heap, std::ostream& out) {
 
 auto CurrentEnv(State* state) -> Env {
   Frame* frame = state->stack.Top();
-  return frame->scopes.Top()->env;
+  return frame->scopes.Top()->values;
 }
 
 void PrintState(std::ostream& out) {
@@ -206,7 +206,7 @@ void PrintState(std::ostream& out) {
   out << std::endl << "heap: ";
   PrintHeap(state->heap, out);
   if (!state->stack.IsEmpty() && !state->stack.Top()->scopes.IsEmpty()) {
-    out << std::endl << "env: ";
+    out << std::endl << "values: ";
     PrintEnv(CurrentEnv(state), out);
   }
   out << std::endl << "}" << std::endl;
@@ -328,8 +328,8 @@ auto StructDeclaration::InitGlobals(Env& globals) const -> void {
 }
 
 auto FunctionDeclaration::InitGlobals(Env& globals) const -> void {
-  Env env;
-  auto pt = InterpExp(env, definition->param_pattern);
+  Env values;
+  auto pt = InterpExp(values, definition->param_pattern);
   auto f = MakeFunVal(definition->name, pt, definition->body);
   Address a = AllocateValue(f);
   globals.Set(definition->name, a);
@@ -353,15 +353,15 @@ void CallFunction(int line_num, std::vector<const Value*> operas,
     case ValKind::FunV: {
       // Bind arguments to parameters
       std::list<std::string> params;
-      std::optional<Env> env_with_matches = PatternMatch(
+      std::optional<Env> matches = PatternMatch(
           operas[0]->u.fun.param, operas[1], globals, &params, line_num);
-      if (!env_with_matches) {
+      if (!matches) {
         std::cerr << "internal error in call_function, pattern match failed"
                   << std::endl;
         exit(-1);
       }
       // Create the new frame and push it on the stack
-      auto* scope = new Scope(*env_with_matches, params);
+      auto* scope = new Scope(*matches, params);
       auto* frame = new Frame(*operas[0]->u.fun.name, Stack(scope),
                               Stack(MakeStmtAct(operas[0]->u.fun.body)));
       state->stack.Push(frame);
@@ -393,7 +393,7 @@ void CallFunction(int line_num, std::vector<const Value*> operas,
 
 void KillScope(int line_num, Scope* scope) {
   for (const auto& l : scope->locals) {
-    std::optional<Address> a = scope->env.Get(l);
+    std::optional<Address> a = scope->values.Get(l);
     if (!a) {
       std::cerr << "internal error in KillScope" << std::endl;
       exit(-1);
@@ -427,15 +427,15 @@ void CreateTuple(Frame* frame, Action* act, Expression* /*exp*/) {
 //
 // The names of the pattern variables are added to the vars parameter.
 // Returns nullopt if the value doesn't match the pattern.
-auto PatternMatch(const Value* p, const Value* v, Env env,
+auto PatternMatch(const Value* p, const Value* v, Env values,
                   std::list<std::string>* vars, int line_num)
     -> std::optional<Env> {
   switch (p->tag) {
     case ValKind::VarPatV: {
       Address a = AllocateValue(CopyVal(v, line_num));
       vars->push_back(*p->u.var_pat.name);
-      env.Set(*p->u.var_pat.name, a);
-      return env;
+      values.Set(*p->u.var_pat.name, a);
+      return values;
     }
     case ValKind::TupleV:
       switch (v->tag) {
@@ -453,14 +453,15 @@ auto PatternMatch(const Value* p, const Value* v, Env env,
               std::cerr << std::endl;
               exit(-1);
             }
-            std::optional<Env> env_with_matches = PatternMatch(
-                state->heap[elt.second], state->heap[*a], env, vars, line_num);
-            if (!env_with_matches) {
+            std::optional<Env> matches =
+                PatternMatch(state->heap[elt.second], state->heap[*a], values,
+                             vars, line_num);
+            if (!matches) {
               return std::nullopt;
             }
-            env = *env_with_matches;
+            values = *matches;
           }  // for
-          return env;
+          return values;
         }
         default:
           std::cerr
@@ -476,13 +477,13 @@ auto PatternMatch(const Value* p, const Value* v, Env env,
               *p->u.alt.alt_name != *v->u.alt.alt_name) {
             return std::nullopt;
           }
-          std::optional<Env> env_with_matches =
-              PatternMatch(state->heap[p->u.alt.argument],
-                           state->heap[v->u.alt.argument], env, vars, line_num);
-          if (!env_with_matches) {
+          std::optional<Env> matches = PatternMatch(
+              state->heap[p->u.alt.argument], state->heap[v->u.alt.argument],
+              values, vars, line_num);
+          if (!matches) {
             return std::nullopt;
           }
-          return *env_with_matches;
+          return *matches;
         }
         default:
           std::cerr
@@ -495,20 +496,20 @@ auto PatternMatch(const Value* p, const Value* v, Env env,
     case ValKind::FunctionTV:
       switch (v->tag) {
         case ValKind::FunctionTV: {
-          std::optional<Env> env_with_matches = PatternMatch(
-              p->u.fun_type.param, v->u.fun_type.param, env, vars, line_num);
-          if (!env_with_matches) {
+          std::optional<Env> matches = PatternMatch(
+              p->u.fun_type.param, v->u.fun_type.param, values, vars, line_num);
+          if (!matches) {
             return std::nullopt;
           }
-          return PatternMatch(p->u.fun_type.ret, v->u.fun_type.ret,
-                              *env_with_matches, vars, line_num);
+          return PatternMatch(p->u.fun_type.ret, v->u.fun_type.ret, *matches,
+                              vars, line_num);
         }
         default:
           return std::nullopt;
       }
     default:
       if (ValueEqual(p, v, line_num)) {
-        return env;
+        return values;
       } else {
         return std::nullopt;
       }
@@ -925,8 +926,8 @@ void StepStmt() {
       // Store the continuation's address in the frame.
       continuation_frame->continuation = continuation_address;
       // Bind the continuation object to the continuation variable
-      frame->scopes.Top()->env.Set(*stmt->u.continuation.continuation_variable,
-                                   continuation_address);
+      frame->scopes.Top()->values.Set(
+          *stmt->u.continuation.continuation_variable, continuation_address);
       // Pop the continuation statement.
       frame->todo.Pop();
       break;
@@ -1249,17 +1250,17 @@ void HandleValue() {
             const Value* v = act->results[0];
             const Value* p = act->results[1];
 
-            std::optional<Env> env_with_matches =
-                PatternMatch(p, v, frame->scopes.Top()->env,
+            std::optional<Env> matches =
+                PatternMatch(p, v, frame->scopes.Top()->values,
                              &frame->scopes.Top()->locals, stmt->line_num);
-            if (!env_with_matches) {
+            if (!matches) {
               std::cerr
                   << stmt->line_num
                   << ": internal error in variable definition, match failed"
                   << std::endl;
               exit(-1);
             }
-            frame->scopes.Top()->env = *env_with_matches;
+            frame->scopes.Top()->values = *matches;
             frame->todo.Pop(2);
           }
           break;
@@ -1341,12 +1342,12 @@ void HandleValue() {
           } else {  // try to match
             auto v = act->results[0];
             auto pat = act->results[clause_num + 1];
-            auto env = CurrentEnv(state);
+            auto values = CurrentEnv(state);
             std::list<std::string> vars;
-            std::optional<Env> env_with_matches =
-                PatternMatch(pat, v, env, &vars, stmt->line_num);
-            if (env_with_matches) {  // we have a match, start the body
-              auto* new_scope = new Scope(*env_with_matches, vars);
+            std::optional<Env> matches =
+                PatternMatch(pat, v, values, &vars, stmt->line_num);
+            if (matches) {  // we have a match, start the body
+              auto* new_scope = new Scope(*matches, vars);
               frame->scopes.Push(new_scope);
               Statement* body_block = MakeBlock(stmt->line_num, c->second);
               Action* body_act = MakeStmtAct(body_block);
@@ -1486,9 +1487,9 @@ auto InterpProgram(std::list<Declaration>* fs) -> int {
 }
 
 // Interpret an expression at compile-time.
-auto InterpExp(Env env, Expression* e) -> const Value* {
+auto InterpExp(Env values, Expression* e) -> const Value* {
   auto todo = Stack(MakeExpAct(e));
-  auto* scope = new Scope(env, std::list<std::string>());
+  auto* scope = new Scope(values, std::list<std::string>());
   auto* frame = new Frame("InterpExp", Stack(scope), todo);
   state->stack = Stack(frame);
 

+ 5 - 4
executable_semantics/interpreter/interpreter.h

@@ -22,8 +22,9 @@ using Env = Dictionary<std::string, Address>;
 /***** Scopes *****/
 
 struct Scope {
-  Scope(Env e, std::list<std::string> l) : env(e), locals(std::move(l)) {}
-  Env env;
+  Scope(Env values, std::list<std::string> l)
+      : values(values), locals(std::move(l)) {}
+  Env values;
   std::list<std::string> locals;
 };
 
@@ -68,7 +69,7 @@ extern State* state;
 
 auto PrintFrame(Frame* frame, std::ostream& out) -> void;
 void PrintStack(Stack<Frame*> ls, std::ostream& out);
-void PrintEnv(Env env);
+void PrintEnv(Env values);
 auto AllocateValue(const Value* v) -> Address;
 auto CopyVal(const Value* val, int line_num) -> const Value*;
 auto ToInteger(const Value* v) -> int;
@@ -76,7 +77,7 @@ auto ToInteger(const Value* v) -> int;
 /***** Interpreters *****/
 
 auto InterpProgram(std::list<Declaration>* fs) -> int;
-auto InterpExp(Env env, Expression* e) -> const Value*;
+auto InterpExp(Env values, Expression* e) -> const Value*;
 
 }  // namespace Carbon
 

+ 112 - 109
executable_semantics/interpreter/typecheck.cpp

@@ -31,8 +31,8 @@ void ExpectType(int line_num, const std::string& context, const Value* expected,
 
 void PrintErrorString(const std::string& s) { std::cerr << s; }
 
-void PrintTypeEnv(TypeEnv env, std::ostream& out) {
-  for (const auto& [name, value] : env) {
+void PrintTypeEnv(TypeEnv types, std::ostream& out) {
+  for (const auto& [name, value] : types) {
     out << name << ": ";
     PrintValue(value, out);
     out << ", ";
@@ -132,16 +132,16 @@ auto ReifyType(const Value* t, int line_num) -> Expression* {
 // generic.
 //
 // e is the expression to be analyzed.
-// env maps variable names to the type of their run-time value.
-// ct_env maps variable names to their compile-time values. It is not
+// 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.
 // expected is the type that this expression is expected to have.
 //    This parameter is non-null when the expression is in a pattern context
 //    and it is used to implement `auto`, otherwise it is null.
 // context says what kind of position this expression is nested in,
 //    whether it's a position that expects a value, a pattern, or a type.
-auto TypeCheckExp(Expression* e, TypeEnv env, Env ct_env, const Value* expected,
-                  TCContext context) -> TCResult {
+auto TypeCheckExp(Expression* e, TypeEnv types, Env values,
+                  const Value* expected, TCContext context) -> TCResult {
   switch (e->tag) {
     case ExpressionKind::PatternVariable: {
       if (context != TCContext::PatternContext) {
@@ -153,7 +153,7 @@ auto TypeCheckExp(Expression* e, TypeEnv env, Env ct_env, const Value* expected,
         exit(-1);
       }
       auto t =
-          ToType(e->line_num, InterpExp(ct_env, e->u.pattern_variable.type));
+          ToType(e->line_num, InterpExp(values, e->u.pattern_variable.type));
       if (t->tag == ValKind::AutoTV) {
         if (expected == nullptr) {
           std::cerr << e->line_num
@@ -166,16 +166,16 @@ auto TypeCheckExp(Expression* e, TypeEnv env, Env ct_env, const Value* expected,
       }
       auto new_e = MakeVarPat(e->line_num, *e->u.pattern_variable.name,
                               ReifyType(t, e->line_num));
-      env.Set(*e->u.pattern_variable.name, t);
-      return TCResult(new_e, t, env);
+      types.Set(*e->u.pattern_variable.name, t);
+      return TCResult(new_e, t, types);
     }
     case ExpressionKind::Index: {
-      auto res = TypeCheckExp(e->u.get_field.aggregate, env, ct_env, nullptr,
+      auto res = TypeCheckExp(e->u.get_field.aggregate, types, values, nullptr,
                               TCContext::ValueContext);
       auto t = res.type;
       switch (t->tag) {
         case ValKind::TupleTV: {
-          auto i = ToInteger(InterpExp(ct_env, e->u.index.offset));
+          auto i = ToInteger(InterpExp(values, e->u.index.offset));
           std::string f = std::to_string(i);
           auto field_t = FindInVarValues(f, t->u.tuple_type.fields);
           if (field_t == nullptr) {
@@ -186,7 +186,7 @@ auto TypeCheckExp(Expression* e, TypeEnv env, Env ct_env, const Value* expected,
             exit(-1);
           }
           auto new_e = MakeIndex(e->line_num, res.exp, MakeInt(e->line_num, i));
-          return TCResult(new_e, field_t, res.env);
+          return TCResult(new_e, field_t, res.types);
         }
         default:
           std::cerr << e->line_num << ": compilation error, expected a tuple"
@@ -197,7 +197,7 @@ auto TypeCheckExp(Expression* e, TypeEnv env, Env ct_env, const Value* expected,
     case ExpressionKind::Tuple: {
       auto new_args = new std::vector<std::pair<std::string, Expression*>>();
       auto arg_types = new VarValues();
-      auto new_env = env;
+      auto new_types = types;
       int i = 0;
       for (auto arg = e->u.tuple.fields->begin();
            arg != e->u.tuple.fields->end(); ++arg, ++i) {
@@ -212,17 +212,17 @@ auto TypeCheckExp(Expression* e, TypeEnv env, Env ct_env, const Value* expected,
           }
         }
         auto arg_res =
-            TypeCheckExp(arg->second, new_env, ct_env, arg_expected, context);
-        new_env = arg_res.env;
+            TypeCheckExp(arg->second, new_types, values, arg_expected, context);
+        new_types = arg_res.types;
         new_args->push_back(std::make_pair(arg->first, arg_res.exp));
         arg_types->push_back(std::make_pair(arg->first, arg_res.type));
       }
       auto tuple_e = MakeTuple(e->line_num, new_args);
       auto tuple_t = MakeTupleTypeVal(arg_types);
-      return TCResult(tuple_e, tuple_t, new_env);
+      return TCResult(tuple_e, tuple_t, new_types);
     }
     case ExpressionKind::GetField: {
-      auto res = TypeCheckExp(e->u.get_field.aggregate, env, ct_env, nullptr,
+      auto res = TypeCheckExp(e->u.get_field.aggregate, types, values, nullptr,
                               TCContext::ValueContext);
       auto t = res.type;
       switch (t->tag) {
@@ -232,7 +232,7 @@ auto TypeCheckExp(Expression* e, TypeEnv env, Env ct_env, const Value* expected,
             if (*e->u.get_field.field == field.first) {
               Expression* new_e =
                   MakeGetField(e->line_num, res.exp, *e->u.get_field.field);
-              return TCResult(new_e, field.second, res.env);
+              return TCResult(new_e, field.second, res.types);
             }
           }
           // Search for a method
@@ -240,7 +240,7 @@ auto TypeCheckExp(Expression* e, TypeEnv env, Env ct_env, const Value* expected,
             if (*e->u.get_field.field == method.first) {
               Expression* new_e =
                   MakeGetField(e->line_num, res.exp, *e->u.get_field.field);
-              return TCResult(new_e, method.second, res.env);
+              return TCResult(new_e, method.second, res.types);
             }
           }
           std::cerr << e->line_num << ": compilation error, struct "
@@ -252,7 +252,7 @@ auto TypeCheckExp(Expression* e, TypeEnv env, Env ct_env, const Value* expected,
             if (*e->u.get_field.field == field.first) {
               auto new_e =
                   MakeGetField(e->line_num, res.exp, *e->u.get_field.field);
-              return TCResult(new_e, field.second, res.env);
+              return TCResult(new_e, field.second, res.types);
             }
           }
           std::cerr << e->line_num << ": compilation error, struct "
@@ -266,7 +266,7 @@ auto TypeCheckExp(Expression* e, TypeEnv env, Env ct_env, const Value* expected,
               Expression* new_e =
                   MakeGetField(e->line_num, res.exp, *e->u.get_field.field);
               auto fun_ty = MakeFunTypeVal(vt->second, t);
-              return TCResult(new_e, fun_ty, res.env);
+              return TCResult(new_e, fun_ty, res.types);
             }
           }
           std::cerr << e->line_num << ": compilation error, struct "
@@ -284,9 +284,9 @@ auto TypeCheckExp(Expression* e, TypeEnv env, Env ct_env, const Value* expected,
       }
     }
     case ExpressionKind::Variable: {
-      std::optional<const Value*> type = env.Get(*(e->u.variable.name));
+      std::optional<const Value*> type = types.Get(*(e->u.variable.name));
       if (type) {
-        return TCResult(e, *type, env);
+        return TCResult(e, *type, types);
       } else {
         std::cerr << e->line_num << ": could not find `"
                   << *(e->u.variable.name) << "`" << std::endl;
@@ -294,17 +294,17 @@ auto TypeCheckExp(Expression* e, TypeEnv env, Env ct_env, const Value* expected,
       }
     }
     case ExpressionKind::Integer:
-      return TCResult(e, MakeIntTypeVal(), env);
+      return TCResult(e, MakeIntTypeVal(), types);
     case ExpressionKind::Boolean:
-      return TCResult(e, MakeBoolTypeVal(), env);
+      return TCResult(e, MakeBoolTypeVal(), types);
     case ExpressionKind::PrimitiveOp: {
       auto es = new std::vector<Expression*>();
       std::vector<const Value*> ts;
-      auto new_env = env;
+      auto new_types = types;
       for (auto& argument : *e->u.primitive_op.arguments) {
-        auto res = TypeCheckExp(argument, env, ct_env, nullptr,
+        auto res = TypeCheckExp(argument, types, values, nullptr,
                                 TCContext::ValueContext);
-        new_env = res.env;
+        new_types = res.types;
         es->push_back(res.exp);
         ts.push_back(res.type);
       }
@@ -312,42 +312,42 @@ auto TypeCheckExp(Expression* e, TypeEnv env, Env ct_env, const Value* expected,
       switch (e->u.primitive_op.op) {
         case Operator::Neg:
           ExpectType(e->line_num, "negation", MakeIntTypeVal(), ts[0]);
-          return TCResult(new_e, MakeIntTypeVal(), new_env);
+          return TCResult(new_e, MakeIntTypeVal(), new_types);
         case Operator::Add:
         case Operator::Sub:
           ExpectType(e->line_num, "subtraction(1)", MakeIntTypeVal(), ts[0]);
           ExpectType(e->line_num, "substration(2)", MakeIntTypeVal(), ts[1]);
-          return TCResult(new_e, MakeIntTypeVal(), new_env);
+          return TCResult(new_e, MakeIntTypeVal(), new_types);
         case Operator::And:
           ExpectType(e->line_num, "&&(1)", MakeBoolTypeVal(), ts[0]);
           ExpectType(e->line_num, "&&(2)", MakeBoolTypeVal(), ts[1]);
-          return TCResult(new_e, MakeBoolTypeVal(), new_env);
+          return TCResult(new_e, MakeBoolTypeVal(), new_types);
         case Operator::Or:
           ExpectType(e->line_num, "||(1)", MakeBoolTypeVal(), ts[0]);
           ExpectType(e->line_num, "||(2)", MakeBoolTypeVal(), ts[1]);
-          return TCResult(new_e, MakeBoolTypeVal(), new_env);
+          return TCResult(new_e, MakeBoolTypeVal(), new_types);
         case Operator::Not:
           ExpectType(e->line_num, "!", MakeBoolTypeVal(), ts[0]);
-          return TCResult(new_e, MakeBoolTypeVal(), new_env);
+          return TCResult(new_e, MakeBoolTypeVal(), new_types);
         case Operator::Eq:
           ExpectType(e->line_num, "==(1)", MakeIntTypeVal(), ts[0]);
           ExpectType(e->line_num, "==(2)", MakeIntTypeVal(), ts[1]);
-          return TCResult(new_e, MakeBoolTypeVal(), new_env);
+          return TCResult(new_e, MakeBoolTypeVal(), new_types);
       }
       break;
     }
     case ExpressionKind::Call: {
-      auto fun_res = TypeCheckExp(e->u.call.function, env, ct_env, nullptr,
+      auto fun_res = TypeCheckExp(e->u.call.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->u.call.argument, fun_res.env, ct_env,
+          auto arg_res = TypeCheckExp(e->u.call.argument, fun_res.types, values,
                                       fun_t->u.fun_type.param, context);
           ExpectType(e->line_num, "call", fun_t->u.fun_type.param,
                      arg_res.type);
           auto new_e = MakeCall(e->line_num, fun_res.exp, arg_res.exp);
-          return TCResult(new_e, fun_t->u.fun_type.ret, arg_res.env);
+          return TCResult(new_e, fun_t->u.fun_type.ret, arg_res.types);
         }
         default: {
           std::cerr << e->line_num
@@ -365,44 +365,45 @@ auto TypeCheckExp(Expression* e, TypeEnv env, Env ct_env, const Value* expected,
         case TCContext::ValueContext:
         case TCContext::TypeContext: {
           auto pt = ToType(e->line_num,
-                           InterpExp(ct_env, e->u.function_type.parameter));
+                           InterpExp(values, e->u.function_type.parameter));
           auto rt = ToType(e->line_num,
-                           InterpExp(ct_env, e->u.function_type.return_type));
+                           InterpExp(values, e->u.function_type.return_type));
           auto new_e = MakeFunType(e->line_num, ReifyType(pt, e->line_num),
                                    ReifyType(rt, e->line_num));
-          return TCResult(new_e, MakeTypeTypeVal(), env);
+          return TCResult(new_e, MakeTypeTypeVal(), types);
         }
         case TCContext::PatternContext: {
-          auto param_res = TypeCheckExp(e->u.function_type.parameter, env,
-                                        ct_env, nullptr, context);
-          auto ret_res = TypeCheckExp(e->u.function_type.return_type,
-                                      param_res.env, ct_env, nullptr, context);
+          auto param_res = TypeCheckExp(e->u.function_type.parameter, types,
+                                        values, nullptr, context);
+          auto ret_res =
+              TypeCheckExp(e->u.function_type.return_type, param_res.types,
+                           values, nullptr, context);
           auto new_e =
               MakeFunType(e->line_num, ReifyType(param_res.type, e->line_num),
                           ReifyType(ret_res.type, e->line_num));
-          return TCResult(new_e, MakeTypeTypeVal(), ret_res.env);
+          return TCResult(new_e, MakeTypeTypeVal(), ret_res.types);
         }
       }
     }
     case ExpressionKind::IntT:
-      return TCResult(e, MakeIntTypeVal(), env);
+      return TCResult(e, MakeIntTypeVal(), types);
     case ExpressionKind::BoolT:
-      return TCResult(e, MakeBoolTypeVal(), env);
+      return TCResult(e, MakeBoolTypeVal(), types);
     case ExpressionKind::TypeT:
-      return TCResult(e, MakeTypeTypeVal(), env);
+      return TCResult(e, MakeTypeTypeVal(), types);
     case ExpressionKind::AutoT:
-      return TCResult(e, MakeAutoTypeVal(), env);
+      return TCResult(e, MakeAutoTypeVal(), types);
     case ExpressionKind::ContinuationT:
-      return TCResult(e, MakeContinuationTypeVal(), env);
+      return TCResult(e, MakeContinuationTypeVal(), types);
   }
 }
 
 auto TypecheckCase(const Value* expected, Expression* pat, Statement* body,
-                   TypeEnv env, Env ct_env, const Value*& ret_type)
+                   TypeEnv types, Env values, const Value*& ret_type)
     -> std::pair<Expression*, Statement*> {
   auto pat_res =
-      TypeCheckExp(pat, env, ct_env, expected, TCContext::PatternContext);
-  auto res = TypeCheckStmt(body, pat_res.env, ct_env, ret_type);
+      TypeCheckExp(pat, types, values, expected, TCContext::PatternContext);
+  auto res = TypeCheckStmt(body, pat_res.types, values, ret_type);
   return std::make_pair(pat, res.stmt);
 }
 
@@ -413,90 +414,92 @@ auto TypecheckCase(const Value* expected, Expression* pat, Statement* body,
 // It is the 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(Statement* s, TypeEnv env, Env ct_env,
+auto TypeCheckStmt(Statement* s, TypeEnv types, Env values,
                    const Value*& ret_type) -> TCStatement {
   if (!s) {
-    return TCStatement(s, env);
+    return TCStatement(s, types);
   }
   switch (s->tag) {
     case StatementKind::Match: {
-      auto res = TypeCheckExp(s->u.match_stmt.exp, env, ct_env, nullptr,
+      auto res = TypeCheckExp(s->u.match_stmt.exp, types, values, nullptr,
                               TCContext::ValueContext);
       auto res_type = res.type;
       auto new_clauses = new std::list<std::pair<Expression*, Statement*>>();
       for (auto& clause : *s->u.match_stmt.clauses) {
         new_clauses->push_back(TypecheckCase(
-            res_type, clause.first, clause.second, env, ct_env, ret_type));
+            res_type, clause.first, clause.second, types, values, ret_type));
       }
       Statement* new_s = MakeMatch(s->line_num, res.exp, new_clauses);
-      return TCStatement(new_s, env);
+      return TCStatement(new_s, types);
     }
     case StatementKind::While: {
-      auto cnd_res = TypeCheckExp(s->u.while_stmt.cond, env, ct_env, nullptr,
+      auto cnd_res = TypeCheckExp(s->u.while_stmt.cond, types, values, nullptr,
                                   TCContext::ValueContext);
       ExpectType(s->line_num, "condition of `while`", MakeBoolTypeVal(),
                  cnd_res.type);
       auto body_res =
-          TypeCheckStmt(s->u.while_stmt.body, env, ct_env, ret_type);
+          TypeCheckStmt(s->u.while_stmt.body, types, values, ret_type);
       auto new_s = MakeWhile(s->line_num, cnd_res.exp, body_res.stmt);
-      return TCStatement(new_s, env);
+      return TCStatement(new_s, types);
     }
     case StatementKind::Break:
     case StatementKind::Continue:
-      return TCStatement(s, env);
+      return TCStatement(s, types);
     case StatementKind::Block: {
-      auto stmt_res = TypeCheckStmt(s->u.block.stmt, env, ct_env, ret_type);
-      return TCStatement(MakeBlock(s->line_num, stmt_res.stmt), env);
+      auto stmt_res = TypeCheckStmt(s->u.block.stmt, types, values, ret_type);
+      return TCStatement(MakeBlock(s->line_num, stmt_res.stmt), types);
     }
     case StatementKind::VariableDefinition: {
-      auto res = TypeCheckExp(s->u.variable_definition.init, env, ct_env,
+      auto res = TypeCheckExp(s->u.variable_definition.init, types, values,
                               nullptr, TCContext::ValueContext);
       const Value* rhs_ty = res.type;
-      auto lhs_res = TypeCheckExp(s->u.variable_definition.pat, env, ct_env,
+      auto lhs_res = TypeCheckExp(s->u.variable_definition.pat, types, values,
                                   rhs_ty, TCContext::PatternContext);
       Statement* new_s =
           MakeVarDef(s->line_num, s->u.variable_definition.pat, res.exp);
-      return TCStatement(new_s, lhs_res.env);
+      return TCStatement(new_s, lhs_res.types);
     }
     case StatementKind::Sequence: {
-      auto stmt_res = TypeCheckStmt(s->u.sequence.stmt, env, ct_env, ret_type);
-      auto env2 = stmt_res.env;
-      auto next_res = TypeCheckStmt(s->u.sequence.next, env2, ct_env, ret_type);
-      auto env3 = next_res.env;
+      auto stmt_res =
+          TypeCheckStmt(s->u.sequence.stmt, types, values, ret_type);
+      auto types2 = stmt_res.types;
+      auto next_res =
+          TypeCheckStmt(s->u.sequence.next, types2, values, ret_type);
+      auto types3 = next_res.types;
       return TCStatement(MakeSeq(s->line_num, stmt_res.stmt, next_res.stmt),
-                         env3);
+                         types3);
     }
     case StatementKind::Assign: {
-      auto rhs_res = TypeCheckExp(s->u.assign.rhs, env, ct_env, nullptr,
+      auto rhs_res = TypeCheckExp(s->u.assign.rhs, types, values, nullptr,
                                   TCContext::ValueContext);
       auto rhs_t = rhs_res.type;
-      auto lhs_res = TypeCheckExp(s->u.assign.lhs, env, ct_env, rhs_t,
+      auto lhs_res = TypeCheckExp(s->u.assign.lhs, types, values, rhs_t,
                                   TCContext::ValueContext);
       auto lhs_t = lhs_res.type;
       ExpectType(s->line_num, "assign", lhs_t, rhs_t);
       auto new_s = MakeAssign(s->line_num, lhs_res.exp, rhs_res.exp);
-      return TCStatement(new_s, lhs_res.env);
+      return TCStatement(new_s, lhs_res.types);
     }
     case StatementKind::ExpressionStatement: {
-      auto res =
-          TypeCheckExp(s->u.exp, env, ct_env, nullptr, TCContext::ValueContext);
+      auto res = TypeCheckExp(s->u.exp, types, values, nullptr,
+                              TCContext::ValueContext);
       auto new_s = MakeExpStmt(s->line_num, res.exp);
-      return TCStatement(new_s, env);
+      return TCStatement(new_s, types);
     }
     case StatementKind::If: {
-      auto cnd_res = TypeCheckExp(s->u.if_stmt.cond, env, ct_env, nullptr,
+      auto cnd_res = TypeCheckExp(s->u.if_stmt.cond, types, values, nullptr,
                                   TCContext::ValueContext);
       ExpectType(s->line_num, "condition of `if`", MakeBoolTypeVal(),
                  cnd_res.type);
       auto thn_res =
-          TypeCheckStmt(s->u.if_stmt.then_stmt, env, ct_env, ret_type);
+          TypeCheckStmt(s->u.if_stmt.then_stmt, types, values, ret_type);
       auto els_res =
-          TypeCheckStmt(s->u.if_stmt.else_stmt, env, ct_env, ret_type);
+          TypeCheckStmt(s->u.if_stmt.else_stmt, types, values, ret_type);
       auto new_s = MakeIf(s->line_num, cnd_res.exp, thn_res.stmt, els_res.stmt);
-      return TCStatement(new_s, env);
+      return TCStatement(new_s, types);
     }
     case StatementKind::Return: {
-      auto res = TypeCheckExp(s->u.return_stmt, env, ct_env, nullptr,
+      auto res = TypeCheckExp(s->u.return_stmt, types, values, nullptr,
                               TCContext::ValueContext);
       if (ret_type->tag == ValKind::AutoTV) {
         // The following infers the return type from the first 'return'
@@ -506,29 +509,29 @@ auto TypeCheckStmt(Statement* s, TypeEnv env, Env ct_env,
       } else {
         ExpectType(s->line_num, "return", ret_type, res.type);
       }
-      return TCStatement(MakeReturn(s->line_num, res.exp), env);
+      return TCStatement(MakeReturn(s->line_num, res.exp), types);
     }
     case StatementKind::Continuation: {
       TCStatement body_result =
-          TypeCheckStmt(s->u.continuation.body, env, ct_env, ret_type);
+          TypeCheckStmt(s->u.continuation.body, types, values, ret_type);
       Statement* new_continuation = MakeContinuationStatement(
           s->line_num, *s->u.continuation.continuation_variable,
           body_result.stmt);
-      env.Set(*s->u.continuation.continuation_variable,
-              MakeContinuationTypeVal());
-      return TCStatement(new_continuation, env);
+      types.Set(*s->u.continuation.continuation_variable,
+                MakeContinuationTypeVal());
+      return TCStatement(new_continuation, types);
     }
     case StatementKind::Run: {
-      TCResult argument_result = TypeCheckExp(s->u.run.argument, env, ct_env,
+      TCResult argument_result = TypeCheckExp(s->u.run.argument, types, values,
                                               nullptr, TCContext::ValueContext);
       ExpectType(s->line_num, "argument of `run`", MakeContinuationTypeVal(),
                  argument_result.type);
       Statement* new_run = MakeRun(s->line_num, argument_result.exp);
-      return TCStatement(new_run, env);
+      return TCStatement(new_run, types);
     }
     case StatementKind::Await: {
       // nothing to do here
-      return TCStatement(s, env);
+      return TCStatement(s, types);
     }
   }  // switch
 }
@@ -603,37 +606,37 @@ auto CheckOrEnsureReturn(Statement* stmt, bool void_return, int line_num)
   }
 }
 
-auto TypeCheckFunDef(const FunctionDefinition* f, TypeEnv env, Env ct_env)
+auto TypeCheckFunDef(const FunctionDefinition* f, TypeEnv types, Env values)
     -> struct FunctionDefinition* {
-  auto param_res = TypeCheckExp(f->param_pattern, env, ct_env, nullptr,
+  auto param_res = TypeCheckExp(f->param_pattern, types, values, nullptr,
                                 TCContext::PatternContext);
-  auto return_type = ToType(f->line_num, InterpExp(ct_env, f->return_type));
+  auto return_type = ToType(f->line_num, InterpExp(values, f->return_type));
   if (f->name == "main") {
     ExpectType(f->line_num, "return type of `main`", MakeIntTypeVal(),
                return_type);
     // TODO: Check that main doesn't have any parameters.
   }
-  auto res = TypeCheckStmt(f->body, param_res.env, ct_env, return_type);
+  auto res = TypeCheckStmt(f->body, param_res.types, values, return_type);
   bool void_return = TypeEqual(return_type, MakeVoidTypeVal());
   auto body = CheckOrEnsureReturn(res.stmt, void_return, f->line_num);
   return MakeFunDef(f->line_num, f->name, ReifyType(return_type, f->line_num),
                     f->param_pattern, body);
 }
 
-auto TypeOfFunDef(TypeEnv env, Env ct_env, const FunctionDefinition* fun_def)
+auto TypeOfFunDef(TypeEnv types, Env values, const FunctionDefinition* fun_def)
     -> const Value* {
-  auto param_res = TypeCheckExp(fun_def->param_pattern, env, ct_env, nullptr,
+  auto param_res = TypeCheckExp(fun_def->param_pattern, types, values, nullptr,
                                 TCContext::PatternContext);
   auto param_type = ToType(fun_def->line_num, param_res.type);
-  auto ret = InterpExp(ct_env, fun_def->return_type);
+  auto ret = InterpExp(values, fun_def->return_type);
   if (ret->tag == ValKind::AutoTV) {
-    auto f = TypeCheckFunDef(fun_def, env, ct_env);
-    ret = InterpExp(ct_env, f->return_type);
+    auto f = TypeCheckFunDef(fun_def, types, values);
+    ret = InterpExp(values, f->return_type);
   }
   return MakeFunTypeVal(param_type, ret);
 }
 
-auto TypeOfStructDef(const StructDefinition* sd, TypeEnv /*env*/, Env ct_top)
+auto TypeOfStructDef(const StructDefinition* sd, TypeEnv /*types*/, Env ct_top)
     -> const Value* {
   auto fields = new VarValues();
   auto methods = new VarValues();
@@ -657,7 +660,7 @@ auto ChoiceDeclaration::Name() const -> std::string { return name; }
 // Returns the name of the declared variable.
 auto VariableDeclaration::Name() const -> std::string { return name; }
 
-auto StructDeclaration::TypeChecked(TypeEnv env, Env ct_env) const
+auto StructDeclaration::TypeChecked(TypeEnv types, Env values) const
     -> Declaration {
   auto fields = new std::list<Member*>();
   for (auto& m : *definition.members) {
@@ -669,12 +672,12 @@ auto StructDeclaration::TypeChecked(TypeEnv env, Env ct_env) const
   return StructDeclaration(definition.line_num, *definition.name, fields);
 }
 
-auto FunctionDeclaration::TypeChecked(TypeEnv env, Env ct_env) const
+auto FunctionDeclaration::TypeChecked(TypeEnv types, Env values) const
     -> Declaration {
-  return FunctionDeclaration(TypeCheckFunDef(definition, env, ct_env));
+  return FunctionDeclaration(TypeCheckFunDef(definition, types, values));
 }
 
-auto ChoiceDeclaration::TypeChecked(TypeEnv env, Env ct_env) const
+auto ChoiceDeclaration::TypeChecked(TypeEnv types, Env values) const
     -> Declaration {
   return *this;  // TODO.
 }
@@ -682,11 +685,11 @@ auto ChoiceDeclaration::TypeChecked(TypeEnv env, Env ct_env) const
 // Signals a type error if the initializing expression does not have
 // the declared type of the variable, otherwise returns this
 // declaration with annotated types.
-auto VariableDeclaration::TypeChecked(TypeEnv env, Env ct_env) const
+auto VariableDeclaration::TypeChecked(TypeEnv types, Env values) const
     -> Declaration {
-  TCResult type_checked_initializer =
-      TypeCheckExp(initializer, env, ct_env, nullptr, TCContext::ValueContext);
-  const Value* declared_type = ToType(source_location, InterpExp(ct_env, type));
+  TCResult type_checked_initializer = TypeCheckExp(
+      initializer, types, values, nullptr, TCContext::ValueContext);
+  const Value* declared_type = ToType(source_location, InterpExp(values, type));
   ExpectType(source_location, "initializer of variable", declared_type,
              type_checked_initializer.type);
   return *this;

+ 8 - 8
executable_semantics/interpreter/typecheck.h

@@ -16,30 +16,30 @@ namespace Carbon {
 
 using TypeEnv = Dictionary<std::string, const Value*>;
 
-void PrintTypeEnv(TypeEnv env);
+void PrintTypeEnv(TypeEnv types);
 
 enum class TCContext { ValueContext, PatternContext, TypeContext };
 
 struct TCResult {
-  TCResult(Expression* e, const Value* t, TypeEnv env)
-      : exp(e), type(t), env(env) {}
+  TCResult(Expression* e, const Value* t, TypeEnv types)
+      : exp(e), type(t), types(types) {}
 
   Expression* exp;
   const Value* type;
-  TypeEnv env;
+  TypeEnv types;
 };
 
 struct TCStatement {
-  TCStatement(Statement* s, TypeEnv e) : stmt(s), env(e) {}
+  TCStatement(Statement* s, TypeEnv types) : stmt(s), types(types) {}
 
   Statement* stmt;
-  TypeEnv env;
+  TypeEnv types;
 };
 
 auto ToType(int line_num, const Value* val) -> const Value*;
 
-auto TypeCheckExp(Expression* e, TypeEnv env, Env ct_env, const Value* expected,
-                  TCContext context) -> TCResult;
+auto TypeCheckExp(Expression* e, TypeEnv types, Env values,
+                  const Value* expected, TCContext context) -> TCResult;
 
 auto TypeCheckStmt(Statement*, TypeEnv, Env, Value const*&) -> TCStatement;