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

Revert "improve abstraction for AssocList, fix bug in optional else (#315)" (#320)

This reverts commit bf6bb800c4ce013274697d67b6d4a356f9689469.
Dave Abrahams 5 лет назад
Родитель
Сommit
f5300a84e5
55 измененных файлов с 7430 добавлено и 292 удалено
  1. 5 1
      executable_semantics/BUILD
  2. 3 2
      executable_semantics/ast/declaration.cpp
  3. 14 16
      executable_semantics/ast/declaration.h
  4. 40 32
      executable_semantics/ast/expression.cpp
  5. 1 2
      executable_semantics/ast/expression.h
  6. 4 2
      executable_semantics/ast/function_definition.cpp
  7. 3 2
      executable_semantics/ast/member.cpp
  8. 26 9
      executable_semantics/ast/statement.cpp
  9. 2 2
      executable_semantics/interpreter/action.cpp
  10. 1 1
      executable_semantics/interpreter/action.h
  11. 17 27
      executable_semantics/interpreter/assoc_list.h
  12. 6 1
      executable_semantics/interpreter/cons_list.h
  13. 79 110
      executable_semantics/interpreter/interpreter.cpp
  14. 4 4
      executable_semantics/interpreter/interpreter.h
  15. 0 2
      executable_semantics/interpreter/stack.h
  16. 31 33
      executable_semantics/interpreter/typecheck.cpp
  17. 10 10
      executable_semantics/interpreter/typecheck.h
  18. 0 5
      executable_semantics/interpreter/value.cpp
  19. 0 2
      executable_semantics/interpreter/value.h
  20. 0 5
      executable_semantics/main.cpp
  21. 12 16
      executable_semantics/syntax_helpers.cpp
  22. 0 2
      executable_semantics/syntax_helpers.h
  23. 264 0
      executable_semantics/testdata/block1.golden
  24. 819 0
      executable_semantics/testdata/break1.golden
  25. 44 1
      executable_semantics/testdata/choice1.golden
  26. 615 0
      executable_semantics/testdata/continue1.golden
  27. 20 1
      executable_semantics/testdata/fun1.golden
  28. 26 1
      executable_semantics/testdata/fun2.golden
  29. 210 0
      executable_semantics/testdata/fun3.golden
  30. 147 0
      executable_semantics/testdata/fun4.golden
  31. 213 0
      executable_semantics/testdata/fun5.golden
  32. 22 1
      executable_semantics/testdata/fun_recur.golden
  33. 26 1
      executable_semantics/testdata/funptr1.golden
  34. 160 0
      executable_semantics/testdata/if1.golden
  35. 143 1
      executable_semantics/testdata/if2.golden
  36. 235 0
      executable_semantics/testdata/if3.golden
  37. 174 0
      executable_semantics/testdata/match_int.golden
  38. 216 0
      executable_semantics/testdata/match_int_default.golden
  39. 652 0
      executable_semantics/testdata/match_type.golden
  40. 123 0
      executable_semantics/testdata/next.golden
  41. 234 0
      executable_semantics/testdata/pattern_init.golden
  42. 297 0
      executable_semantics/testdata/record1.golden
  43. 255 0
      executable_semantics/testdata/struct1.golden
  44. 321 0
      executable_semantics/testdata/struct2.golden
  45. 185 0
      executable_semantics/testdata/struct3.golden
  46. 388 0
      executable_semantics/testdata/tuple1.golden
  47. 198 0
      executable_semantics/testdata/tuple2.golden
  48. 297 0
      executable_semantics/testdata/tuple_assign.golden
  49. 317 0
      executable_semantics/testdata/tuple_match.golden
  50. 18 0
      executable_semantics/testdata/undef1.6c
  51. 2 0
      executable_semantics/testdata/undef1.golden
  52. 13 0
      executable_semantics/testdata/undef2.6c
  53. 4 0
      executable_semantics/testdata/undef2.golden
  54. 463 0
      executable_semantics/testdata/while1.golden
  55. 71 0
      executable_semantics/testdata/zero.golden

+ 5 - 1
executable_semantics/BUILD

@@ -81,7 +81,9 @@ EXAMPLES = [
     "fun6_fail_type",
     "funptr1",
     "if1",
-    "if2",
+    # (Temporarily disabled pending
+    # https://github.com/carbon-language/carbon-lang/issues/311)
+    # "if2",
     "if3",
     "match_int_default",
     "match_int",
@@ -96,6 +98,8 @@ EXAMPLES = [
     "tuple_match",
     "tuple1",
     "tuple2",
+    "undef1",
+    "undef2",
     "while1",
     "zero",
 ]

+ 3 - 2
executable_semantics/ast/declaration.cpp

@@ -21,8 +21,9 @@ void StructDeclaration::Print() const {
 void ChoiceDeclaration::Print() const {
   std::cout << "choice " << name << " {" << std::endl;
   for (auto& alternative : alternatives) {
-    std::cout << "alt " << alternative.first << " " << *alternative.second
-              << ";" << std::endl;
+    std::cout << "alt " << alternative.first << " ";
+    PrintExp(alternative.second);
+    std::cout << ";" << std::endl;
   }
   std::cout << "}" << std::endl;
 }

+ 14 - 16
executable_semantics/ast/declaration.h

@@ -15,16 +15,14 @@
 namespace Carbon {
 
 struct Value;
-
 template <class K, class V>
-class AssocList;
-
+struct AssocList;
 using Address = unsigned int;
 using TypeEnv = AssocList<std::string, Value*>;
 using Env = AssocList<std::string, Address>;
 
 /// TODO:explain this. Also name it if necessary. Consult with jsiek.
-using ExecutionEnvironment = std::pair<TypeEnv, Env>;
+using ExecutionEnvironment = std::pair<TypeEnv*, Env*>;
 
 /// An existential AST declaration satisfying the Declaration concept.
 class Declaration {
@@ -40,10 +38,10 @@ class Declaration {
  public:  // Declaration concept API, in addition to ValueSemantic.
   void Print() const { box->Print(); }
   auto Name() const -> std::string { return box->Name(); }
-  auto TypeChecked(TypeEnv env, Env ct_env) const -> Declaration {
+  auto TypeChecked(TypeEnv* env, Env* ct_env) const -> Declaration {
     return box->TypeChecked(env, ct_env);
   }
-  void InitGlobals(Env& globals) const { return box->InitGlobals(globals); }
+  void InitGlobals(Env*& globals) const { return box->InitGlobals(globals); }
   auto TopLevel(ExecutionEnvironment& e) const -> void {
     return box->TopLevel(e);
   }
@@ -62,9 +60,9 @@ class Declaration {
     virtual ~Box() {}
     virtual auto Print() const -> void = 0;
     virtual auto Name() const -> std::string = 0;
-    virtual auto TypeChecked(TypeEnv env, Env ct_env) const
+    virtual auto TypeChecked(TypeEnv* env, Env* ct_env) const
         -> Declaration = 0;
-    virtual auto InitGlobals(Env& globals) const -> void = 0;
+    virtual auto InitGlobals(Env*& globals) const -> void = 0;
     virtual auto TopLevel(ExecutionEnvironment&) const -> void = 0;
   };
 
@@ -77,10 +75,10 @@ class Declaration {
 
     auto Print() const -> void override { return content.Print(); }
     auto Name() const -> std::string override { return content.Name(); }
-    auto TypeChecked(TypeEnv env, Env ct_env) const -> Declaration override {
+    auto TypeChecked(TypeEnv* env, Env* ct_env) const -> Declaration override {
       return content.TypeChecked(env, ct_env);
     }
-    auto InitGlobals(Env& globals) const -> void override {
+    auto InitGlobals(Env*& globals) const -> void override {
       content.InitGlobals(globals);
     }
     auto TopLevel(ExecutionEnvironment& e) const -> void override {
@@ -100,8 +98,8 @@ struct FunctionDeclaration {
 
   auto Print() const -> void;
   auto Name() const -> std::string;
-  auto TypeChecked(TypeEnv env, Env ct_env) const -> Declaration;
-  auto InitGlobals(Env& globals) const -> void;
+  auto TypeChecked(TypeEnv* env, Env* ct_env) const -> Declaration;
+  auto InitGlobals(Env*& globals) const -> void;
   auto TopLevel(ExecutionEnvironment&) const -> void;
 };
 
@@ -112,8 +110,8 @@ struct StructDeclaration {
 
   void Print() const;
   auto Name() const -> std::string;
-  auto TypeChecked(TypeEnv env, Env ct_env) const -> Declaration;
-  void InitGlobals(Env& globals) const;
+  auto TypeChecked(TypeEnv* env, Env* ct_env) const -> Declaration;
+  void InitGlobals(Env*& globals) const;
   auto TopLevel(ExecutionEnvironment&) const -> void;
 };
 
@@ -128,8 +126,8 @@ struct ChoiceDeclaration {
 
   void Print() const;
   auto Name() const -> std::string;
-  auto TypeChecked(TypeEnv env, Env ct_env) const -> Declaration;
-  void InitGlobals(Env& globals) const;
+  auto TypeChecked(TypeEnv* env, Env* ct_env) const -> Declaration;
+  void InitGlobals(Env*& globals) const;
   auto TopLevel(ExecutionEnvironment&) const -> void;
 };
 

+ 40 - 32
executable_semantics/ast/expression.cpp

@@ -192,85 +192,93 @@ static void PrintFields(
     if (i != 0) {
       std::cout << ", ";
     }
-    std::cout << iter->first << " = " << *iter->second;
+    std::cout << iter->first << " = ";
+    PrintExp(iter->second);
   }
 }
 
-void PrintExp(const Expression* e, std::ostream& out) {
+void PrintExp(const Expression* e) {
   switch (e->tag) {
     case ExpressionKind::Index:
-      out << *e->u.index.aggregate << "[" << *e->u.index.offset << "]";
+      PrintExp(e->u.index.aggregate);
+      std::cout << "[";
+      PrintExp(e->u.index.offset);
+      std::cout << "]";
       break;
     case ExpressionKind::GetField:
-      out << *e->u.get_field.aggregate << "." << *e->u.get_field.field;
+      PrintExp(e->u.get_field.aggregate);
+      std::cout << ".";
+      std::cout << *e->u.get_field.field;
       break;
     case ExpressionKind::Tuple:
-      out << "(";
+      std::cout << "(";
       PrintFields(e->u.tuple.fields);
-      out << ")";
+      std::cout << ")";
       break;
     case ExpressionKind::Integer:
-      out << e->u.integer;
+      std::cout << e->u.integer;
       break;
     case ExpressionKind::Boolean:
-      out << std::boolalpha;
-      out << e->u.boolean;
+      std::cout << std::boolalpha;
+      std::cout << e->u.boolean;
       break;
     case ExpressionKind::PrimitiveOp:
-      out << "(";
+      std::cout << "(";
       if (e->u.primitive_op.arguments->size() == 0) {
         PrintOp(e->u.primitive_op.op);
       } else if (e->u.primitive_op.arguments->size() == 1) {
         PrintOp(e->u.primitive_op.op);
-        out << " ";
+        std::cout << " ";
         auto iter = e->u.primitive_op.arguments->begin();
-        PrintExp(*iter, out);
+        PrintExp(*iter);
       } else if (e->u.primitive_op.arguments->size() == 2) {
         auto iter = e->u.primitive_op.arguments->begin();
-        out << **iter << " ";
+        PrintExp(*iter);
+        std::cout << " ";
         PrintOp(e->u.primitive_op.op);
-        out << " ";
+        std::cout << " ";
         ++iter;
-        out << **iter;
+        PrintExp(*iter);
       }
-      out << ")";
+      std::cout << ")";
       break;
     case ExpressionKind::Variable:
-      out << *e->u.variable.name;
+      std::cout << *e->u.variable.name;
       break;
     case ExpressionKind::PatternVariable:
-      out << *e->u.pattern_variable.type << ": " << *e->u.pattern_variable.name;
+      PrintExp(e->u.pattern_variable.type);
+      std::cout << ": ";
+      std::cout << *e->u.pattern_variable.name;
       break;
     case ExpressionKind::Call:
-      out << *e->u.call.function;
+      PrintExp(e->u.call.function);
       if (e->u.call.argument->tag == ExpressionKind::Tuple) {
-        out << *e->u.call.argument;
+        PrintExp(e->u.call.argument);
       } else {
-        out << "(" << *e->u.call.argument << ")";
+        std::cout << "(";
+        PrintExp(e->u.call.argument);
+        std::cout << ")";
       }
       break;
     case ExpressionKind::BoolT:
-      out << "Bool";
+      std::cout << "Bool";
       break;
     case ExpressionKind::IntT:
-      out << "Int";
+      std::cout << "Int";
       break;
     case ExpressionKind::TypeT:
-      out << "Type";
+      std::cout << "Type";
       break;
     case ExpressionKind::AutoT:
-      out << "auto";
+      std::cout << "auto";
       break;
     case ExpressionKind::FunctionT:
-      out << "fn " << *e->u.function_type.parameter << " -> "
-          << *e->u.function_type.return_type;
+      std::cout << "fn ";
+      PrintExp(e->u.function_type.parameter);
+      std::cout << " -> ";
+      PrintExp(e->u.function_type.return_type);
       break;
   }
 }
 
-auto operator<<(std::ostream& out, const Expression& e) -> std::ostream& {
-  PrintExp(&e, out);
-  return out;
-}
-
 }  // namespace Carbon

+ 1 - 2
executable_semantics/ast/expression.h

@@ -109,8 +109,7 @@ auto MakeFunType(int line_num, Expression* param, Expression* ret)
     -> Expression*;
 auto MakeAutoType(int line_num) -> Expression*;
 
-void PrintExp(const Expression* exp, std::ostream& out);
-auto operator<<(std::ostream& os, const Expression& v) -> std::ostream&;
+void PrintExp(const Expression* exp);
 
 }  // namespace Carbon
 

+ 4 - 2
executable_semantics/ast/function_definition.cpp

@@ -21,8 +21,10 @@ auto MakeFunDef(int line_num, std::string name, Expression* ret_type,
 }
 
 void PrintFunDefDepth(const FunctionDefinition* f, int depth) {
-  std::cout << "fn " << f->name << " " << *f->param_pattern << " -> "
-            << *f->return_type;
+  std::cout << "fn " << f->name << " ";
+  PrintExp(f->param_pattern);
+  std::cout << " -> ";
+  PrintExp(f->return_type);
   if (f->body) {
     std::cout << " {" << std::endl;
     PrintStatement(f->body, depth);

+ 3 - 2
executable_semantics/ast/member.cpp

@@ -20,8 +20,9 @@ auto MakeField(int line_num, std::string name, Expression* type) -> Member* {
 void PrintMember(Member* m) {
   switch (m->tag) {
     case MemberKind::FieldMember:
-      std::cout << "var " << *m->u.field.name << " : " << *m->u.field.type
-                << ";" << std::endl;
+      std::cout << "var " << *m->u.field.name << " : ";
+      PrintExp(m->u.field.type);
+      std::cout << ";" << std::endl;
       break;
   }
 }

+ 26 - 9
executable_semantics/ast/statement.cpp

@@ -115,11 +115,15 @@ void PrintStatement(Statement* s, int depth) {
   }
   switch (s->tag) {
     case StatementKind::Match:
-      std::cout << "match (" << *s->u.match_stmt.exp << ") {";
+      std::cout << "match (";
+      PrintExp(s->u.match_stmt.exp);
+      std::cout << ") {";
       if (depth < 0 || depth > 1) {
         std::cout << std::endl;
         for (auto& clause : *s->u.match_stmt.clauses) {
-          std::cout << "case " << *clause.first << " =>" << std::endl;
+          std::cout << "case ";
+          PrintExp(clause.first);
+          std::cout << " =>" << std::endl;
           PrintStatement(clause.second, depth - 1);
           std::cout << std::endl;
         }
@@ -129,7 +133,9 @@ void PrintStatement(Statement* s, int depth) {
       std::cout << "}";
       break;
     case StatementKind::While:
-      std::cout << "while (" << *s->u.while_stmt.cond << ")" << std::endl;
+      std::cout << "while (";
+      PrintExp(s->u.while_stmt.cond);
+      std::cout << ")" << std::endl;
       PrintStatement(s->u.while_stmt.body, depth - 1);
       break;
     case StatementKind::Break:
@@ -139,23 +145,34 @@ void PrintStatement(Statement* s, int depth) {
       std::cout << "continue;";
       break;
     case StatementKind::VariableDefinition:
-      std::cout << "var " << *s->u.variable_definition.pat << " = "
-                << *s->u.variable_definition.init << ";";
+      std::cout << "var ";
+      PrintExp(s->u.variable_definition.pat);
+      std::cout << " = ";
+      PrintExp(s->u.variable_definition.init);
+      std::cout << ";";
       break;
     case StatementKind::ExpressionStatement:
-      std::cout << *s->u.exp << ";";
+      PrintExp(s->u.exp);
+      std::cout << ";";
       break;
     case StatementKind::Assign:
-      std::cout << *s->u.assign.lhs << " = " << *s->u.assign.rhs << ";";
+      PrintExp(s->u.assign.lhs);
+      std::cout << " = ";
+      PrintExp(s->u.assign.rhs);
+      std::cout << ";";
       break;
     case StatementKind::If:
-      std::cout << "if (" << *s->u.if_stmt.cond << ")" << std::endl;
+      std::cout << "if (";
+      PrintExp(s->u.if_stmt.cond);
+      std::cout << ")" << std::endl;
       PrintStatement(s->u.if_stmt.then_stmt, depth - 1);
       std::cout << std::endl << "else" << std::endl;
       PrintStatement(s->u.if_stmt.else_stmt, depth - 1);
       break;
     case StatementKind::Return:
-      std::cout << "return " << *s->u.return_stmt << ";";
+      std::cout << "return ";
+      PrintExp(s->u.return_stmt);
+      std::cout << ";";
       break;
     case StatementKind::Sequence:
       PrintStatement(s->u.sequence.stmt, depth);

+ 2 - 2
executable_semantics/interpreter/action.cpp

@@ -20,14 +20,14 @@ namespace Carbon {
 void PrintAct(Action* act, std::ostream& out) {
   switch (act->tag) {
     case ActionKind::DeleteTmpAction:
-      out << "delete_tmp(" << act->u.delete_tmp << ")";
+      std::cout << "delete_tmp(" << act->u.delete_tmp << ")";
       break;
     case ActionKind::ExpToLValAction:
       out << "exp=>lval";
       break;
     case ActionKind::LValAction:
     case ActionKind::ExpressionAction:
-      out << *act->u.exp;
+      PrintExp(act->u.exp);
       break;
     case ActionKind::StatementAction:
       PrintStatement(act->u.stmt, 1);

+ 1 - 1
executable_semantics/interpreter/action.h

@@ -10,7 +10,7 @@
 
 #include "executable_semantics/ast/expression.h"
 #include "executable_semantics/ast/statement.h"
-#include "executable_semantics/interpreter/stack.h"
+#include "executable_semantics/interpreter/cons_list.h"
 #include "executable_semantics/interpreter/value.h"
 
 namespace Carbon {

+ 17 - 27
executable_semantics/interpreter/assoc_list.h

@@ -7,41 +7,31 @@
 
 #include <iostream>
 #include <list>
-#include <optional>
 #include <string>
 
-#include "executable_semantics/interpreter/cons_list.h"
-
 namespace Carbon {
 
 template <class K, class V>
-class AssocList {
- public:
-  AssocList() { head = nullptr; }
-
-  auto Lookup(const K& key) -> std::optional<V> {
-    if (head == nullptr) {
-      return std::nullopt;
-    } else if (head->curr.first == key) {
-      return head->curr.second;
-    } else {
-      auto next = AssocList(head->next);
-      return next.Lookup(key);
-    }
-  }
+struct AssocList {
+  AssocList(K k, V v, AssocList* n) : key(k), value(v), next(n) {}
 
-  auto Extend(const K& k, const V& v) -> void {
-    head = new Cons<std::pair<K, V> >(std::make_pair(k, v), head);
-  }
+  K key;
+  V value;
+  AssocList* next;
+};
 
-  auto Extending(const K& k, const V& v) -> AssocList<K, V> {
-    return AssocList(new Cons<std::pair<K, V> >(std::make_pair(k, v), head));
+template <class K, class V>
+auto Lookup(int line_num, AssocList<K, V>* alist, const K& key,
+            void (*print_key)(const K&)) -> V {
+  if (alist == NULL) {
+    std::cerr << line_num << ": could not find `" << key << "`" << std::endl;
+    exit(-1);
+  } else if (alist->key == key) {
+    return alist->value;
+  } else {
+    return Lookup(line_num, alist->next, key, print_key);
   }
-
-  AssocList(Cons<std::pair<K, V> >* h) : head(h) {}
-
-  Cons<std::pair<K, V> >* head;
-};
+}
 
 }  // namespace Carbon
 

+ 6 - 1
executable_semantics/interpreter/cons_list.h

@@ -7,14 +7,19 @@
 
 namespace Carbon {
 
+template <class T>
+struct Stack;
+
 template <class T>
 struct Cons {
+  friend struct Stack<T>;
+
+ private:
   Cons(T e, Cons* n) : curr(e), next(n) {}
 
   const T curr;
   Cons* const next;
 
- private:
   // Cons cells are part of a "persistent data structure" and are thus
   // immutable.
   Cons& operator=(const Cons&) = delete;

+ 79 - 110
executable_semantics/interpreter/interpreter.cpp

@@ -19,12 +19,10 @@
 
 namespace Carbon {
 
-extern bool tracing_output;
-
 State* state = nullptr;
 
-auto PatternMatch(Value* pat, Value* val, Env, std::list<std::string>*, int)
-    -> std::optional<Env>;
+auto PatternMatch(Value* pat, Value* val, Env*, std::list<std::string>*, int)
+    -> Env*;
 void HandleValue();
 
 template <class T>
@@ -136,12 +134,12 @@ void KillValue(Value* val) {
   }
 }
 
-void PrintEnv(Env env, std::ostream& out) {
-  if (env.head) {
-    std::cout << env.head->curr.first << ": ";
-    PrintValue(state->heap[env.head->curr.second], out);
+void PrintEnv(Env* env, std::ostream& out) {
+  if (env) {
+    std::cout << env->key << ": ";
+    PrintValue(state->heap[env->value], out);
     std::cout << ", ";
-    PrintEnv(Env(env.head->next), out);
+    PrintEnv(env->next, out);
   }
 }
 
@@ -175,7 +173,7 @@ void PrintHeap(const std::vector<Value*>& heap, std::ostream& out) {
   }
 }
 
-auto CurrentEnv(State* state) -> Env {
+auto CurrentEnv(State* state) -> Env* {
   Frame* frame = state->stack.Top();
   return frame->scopes.Top()->env;
 }
@@ -253,7 +251,7 @@ auto EvalPrim(Operator op, const std::vector<Value*>& args, int line_num)
   }
 }
 
-Env globals;
+Env* globals;
 
 void InitGlobals(std::list<Declaration>* fs) {
   globals = nullptr;
@@ -262,7 +260,7 @@ void InitGlobals(std::list<Declaration>* fs) {
   }
 }
 
-auto ChoiceDeclaration::InitGlobals(Env& globals) const -> void {
+auto ChoiceDeclaration::InitGlobals(Env*& globals) const -> void {
   auto alts = new VarValues();
   for (auto kv : alternatives) {
     auto t = ToType(line_num, InterpExp(nullptr, kv.second));
@@ -270,10 +268,10 @@ auto ChoiceDeclaration::InitGlobals(Env& globals) const -> void {
   }
   auto ct = MakeChoiceTypeVal(name, alts);
   auto a = AllocateValue(ct);
-  globals.Extend(name, a);
+  globals = new Env(name, a, globals);
 }
 
-auto StructDeclaration::InitGlobals(Env& globals) const -> void {
+auto StructDeclaration::InitGlobals(Env*& globals) const -> void {
   auto fields = new VarValues();
   auto methods = new VarValues();
   for (auto i = definition.members->begin(); i != definition.members->end();
@@ -289,15 +287,15 @@ auto StructDeclaration::InitGlobals(Env& globals) const -> void {
   }
   auto st = MakeStructTypeVal(*definition.name, fields, methods);
   auto a = AllocateValue(st);
-  globals.Extend(*definition.name, a);
+  globals = new Env(*definition.name, a, globals);
 }
 
-auto FunctionDeclaration::InitGlobals(Env& globals) const -> void {
-  Env env;
+auto FunctionDeclaration::InitGlobals(Env*& globals) const -> void {
+  Env* env = nullptr;
   auto pt = InterpExp(env, definition->param_pattern);
   auto f = MakeFunVal(definition->name, pt, definition->body);
   Address a = AllocateValue(f);
-  globals.Extend(definition->name, a);
+  globals = new Env(definition->name, a, globals);
 }
 
 //    { S, H} -> { { C, E, F} :: S, H}
@@ -310,7 +308,7 @@ void CallFunction(int line_num, std::vector<Value*> operas, State* state) {
     case ValKind::FunV: {
       // Bind arguments to parameters
       std::list<std::string> params;
-      auto env = PatternMatch(operas[0]->u.fun.param, operas[1], globals,
+      Env* env = PatternMatch(operas[0]->u.fun.param, operas[1], globals,
                               &params, line_num);
       if (!env) {
         std::cerr << "internal error in call_function, pattern match failed"
@@ -318,7 +316,7 @@ void CallFunction(int line_num, std::vector<Value*> operas, State* state) {
         exit(-1);
       }
       // Create the new frame and push it on the stack
-      auto* scope = new Scope(*env, params);
+      auto* scope = new Scope(env, params);
       auto* frame = new Frame(*operas[0]->u.fun.name, Stack(scope),
                               Stack(MakeStmtAct(operas[0]->u.fun.body)));
       state->stack.Push(frame);
@@ -349,12 +347,8 @@ void CallFunction(int line_num, std::vector<Value*> operas, State* state) {
 
 void KillScope(int line_num, Scope* scope) {
   for (const auto& l : scope->locals) {
-    auto a = scope->env.Lookup(l);
-    if (a) {
-      KillValue(state->heap[*a]);
-    } else {
-      std::cerr << "internal error" << std::endl;
-    }
+    Address a = Lookup(line_num, scope->env, l, PrintErrorString);
+    KillValue(state->heap[a]);
   }
 }
 
@@ -393,23 +387,26 @@ auto ToValue(Expression* value) -> Value* {
     case ExpressionKind::FunctionT:
       // Instead add to patterns?
     default:
-      std::cerr << "internal error in to_value, didn't expect " << *value
-                << std::endl;
+      std::cerr << "internal error in to_value, didn't expect ";
+      PrintExp(value);
+      std::cerr << std::endl;
       exit(-1);
   }
 }
 
 // Returns 0 if the value doesn't match the pattern.
-auto PatternMatch(Value* p, Value* v, Env env, std::list<std::string>* vars,
-                  int line_num) -> std::optional<Env> {
-  if (tracing_output) {
-    std::cout << "pattern_match(" << *p << ", " << *v << ")" << std::endl;
-  }
+auto PatternMatch(Value* p, Value* v, Env* env, std::list<std::string>* vars,
+                  int line_num) -> Env* {
+  std::cout << "pattern_match(";
+  PrintValue(p, std::cout);
+  std::cout << ", ";
+  PrintValue(v, std::cout);
+  std::cout << ")" << std::endl;
   switch (p->tag) {
     case ValKind::VarPatV: {
       Address a = AllocateValue(CopyVal(v, line_num));
       vars->push_back(*p->u.var_pat.name);
-      return env.Extending(*p->u.var_pat.name, a);
+      return new Env(*p->u.var_pat.name, a, env);
     }
     case ValKind::TupleV:
       switch (v->tag) {
@@ -427,12 +424,8 @@ auto PatternMatch(Value* p, Value* v, Env env, std::list<std::string>* vars,
               std::cerr << std::endl;
               exit(-1);
             }
-            auto result = PatternMatch(state->heap[elt.second], state->heap[*a],
-                                       env, vars, line_num);
-            if (result)
-              env = *result;
-            else
-              return env;
+            env = PatternMatch(state->heap[elt.second], state->heap[*a], env,
+                               vars, line_num);
           }
           return env;
         }
@@ -448,9 +441,10 @@ auto PatternMatch(Value* p, Value* v, Env env, std::list<std::string>* vars,
         case ValKind::AltV: {
           if (*p->u.alt.choice_name != *v->u.alt.choice_name ||
               *p->u.alt.alt_name != *v->u.alt.alt_name) {
-            return std::nullopt;
+            return nullptr;
           }
-          return PatternMatch(p->u.alt.arg, v->u.alt.arg, env, vars, line_num);
+          env = PatternMatch(p->u.alt.arg, v->u.alt.arg, env, vars, line_num);
+          return env;
         }
         default:
           std::cerr
@@ -462,24 +456,20 @@ auto PatternMatch(Value* p, Value* v, Env env, std::list<std::string>* vars,
       }
     case ValKind::FunctionTV:
       switch (v->tag) {
-        case ValKind::FunctionTV: {
-          auto result = PatternMatch(p->u.fun_type.param, v->u.fun_type.param,
-                                     env, vars, line_num);
-          if (result)
-            env = *result;
-          else
-            return env;
-          return PatternMatch(p->u.fun_type.ret, v->u.fun_type.ret, env, vars,
-                              line_num);
-        }
+        case ValKind::FunctionTV:
+          env = PatternMatch(p->u.fun_type.param, v->u.fun_type.param, env,
+                             vars, line_num);
+          env = PatternMatch(p->u.fun_type.ret, v->u.fun_type.ret, env, vars,
+                             line_num);
+          return env;
         default:
-          return std::nullopt;
+          return nullptr;
       }
     default:
       if (ValueEqual(p, v, line_num)) {
         return env;
       } else {
-        return std::nullopt;
+        return nullptr;
       }
   }
 }
@@ -555,24 +545,19 @@ void StepLvalue() {
   Frame* frame = state->stack.Top();
   Action* act = frame->todo.Top();
   Expression* exp = act->u.exp;
-  if (tracing_output) {
-    std::cout << "--- step lvalue " << *exp << " --->" << std::endl;
-  }
+  std::cout << "--- step lvalue ";
+  PrintExp(exp);
+  std::cout << " --->" << std::endl;
   switch (exp->tag) {
     case ExpressionKind::Variable: {
       //    { {x :: C, E, F} :: S, H}
       // -> { {E(x) :: C, E, F} :: S, H}
-      auto a = CurrentEnv(state).Lookup(*(exp->u.variable.name));
-      if (a) {
-        Value* v = MakePtrVal(*a);
-        CheckAlive(v, exp->line_num);
-        frame->todo.Pop();
-        frame->todo.Push(MakeValAct(v));
-      } else {
-        std::cerr << exp->line_num << ": variable " << *(exp->u.variable.name)
-                  << " is not defined" << std::endl;
-        exit(-1);
-      }
+      Address a = Lookup(exp->line_num, CurrentEnv(state),
+                         *(exp->u.variable.name), PrintErrorString);
+      Value* v = MakePtrVal(a);
+      CheckAlive(v, exp->line_num);
+      frame->todo.Pop();
+      frame->todo.Push(MakeValAct(v));
       break;
     }
     case ExpressionKind::GetField: {
@@ -620,9 +605,9 @@ void StepExp() {
   Frame* frame = state->stack.Top();
   Action* act = frame->todo.Top();
   Expression* exp = act->u.exp;
-  if (tracing_output) {
-    std::cout << "--- step exp " << *exp << " --->" << std::endl;
-  }
+  std::cout << "--- step exp ";
+  PrintExp(exp);
+  std::cout << " --->" << std::endl;
   switch (exp->tag) {
     case ExpressionKind::PatternVariable: {
       frame->todo.Push(MakeExpAct(exp->u.pattern_variable.type));
@@ -657,16 +642,11 @@ void StepExp() {
     }
     case ExpressionKind::Variable: {
       // { {x :: C, E, F} :: S, H} -> { {H(E(x)) :: C, E, F} :: S, H}
-      auto a = CurrentEnv(state).Lookup(*(exp->u.variable.name));
-      if (a) {
-        Value* v = state->heap[*a];
-        frame->todo.Pop(1);
-        frame->todo.Push(MakeValAct(v));
-      } else {
-        std::cerr << exp->line_num << ": variable " << *(exp->u.variable.name)
-                  << " is not defined " << std::endl;
-        exit(-1);
-      }
+      Address a = Lookup(exp->line_num, CurrentEnv(state),
+                         *(exp->u.variable.name), PrintErrorString);
+      Value* v = state->heap[a];
+      frame->todo.Pop(1);
+      frame->todo.Push(MakeValAct(v));
       break;
     }
     case ExpressionKind::Integer:
@@ -767,11 +747,9 @@ void StepStmt() {
   Action* act = frame->todo.Top();
   Statement* const stmt = act->u.stmt;
   assert(stmt != nullptr && "null statement!");
-  if (tracing_output) {
-    std::cout << "--- step stmt ";
-    PrintStatement(stmt, 1);
-    std::cout << " --->" << std::endl;
-  }
+  std::cout << "--- step stmt ";
+  PrintStatement(stmt, 1);
+  std::cout << " --->" << std::endl;
   switch (stmt->tag) {
     case StatementKind::Match:
       //    { { (match (e) ...) :: C, E, F} :: S, H}
@@ -940,11 +918,11 @@ void HandleValue() {
   act->results.push_back(val_act->u.val);
   act->pos++;
 
-  if (tracing_output) {
-    std::cout << "--- handle value " << *val_act->u.val << " with ";
-    PrintAct(act, std::cout);
-    std::cout << " --->" << std::endl;
-  }
+  std::cout << "--- handle value ";
+  PrintValue(val_act->u.val, std::cout);
+  std::cout << " with ";
+  PrintAct(act, std::cout);
+  std::cout << " --->" << std::endl;
 
   switch (act->tag) {
     case ActionKind::DeleteTmpAction: {
@@ -1163,17 +1141,16 @@ void HandleValue() {
             Value* v = act->results[0];
             Value* p = act->results[1];
             // Address a = AllocateValue(CopyVal(v));
-            auto result =
+            frame->scopes.Top()->env =
                 PatternMatch(p, v, frame->scopes.Top()->env,
                              &frame->scopes.Top()->locals, stmt->line_num);
-            if (!result) {
+            if (!frame->scopes.Top()->env) {
               std::cerr
                   << stmt->line_num
                   << ": internal error in variable definition, match failed"
                   << std::endl;
               exit(-1);
             }
-            frame->scopes.Top()->env = *result;
             frame->todo.Pop(2);
           }
           break;
@@ -1200,14 +1177,12 @@ void HandleValue() {
             // -> { { then_stmt :: C, E, F } :: S, H}
             frame->todo.Pop(2);
             frame->todo.Push(MakeStmtAct(stmt->u.if_stmt.then_stmt));
-          } else if (stmt->u.if_stmt.else_stmt) {
+          } else {
             //    { {false :: if ([]) then_stmt else else_stmt :: C, E, F} ::
             //      S, H}
             // -> { { else_stmt :: C, E, F } :: S, H}
             frame->todo.Pop(2);
             frame->todo.Push(MakeStmtAct(stmt->u.if_stmt.else_stmt));
-          } else {
-            frame->todo.Pop(2);
           }
           break;
         case StatementKind::While:
@@ -1257,9 +1232,9 @@ void HandleValue() {
             auto pat = act->results[clause_num + 1];
             auto env = CurrentEnv(state);
             std::list<std::string> vars;
-            auto new_env = PatternMatch(pat, v, env, &vars, stmt->line_num);
+            Env* new_env = PatternMatch(pat, v, env, &vars, stmt->line_num);
             if (new_env) {  // we have a match, start the body
-              auto* new_scope = new Scope(*new_env, vars);
+              auto* new_scope = new Scope(new_env, vars);
               frame->scopes.Push(new_scope);
               Statement* body_block = MakeBlock(stmt->line_num, c->second);
               Action* body_act = MakeStmtAct(body_block);
@@ -1348,9 +1323,7 @@ void Step() {
 // Interpret the whole porogram.
 auto InterpProgram(std::list<Declaration>* fs) -> int {
   state = new State();  // Runtime state.
-  if (tracing_output) {
-    std::cout << "********** initializing globals **********" << std::endl;
-  }
+  std::cout << "********** initializing globals **********" << std::endl;
   InitGlobals(fs);
 
   Expression* arg =
@@ -1361,25 +1334,21 @@ auto InterpProgram(std::list<Declaration>* fs) -> int {
   auto* frame = new Frame("top", Stack(scope), todo);
   state->stack = Stack(frame);
 
-  if (tracing_output) {
-    std::cout << "********** calling main function **********" << std::endl;
-    PrintState(std::cout);
-  }
+  std::cout << "********** calling main function **********" << std::endl;
+  PrintState(std::cout);
 
   while (state->stack.CountExceeds(1) ||
          state->stack.Top()->todo.CountExceeds(1) ||
          state->stack.Top()->todo.Top()->tag != ActionKind::ValAction) {
     Step();
-    if (tracing_output) {
-      PrintState(std::cout);
-    }
+    PrintState(std::cout);
   }
   Value* v = state->stack.Top()->todo.Top()->u.val;
   return ValToInt(v, 0);
 }
 
 // Interpret an expression at compile-time.
-auto InterpExp(Env env, Expression* e) -> Value* {
+auto InterpExp(Env* env, Expression* e) -> Value* {
   auto todo = Stack(MakeExpAct(e));
   auto* scope = new Scope(env, std::list<std::string>());
   auto* frame = new Frame("InterpExp", Stack(scope), todo);

+ 4 - 4
executable_semantics/interpreter/interpreter.h

@@ -22,8 +22,8 @@ using Env = AssocList<std::string, Address>;
 /***** Scopes *****/
 
 struct Scope {
-  Scope(Env e, std::list<std::string> l) : env(e), locals(std::move(l)) {}
-  Env env;
+  Scope(Env* e, std::list<std::string> l) : env(e), locals(std::move(l)) {}
+  Env* env;
   std::list<std::string> locals;
 };
 
@@ -45,7 +45,7 @@ struct State {
 
 extern State* state;
 
-void PrintEnv(Env env);
+void PrintEnv(Env* env);
 auto AllocateValue(Value* v) -> Address;
 auto CopyVal(Value* val, int line_num) -> Value*;
 auto ToInteger(Value* v) -> int;
@@ -53,7 +53,7 @@ auto ToInteger(Value* v) -> int;
 /***** Interpreters *****/
 
 auto InterpProgram(std::list<Declaration>* fs) -> int;
-auto InterpExp(Env env, Expression* e) -> Value*;
+auto InterpExp(Env* env, Expression* e) -> Value*;
 
 }  // namespace Carbon
 

+ 0 - 2
executable_semantics/interpreter/stack.h

@@ -9,8 +9,6 @@
 #include <cstddef>
 #include <iterator>
 
-#include "executable_semantics/interpreter/cons_list.h"
-
 namespace Carbon {
 
 /// A persistent stack data structure.

+ 31 - 33
executable_semantics/interpreter/typecheck.cpp

@@ -32,12 +32,12 @@ void ExpectType(int line_num, const std::string& context, Value* expected,
 
 void PrintErrorString(const std::string& s) { std::cerr << s; }
 
-void PrintTypeEnv(TypeEnv env, std::ostream& out) {
-  if (env.head) {
-    out << env.head->curr.first << ": ";
-    PrintValue(env.head->curr.second, out);
+void PrintTypeEnv(TypeEnv* env, std::ostream& out) {
+  if (env) {
+    out << env->key << ": ";
+    PrintValue(env->value, out);
     out << ", ";
-    PrintTypeEnv(TypeEnv(env.head->next), out);
+    PrintTypeEnv(env->next, out);
   }
 }
 
@@ -139,7 +139,7 @@ auto ReifyType(Value* t, int line_num) -> Expression* {
 //    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, Value* expected,
+auto TypeCheckExp(Expression* e, TypeEnv* env, Env* ct_env, Value* expected,
                   TCContext context) -> TCResult {
   switch (e->tag) {
     case ExpressionKind::PatternVariable: {
@@ -164,7 +164,8 @@ auto TypeCheckExp(Expression* e, TypeEnv env, Env ct_env, Value* expected,
       }
       auto new_e = MakeVarPat(e->line_num, *e->u.pattern_variable.name,
                               ReifyType(t, e->line_num));
-      return TCResult(new_e, t, env.Extending(*e->u.pattern_variable.name, t));
+      return TCResult(new_e, t,
+                      new TypeEnv(*e->u.pattern_variable.name, t, env));
     }
     case ExpressionKind::Index: {
       auto res = TypeCheckExp(e->u.get_field.aggregate, env, ct_env, nullptr,
@@ -274,20 +275,16 @@ auto TypeCheckExp(Expression* e, TypeEnv env, Env ct_env, Value* expected,
         default:
           std::cerr << e->line_num
                     << ": compilation error in field access, expected a struct"
-                    << std::endl
-                    << *e << std::endl;
+                    << std::endl;
+          PrintExp(e);
+          std::cerr << std::endl;
           exit(-1);
       }
     }
     case ExpressionKind::Variable: {
-      auto t = env.Lookup(*(e->u.variable.name));
-      if (t) {
-        return TCResult(e, *t, env);
-      } else {
-        std::cerr << e->line_num << ": variable " << *(e->u.variable.name)
-                  << " is not defined" << std::endl;
-        exit(-1);
-      }
+      auto t =
+          Lookup(e->line_num, env, *(e->u.variable.name), PrintErrorString);
+      return TCResult(e, t, env);
     }
     case ExpressionKind::Integer:
       return TCResult(e, MakeIntTypeVal(), env);
@@ -349,8 +346,9 @@ auto TypeCheckExp(Expression* e, TypeEnv env, Env ct_env, Value* expected,
         default: {
           std::cerr << e->line_num
                     << ": compilation error in call, expected a function"
-                    << std::endl
-                    << *e << std::endl;
+                    << std::endl;
+          PrintExp(e);
+          std::cerr << std::endl;
           exit(-1);
         }
       }
@@ -389,7 +387,7 @@ auto TypeCheckExp(Expression* e, TypeEnv env, Env ct_env, Value* expected,
 }
 
 auto TypecheckCase(Value* expected, Expression* pat, Statement* body,
-                   TypeEnv env, Env ct_env, Value* ret_type)
+                   TypeEnv* env, Env* ct_env, Value* ret_type)
     -> std::pair<Expression*, Statement*> {
   auto pat_res =
       TypeCheckExp(pat, env, ct_env, expected, TCContext::PatternContext);
@@ -404,7 +402,7 @@ auto TypecheckCase(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, Value* ret_type)
+auto TypeCheckStmt(Statement* s, TypeEnv* env, Env* ct_env, Value* ret_type)
     -> TCStatement {
   if (!s) {
     return TCStatement(s, env);
@@ -568,7 +566,7 @@ 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* env, Env* ct_env)
     -> struct FunctionDefinition* {
   auto param_res = TypeCheckExp(f->param_pattern, env, ct_env, nullptr,
                                 TCContext::PatternContext);
@@ -585,7 +583,7 @@ auto TypeCheckFunDef(const FunctionDefinition* f, TypeEnv env, Env ct_env)
                     f->param_pattern, body);
 }
 
-auto TypeOfFunDef(TypeEnv env, Env ct_env, const FunctionDefinition* fun_def)
+auto TypeOfFunDef(TypeEnv* env, Env* ct_env, const FunctionDefinition* fun_def)
     -> Value* {
   auto param_res = TypeCheckExp(fun_def->param_pattern, env, ct_env, nullptr,
                                 TCContext::PatternContext);
@@ -598,7 +596,7 @@ auto TypeOfFunDef(TypeEnv env, Env ct_env, const FunctionDefinition* fun_def)
   return MakeFunTypeVal(param_type, ret);
 }
 
-auto TypeOfStructDef(const StructDefinition* sd, TypeEnv /*env*/, Env ct_top)
+auto TypeOfStructDef(const StructDefinition* sd, TypeEnv* /*env*/, Env* ct_top)
     -> Value* {
   auto fields = new VarValues();
   auto methods = new VarValues();
@@ -619,7 +617,7 @@ auto StructDeclaration::Name() const -> std::string { return *definition.name; }
 
 auto ChoiceDeclaration::Name() const -> std::string { return name; }
 
-auto StructDeclaration::TypeChecked(TypeEnv env, Env ct_env) const
+auto StructDeclaration::TypeChecked(TypeEnv* env, Env* ct_env) const
     -> Declaration {
   auto fields = new std::list<Member*>();
   for (auto& m : *definition.members) {
@@ -631,17 +629,17 @@ 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* env, Env* ct_env) const
     -> Declaration {
   return FunctionDeclaration(TypeCheckFunDef(definition, env, ct_env));
 }
 
-auto ChoiceDeclaration::TypeChecked(TypeEnv env, Env ct_env) const
+auto ChoiceDeclaration::TypeChecked(TypeEnv* env, Env* ct_env) const
     -> Declaration {
   return *this;  // TODO.
 }
 
-auto TopLevel(std::list<Declaration>* fs) -> std::pair<TypeEnv, Env> {
+auto TopLevel(std::list<Declaration>* fs) -> std::pair<TypeEnv*, Env*> {
   ExecutionEnvironment tops = {nullptr, nullptr};
   bool found_main = false;
 
@@ -662,16 +660,16 @@ auto TopLevel(std::list<Declaration>* fs) -> std::pair<TypeEnv, Env> {
 
 auto FunctionDeclaration::TopLevel(ExecutionEnvironment& tops) const -> void {
   auto t = TypeOfFunDef(tops.first, tops.second, definition);
-  tops.first.Extend(Name(), t);
+  tops.first = new TypeEnv(Name(), t, tops.first);
 }
 
 auto StructDeclaration::TopLevel(ExecutionEnvironment& tops) const -> void {
   auto st = TypeOfStructDef(&definition, tops.first, tops.second);
   Address a = AllocateValue(st);
-  tops.second.Extend(Name(), a);  // Is this obsolete?
+  tops.second = new Env(Name(), a, tops.second);  // Is this obsolete?
   auto params = MakeTupleTypeVal(st->u.struct_type.fields);
   auto fun_ty = MakeFunTypeVal(params, st);
-  tops.first.Extend(Name(), fun_ty);
+  tops.first = new TypeEnv(Name(), fun_ty, tops.first);
 }
 
 auto ChoiceDeclaration::TopLevel(ExecutionEnvironment& tops) const -> void {
@@ -682,8 +680,8 @@ auto ChoiceDeclaration::TopLevel(ExecutionEnvironment& tops) const -> void {
   }
   auto ct = MakeChoiceTypeVal(name, alts);
   Address a = AllocateValue(ct);
-  tops.second.Extend(Name(), a);  // Is this obsolete?
-  tops.first.Extend(Name(), ct);
+  tops.second = new Env(Name(), a, tops.second);  // Is this obsolete?
+  tops.first = new TypeEnv(Name(), ct, tops.first);
 }
 
 }  // namespace Carbon

+ 10 - 10
executable_semantics/interpreter/typecheck.h

@@ -16,37 +16,37 @@ namespace Carbon {
 
 using TypeEnv = AssocList<std::string, Value*>;
 
-void PrintTypeEnv(TypeEnv env);
+void PrintTypeEnv(TypeEnv* env);
 
 enum class TCContext { ValueContext, PatternContext, TypeContext };
 
 struct TCResult {
-  TCResult(Expression* e, Value* t, TypeEnv env) : exp(e), type(t), env(env) {}
+  TCResult(Expression* e, Value* t, TypeEnv* env) : exp(e), type(t), env(env) {}
 
   Expression* exp;
   Value* type;
-  TypeEnv env;
+  TypeEnv* env;
 };
 
 struct TCStatement {
-  TCStatement(Statement* s, TypeEnv e) : stmt(s), env(e) {}
+  TCStatement(Statement* s, TypeEnv* e) : stmt(s), env(e) {}
 
   Statement* stmt;
-  TypeEnv env;
+  TypeEnv* env;
 };
 
 auto ToType(int line_num, Value* val) -> Value*;
 
-auto TypeCheckExp(Expression* e, TypeEnv env, Env ct_env, Value* expected,
+auto TypeCheckExp(Expression* e, TypeEnv* env, Env* ct_env, Value* expected,
                   TCContext context) -> TCResult;
 
-auto TypeCheckStmt(Statement*, TypeEnv, Env, Value*) -> TCStatement;
+auto TypeCheckStmt(Statement*, TypeEnv*, Env*, Value*) -> TCStatement;
 
-auto TypeCheckFunDef(struct FunctionDefinition*, TypeEnv)
+auto TypeCheckFunDef(struct FunctionDefinition*, TypeEnv*)
     -> struct FunctionDefinition*;
 
-auto TopLevel(std::list<Declaration>* fs) -> std::pair<TypeEnv, Env>;
-  
+auto TopLevel(std::list<Declaration>* fs) -> std::pair<TypeEnv*, Env*>;
+
 void PrintErrorString(const std::string& s);
 
 }  // namespace Carbon

+ 0 - 5
executable_semantics/interpreter/value.cpp

@@ -314,11 +314,6 @@ void PrintValue(Value* val, std::ostream& out) {
   }
 }
 
-auto operator<<(std::ostream& out, const Value& v) -> std::ostream& {
-  PrintValue((Value*)&v, out);
-  return out;
-}
-
 auto TypeEqual(Value* t1, Value* t2) -> bool {
   if (t1->tag != t2->tag) {
     return false;

+ 0 - 2
executable_semantics/interpreter/value.h

@@ -5,7 +5,6 @@
 #ifndef EXECUTABLE_SEMANTICS_INTERPRETER_VALUE_H_
 #define EXECUTABLE_SEMANTICS_INTERPRETER_VALUE_H_
 
-#include <iostream>
 #include <list>
 #include <vector>
 
@@ -128,7 +127,6 @@ auto MakeVoidTypeVal() -> Value*;
 auto MakeChoiceTypeVal(std::string name, VarValues* alts) -> Value*;
 
 void PrintValue(Value* val, std::ostream& out);
-auto operator<<(std::ostream& os, const Value& v) -> std::ostream&;
 
 auto TypeEqual(Value* t1, Value* t2) -> bool;
 auto ValueEqual(Value* v1, Value* v2, int line_num) -> bool;

+ 0 - 5
executable_semantics/main.cpp

@@ -5,7 +5,6 @@
 #include <cstdio>
 #include <cstring>
 #include <iostream>
-#include <string>
 
 #include "executable_semantics/syntax_helpers.h"
 
@@ -24,9 +23,5 @@ int main(int argc, char* argv[]) {
       return 1;
     }
   }
-
-  if (argc > 2 && argv[2] == std::string("-trace")) {
-    Carbon::tracing_output = true;
-  }
   return yyparse();
 }

+ 12 - 16
executable_semantics/syntax_helpers.cpp

@@ -11,8 +11,6 @@
 
 namespace Carbon {
 
-bool tracing_output = false;
-
 char* input_filename = nullptr;
 
 void PrintSyntaxError(char* error, int line_num) {
@@ -21,27 +19,25 @@ void PrintSyntaxError(char* error, int line_num) {
 }
 
 void ExecProgram(std::list<Declaration>* fs) {
-  if (tracing_output) {
-    std::cout << "********** source program **********" << std::endl;
-    for (const auto& decl : *fs) {
-      decl.Print();
-    std::cout << "********** type checking **********" << std::endl;
+  std::cout << "********** source program **********" << std::endl;
+  for (const auto& decl : *fs) {
+    decl.Print();
   }
+  std::cout << "********** type checking **********" << std::endl;
   state = new State();  // Compile-time state.
-  std::pair<TypeEnv, Env> p = TopLevel(fs);
-  TypeEnv top = p.first;
-  Env ct_top = p.second;
+  std::pair<TypeEnv*, Env*> p = TopLevel(fs);
+  TypeEnv* top = p.first;
+  Env* ct_top = p.second;
   std::list<Declaration> new_decls;
   for (const auto& decl : *fs) {
     new_decls.push_back(decl.TypeChecked(top, ct_top));
   }
-  if (tracing_output) {
-    std::cout << std::endl;
-    std::cout << "********** type checking complete **********" << std::endl;
-    for (const auto& decl : new_decls) {
-      decl.Print();
-    }
+  std::cout << std::endl;
+  std::cout << "********** type checking complete **********" << std::endl;
+  for (const auto& decl : new_decls) {
+    decl.Print();
   }
+  std::cout << "********** starting execution **********" << std::endl;
   int result = InterpProgram(&new_decls);
   std::cout << "result: " << result << std::endl;
 }

+ 0 - 2
executable_semantics/syntax_helpers.h

@@ -24,8 +24,6 @@ void PrintSyntaxError(char* error, int line_num);
 // Runs the top-level declaration list.
 void ExecProgram(std::list<Declaration>* fs);
 
-extern bool tracing_output;
-
 }  // namespace Carbon
 
 #endif  // EXECUTABLE_SEMANTICS_EXEC_H_

+ 264 - 0
executable_semantics/testdata/block1.golden

@@ -1 +1,265 @@
+********** source program **********
+fn main () -> Int {
+var Int: x = 0;
+{
+var Int: x = 1;
+
+}
+
+return x;
+
+}
+********** type checking **********
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+
+********** type checking complete **********
+fn main () -> Int {
+var Int: x = 0;
+{
+var Int: x = 1;
+
+}
+
+return x;
+}
+********** starting execution **********
+********** initializing globals **********
+--- step exp () --->
+********** calling main function **********
+{
+stack: top{main()<-1>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main() --->
+{
+stack: top{main<-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main --->
+{
+stack: top{fun<main><-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value fun<main> with main()<1>(fun<main>,) --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp () --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value () with main()<2>(fun<main>,(),) --->
+pattern_match((), ())
+{
+stack: main{var Int: x = 0; ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt var Int: x = 0; ...  --->
+{
+stack: main{var Int: x = 0;<-1> :: {
+ ... 
+}
+ ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt var Int: x = 0; --->
+{
+stack: main{0<-1> :: var Int: x = 0;<0> :: {
+ ... 
+}
+ ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 0 --->
+{
+stack: main{0<-1> :: var Int: x = 0;<0> :: {
+ ... 
+}
+ ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 0 with var Int: x = 0;<1>(0,) --->
+{
+stack: main{Int: x<-1> :: var Int: x = 0;<1>(0,) :: {
+ ... 
+}
+ ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp Int: x --->
+{
+stack: main{Int<-1> :: Int: x<0> :: var Int: x = 0;<1>(0,) :: {
+ ... 
+}
+ ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp Int --->
+{
+stack: main{Int<-1> :: Int: x<0> :: var Int: x = 0;<1>(0,) :: {
+ ... 
+}
+ ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value Int with Int: x<1>(Int,) --->
+{
+stack: main{Int: x<-1> :: var Int: x = 0;<1>(0,) :: {
+ ... 
+}
+ ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value Int: x with var Int: x = 0;<2>(0,Int: x,) --->
+pattern_match(Int: x, 0)
+{
+stack: main{{
+ ... 
+}
+ ... <-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step stmt {
+ ... 
+}
+ ...  --->
+{
+stack: main{{
+ ... 
+}
+<-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step stmt {
+ ... 
+}
+ --->
+{
+stack: main{var Int: x = 1;<-1> :: {
+ ... 
+}
+<0> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step stmt var Int: x = 1; --->
+{
+stack: main{var Int: x = 1;<-1> :: {
+ ... 
+}
+<0> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step stmt var Int: x = 1; --->
+{
+stack: main{1<-1> :: var Int: x = 1;<0> :: {
+ ... 
+}
+<0> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step exp 1 --->
+{
+stack: main{1<-1> :: var Int: x = 1;<0> :: {
+ ... 
+}
+<0> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- handle value 1 with var Int: x = 1;<1>(1,) --->
+{
+stack: main{Int: x<-1> :: var Int: x = 1;<1>(1,) :: {
+ ... 
+}
+<0> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step exp Int: x --->
+{
+stack: main{Int<-1> :: Int: x<0> :: var Int: x = 1;<1>(1,) :: {
+ ... 
+}
+<0> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step exp Int --->
+{
+stack: main{Int<-1> :: Int: x<0> :: var Int: x = 1;<1>(1,) :: {
+ ... 
+}
+<0> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- handle value Int with Int: x<1>(Int,) --->
+{
+stack: main{Int: x<-1> :: var Int: x = 1;<1>(1,) :: {
+ ... 
+}
+<0> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- handle value Int: x with var Int: x = 1;<2>(1,Int: x,) --->
+pattern_match(Int: x, 1)
+{
+stack: main{{
+ ... 
+}
+<0> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 1, 
+env: x: 1, x: 0, main: fun<main>, 
+}
+--- step stmt {
+ ... 
+}
+ --->
+{
+stack: main{return x;<-1>} :: top{}
+heap: fun<main>, 0, !!1, 
+env: x: 0, main: fun<main>, 
+}
+--- step stmt return x; --->
+{
+stack: main{x<-1> :: return x;<0>} :: top{}
+heap: fun<main>, 0, !!1, 
+env: x: 0, main: fun<main>, 
+}
+--- step exp x --->
+{
+stack: main{0<-1> :: return x;<0>} :: top{}
+heap: fun<main>, 0, !!1, 
+env: x: 0, main: fun<main>, 
+}
+--- handle value 0 with return x;<1>(0,) --->
+{
+stack: top{0<-1>}
+heap: fun<main>, !!0, !!1, 
+env: main: fun<main>, 
+}
 result: 0

+ 819 - 0
executable_semantics/testdata/break1.golden

@@ -1,2 +1,821 @@
 MakeBlock
+********** source program **********
+fn main () -> Int {
+var Int: x = 2;
+while (true)
+{
+if ((x == 0))
+break;
+else
+x = (x - 1);
+
+}
+
+return x;
+
+}
+********** type checking **********
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+
+********** type checking complete **********
+fn main () -> Int {
+var Int: x = 2;
+while (true)
+{
+if ((x == 0))
+break;
+else
+x = (x - 1);
+
+}
+
+return x;
+}
+********** starting execution **********
+********** initializing globals **********
+--- step exp () --->
+********** calling main function **********
+{
+stack: top{main()<-1>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main() --->
+{
+stack: top{main<-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main --->
+{
+stack: top{fun<main><-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value fun<main> with main()<1>(fun<main>,) --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp () --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value () with main()<2>(fun<main>,(),) --->
+pattern_match((), ())
+{
+stack: main{var Int: x = 2; ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt var Int: x = 2; ...  --->
+{
+stack: main{var Int: x = 2;<-1> :: while (true)
+ ...  ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt var Int: x = 2; --->
+{
+stack: main{2<-1> :: var Int: x = 2;<0> :: while (true)
+ ...  ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 2 --->
+{
+stack: main{2<-1> :: var Int: x = 2;<0> :: while (true)
+ ...  ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 2 with var Int: x = 2;<1>(2,) --->
+{
+stack: main{Int: x<-1> :: var Int: x = 2;<1>(2,) :: while (true)
+ ...  ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp Int: x --->
+{
+stack: main{Int<-1> :: Int: x<0> :: var Int: x = 2;<1>(2,) :: while (true)
+ ...  ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp Int --->
+{
+stack: main{Int<-1> :: Int: x<0> :: var Int: x = 2;<1>(2,) :: while (true)
+ ...  ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value Int with Int: x<1>(Int,) --->
+{
+stack: main{Int: x<-1> :: var Int: x = 2;<1>(2,) :: while (true)
+ ...  ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value Int: x with var Int: x = 2;<2>(2,Int: x,) --->
+pattern_match(Int: x, 2)
+{
+stack: main{while (true)
+ ...  ... <-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step stmt while (true)
+ ...  ...  --->
+{
+stack: main{while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step stmt while (true)
+ ...  --->
+{
+stack: main{true<-1> :: while (true)
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step exp true --->
+{
+stack: main{true<-1> :: while (true)
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- handle value true with while (true)
+ ... <1>(true,) --->
+{
+stack: main{{
+ ... 
+}
+<-1> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step stmt {
+ ... 
+}
+ --->
+{
+stack: main{if ((x == 0))
+ ... 
+else
+ ... <-1> :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step stmt if ((x == 0))
+ ... 
+else
+ ...  --->
+{
+stack: main{if ((x == 0))
+ ... 
+else
+ ... <-1> :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step stmt if ((x == 0))
+ ... 
+else
+ ...  --->
+{
+stack: main{(x == 0)<-1> :: if ((x == 0))
+ ... 
+else
+ ... <0> :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step exp (x == 0) --->
+{
+stack: main{x<-1> :: (x == 0)<0> :: if ((x == 0))
+ ... 
+else
+ ... <0> :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step exp x --->
+{
+stack: main{2<-1> :: (x == 0)<0> :: if ((x == 0))
+ ... 
+else
+ ... <0> :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- handle value 2 with (x == 0)<1>(2,) --->
+{
+stack: main{0<-1> :: (x == 0)<1>(2,) :: if ((x == 0))
+ ... 
+else
+ ... <0> :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step exp 0 --->
+{
+stack: main{0<-1> :: (x == 0)<1>(2,) :: if ((x == 0))
+ ... 
+else
+ ... <0> :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- handle value 0 with (x == 0)<2>(2,0,) --->
+{
+stack: main{false<-1> :: if ((x == 0))
+ ... 
+else
+ ... <0> :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- handle value false with if ((x == 0))
+ ... 
+else
+ ... <1>(false,) --->
+{
+stack: main{x = (x - 1);<-1> :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step stmt x = (x - 1); --->
+{
+stack: main{x<-1> :: x = (x - 1);<0> :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step lvalue x --->
+{
+stack: main{ptr<1><-1> :: x = (x - 1);<0> :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- handle value ptr<1> with x = (x - 1);<1>(ptr<1>,) --->
+{
+stack: main{(x - 1)<-1> :: x = (x - 1);<1>(ptr<1>,) :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step exp (x - 1) --->
+{
+stack: main{x<-1> :: (x - 1)<0> :: x = (x - 1);<1>(ptr<1>,) :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step exp x --->
+{
+stack: main{2<-1> :: (x - 1)<0> :: x = (x - 1);<1>(ptr<1>,) :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- handle value 2 with (x - 1)<1>(2,) --->
+{
+stack: main{1<-1> :: (x - 1)<1>(2,) :: x = (x - 1);<1>(ptr<1>,) :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step exp 1 --->
+{
+stack: main{1<-1> :: (x - 1)<1>(2,) :: x = (x - 1);<1>(ptr<1>,) :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- handle value 1 with (x - 1)<2>(2,1,) --->
+{
+stack: main{1<-1> :: x = (x - 1);<1>(ptr<1>,) :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- handle value 1 with x = (x - 1);<2>(ptr<1>,1,) --->
+{
+stack: main{{
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step stmt {
+ ... 
+}
+ --->
+{
+stack: main{while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step stmt while (true)
+ ...  --->
+{
+stack: main{true<-1> :: while (true)
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step exp true --->
+{
+stack: main{true<-1> :: while (true)
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- handle value true with while (true)
+ ... <1>(true,) --->
+{
+stack: main{{
+ ... 
+}
+<-1> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step stmt {
+ ... 
+}
+ --->
+{
+stack: main{if ((x == 0))
+ ... 
+else
+ ... <-1> :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step stmt if ((x == 0))
+ ... 
+else
+ ...  --->
+{
+stack: main{if ((x == 0))
+ ... 
+else
+ ... <-1> :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step stmt if ((x == 0))
+ ... 
+else
+ ...  --->
+{
+stack: main{(x == 0)<-1> :: if ((x == 0))
+ ... 
+else
+ ... <0> :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step exp (x == 0) --->
+{
+stack: main{x<-1> :: (x == 0)<0> :: if ((x == 0))
+ ... 
+else
+ ... <0> :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step exp x --->
+{
+stack: main{1<-1> :: (x == 0)<0> :: if ((x == 0))
+ ... 
+else
+ ... <0> :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- handle value 1 with (x == 0)<1>(1,) --->
+{
+stack: main{0<-1> :: (x == 0)<1>(1,) :: if ((x == 0))
+ ... 
+else
+ ... <0> :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step exp 0 --->
+{
+stack: main{0<-1> :: (x == 0)<1>(1,) :: if ((x == 0))
+ ... 
+else
+ ... <0> :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- handle value 0 with (x == 0)<2>(1,0,) --->
+{
+stack: main{false<-1> :: if ((x == 0))
+ ... 
+else
+ ... <0> :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- handle value false with if ((x == 0))
+ ... 
+else
+ ... <1>(false,) --->
+{
+stack: main{x = (x - 1);<-1> :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step stmt x = (x - 1); --->
+{
+stack: main{x<-1> :: x = (x - 1);<0> :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step lvalue x --->
+{
+stack: main{ptr<1><-1> :: x = (x - 1);<0> :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- handle value ptr<1> with x = (x - 1);<1>(ptr<1>,) --->
+{
+stack: main{(x - 1)<-1> :: x = (x - 1);<1>(ptr<1>,) :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step exp (x - 1) --->
+{
+stack: main{x<-1> :: (x - 1)<0> :: x = (x - 1);<1>(ptr<1>,) :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step exp x --->
+{
+stack: main{1<-1> :: (x - 1)<0> :: x = (x - 1);<1>(ptr<1>,) :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- handle value 1 with (x - 1)<1>(1,) --->
+{
+stack: main{1<-1> :: (x - 1)<1>(1,) :: x = (x - 1);<1>(ptr<1>,) :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step exp 1 --->
+{
+stack: main{1<-1> :: (x - 1)<1>(1,) :: x = (x - 1);<1>(ptr<1>,) :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- handle value 1 with (x - 1)<2>(1,1,) --->
+{
+stack: main{0<-1> :: x = (x - 1);<1>(ptr<1>,) :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- handle value 0 with x = (x - 1);<2>(ptr<1>,0,) --->
+{
+stack: main{{
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step stmt {
+ ... 
+}
+ --->
+{
+stack: main{while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step stmt while (true)
+ ...  --->
+{
+stack: main{true<-1> :: while (true)
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step exp true --->
+{
+stack: main{true<-1> :: while (true)
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- handle value true with while (true)
+ ... <1>(true,) --->
+{
+stack: main{{
+ ... 
+}
+<-1> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step stmt {
+ ... 
+}
+ --->
+{
+stack: main{if ((x == 0))
+ ... 
+else
+ ... <-1> :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step stmt if ((x == 0))
+ ... 
+else
+ ...  --->
+{
+stack: main{if ((x == 0))
+ ... 
+else
+ ... <-1> :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step stmt if ((x == 0))
+ ... 
+else
+ ...  --->
+{
+stack: main{(x == 0)<-1> :: if ((x == 0))
+ ... 
+else
+ ... <0> :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step exp (x == 0) --->
+{
+stack: main{x<-1> :: (x == 0)<0> :: if ((x == 0))
+ ... 
+else
+ ... <0> :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step exp x --->
+{
+stack: main{0<-1> :: (x == 0)<0> :: if ((x == 0))
+ ... 
+else
+ ... <0> :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- handle value 0 with (x == 0)<1>(0,) --->
+{
+stack: main{0<-1> :: (x == 0)<1>(0,) :: if ((x == 0))
+ ... 
+else
+ ... <0> :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step exp 0 --->
+{
+stack: main{0<-1> :: (x == 0)<1>(0,) :: if ((x == 0))
+ ... 
+else
+ ... <0> :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- handle value 0 with (x == 0)<2>(0,0,) --->
+{
+stack: main{true<-1> :: if ((x == 0))
+ ... 
+else
+ ... <0> :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- handle value true with if ((x == 0))
+ ... 
+else
+ ... <1>(true,) --->
+{
+stack: main{break;<-1> :: {
+ ... 
+}
+<0> :: while (true)
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step stmt break; --->
+{
+stack: main{return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step stmt return x; --->
+{
+stack: main{x<-1> :: return x;<0>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step exp x --->
+{
+stack: main{0<-1> :: return x;<0>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- handle value 0 with return x;<1>(0,) --->
+{
+stack: top{0<-1>}
+heap: fun<main>, !!0, 
+env: main: fun<main>, 
+}
 result: 0

+ 44 - 1
executable_semantics/testdata/choice1.golden

@@ -1 +1,44 @@
-result: 0
+********** source program **********
+choice Ints {
+alt None ();
+alt One Int;
+alt Two (0 = Int, 1 = Int);
+}
+fn main () -> Int {
+var auto: x = Ints.None();
+var auto: y = Ints.One(0 = 42);
+var auto: n = 0;
+match (y) {
+case Ints.None =>
+n = (n + 2);
+case Ints.One(0 = auto: x) =>
+n = ((x + 1) - 42);
+case Ints.Two(0 = auto: a, 1 = auto: b) =>
+n = 2;
+}
+match (x) {
+case Ints.One(0 = auto: x) =>
+n = (x + 2);
+case Ints.None() =>
+n = (n - 1);
+case Ints.Two(0 = auto: x, 1 = auto: y) =>
+n = 5;
+}
+return n;
+
+}
+********** type checking **********
+--- step exp () --->
+--- step exp Int --->
+--- step exp (0 = Int, 1 = Int) --->
+--- step exp Int --->
+--- handle value Int with (0 = Int, 1 = Int)<1>(Int,) --->
+--- step exp Int --->
+--- handle value Int with (0 = Int, 1 = Int)<2>(Int,Int,) --->
+--- step exp Int --->
+--- step exp Int --->
+--- step exp auto --->
+13: type error in call
+expected: Int
+actual: Tuple(0 = Int)
+EXIT CODE: 255

+ 615 - 0
executable_semantics/testdata/continue1.golden

@@ -1 +1,616 @@
+********** source program **********
+fn main () -> Int {
+var auto: x = 2;
+while ((! (x == 0)))
+{
+x = (x - 1);
+continue;
+x = (x + 1);
+
+}
+
+return x;
+
+}
+********** type checking **********
+--- step exp Int --->
+--- step exp Int --->
+--- step exp auto --->
+
+********** type checking complete **********
+fn main () -> Int {
+var auto: x = 2;
+while ((! (x == 0)))
+{
+x = (x - 1);
+continue;
+x = (x + 1);
+
+}
+
+return x;
+}
+********** starting execution **********
+********** initializing globals **********
+--- step exp () --->
+********** calling main function **********
+{
+stack: top{main()<-1>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main() --->
+{
+stack: top{main<-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main --->
+{
+stack: top{fun<main><-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value fun<main> with main()<1>(fun<main>,) --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp () --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value () with main()<2>(fun<main>,(),) --->
+pattern_match((), ())
+{
+stack: main{var auto: x = 2; ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt var auto: x = 2; ...  --->
+{
+stack: main{var auto: x = 2;<-1> :: while ((! (x == 0)))
+ ...  ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt var auto: x = 2; --->
+{
+stack: main{2<-1> :: var auto: x = 2;<0> :: while ((! (x == 0)))
+ ...  ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 2 --->
+{
+stack: main{2<-1> :: var auto: x = 2;<0> :: while ((! (x == 0)))
+ ...  ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 2 with var auto: x = 2;<1>(2,) --->
+{
+stack: main{auto: x<-1> :: var auto: x = 2;<1>(2,) :: while ((! (x == 0)))
+ ...  ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp auto: x --->
+{
+stack: main{auto<-1> :: auto: x<0> :: var auto: x = 2;<1>(2,) :: while ((! (x == 0)))
+ ...  ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp auto --->
+{
+stack: main{auto<-1> :: auto: x<0> :: var auto: x = 2;<1>(2,) :: while ((! (x == 0)))
+ ...  ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value auto with auto: x<1>(auto,) --->
+{
+stack: main{auto: x<-1> :: var auto: x = 2;<1>(2,) :: while ((! (x == 0)))
+ ...  ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value auto: x with var auto: x = 2;<2>(2,auto: x,) --->
+pattern_match(auto: x, 2)
+{
+stack: main{while ((! (x == 0)))
+ ...  ... <-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step stmt while ((! (x == 0)))
+ ...  ...  --->
+{
+stack: main{while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step stmt while ((! (x == 0)))
+ ...  --->
+{
+stack: main{(! (x == 0))<-1> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step exp (! (x == 0)) --->
+{
+stack: main{(x == 0)<-1> :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step exp (x == 0) --->
+{
+stack: main{x<-1> :: (x == 0)<0> :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step exp x --->
+{
+stack: main{2<-1> :: (x == 0)<0> :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- handle value 2 with (x == 0)<1>(2,) --->
+{
+stack: main{0<-1> :: (x == 0)<1>(2,) :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step exp 0 --->
+{
+stack: main{0<-1> :: (x == 0)<1>(2,) :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- handle value 0 with (x == 0)<2>(2,0,) --->
+{
+stack: main{false<-1> :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- handle value false with (! (x == 0))<1>(false,) --->
+{
+stack: main{true<-1> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- handle value true with while ((! (x == 0)))
+ ... <1>(true,) --->
+{
+stack: main{{
+ ... 
+}
+<-1> :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step stmt {
+ ... 
+}
+ --->
+{
+stack: main{x = (x - 1); ... <-1> :: {
+ ... 
+}
+<0> :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step stmt x = (x - 1); ...  --->
+{
+stack: main{x = (x - 1);<-1> :: continue; ... <-1> :: {
+ ... 
+}
+<0> :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step stmt x = (x - 1); --->
+{
+stack: main{x<-1> :: x = (x - 1);<0> :: continue; ... <-1> :: {
+ ... 
+}
+<0> :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step lvalue x --->
+{
+stack: main{ptr<1><-1> :: x = (x - 1);<0> :: continue; ... <-1> :: {
+ ... 
+}
+<0> :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- handle value ptr<1> with x = (x - 1);<1>(ptr<1>,) --->
+{
+stack: main{(x - 1)<-1> :: x = (x - 1);<1>(ptr<1>,) :: continue; ... <-1> :: {
+ ... 
+}
+<0> :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step exp (x - 1) --->
+{
+stack: main{x<-1> :: (x - 1)<0> :: x = (x - 1);<1>(ptr<1>,) :: continue; ... <-1> :: {
+ ... 
+}
+<0> :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step exp x --->
+{
+stack: main{2<-1> :: (x - 1)<0> :: x = (x - 1);<1>(ptr<1>,) :: continue; ... <-1> :: {
+ ... 
+}
+<0> :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- handle value 2 with (x - 1)<1>(2,) --->
+{
+stack: main{1<-1> :: (x - 1)<1>(2,) :: x = (x - 1);<1>(ptr<1>,) :: continue; ... <-1> :: {
+ ... 
+}
+<0> :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step exp 1 --->
+{
+stack: main{1<-1> :: (x - 1)<1>(2,) :: x = (x - 1);<1>(ptr<1>,) :: continue; ... <-1> :: {
+ ... 
+}
+<0> :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- handle value 1 with (x - 1)<2>(2,1,) --->
+{
+stack: main{1<-1> :: x = (x - 1);<1>(ptr<1>,) :: continue; ... <-1> :: {
+ ... 
+}
+<0> :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- handle value 1 with x = (x - 1);<2>(ptr<1>,1,) --->
+{
+stack: main{continue; ... <-1> :: {
+ ... 
+}
+<0> :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step stmt continue; ...  --->
+{
+stack: main{continue;<-1> :: x = (x + 1);<-1> :: {
+ ... 
+}
+<0> :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step stmt continue; --->
+{
+stack: main{while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step stmt while ((! (x == 0)))
+ ...  --->
+{
+stack: main{(! (x == 0))<-1> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step exp (! (x == 0)) --->
+{
+stack: main{(x == 0)<-1> :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step exp (x == 0) --->
+{
+stack: main{x<-1> :: (x == 0)<0> :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step exp x --->
+{
+stack: main{1<-1> :: (x == 0)<0> :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- handle value 1 with (x == 0)<1>(1,) --->
+{
+stack: main{0<-1> :: (x == 0)<1>(1,) :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step exp 0 --->
+{
+stack: main{0<-1> :: (x == 0)<1>(1,) :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- handle value 0 with (x == 0)<2>(1,0,) --->
+{
+stack: main{false<-1> :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- handle value false with (! (x == 0))<1>(false,) --->
+{
+stack: main{true<-1> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- handle value true with while ((! (x == 0)))
+ ... <1>(true,) --->
+{
+stack: main{{
+ ... 
+}
+<-1> :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step stmt {
+ ... 
+}
+ --->
+{
+stack: main{x = (x - 1); ... <-1> :: {
+ ... 
+}
+<0> :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step stmt x = (x - 1); ...  --->
+{
+stack: main{x = (x - 1);<-1> :: continue; ... <-1> :: {
+ ... 
+}
+<0> :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step stmt x = (x - 1); --->
+{
+stack: main{x<-1> :: x = (x - 1);<0> :: continue; ... <-1> :: {
+ ... 
+}
+<0> :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step lvalue x --->
+{
+stack: main{ptr<1><-1> :: x = (x - 1);<0> :: continue; ... <-1> :: {
+ ... 
+}
+<0> :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- handle value ptr<1> with x = (x - 1);<1>(ptr<1>,) --->
+{
+stack: main{(x - 1)<-1> :: x = (x - 1);<1>(ptr<1>,) :: continue; ... <-1> :: {
+ ... 
+}
+<0> :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step exp (x - 1) --->
+{
+stack: main{x<-1> :: (x - 1)<0> :: x = (x - 1);<1>(ptr<1>,) :: continue; ... <-1> :: {
+ ... 
+}
+<0> :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step exp x --->
+{
+stack: main{1<-1> :: (x - 1)<0> :: x = (x - 1);<1>(ptr<1>,) :: continue; ... <-1> :: {
+ ... 
+}
+<0> :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- handle value 1 with (x - 1)<1>(1,) --->
+{
+stack: main{1<-1> :: (x - 1)<1>(1,) :: x = (x - 1);<1>(ptr<1>,) :: continue; ... <-1> :: {
+ ... 
+}
+<0> :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step exp 1 --->
+{
+stack: main{1<-1> :: (x - 1)<1>(1,) :: x = (x - 1);<1>(ptr<1>,) :: continue; ... <-1> :: {
+ ... 
+}
+<0> :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- handle value 1 with (x - 1)<2>(1,1,) --->
+{
+stack: main{0<-1> :: x = (x - 1);<1>(ptr<1>,) :: continue; ... <-1> :: {
+ ... 
+}
+<0> :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- handle value 0 with x = (x - 1);<2>(ptr<1>,0,) --->
+{
+stack: main{continue; ... <-1> :: {
+ ... 
+}
+<0> :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step stmt continue; ...  --->
+{
+stack: main{continue;<-1> :: x = (x + 1);<-1> :: {
+ ... 
+}
+<0> :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step stmt continue; --->
+{
+stack: main{while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step stmt while ((! (x == 0)))
+ ...  --->
+{
+stack: main{(! (x == 0))<-1> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step exp (! (x == 0)) --->
+{
+stack: main{(x == 0)<-1> :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step exp (x == 0) --->
+{
+stack: main{x<-1> :: (x == 0)<0> :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step exp x --->
+{
+stack: main{0<-1> :: (x == 0)<0> :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- handle value 0 with (x == 0)<1>(0,) --->
+{
+stack: main{0<-1> :: (x == 0)<1>(0,) :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step exp 0 --->
+{
+stack: main{0<-1> :: (x == 0)<1>(0,) :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- handle value 0 with (x == 0)<2>(0,0,) --->
+{
+stack: main{true<-1> :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- handle value true with (! (x == 0))<1>(true,) --->
+{
+stack: main{false<-1> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- handle value false with while ((! (x == 0)))
+ ... <1>(false,) --->
+{
+stack: main{return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step stmt return x; --->
+{
+stack: main{x<-1> :: return x;<0>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step exp x --->
+{
+stack: main{0<-1> :: return x;<0>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- handle value 0 with return x;<1>(0,) --->
+{
+stack: top{0<-1>}
+heap: fun<main>, !!0, 
+env: main: fun<main>, 
+}
 result: 0

+ 20 - 1
executable_semantics/testdata/fun1.golden

@@ -1 +1,20 @@
-result: 0
+********** source program **********
+fn f Int: x -> Int {
+return (x - 1);
+
+}
+fn main () -> Int {
+return f(0 = 1);
+
+}
+********** type checking **********
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+10: type error in call
+expected: Int
+actual: Tuple(0 = Int)
+EXIT CODE: 255

+ 26 - 1
executable_semantics/testdata/fun2.golden

@@ -1 +1,26 @@
-result: 0
+********** source program **********
+fn f Int: x -> Int {
+return 0;
+
+}
+fn main () -> Int {
+var Int: a = 0;
+var Int: b = 1;
+f(0 = a);
+b = a;
+return b;
+
+}
+********** type checking **********
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+15: type error in call
+expected: Int
+actual: Tuple(0 = Int)
+EXIT CODE: 255

+ 210 - 0
executable_semantics/testdata/fun3.golden

@@ -1 +1,211 @@
+********** source program **********
+fn f (0 = Int: x, 1 = Int: y) -> Int {
+return (x + y);
+
+}
+fn main () -> Int {
+return (f(0 = 2, 1 = 3) - 5);
+
+}
+********** type checking **********
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+
+********** type checking complete **********
+fn f (0 = Int: x, 1 = Int: y) -> Int {
+return (x + y);
+}
+fn main () -> Int {
+return (f(0 = 2, 1 = 3) - 5);
+}
+********** starting execution **********
+********** initializing globals **********
+--- step exp (0 = Int: x, 1 = Int: y) --->
+--- step exp Int: x --->
+--- step exp Int --->
+--- handle value Int with Int: x<1>(Int,) --->
+--- handle value Int: x with (0 = Int: x, 1 = Int: y)<1>(Int: x,) --->
+--- step exp Int: y --->
+--- step exp Int --->
+--- handle value Int with Int: y<1>(Int,) --->
+--- handle value Int: y with (0 = Int: x, 1 = Int: y)<2>(Int: x,Int: y,) --->
+--- step exp () --->
+********** calling main function **********
+{
+stack: top{main()<-1>}
+heap: Int: x, Int: y, fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- step exp main() --->
+{
+stack: top{main<-1> :: main()<0>}
+heap: Int: x, Int: y, fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- step exp main --->
+{
+stack: top{fun<main><-1> :: main()<0>}
+heap: Int: x, Int: y, fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- handle value fun<main> with main()<1>(fun<main>,) --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: Int: x, Int: y, fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- step exp () --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: Int: x, Int: y, fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- handle value () with main()<2>(fun<main>,(),) --->
+pattern_match((), ())
+{
+stack: main{return (f(0 = 2, 1 = 3) - 5);<-1>} :: top{}
+heap: Int: x, Int: y, fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- step stmt return (f(0 = 2, 1 = 3) - 5); --->
+{
+stack: main{(f(0 = 2, 1 = 3) - 5)<-1> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
+heap: Int: x, Int: y, fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- step exp (f(0 = 2, 1 = 3) - 5) --->
+{
+stack: main{f(0 = 2, 1 = 3)<-1> :: (f(0 = 2, 1 = 3) - 5)<0> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
+heap: Int: x, Int: y, fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- step exp f(0 = 2, 1 = 3) --->
+{
+stack: main{f<-1> :: f(0 = 2, 1 = 3)<0> :: (f(0 = 2, 1 = 3) - 5)<0> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
+heap: Int: x, Int: y, fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- step exp f --->
+{
+stack: main{fun<f><-1> :: f(0 = 2, 1 = 3)<0> :: (f(0 = 2, 1 = 3) - 5)<0> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
+heap: Int: x, Int: y, fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- handle value fun<f> with f(0 = 2, 1 = 3)<1>(fun<f>,) --->
+{
+stack: main{(0 = 2, 1 = 3)<-1> :: f(0 = 2, 1 = 3)<1>(fun<f>,) :: (f(0 = 2, 1 = 3) - 5)<0> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
+heap: Int: x, Int: y, fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- step exp (0 = 2, 1 = 3) --->
+{
+stack: main{2<-1> :: (0 = 2, 1 = 3)<0> :: f(0 = 2, 1 = 3)<1>(fun<f>,) :: (f(0 = 2, 1 = 3) - 5)<0> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
+heap: Int: x, Int: y, fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- step exp 2 --->
+{
+stack: main{2<-1> :: (0 = 2, 1 = 3)<0> :: f(0 = 2, 1 = 3)<1>(fun<f>,) :: (f(0 = 2, 1 = 3) - 5)<0> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
+heap: Int: x, Int: y, fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- handle value 2 with (0 = 2, 1 = 3)<1>(2,) --->
+{
+stack: main{3<-1> :: (0 = 2, 1 = 3)<1>(2,) :: f(0 = 2, 1 = 3)<1>(fun<f>,) :: (f(0 = 2, 1 = 3) - 5)<0> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
+heap: Int: x, Int: y, fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- step exp 3 --->
+{
+stack: main{3<-1> :: (0 = 2, 1 = 3)<1>(2,) :: f(0 = 2, 1 = 3)<1>(fun<f>,) :: (f(0 = 2, 1 = 3) - 5)<0> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
+heap: Int: x, Int: y, fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- handle value 3 with (0 = 2, 1 = 3)<2>(2,3,) --->
+{
+stack: main{(0 = 2@4, 1 = 3@5)<-1> :: f(0 = 2, 1 = 3)<1>(fun<f>,) :: (f(0 = 2, 1 = 3) - 5)<0> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
+heap: Int: x, Int: y, fun<f>, fun<main>, 2, 3, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- handle value (0 = 2@4, 1 = 3@5) with f(0 = 2, 1 = 3)<2>(fun<f>,(0 = 2@4, 1 = 3@5),) --->
+pattern_match((0 = Int: x@0, 1 = Int: y@1), (0 = 2@4, 1 = 3@5))
+pattern_match(Int: x, 2)
+pattern_match(Int: y, 3)
+{
+stack: f{return (x + y);<-1>} :: main{(f(0 = 2, 1 = 3) - 5)<0> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
+heap: Int: x, Int: y, fun<f>, fun<main>, 2, 3, 2, 3, 
+env: y: 3, x: 2, main: fun<main>, f: fun<f>, 
+}
+--- step stmt return (x + y); --->
+{
+stack: f{(x + y)<-1> :: return (x + y);<0>} :: main{(f(0 = 2, 1 = 3) - 5)<0> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
+heap: Int: x, Int: y, fun<f>, fun<main>, 2, 3, 2, 3, 
+env: y: 3, x: 2, main: fun<main>, f: fun<f>, 
+}
+--- step exp (x + y) --->
+{
+stack: f{x<-1> :: (x + y)<0> :: return (x + y);<0>} :: main{(f(0 = 2, 1 = 3) - 5)<0> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
+heap: Int: x, Int: y, fun<f>, fun<main>, 2, 3, 2, 3, 
+env: y: 3, x: 2, main: fun<main>, f: fun<f>, 
+}
+--- step exp x --->
+{
+stack: f{2<-1> :: (x + y)<0> :: return (x + y);<0>} :: main{(f(0 = 2, 1 = 3) - 5)<0> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
+heap: Int: x, Int: y, fun<f>, fun<main>, 2, 3, 2, 3, 
+env: y: 3, x: 2, main: fun<main>, f: fun<f>, 
+}
+--- handle value 2 with (x + y)<1>(2,) --->
+{
+stack: f{y<-1> :: (x + y)<1>(2,) :: return (x + y);<0>} :: main{(f(0 = 2, 1 = 3) - 5)<0> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
+heap: Int: x, Int: y, fun<f>, fun<main>, 2, 3, 2, 3, 
+env: y: 3, x: 2, main: fun<main>, f: fun<f>, 
+}
+--- step exp y --->
+{
+stack: f{3<-1> :: (x + y)<1>(2,) :: return (x + y);<0>} :: main{(f(0 = 2, 1 = 3) - 5)<0> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
+heap: Int: x, Int: y, fun<f>, fun<main>, 2, 3, 2, 3, 
+env: y: 3, x: 2, main: fun<main>, f: fun<f>, 
+}
+--- handle value 3 with (x + y)<2>(2,3,) --->
+{
+stack: f{5<-1> :: return (x + y);<0>} :: main{(f(0 = 2, 1 = 3) - 5)<0> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
+heap: Int: x, Int: y, fun<f>, fun<main>, 2, 3, 2, 3, 
+env: y: 3, x: 2, main: fun<main>, f: fun<f>, 
+}
+--- handle value 5 with return (x + y);<1>(5,) --->
+{
+stack: main{5<-1> :: (f(0 = 2, 1 = 3) - 5)<0> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
+heap: Int: x, Int: y, fun<f>, fun<main>, 2, 3, !!2, !!3, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- handle value 5 with (f(0 = 2, 1 = 3) - 5)<1>(5,) --->
+{
+stack: main{5<-1> :: (f(0 = 2, 1 = 3) - 5)<1>(5,) :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
+heap: Int: x, Int: y, fun<f>, fun<main>, 2, 3, !!2, !!3, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- step exp 5 --->
+{
+stack: main{5<-1> :: (f(0 = 2, 1 = 3) - 5)<1>(5,) :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
+heap: Int: x, Int: y, fun<f>, fun<main>, 2, 3, !!2, !!3, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- handle value 5 with (f(0 = 2, 1 = 3) - 5)<2>(5,5,) --->
+{
+stack: main{0<-1> :: return (f(0 = 2, 1 = 3) - 5);<0>} :: top{}
+heap: Int: x, Int: y, fun<f>, fun<main>, 2, 3, !!2, !!3, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- handle value 0 with return (f(0 = 2, 1 = 3) - 5);<1>(0,) --->
+{
+stack: top{0<-1>}
+heap: Int: x, Int: y, fun<f>, fun<main>, 2, 3, !!2, !!3, 
+env: main: fun<main>, f: fun<f>, 
+}
 result: 0

+ 147 - 0
executable_semantics/testdata/fun4.golden

@@ -1 +1,148 @@
+********** source program **********
+fn f () -> ();
+fn main () -> Int {
+f();
+return 0;
+
+}
+********** type checking **********
+--- step exp () --->
+--- step exp Int --->
+--- step exp () --->
+--- step exp Int --->
+
+********** type checking complete **********
+fn f () -> () {
+return ();
+}
+fn main () -> Int {
+f();
+return 0;
+}
+********** starting execution **********
+********** initializing globals **********
+--- step exp () --->
+--- step exp () --->
+********** calling main function **********
+{
+stack: top{main()<-1>}
+heap: fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- step exp main() --->
+{
+stack: top{main<-1> :: main()<0>}
+heap: fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- step exp main --->
+{
+stack: top{fun<main><-1> :: main()<0>}
+heap: fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- handle value fun<main> with main()<1>(fun<main>,) --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- step exp () --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- handle value () with main()<2>(fun<main>,(),) --->
+pattern_match((), ())
+{
+stack: main{f(); ... <-1>} :: top{}
+heap: fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- step stmt f(); ...  --->
+{
+stack: main{f();<-1> :: return 0;<-1>} :: top{}
+heap: fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- step stmt f(); --->
+{
+stack: main{f()<-1> :: f();<-1> :: return 0;<-1>} :: top{}
+heap: fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- step exp f() --->
+{
+stack: main{f<-1> :: f()<0> :: f();<-1> :: return 0;<-1>} :: top{}
+heap: fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- step exp f --->
+{
+stack: main{fun<f><-1> :: f()<0> :: f();<-1> :: return 0;<-1>} :: top{}
+heap: fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- handle value fun<f> with f()<1>(fun<f>,) --->
+{
+stack: main{()<-1> :: f()<1>(fun<f>,) :: f();<-1> :: return 0;<-1>} :: top{}
+heap: fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- step exp () --->
+{
+stack: main{()<-1> :: f()<1>(fun<f>,) :: f();<-1> :: return 0;<-1>} :: top{}
+heap: fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- handle value () with f()<2>(fun<f>,(),) --->
+pattern_match((), ())
+{
+stack: f{return ();<-1>} :: main{f();<-1> :: return 0;<-1>} :: top{}
+heap: fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- step stmt return (); --->
+{
+stack: f{()<-1> :: return ();<0>} :: main{f();<-1> :: return 0;<-1>} :: top{}
+heap: fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- step exp () --->
+{
+stack: f{()<-1> :: return ();<0>} :: main{f();<-1> :: return 0;<-1>} :: top{}
+heap: fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- handle value () with return ();<1>((),) --->
+{
+stack: main{()<-1> :: f();<-1> :: return 0;<-1>} :: top{}
+heap: fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- handle value () with f();<0>((),) --->
+{
+stack: main{return 0;<-1>} :: top{}
+heap: fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- step stmt return 0; --->
+{
+stack: main{0<-1> :: return 0;<0>} :: top{}
+heap: fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- step exp 0 --->
+{
+stack: main{0<-1> :: return 0;<0>} :: top{}
+heap: fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
+--- handle value 0 with return 0;<1>(0,) --->
+{
+stack: top{0<-1>}
+heap: fun<f>, fun<main>, 
+env: main: fun<main>, f: fun<f>, 
+}
 result: 0

+ 213 - 0
executable_semantics/testdata/fun5.golden

@@ -1 +1,214 @@
+********** source program **********
+fn add (0 = Int: x, 1 = Int: y) -> auto {
+return (x + y);
+}
+fn main () -> Int {
+return (add(0 = 1, 1 = 2) - 3);
+
+}
+********** type checking **********
+--- step exp Int --->
+--- step exp Int --->
+--- step exp auto --->
+--- step exp Int --->
+--- step exp Int --->
+--- step exp auto --->
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+--- step exp auto --->
+--- step exp Int --->
+
+********** type checking complete **********
+fn add (0 = Int: x, 1 = Int: y) -> Int {
+return (x + y);
+}
+fn main () -> Int {
+return (add(0 = 1, 1 = 2) - 3);
+}
+********** starting execution **********
+********** initializing globals **********
+--- step exp (0 = Int: x, 1 = Int: y) --->
+--- step exp Int: x --->
+--- step exp Int --->
+--- handle value Int with Int: x<1>(Int,) --->
+--- handle value Int: x with (0 = Int: x, 1 = Int: y)<1>(Int: x,) --->
+--- step exp Int: y --->
+--- step exp Int --->
+--- handle value Int with Int: y<1>(Int,) --->
+--- handle value Int: y with (0 = Int: x, 1 = Int: y)<2>(Int: x,Int: y,) --->
+--- step exp () --->
+********** calling main function **********
+{
+stack: top{main()<-1>}
+heap: Int: x, Int: y, fun<add>, fun<main>, 
+env: main: fun<main>, add: fun<add>, 
+}
+--- step exp main() --->
+{
+stack: top{main<-1> :: main()<0>}
+heap: Int: x, Int: y, fun<add>, fun<main>, 
+env: main: fun<main>, add: fun<add>, 
+}
+--- step exp main --->
+{
+stack: top{fun<main><-1> :: main()<0>}
+heap: Int: x, Int: y, fun<add>, fun<main>, 
+env: main: fun<main>, add: fun<add>, 
+}
+--- handle value fun<main> with main()<1>(fun<main>,) --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: Int: x, Int: y, fun<add>, fun<main>, 
+env: main: fun<main>, add: fun<add>, 
+}
+--- step exp () --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: Int: x, Int: y, fun<add>, fun<main>, 
+env: main: fun<main>, add: fun<add>, 
+}
+--- handle value () with main()<2>(fun<main>,(),) --->
+pattern_match((), ())
+{
+stack: main{return (add(0 = 1, 1 = 2) - 3);<-1>} :: top{}
+heap: Int: x, Int: y, fun<add>, fun<main>, 
+env: main: fun<main>, add: fun<add>, 
+}
+--- step stmt return (add(0 = 1, 1 = 2) - 3); --->
+{
+stack: main{(add(0 = 1, 1 = 2) - 3)<-1> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
+heap: Int: x, Int: y, fun<add>, fun<main>, 
+env: main: fun<main>, add: fun<add>, 
+}
+--- step exp (add(0 = 1, 1 = 2) - 3) --->
+{
+stack: main{add(0 = 1, 1 = 2)<-1> :: (add(0 = 1, 1 = 2) - 3)<0> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
+heap: Int: x, Int: y, fun<add>, fun<main>, 
+env: main: fun<main>, add: fun<add>, 
+}
+--- step exp add(0 = 1, 1 = 2) --->
+{
+stack: main{add<-1> :: add(0 = 1, 1 = 2)<0> :: (add(0 = 1, 1 = 2) - 3)<0> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
+heap: Int: x, Int: y, fun<add>, fun<main>, 
+env: main: fun<main>, add: fun<add>, 
+}
+--- step exp add --->
+{
+stack: main{fun<add><-1> :: add(0 = 1, 1 = 2)<0> :: (add(0 = 1, 1 = 2) - 3)<0> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
+heap: Int: x, Int: y, fun<add>, fun<main>, 
+env: main: fun<main>, add: fun<add>, 
+}
+--- handle value fun<add> with add(0 = 1, 1 = 2)<1>(fun<add>,) --->
+{
+stack: main{(0 = 1, 1 = 2)<-1> :: add(0 = 1, 1 = 2)<1>(fun<add>,) :: (add(0 = 1, 1 = 2) - 3)<0> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
+heap: Int: x, Int: y, fun<add>, fun<main>, 
+env: main: fun<main>, add: fun<add>, 
+}
+--- step exp (0 = 1, 1 = 2) --->
+{
+stack: main{1<-1> :: (0 = 1, 1 = 2)<0> :: add(0 = 1, 1 = 2)<1>(fun<add>,) :: (add(0 = 1, 1 = 2) - 3)<0> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
+heap: Int: x, Int: y, fun<add>, fun<main>, 
+env: main: fun<main>, add: fun<add>, 
+}
+--- step exp 1 --->
+{
+stack: main{1<-1> :: (0 = 1, 1 = 2)<0> :: add(0 = 1, 1 = 2)<1>(fun<add>,) :: (add(0 = 1, 1 = 2) - 3)<0> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
+heap: Int: x, Int: y, fun<add>, fun<main>, 
+env: main: fun<main>, add: fun<add>, 
+}
+--- handle value 1 with (0 = 1, 1 = 2)<1>(1,) --->
+{
+stack: main{2<-1> :: (0 = 1, 1 = 2)<1>(1,) :: add(0 = 1, 1 = 2)<1>(fun<add>,) :: (add(0 = 1, 1 = 2) - 3)<0> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
+heap: Int: x, Int: y, fun<add>, fun<main>, 
+env: main: fun<main>, add: fun<add>, 
+}
+--- step exp 2 --->
+{
+stack: main{2<-1> :: (0 = 1, 1 = 2)<1>(1,) :: add(0 = 1, 1 = 2)<1>(fun<add>,) :: (add(0 = 1, 1 = 2) - 3)<0> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
+heap: Int: x, Int: y, fun<add>, fun<main>, 
+env: main: fun<main>, add: fun<add>, 
+}
+--- handle value 2 with (0 = 1, 1 = 2)<2>(1,2,) --->
+{
+stack: main{(0 = 1@4, 1 = 2@5)<-1> :: add(0 = 1, 1 = 2)<1>(fun<add>,) :: (add(0 = 1, 1 = 2) - 3)<0> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
+heap: Int: x, Int: y, fun<add>, fun<main>, 1, 2, 
+env: main: fun<main>, add: fun<add>, 
+}
+--- handle value (0 = 1@4, 1 = 2@5) with add(0 = 1, 1 = 2)<2>(fun<add>,(0 = 1@4, 1 = 2@5),) --->
+pattern_match((0 = Int: x@0, 1 = Int: y@1), (0 = 1@4, 1 = 2@5))
+pattern_match(Int: x, 1)
+pattern_match(Int: y, 2)
+{
+stack: add{return (x + y);<-1>} :: main{(add(0 = 1, 1 = 2) - 3)<0> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
+heap: Int: x, Int: y, fun<add>, fun<main>, 1, 2, 1, 2, 
+env: y: 2, x: 1, main: fun<main>, add: fun<add>, 
+}
+--- step stmt return (x + y); --->
+{
+stack: add{(x + y)<-1> :: return (x + y);<0>} :: main{(add(0 = 1, 1 = 2) - 3)<0> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
+heap: Int: x, Int: y, fun<add>, fun<main>, 1, 2, 1, 2, 
+env: y: 2, x: 1, main: fun<main>, add: fun<add>, 
+}
+--- step exp (x + y) --->
+{
+stack: add{x<-1> :: (x + y)<0> :: return (x + y);<0>} :: main{(add(0 = 1, 1 = 2) - 3)<0> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
+heap: Int: x, Int: y, fun<add>, fun<main>, 1, 2, 1, 2, 
+env: y: 2, x: 1, main: fun<main>, add: fun<add>, 
+}
+--- step exp x --->
+{
+stack: add{1<-1> :: (x + y)<0> :: return (x + y);<0>} :: main{(add(0 = 1, 1 = 2) - 3)<0> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
+heap: Int: x, Int: y, fun<add>, fun<main>, 1, 2, 1, 2, 
+env: y: 2, x: 1, main: fun<main>, add: fun<add>, 
+}
+--- handle value 1 with (x + y)<1>(1,) --->
+{
+stack: add{y<-1> :: (x + y)<1>(1,) :: return (x + y);<0>} :: main{(add(0 = 1, 1 = 2) - 3)<0> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
+heap: Int: x, Int: y, fun<add>, fun<main>, 1, 2, 1, 2, 
+env: y: 2, x: 1, main: fun<main>, add: fun<add>, 
+}
+--- step exp y --->
+{
+stack: add{2<-1> :: (x + y)<1>(1,) :: return (x + y);<0>} :: main{(add(0 = 1, 1 = 2) - 3)<0> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
+heap: Int: x, Int: y, fun<add>, fun<main>, 1, 2, 1, 2, 
+env: y: 2, x: 1, main: fun<main>, add: fun<add>, 
+}
+--- handle value 2 with (x + y)<2>(1,2,) --->
+{
+stack: add{3<-1> :: return (x + y);<0>} :: main{(add(0 = 1, 1 = 2) - 3)<0> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
+heap: Int: x, Int: y, fun<add>, fun<main>, 1, 2, 1, 2, 
+env: y: 2, x: 1, main: fun<main>, add: fun<add>, 
+}
+--- handle value 3 with return (x + y);<1>(3,) --->
+{
+stack: main{3<-1> :: (add(0 = 1, 1 = 2) - 3)<0> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
+heap: Int: x, Int: y, fun<add>, fun<main>, 1, 2, !!1, !!2, 
+env: main: fun<main>, add: fun<add>, 
+}
+--- handle value 3 with (add(0 = 1, 1 = 2) - 3)<1>(3,) --->
+{
+stack: main{3<-1> :: (add(0 = 1, 1 = 2) - 3)<1>(3,) :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
+heap: Int: x, Int: y, fun<add>, fun<main>, 1, 2, !!1, !!2, 
+env: main: fun<main>, add: fun<add>, 
+}
+--- step exp 3 --->
+{
+stack: main{3<-1> :: (add(0 = 1, 1 = 2) - 3)<1>(3,) :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
+heap: Int: x, Int: y, fun<add>, fun<main>, 1, 2, !!1, !!2, 
+env: main: fun<main>, add: fun<add>, 
+}
+--- handle value 3 with (add(0 = 1, 1 = 2) - 3)<2>(3,3,) --->
+{
+stack: main{0<-1> :: return (add(0 = 1, 1 = 2) - 3);<0>} :: top{}
+heap: Int: x, Int: y, fun<add>, fun<main>, 1, 2, !!1, !!2, 
+env: main: fun<main>, add: fun<add>, 
+}
+--- handle value 0 with return (add(0 = 1, 1 = 2) - 3);<1>(0,) --->
+{
+stack: top{0<-1>}
+heap: Int: x, Int: y, fun<add>, fun<main>, 1, 2, !!1, !!2, 
+env: main: fun<main>, add: fun<add>, 
+}
 result: 0

+ 22 - 1
executable_semantics/testdata/fun_recur.golden

@@ -1 +1,22 @@
-result: 0
+********** source program **********
+fn f Int: x -> Int {
+if ((x == 0))
+return x;
+else
+return f(0 = (x - 1));
+
+}
+fn main () -> Int {
+return f(0 = 2);
+
+}
+********** type checking **********
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+9: type error in call
+expected: Int
+actual: Tuple(0 = Int)
+EXIT CODE: 255

+ 26 - 1
executable_semantics/testdata/funptr1.golden

@@ -1 +1,26 @@
-result: 0
+********** source program **********
+fn add1 Int: x -> Int {
+return (x + 1);
+
+}
+fn main () -> Int {
+var fn Int -> Int: f = add1;
+return f(0 = (- 1));
+
+}
+********** type checking **********
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+--- step exp fn Int -> Int --->
+--- step exp Int --->
+--- handle value Int with fn Int -> Int<1>(Int,) --->
+--- step exp Int --->
+--- handle value Int with fn Int -> Int<2>(Int,Int,) --->
+11: type error in call
+expected: Int
+actual: Tuple(0 = Int)
+EXIT CODE: 255

+ 160 - 0
executable_semantics/testdata/if1.golden

@@ -1 +1,161 @@
+********** source program **********
+fn main () -> Int {
+if ((1 == 1))
+return 0;
+else
+
+return 1;
+
+}
+********** type checking **********
+--- step exp Int --->
+--- step exp Int --->
+
+********** type checking complete **********
+fn main () -> Int {
+if ((1 == 1))
+return 0;
+else
+
+return 1;
+}
+********** starting execution **********
+********** initializing globals **********
+--- step exp () --->
+********** calling main function **********
+{
+stack: top{main()<-1>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main() --->
+{
+stack: top{main<-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main --->
+{
+stack: top{fun<main><-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value fun<main> with main()<1>(fun<main>,) --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp () --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value () with main()<2>(fun<main>,(),) --->
+pattern_match((), ())
+{
+stack: main{if ((1 == 1))
+ ... 
+else
+ ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt if ((1 == 1))
+ ... 
+else
+ ...  --->
+{
+stack: main{if ((1 == 1))
+ ... 
+else
+<-1> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt if ((1 == 1))
+ ... 
+else
+ --->
+{
+stack: main{(1 == 1)<-1> :: if ((1 == 1))
+ ... 
+else
+<0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp (1 == 1) --->
+{
+stack: main{1<-1> :: (1 == 1)<0> :: if ((1 == 1))
+ ... 
+else
+<0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 1 --->
+{
+stack: main{1<-1> :: (1 == 1)<0> :: if ((1 == 1))
+ ... 
+else
+<0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 1 with (1 == 1)<1>(1,) --->
+{
+stack: main{1<-1> :: (1 == 1)<1>(1,) :: if ((1 == 1))
+ ... 
+else
+<0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 1 --->
+{
+stack: main{1<-1> :: (1 == 1)<1>(1,) :: if ((1 == 1))
+ ... 
+else
+<0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 1 with (1 == 1)<2>(1,1,) --->
+{
+stack: main{true<-1> :: if ((1 == 1))
+ ... 
+else
+<0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value true with if ((1 == 1))
+ ... 
+else
+<1>(true,) --->
+{
+stack: main{return 0;<-1> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt return 0; --->
+{
+stack: main{0<-1> :: return 0;<0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 0 --->
+{
+stack: main{0<-1> :: return 0;<0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 0 with return 0;<1>(0,) --->
+{
+stack: top{0<-1>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
 result: 0

+ 143 - 1
executable_semantics/testdata/if2.golden

@@ -1 +1,143 @@
-result: 0
+********** source program **********
+fn main () -> Int {
+if ((0 == 1))
+return 1;
+else
+
+return 0;
+
+}
+********** type checking **********
+--- step exp Int --->
+--- step exp Int --->
+
+********** type checking complete **********
+fn main () -> Int {
+if ((0 == 1))
+return 1;
+else
+
+return 0;
+}
+********** starting execution **********
+********** initializing globals **********
+--- step exp () --->
+********** calling main function **********
+{
+stack: top{main()<-1>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main() --->
+{
+stack: top{main<-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main --->
+{
+stack: top{fun<main><-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value fun<main> with main()<1>(fun<main>,) --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp () --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value () with main()<2>(fun<main>,(),) --->
+pattern_match((), ())
+{
+stack: main{if ((0 == 1))
+ ... 
+else
+ ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt if ((0 == 1))
+ ... 
+else
+ ...  --->
+{
+stack: main{if ((0 == 1))
+ ... 
+else
+<-1> :: return 0;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt if ((0 == 1))
+ ... 
+else
+ --->
+{
+stack: main{(0 == 1)<-1> :: if ((0 == 1))
+ ... 
+else
+<0> :: return 0;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp (0 == 1) --->
+{
+stack: main{0<-1> :: (0 == 1)<0> :: if ((0 == 1))
+ ... 
+else
+<0> :: return 0;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 0 --->
+{
+stack: main{0<-1> :: (0 == 1)<0> :: if ((0 == 1))
+ ... 
+else
+<0> :: return 0;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 0 with (0 == 1)<1>(0,) --->
+{
+stack: main{1<-1> :: (0 == 1)<1>(0,) :: if ((0 == 1))
+ ... 
+else
+<0> :: return 0;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 1 --->
+{
+stack: main{1<-1> :: (0 == 1)<1>(0,) :: if ((0 == 1))
+ ... 
+else
+<0> :: return 0;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 1 with (0 == 1)<2>(0,1,) --->
+{
+stack: main{false<-1> :: if ((0 == 1))
+ ... 
+else
+<0> :: return 0;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value false with if ((0 == 1))
+ ... 
+else
+<1>(false,) --->
+{
+stack: main{<-1> :: return 0;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt  --->

+ 235 - 0
executable_semantics/testdata/if3.golden

@@ -1 +1,236 @@
+********** source program **********
+fn main () -> Int {
+if ((0 == 0))
+if ((0 == 1))
+return 1;
+else
+return 0;
+else
+
+return 1;
+
+}
+********** type checking **********
+--- step exp Int --->
+--- step exp Int --->
+
+********** type checking complete **********
+fn main () -> Int {
+if ((0 == 0))
+if ((0 == 1))
+return 1;
+else
+return 0;
+else
+
+return 1;
+}
+********** starting execution **********
+********** initializing globals **********
+--- step exp () --->
+********** calling main function **********
+{
+stack: top{main()<-1>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main() --->
+{
+stack: top{main<-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main --->
+{
+stack: top{fun<main><-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value fun<main> with main()<1>(fun<main>,) --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp () --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value () with main()<2>(fun<main>,(),) --->
+pattern_match((), ())
+{
+stack: main{if ((0 == 0))
+ ... 
+else
+ ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt if ((0 == 0))
+ ... 
+else
+ ...  --->
+{
+stack: main{if ((0 == 0))
+ ... 
+else
+<-1> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt if ((0 == 0))
+ ... 
+else
+ --->
+{
+stack: main{(0 == 0)<-1> :: if ((0 == 0))
+ ... 
+else
+<0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp (0 == 0) --->
+{
+stack: main{0<-1> :: (0 == 0)<0> :: if ((0 == 0))
+ ... 
+else
+<0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 0 --->
+{
+stack: main{0<-1> :: (0 == 0)<0> :: if ((0 == 0))
+ ... 
+else
+<0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 0 with (0 == 0)<1>(0,) --->
+{
+stack: main{0<-1> :: (0 == 0)<1>(0,) :: if ((0 == 0))
+ ... 
+else
+<0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 0 --->
+{
+stack: main{0<-1> :: (0 == 0)<1>(0,) :: if ((0 == 0))
+ ... 
+else
+<0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 0 with (0 == 0)<2>(0,0,) --->
+{
+stack: main{true<-1> :: if ((0 == 0))
+ ... 
+else
+<0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value true with if ((0 == 0))
+ ... 
+else
+<1>(true,) --->
+{
+stack: main{if ((0 == 1))
+ ... 
+else
+ ... <-1> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt if ((0 == 1))
+ ... 
+else
+ ...  --->
+{
+stack: main{(0 == 1)<-1> :: if ((0 == 1))
+ ... 
+else
+ ... <0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp (0 == 1) --->
+{
+stack: main{0<-1> :: (0 == 1)<0> :: if ((0 == 1))
+ ... 
+else
+ ... <0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 0 --->
+{
+stack: main{0<-1> :: (0 == 1)<0> :: if ((0 == 1))
+ ... 
+else
+ ... <0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 0 with (0 == 1)<1>(0,) --->
+{
+stack: main{1<-1> :: (0 == 1)<1>(0,) :: if ((0 == 1))
+ ... 
+else
+ ... <0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 1 --->
+{
+stack: main{1<-1> :: (0 == 1)<1>(0,) :: if ((0 == 1))
+ ... 
+else
+ ... <0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 1 with (0 == 1)<2>(0,1,) --->
+{
+stack: main{false<-1> :: if ((0 == 1))
+ ... 
+else
+ ... <0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value false with if ((0 == 1))
+ ... 
+else
+ ... <1>(false,) --->
+{
+stack: main{return 0;<-1> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt return 0; --->
+{
+stack: main{0<-1> :: return 0;<0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 0 --->
+{
+stack: main{0<-1> :: return 0;<0> :: return 1;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 0 with return 0;<1>(0,) --->
+{
+stack: top{0<-1>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
 result: 0

+ 174 - 0
executable_semantics/testdata/match_int.golden

@@ -1 +1,175 @@
+********** source program **********
+fn main () -> Int {
+var auto: t = 5;
+match (t) {
+case 5 =>
+return 0;
+case auto: _ =>
+return 1;
+}
+
+}
+********** type checking **********
+--- step exp Int --->
+--- step exp Int --->
+--- step exp auto --->
+--- step exp auto --->
+
+********** type checking complete **********
+fn main () -> Int {
+var auto: t = 5;
+match (t) {
+case 5 =>
+return 0;
+case auto: _ =>
+return 1;
+}
+}
+********** starting execution **********
+********** initializing globals **********
+--- step exp () --->
+********** calling main function **********
+{
+stack: top{main()<-1>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main() --->
+{
+stack: top{main<-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main --->
+{
+stack: top{fun<main><-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value fun<main> with main()<1>(fun<main>,) --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp () --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value () with main()<2>(fun<main>,(),) --->
+pattern_match((), ())
+{
+stack: main{var auto: t = 5; ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt var auto: t = 5; ...  --->
+{
+stack: main{var auto: t = 5;<-1> :: match (t) {...}<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt var auto: t = 5; --->
+{
+stack: main{5<-1> :: var auto: t = 5;<0> :: match (t) {...}<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 5 --->
+{
+stack: main{5<-1> :: var auto: t = 5;<0> :: match (t) {...}<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 5 with var auto: t = 5;<1>(5,) --->
+{
+stack: main{auto: t<-1> :: var auto: t = 5;<1>(5,) :: match (t) {...}<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp auto: t --->
+{
+stack: main{auto<-1> :: auto: t<0> :: var auto: t = 5;<1>(5,) :: match (t) {...}<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp auto --->
+{
+stack: main{auto<-1> :: auto: t<0> :: var auto: t = 5;<1>(5,) :: match (t) {...}<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value auto with auto: t<1>(auto,) --->
+{
+stack: main{auto: t<-1> :: var auto: t = 5;<1>(5,) :: match (t) {...}<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value auto: t with var auto: t = 5;<2>(5,auto: t,) --->
+pattern_match(auto: t, 5)
+{
+stack: main{match (t) {...}<-1>} :: top{}
+heap: fun<main>, 5, 
+env: t: 5, main: fun<main>, 
+}
+--- step stmt match (t) {...} --->
+{
+stack: main{t<-1> :: match (t) {...}<0>} :: top{}
+heap: fun<main>, 5, 
+env: t: 5, main: fun<main>, 
+}
+--- step exp t --->
+{
+stack: main{5<-1> :: match (t) {...}<0>} :: top{}
+heap: fun<main>, 5, 
+env: t: 5, main: fun<main>, 
+}
+--- handle value 5 with match (t) {...}<1>(5,) --->
+{
+stack: main{5<-1> :: match (t) {...}<1>(5,)} :: top{}
+heap: fun<main>, 5, 
+env: t: 5, main: fun<main>, 
+}
+--- step exp 5 --->
+{
+stack: main{5<-1> :: match (t) {...}<1>(5,)} :: top{}
+heap: fun<main>, 5, 
+env: t: 5, main: fun<main>, 
+}
+--- handle value 5 with match (t) {...}<2>(5,5,) --->
+pattern_match(5, 5)
+{
+stack: main{return 0;<-1> :: {
+ ... 
+}
+<0>} :: top{}
+heap: fun<main>, 5, 
+env: t: 5, main: fun<main>, 
+}
+--- step stmt return 0; --->
+{
+stack: main{0<-1> :: return 0;<0> :: {
+ ... 
+}
+<0>} :: top{}
+heap: fun<main>, 5, 
+env: t: 5, main: fun<main>, 
+}
+--- step exp 0 --->
+{
+stack: main{0<-1> :: return 0;<0> :: {
+ ... 
+}
+<0>} :: top{}
+heap: fun<main>, 5, 
+env: t: 5, main: fun<main>, 
+}
+--- handle value 0 with return 0;<1>(0,) --->
+{
+stack: top{0<-1>}
+heap: fun<main>, !!5, 
+env: main: fun<main>, 
+}
 result: 0

+ 216 - 0
executable_semantics/testdata/match_int_default.golden

@@ -1 +1,217 @@
+********** source program **********
+fn main () -> Int {
+var auto: t = 5;
+match (t) {
+case 3 =>
+return (- 1);
+case 4 =>
+return (- 1);
+case auto: _ =>
+return 0;
+}
+
+}
+********** type checking **********
+--- step exp Int --->
+--- step exp Int --->
+--- step exp auto --->
+--- step exp auto --->
+
+********** type checking complete **********
+fn main () -> Int {
+var auto: t = 5;
+match (t) {
+case 3 =>
+return (- 1);
+case 4 =>
+return (- 1);
+case auto: _ =>
+return 0;
+}
+}
+********** starting execution **********
+********** initializing globals **********
+--- step exp () --->
+********** calling main function **********
+{
+stack: top{main()<-1>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main() --->
+{
+stack: top{main<-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main --->
+{
+stack: top{fun<main><-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value fun<main> with main()<1>(fun<main>,) --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp () --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value () with main()<2>(fun<main>,(),) --->
+pattern_match((), ())
+{
+stack: main{var auto: t = 5; ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt var auto: t = 5; ...  --->
+{
+stack: main{var auto: t = 5;<-1> :: match (t) {...}<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt var auto: t = 5; --->
+{
+stack: main{5<-1> :: var auto: t = 5;<0> :: match (t) {...}<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 5 --->
+{
+stack: main{5<-1> :: var auto: t = 5;<0> :: match (t) {...}<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 5 with var auto: t = 5;<1>(5,) --->
+{
+stack: main{auto: t<-1> :: var auto: t = 5;<1>(5,) :: match (t) {...}<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp auto: t --->
+{
+stack: main{auto<-1> :: auto: t<0> :: var auto: t = 5;<1>(5,) :: match (t) {...}<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp auto --->
+{
+stack: main{auto<-1> :: auto: t<0> :: var auto: t = 5;<1>(5,) :: match (t) {...}<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value auto with auto: t<1>(auto,) --->
+{
+stack: main{auto: t<-1> :: var auto: t = 5;<1>(5,) :: match (t) {...}<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value auto: t with var auto: t = 5;<2>(5,auto: t,) --->
+pattern_match(auto: t, 5)
+{
+stack: main{match (t) {...}<-1>} :: top{}
+heap: fun<main>, 5, 
+env: t: 5, main: fun<main>, 
+}
+--- step stmt match (t) {...} --->
+{
+stack: main{t<-1> :: match (t) {...}<0>} :: top{}
+heap: fun<main>, 5, 
+env: t: 5, main: fun<main>, 
+}
+--- step exp t --->
+{
+stack: main{5<-1> :: match (t) {...}<0>} :: top{}
+heap: fun<main>, 5, 
+env: t: 5, main: fun<main>, 
+}
+--- handle value 5 with match (t) {...}<1>(5,) --->
+{
+stack: main{3<-1> :: match (t) {...}<1>(5,)} :: top{}
+heap: fun<main>, 5, 
+env: t: 5, main: fun<main>, 
+}
+--- step exp 3 --->
+{
+stack: main{3<-1> :: match (t) {...}<1>(5,)} :: top{}
+heap: fun<main>, 5, 
+env: t: 5, main: fun<main>, 
+}
+--- handle value 3 with match (t) {...}<2>(5,3,) --->
+pattern_match(3, 5)
+{
+stack: main{4<-1> :: match (t) {...}<3>(5,3,)} :: top{}
+heap: fun<main>, 5, 
+env: t: 5, main: fun<main>, 
+}
+--- step exp 4 --->
+{
+stack: main{4<-1> :: match (t) {...}<3>(5,3,)} :: top{}
+heap: fun<main>, 5, 
+env: t: 5, main: fun<main>, 
+}
+--- handle value 4 with match (t) {...}<4>(5,3,4,) --->
+pattern_match(4, 5)
+{
+stack: main{auto: _<-1> :: match (t) {...}<5>(5,3,4,)} :: top{}
+heap: fun<main>, 5, 
+env: t: 5, main: fun<main>, 
+}
+--- step exp auto: _ --->
+{
+stack: main{auto<-1> :: auto: _<0> :: match (t) {...}<5>(5,3,4,)} :: top{}
+heap: fun<main>, 5, 
+env: t: 5, main: fun<main>, 
+}
+--- step exp auto --->
+{
+stack: main{auto<-1> :: auto: _<0> :: match (t) {...}<5>(5,3,4,)} :: top{}
+heap: fun<main>, 5, 
+env: t: 5, main: fun<main>, 
+}
+--- handle value auto with auto: _<1>(auto,) --->
+{
+stack: main{auto: _<-1> :: match (t) {...}<5>(5,3,4,)} :: top{}
+heap: fun<main>, 5, 
+env: t: 5, main: fun<main>, 
+}
+--- handle value auto: _ with match (t) {...}<6>(5,3,4,auto: _,) --->
+pattern_match(auto: _, 5)
+{
+stack: main{return 0;<-1> :: {
+ ... 
+}
+<0>} :: top{}
+heap: fun<main>, 5, 5, 
+env: _: 5, t: 5, main: fun<main>, 
+}
+--- step stmt return 0; --->
+{
+stack: main{0<-1> :: return 0;<0> :: {
+ ... 
+}
+<0>} :: top{}
+heap: fun<main>, 5, 5, 
+env: _: 5, t: 5, main: fun<main>, 
+}
+--- step exp 0 --->
+{
+stack: main{0<-1> :: return 0;<0> :: {
+ ... 
+}
+<0>} :: top{}
+heap: fun<main>, 5, 5, 
+env: _: 5, t: 5, main: fun<main>, 
+}
+--- handle value 0 with return 0;<1>(0,) --->
+{
+stack: top{0<-1>}
+heap: fun<main>, !!5, !!5, 
+env: main: fun<main>, 
+}
 result: 0

+ 652 - 0
executable_semantics/testdata/match_type.golden

@@ -1 +1,653 @@
+********** source program **********
+fn main () -> Int {
+var auto: t = fn (0 = Int, 1 = Int) -> ();
+var Int: x = 0;
+match (t) {
+case fn (0 = Int, 1 = Int) -> (): z =>
+x = (x + 1);
+}
+match (t) {
+case fn (0 = Type: a, 1 = Type: b) -> () =>
+x = (x - 1);
+}
+return x;
+
+}
+********** type checking **********
+--- step exp Int --->
+--- step exp Int --->
+--- step exp (0 = Int, 1 = Int) --->
+--- step exp Int --->
+--- handle value Int with (0 = Int, 1 = Int)<1>(Int,) --->
+--- step exp Int --->
+--- handle value Int with (0 = Int, 1 = Int)<2>(Int,Int,) --->
+--- step exp () --->
+--- step exp auto --->
+--- step exp Int --->
+--- step exp fn (0 = Int, 1 = Int) -> () --->
+--- step exp (0 = Int, 1 = Int) --->
+--- step exp Int --->
+--- handle value Int with (0 = Int, 1 = Int)<1>(Int,) --->
+--- step exp Int --->
+--- handle value Int with (0 = Int, 1 = Int)<2>(Int,Int,) --->
+--- handle value (0 = Int@2, 1 = Int@3) with fn (0 = Int, 1 = Int) -> ()<1>((0 = Int@2, 1 = Int@3),) --->
+--- step exp () --->
+--- handle value () with fn (0 = Int, 1 = Int) -> ()<2>((0 = Int@2, 1 = Int@3),(),) --->
+--- step exp Type --->
+--- step exp Type --->
+
+********** type checking complete **********
+fn main () -> Int {
+var auto: t = fn (0 = Int, 1 = Int) -> ();
+var Int: x = 0;
+match (t) {
+case fn (0 = Int, 1 = Int) -> (): z =>
+x = (x + 1);
+}
+match (t) {
+case fn (0 = Type: a, 1 = Type: b) -> () =>
+x = (x - 1);
+}
+return x;
+}
+********** starting execution **********
+********** initializing globals **********
+--- step exp () --->
+********** calling main function **********
+{
+stack: top{main()<-1>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main() --->
+{
+stack: top{main<-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main --->
+{
+stack: top{fun<main><-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value fun<main> with main()<1>(fun<main>,) --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp () --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value () with main()<2>(fun<main>,(),) --->
+pattern_match((), ())
+{
+stack: main{var auto: t = fn (0 = Int, 1 = Int) -> (); ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt var auto: t = fn (0 = Int, 1 = Int) -> (); ...  --->
+{
+stack: main{var auto: t = fn (0 = Int, 1 = Int) -> ();<-1> :: var Int: x = 0; ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt var auto: t = fn (0 = Int, 1 = Int) -> (); --->
+{
+stack: main{fn (0 = Int, 1 = Int) -> ()<-1> :: var auto: t = fn (0 = Int, 1 = Int) -> ();<0> :: var Int: x = 0; ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp fn (0 = Int, 1 = Int) -> () --->
+{
+stack: main{(0 = Int, 1 = Int)<-1> :: fn (0 = Int, 1 = Int) -> ()<0> :: var auto: t = fn (0 = Int, 1 = Int) -> ();<0> :: var Int: x = 0; ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp (0 = Int, 1 = Int) --->
+{
+stack: main{Int<-1> :: (0 = Int, 1 = Int)<0> :: fn (0 = Int, 1 = Int) -> ()<0> :: var auto: t = fn (0 = Int, 1 = Int) -> ();<0> :: var Int: x = 0; ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp Int --->
+{
+stack: main{Int<-1> :: (0 = Int, 1 = Int)<0> :: fn (0 = Int, 1 = Int) -> ()<0> :: var auto: t = fn (0 = Int, 1 = Int) -> ();<0> :: var Int: x = 0; ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value Int with (0 = Int, 1 = Int)<1>(Int,) --->
+{
+stack: main{Int<-1> :: (0 = Int, 1 = Int)<1>(Int,) :: fn (0 = Int, 1 = Int) -> ()<0> :: var auto: t = fn (0 = Int, 1 = Int) -> ();<0> :: var Int: x = 0; ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp Int --->
+{
+stack: main{Int<-1> :: (0 = Int, 1 = Int)<1>(Int,) :: fn (0 = Int, 1 = Int) -> ()<0> :: var auto: t = fn (0 = Int, 1 = Int) -> ();<0> :: var Int: x = 0; ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value Int with (0 = Int, 1 = Int)<2>(Int,Int,) --->
+{
+stack: main{(0 = Int@1, 1 = Int@2)<-1> :: fn (0 = Int, 1 = Int) -> ()<0> :: var auto: t = fn (0 = Int, 1 = Int) -> ();<0> :: var Int: x = 0; ... <-1>} :: top{}
+heap: fun<main>, Int, Int, 
+env: main: fun<main>, 
+}
+--- handle value (0 = Int@1, 1 = Int@2) with fn (0 = Int, 1 = Int) -> ()<1>((0 = Int@1, 1 = Int@2),) --->
+{
+stack: main{()<-1> :: fn (0 = Int, 1 = Int) -> ()<1>((0 = Int@1, 1 = Int@2),) :: var auto: t = fn (0 = Int, 1 = Int) -> ();<0> :: var Int: x = 0; ... <-1>} :: top{}
+heap: fun<main>, Int, Int, 
+env: main: fun<main>, 
+}
+--- step exp () --->
+{
+stack: main{()<-1> :: fn (0 = Int, 1 = Int) -> ()<1>((0 = Int@1, 1 = Int@2),) :: var auto: t = fn (0 = Int, 1 = Int) -> ();<0> :: var Int: x = 0; ... <-1>} :: top{}
+heap: fun<main>, Int, Int, 
+env: main: fun<main>, 
+}
+--- handle value () with fn (0 = Int, 1 = Int) -> ()<2>((0 = Int@1, 1 = Int@2),(),) --->
+{
+stack: main{fn (0 = Int@1, 1 = Int@2) -> ()<-1> :: var auto: t = fn (0 = Int, 1 = Int) -> ();<0> :: var Int: x = 0; ... <-1>} :: top{}
+heap: fun<main>, Int, Int, 
+env: main: fun<main>, 
+}
+--- handle value fn (0 = Int@1, 1 = Int@2) -> () with var auto: t = fn (0 = Int, 1 = Int) -> ();<1>(fn (0 = Int@1, 1 = Int@2) -> (),) --->
+{
+stack: main{auto: t<-1> :: var auto: t = fn (0 = Int, 1 = Int) -> ();<1>(fn (0 = Int@1, 1 = Int@2) -> (),) :: var Int: x = 0; ... <-1>} :: top{}
+heap: fun<main>, Int, Int, 
+env: main: fun<main>, 
+}
+--- step exp auto: t --->
+{
+stack: main{auto<-1> :: auto: t<0> :: var auto: t = fn (0 = Int, 1 = Int) -> ();<1>(fn (0 = Int@1, 1 = Int@2) -> (),) :: var Int: x = 0; ... <-1>} :: top{}
+heap: fun<main>, Int, Int, 
+env: main: fun<main>, 
+}
+--- step exp auto --->
+{
+stack: main{auto<-1> :: auto: t<0> :: var auto: t = fn (0 = Int, 1 = Int) -> ();<1>(fn (0 = Int@1, 1 = Int@2) -> (),) :: var Int: x = 0; ... <-1>} :: top{}
+heap: fun<main>, Int, Int, 
+env: main: fun<main>, 
+}
+--- handle value auto with auto: t<1>(auto,) --->
+{
+stack: main{auto: t<-1> :: var auto: t = fn (0 = Int, 1 = Int) -> ();<1>(fn (0 = Int@1, 1 = Int@2) -> (),) :: var Int: x = 0; ... <-1>} :: top{}
+heap: fun<main>, Int, Int, 
+env: main: fun<main>, 
+}
+--- handle value auto: t with var auto: t = fn (0 = Int, 1 = Int) -> ();<2>(fn (0 = Int@1, 1 = Int@2) -> (),auto: t,) --->
+pattern_match(auto: t, fn (0 = Int@1, 1 = Int@2) -> ())
+{
+stack: main{var Int: x = 0; ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 
+env: t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step stmt var Int: x = 0; ...  --->
+{
+stack: main{var Int: x = 0;<-1> :: match (t) {...} ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 
+env: t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step stmt var Int: x = 0; --->
+{
+stack: main{0<-1> :: var Int: x = 0;<0> :: match (t) {...} ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 
+env: t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step exp 0 --->
+{
+stack: main{0<-1> :: var Int: x = 0;<0> :: match (t) {...} ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 
+env: t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- handle value 0 with var Int: x = 0;<1>(0,) --->
+{
+stack: main{Int: x<-1> :: var Int: x = 0;<1>(0,) :: match (t) {...} ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 
+env: t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step exp Int: x --->
+{
+stack: main{Int<-1> :: Int: x<0> :: var Int: x = 0;<1>(0,) :: match (t) {...} ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 
+env: t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step exp Int --->
+{
+stack: main{Int<-1> :: Int: x<0> :: var Int: x = 0;<1>(0,) :: match (t) {...} ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 
+env: t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- handle value Int with Int: x<1>(Int,) --->
+{
+stack: main{Int: x<-1> :: var Int: x = 0;<1>(0,) :: match (t) {...} ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 
+env: t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- handle value Int: x with var Int: x = 0;<2>(0,Int: x,) --->
+pattern_match(Int: x, 0)
+{
+stack: main{match (t) {...} ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, 
+env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step stmt match (t) {...} ...  --->
+{
+stack: main{match (t) {...}<-1> :: match (t) {...} ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, 
+env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step stmt match (t) {...} --->
+{
+stack: main{t<-1> :: match (t) {...}<0> :: match (t) {...} ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, 
+env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step exp t --->
+{
+stack: main{fn (0 = Int@3, 1 = Int@4) -> ()<-1> :: match (t) {...}<0> :: match (t) {...} ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, 
+env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- handle value fn (0 = Int@3, 1 = Int@4) -> () with match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) --->
+{
+stack: main{fn (0 = Int, 1 = Int) -> (): z<-1> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: match (t) {...} ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, 
+env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step exp fn (0 = Int, 1 = Int) -> (): z --->
+{
+stack: main{fn (0 = Int, 1 = Int) -> ()<-1> :: fn (0 = Int, 1 = Int) -> (): z<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: match (t) {...} ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, 
+env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step exp fn (0 = Int, 1 = Int) -> () --->
+{
+stack: main{(0 = Int, 1 = Int)<-1> :: fn (0 = Int, 1 = Int) -> ()<0> :: fn (0 = Int, 1 = Int) -> (): z<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: match (t) {...} ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, 
+env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step exp (0 = Int, 1 = Int) --->
+{
+stack: main{Int<-1> :: (0 = Int, 1 = Int)<0> :: fn (0 = Int, 1 = Int) -> ()<0> :: fn (0 = Int, 1 = Int) -> (): z<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: match (t) {...} ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, 
+env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step exp Int --->
+{
+stack: main{Int<-1> :: (0 = Int, 1 = Int)<0> :: fn (0 = Int, 1 = Int) -> ()<0> :: fn (0 = Int, 1 = Int) -> (): z<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: match (t) {...} ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, 
+env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- handle value Int with (0 = Int, 1 = Int)<1>(Int,) --->
+{
+stack: main{Int<-1> :: (0 = Int, 1 = Int)<1>(Int,) :: fn (0 = Int, 1 = Int) -> ()<0> :: fn (0 = Int, 1 = Int) -> (): z<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: match (t) {...} ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, 
+env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step exp Int --->
+{
+stack: main{Int<-1> :: (0 = Int, 1 = Int)<1>(Int,) :: fn (0 = Int, 1 = Int) -> ()<0> :: fn (0 = Int, 1 = Int) -> (): z<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: match (t) {...} ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, 
+env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- handle value Int with (0 = Int, 1 = Int)<2>(Int,Int,) --->
+{
+stack: main{(0 = Int@7, 1 = Int@8)<-1> :: fn (0 = Int, 1 = Int) -> ()<0> :: fn (0 = Int, 1 = Int) -> (): z<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: match (t) {...} ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int, 
+env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- handle value (0 = Int@7, 1 = Int@8) with fn (0 = Int, 1 = Int) -> ()<1>((0 = Int@7, 1 = Int@8),) --->
+{
+stack: main{()<-1> :: fn (0 = Int, 1 = Int) -> ()<1>((0 = Int@7, 1 = Int@8),) :: fn (0 = Int, 1 = Int) -> (): z<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: match (t) {...} ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int, 
+env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step exp () --->
+{
+stack: main{()<-1> :: fn (0 = Int, 1 = Int) -> ()<1>((0 = Int@7, 1 = Int@8),) :: fn (0 = Int, 1 = Int) -> (): z<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: match (t) {...} ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int, 
+env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- handle value () with fn (0 = Int, 1 = Int) -> ()<2>((0 = Int@7, 1 = Int@8),(),) --->
+{
+stack: main{fn (0 = Int@7, 1 = Int@8) -> ()<-1> :: fn (0 = Int, 1 = Int) -> (): z<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: match (t) {...} ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int, 
+env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- handle value fn (0 = Int@7, 1 = Int@8) -> () with fn (0 = Int, 1 = Int) -> (): z<1>(fn (0 = Int@7, 1 = Int@8) -> (),) --->
+{
+stack: main{fn (0 = Int@7, 1 = Int@8) -> (): z<-1> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: match (t) {...} ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int, 
+env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- handle value fn (0 = Int@7, 1 = Int@8) -> (): z with match (t) {...}<2>(fn (0 = Int@3, 1 = Int@4) -> (),fn (0 = Int@7, 1 = Int@8) -> (): z,) --->
+pattern_match(fn (0 = Int@7, 1 = Int@8) -> (): z, fn (0 = Int@3, 1 = Int@4) -> ())
+{
+stack: main{x = (x + 1);<-1> :: {
+ ... 
+}
+<0> :: match (t) {...} ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int, Int, Int, fn (0 = Int@9, 1 = Int@10) -> (), 
+env: z: fn (0 = Int@9, 1 = Int@10) -> (), x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step stmt x = (x + 1); --->
+{
+stack: main{x<-1> :: x = (x + 1);<0> :: {
+ ... 
+}
+<0> :: match (t) {...} ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int, Int, Int, fn (0 = Int@9, 1 = Int@10) -> (), 
+env: z: fn (0 = Int@9, 1 = Int@10) -> (), x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step lvalue x --->
+{
+stack: main{ptr<6><-1> :: x = (x + 1);<0> :: {
+ ... 
+}
+<0> :: match (t) {...} ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int, Int, Int, fn (0 = Int@9, 1 = Int@10) -> (), 
+env: z: fn (0 = Int@9, 1 = Int@10) -> (), x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- handle value ptr<6> with x = (x + 1);<1>(ptr<6>,) --->
+{
+stack: main{(x + 1)<-1> :: x = (x + 1);<1>(ptr<6>,) :: {
+ ... 
+}
+<0> :: match (t) {...} ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int, Int, Int, fn (0 = Int@9, 1 = Int@10) -> (), 
+env: z: fn (0 = Int@9, 1 = Int@10) -> (), x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step exp (x + 1) --->
+{
+stack: main{x<-1> :: (x + 1)<0> :: x = (x + 1);<1>(ptr<6>,) :: {
+ ... 
+}
+<0> :: match (t) {...} ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int, Int, Int, fn (0 = Int@9, 1 = Int@10) -> (), 
+env: z: fn (0 = Int@9, 1 = Int@10) -> (), x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step exp x --->
+{
+stack: main{0<-1> :: (x + 1)<0> :: x = (x + 1);<1>(ptr<6>,) :: {
+ ... 
+}
+<0> :: match (t) {...} ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int, Int, Int, fn (0 = Int@9, 1 = Int@10) -> (), 
+env: z: fn (0 = Int@9, 1 = Int@10) -> (), x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- handle value 0 with (x + 1)<1>(0,) --->
+{
+stack: main{1<-1> :: (x + 1)<1>(0,) :: x = (x + 1);<1>(ptr<6>,) :: {
+ ... 
+}
+<0> :: match (t) {...} ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int, Int, Int, fn (0 = Int@9, 1 = Int@10) -> (), 
+env: z: fn (0 = Int@9, 1 = Int@10) -> (), x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step exp 1 --->
+{
+stack: main{1<-1> :: (x + 1)<1>(0,) :: x = (x + 1);<1>(ptr<6>,) :: {
+ ... 
+}
+<0> :: match (t) {...} ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int, Int, Int, fn (0 = Int@9, 1 = Int@10) -> (), 
+env: z: fn (0 = Int@9, 1 = Int@10) -> (), x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- handle value 1 with (x + 1)<2>(0,1,) --->
+{
+stack: main{1<-1> :: x = (x + 1);<1>(ptr<6>,) :: {
+ ... 
+}
+<0> :: match (t) {...} ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int, Int, Int, fn (0 = Int@9, 1 = Int@10) -> (), 
+env: z: fn (0 = Int@9, 1 = Int@10) -> (), x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- handle value 1 with x = (x + 1);<2>(ptr<6>,1,) --->
+{
+stack: main{{
+ ... 
+}
+<0> :: match (t) {...} ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, fn (0 = Int@9, 1 = Int@10) -> (), 
+env: z: fn (0 = Int@9, 1 = Int@10) -> (), x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step stmt {
+ ... 
+}
+ --->
+{
+stack: main{match (t) {...} ... <-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), 
+env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step stmt match (t) {...} ...  --->
+{
+stack: main{match (t) {...}<-1> :: return x;<-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), 
+env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step stmt match (t) {...} --->
+{
+stack: main{t<-1> :: match (t) {...}<0> :: return x;<-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), 
+env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step exp t --->
+{
+stack: main{fn (0 = Int@3, 1 = Int@4) -> ()<-1> :: match (t) {...}<0> :: return x;<-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), 
+env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- handle value fn (0 = Int@3, 1 = Int@4) -> () with match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) --->
+{
+stack: main{fn (0 = Type: a, 1 = Type: b) -> ()<-1> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: return x;<-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), 
+env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step exp fn (0 = Type: a, 1 = Type: b) -> () --->
+{
+stack: main{(0 = Type: a, 1 = Type: b)<-1> :: fn (0 = Type: a, 1 = Type: b) -> ()<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: return x;<-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), 
+env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step exp (0 = Type: a, 1 = Type: b) --->
+{
+stack: main{Type: a<-1> :: (0 = Type: a, 1 = Type: b)<0> :: fn (0 = Type: a, 1 = Type: b) -> ()<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: return x;<-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), 
+env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step exp Type: a --->
+{
+stack: main{Type<-1> :: Type: a<0> :: (0 = Type: a, 1 = Type: b)<0> :: fn (0 = Type: a, 1 = Type: b) -> ()<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: return x;<-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), 
+env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step exp Type --->
+{
+stack: main{Type<-1> :: Type: a<0> :: (0 = Type: a, 1 = Type: b)<0> :: fn (0 = Type: a, 1 = Type: b) -> ()<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: return x;<-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), 
+env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- handle value Type with Type: a<1>(Type,) --->
+{
+stack: main{Type: a<-1> :: (0 = Type: a, 1 = Type: b)<0> :: fn (0 = Type: a, 1 = Type: b) -> ()<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: return x;<-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), 
+env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- handle value Type: a with (0 = Type: a, 1 = Type: b)<1>(Type: a,) --->
+{
+stack: main{Type: b<-1> :: (0 = Type: a, 1 = Type: b)<1>(Type: a,) :: fn (0 = Type: a, 1 = Type: b) -> ()<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: return x;<-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), 
+env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step exp Type: b --->
+{
+stack: main{Type<-1> :: Type: b<0> :: (0 = Type: a, 1 = Type: b)<1>(Type: a,) :: fn (0 = Type: a, 1 = Type: b) -> ()<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: return x;<-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), 
+env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step exp Type --->
+{
+stack: main{Type<-1> :: Type: b<0> :: (0 = Type: a, 1 = Type: b)<1>(Type: a,) :: fn (0 = Type: a, 1 = Type: b) -> ()<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: return x;<-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), 
+env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- handle value Type with Type: b<1>(Type,) --->
+{
+stack: main{Type: b<-1> :: (0 = Type: a, 1 = Type: b)<1>(Type: a,) :: fn (0 = Type: a, 1 = Type: b) -> ()<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: return x;<-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), 
+env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- handle value Type: b with (0 = Type: a, 1 = Type: b)<2>(Type: a,Type: b,) --->
+{
+stack: main{(0 = Type: a@12, 1 = Type: b@13)<-1> :: fn (0 = Type: a, 1 = Type: b) -> ()<0> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: return x;<-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b, 
+env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- handle value (0 = Type: a@12, 1 = Type: b@13) with fn (0 = Type: a, 1 = Type: b) -> ()<1>((0 = Type: a@12, 1 = Type: b@13),) --->
+{
+stack: main{()<-1> :: fn (0 = Type: a, 1 = Type: b) -> ()<1>((0 = Type: a@12, 1 = Type: b@13),) :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: return x;<-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b, 
+env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step exp () --->
+{
+stack: main{()<-1> :: fn (0 = Type: a, 1 = Type: b) -> ()<1>((0 = Type: a@12, 1 = Type: b@13),) :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: return x;<-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b, 
+env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- handle value () with fn (0 = Type: a, 1 = Type: b) -> ()<2>((0 = Type: a@12, 1 = Type: b@13),(),) --->
+{
+stack: main{fn (0 = Type: a@12, 1 = Type: b@13) -> ()<-1> :: match (t) {...}<1>(fn (0 = Int@3, 1 = Int@4) -> (),) :: return x;<-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b, 
+env: x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- handle value fn (0 = Type: a@12, 1 = Type: b@13) -> () with match (t) {...}<2>(fn (0 = Int@3, 1 = Int@4) -> (),fn (0 = Type: a@12, 1 = Type: b@13) -> (),) --->
+pattern_match(fn (0 = Type: a@12, 1 = Type: b@13) -> (), fn (0 = Int@3, 1 = Int@4) -> ())
+pattern_match((0 = Type: a@12, 1 = Type: b@13), (0 = Int@3, 1 = Int@4))
+pattern_match(Type: a, Int)
+pattern_match(Type: b, Int)
+pattern_match((), ())
+{
+stack: main{x = (x - 1);<-1> :: {
+ ... 
+}
+<0> :: return x;<-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b, Int, Int, 
+env: b: Int, a: Int, x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step stmt x = (x - 1); --->
+{
+stack: main{x<-1> :: x = (x - 1);<0> :: {
+ ... 
+}
+<0> :: return x;<-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b, Int, Int, 
+env: b: Int, a: Int, x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step lvalue x --->
+{
+stack: main{ptr<6><-1> :: x = (x - 1);<0> :: {
+ ... 
+}
+<0> :: return x;<-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b, Int, Int, 
+env: b: Int, a: Int, x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- handle value ptr<6> with x = (x - 1);<1>(ptr<6>,) --->
+{
+stack: main{(x - 1)<-1> :: x = (x - 1);<1>(ptr<6>,) :: {
+ ... 
+}
+<0> :: return x;<-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b, Int, Int, 
+env: b: Int, a: Int, x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step exp (x - 1) --->
+{
+stack: main{x<-1> :: (x - 1)<0> :: x = (x - 1);<1>(ptr<6>,) :: {
+ ... 
+}
+<0> :: return x;<-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b, Int, Int, 
+env: b: Int, a: Int, x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step exp x --->
+{
+stack: main{1<-1> :: (x - 1)<0> :: x = (x - 1);<1>(ptr<6>,) :: {
+ ... 
+}
+<0> :: return x;<-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b, Int, Int, 
+env: b: Int, a: Int, x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- handle value 1 with (x - 1)<1>(1,) --->
+{
+stack: main{1<-1> :: (x - 1)<1>(1,) :: x = (x - 1);<1>(ptr<6>,) :: {
+ ... 
+}
+<0> :: return x;<-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b, Int, Int, 
+env: b: Int, a: Int, x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step exp 1 --->
+{
+stack: main{1<-1> :: (x - 1)<1>(1,) :: x = (x - 1);<1>(ptr<6>,) :: {
+ ... 
+}
+<0> :: return x;<-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b, Int, Int, 
+env: b: Int, a: Int, x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- handle value 1 with (x - 1)<2>(1,1,) --->
+{
+stack: main{0<-1> :: x = (x - 1);<1>(ptr<6>,) :: {
+ ... 
+}
+<0> :: return x;<-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 1, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b, Int, Int, 
+env: b: Int, a: Int, x: 1, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- handle value 0 with x = (x - 1);<2>(ptr<6>,0,) --->
+{
+stack: main{{
+ ... 
+}
+<0> :: return x;<-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b, Int, Int, 
+env: b: Int, a: Int, x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step stmt {
+ ... 
+}
+ --->
+{
+stack: main{return x;<-1>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b, !!Int, !!Int, 
+env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step stmt return x; --->
+{
+stack: main{x<-1> :: return x;<0>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b, !!Int, !!Int, 
+env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- step exp x --->
+{
+stack: main{0<-1> :: return x;<0>} :: top{}
+heap: fun<main>, Int, Int, Int, Int, fn (0 = Int@3, 1 = Int@4) -> (), 0, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b, !!Int, !!Int, 
+env: x: 0, t: fn (0 = Int@3, 1 = Int@4) -> (), main: fun<main>, 
+}
+--- handle value 0 with return x;<1>(0,) --->
+{
+stack: top{0<-1>}
+heap: fun<main>, Int, Int, Int, Int, !!fn (0 = Int@3, 1 = Int@4) -> (), !!0, Int, Int, Int, Int, !!fn (0 = Int@9, 1 = Int@10) -> (), Type: a, Type: b, !!Int, !!Int, 
+env: main: fun<main>, 
+}
 result: 0

+ 123 - 0
executable_semantics/testdata/next.golden

@@ -1 +1,124 @@
+********** source program **********
+fn main () -> Int {
+var Int: x = 0;
+return x;
+
+}
+********** type checking **********
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+
+********** type checking complete **********
+fn main () -> Int {
+var Int: x = 0;
+return x;
+}
+********** starting execution **********
+********** initializing globals **********
+--- step exp () --->
+********** calling main function **********
+{
+stack: top{main()<-1>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main() --->
+{
+stack: top{main<-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main --->
+{
+stack: top{fun<main><-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value fun<main> with main()<1>(fun<main>,) --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp () --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value () with main()<2>(fun<main>,(),) --->
+pattern_match((), ())
+{
+stack: main{var Int: x = 0; ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt var Int: x = 0; ...  --->
+{
+stack: main{var Int: x = 0;<-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt var Int: x = 0; --->
+{
+stack: main{0<-1> :: var Int: x = 0;<0> :: return x;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 0 --->
+{
+stack: main{0<-1> :: var Int: x = 0;<0> :: return x;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 0 with var Int: x = 0;<1>(0,) --->
+{
+stack: main{Int: x<-1> :: var Int: x = 0;<1>(0,) :: return x;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp Int: x --->
+{
+stack: main{Int<-1> :: Int: x<0> :: var Int: x = 0;<1>(0,) :: return x;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp Int --->
+{
+stack: main{Int<-1> :: Int: x<0> :: var Int: x = 0;<1>(0,) :: return x;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value Int with Int: x<1>(Int,) --->
+{
+stack: main{Int: x<-1> :: var Int: x = 0;<1>(0,) :: return x;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value Int: x with var Int: x = 0;<2>(0,Int: x,) --->
+pattern_match(Int: x, 0)
+{
+stack: main{return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step stmt return x; --->
+{
+stack: main{x<-1> :: return x;<0>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step exp x --->
+{
+stack: main{0<-1> :: return x;<0>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- handle value 0 with return x;<1>(0,) --->
+{
+stack: top{0<-1>}
+heap: fun<main>, !!0, 
+env: main: fun<main>, 
+}
 result: 0

+ 234 - 0
executable_semantics/testdata/pattern_init.golden

@@ -1 +1,235 @@
+********** source program **********
+fn main () -> Int {
+var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);
+return ((y - x) - 1);
+
+}
+********** type checking **********
+--- step exp Int --->
+--- step exp Int --->
+--- step exp auto --->
+--- step exp auto --->
+
+********** type checking complete **********
+fn main () -> Int {
+var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);
+return ((y - x) - 1);
+}
+********** starting execution **********
+********** initializing globals **********
+--- step exp () --->
+********** calling main function **********
+{
+stack: top{main()<-1>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main() --->
+{
+stack: top{main<-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main --->
+{
+stack: top{fun<main><-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value fun<main> with main()<1>(fun<main>,) --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp () --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value () with main()<2>(fun<main>,(),) --->
+pattern_match((), ())
+{
+stack: main{var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3); ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3); ...  --->
+{
+stack: main{var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<-1> :: return ((y - x) - 1);<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3); --->
+{
+stack: main{(0 = 2, 1 = 3)<-1> :: var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<0> :: return ((y - x) - 1);<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp (0 = 2, 1 = 3) --->
+{
+stack: main{2<-1> :: (0 = 2, 1 = 3)<0> :: var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<0> :: return ((y - x) - 1);<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 2 --->
+{
+stack: main{2<-1> :: (0 = 2, 1 = 3)<0> :: var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<0> :: return ((y - x) - 1);<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 2 with (0 = 2, 1 = 3)<1>(2,) --->
+{
+stack: main{3<-1> :: (0 = 2, 1 = 3)<1>(2,) :: var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<0> :: return ((y - x) - 1);<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 3 --->
+{
+stack: main{3<-1> :: (0 = 2, 1 = 3)<1>(2,) :: var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<0> :: return ((y - x) - 1);<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 3 with (0 = 2, 1 = 3)<2>(2,3,) --->
+{
+stack: main{(0 = 2@1, 1 = 3@2)<-1> :: var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<0> :: return ((y - x) - 1);<-1>} :: top{}
+heap: fun<main>, 2, 3, 
+env: main: fun<main>, 
+}
+--- handle value (0 = 2@1, 1 = 3@2) with var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<1>((0 = 2@1, 1 = 3@2),) --->
+{
+stack: main{(0 = auto: x, 1 = auto: y)<-1> :: var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<1>((0 = 2@1, 1 = 3@2),) :: return ((y - x) - 1);<-1>} :: top{}
+heap: fun<main>, 2, 3, 
+env: main: fun<main>, 
+}
+--- step exp (0 = auto: x, 1 = auto: y) --->
+{
+stack: main{auto: x<-1> :: (0 = auto: x, 1 = auto: y)<0> :: var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<1>((0 = 2@1, 1 = 3@2),) :: return ((y - x) - 1);<-1>} :: top{}
+heap: fun<main>, 2, 3, 
+env: main: fun<main>, 
+}
+--- step exp auto: x --->
+{
+stack: main{auto<-1> :: auto: x<0> :: (0 = auto: x, 1 = auto: y)<0> :: var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<1>((0 = 2@1, 1 = 3@2),) :: return ((y - x) - 1);<-1>} :: top{}
+heap: fun<main>, 2, 3, 
+env: main: fun<main>, 
+}
+--- step exp auto --->
+{
+stack: main{auto<-1> :: auto: x<0> :: (0 = auto: x, 1 = auto: y)<0> :: var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<1>((0 = 2@1, 1 = 3@2),) :: return ((y - x) - 1);<-1>} :: top{}
+heap: fun<main>, 2, 3, 
+env: main: fun<main>, 
+}
+--- handle value auto with auto: x<1>(auto,) --->
+{
+stack: main{auto: x<-1> :: (0 = auto: x, 1 = auto: y)<0> :: var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<1>((0 = 2@1, 1 = 3@2),) :: return ((y - x) - 1);<-1>} :: top{}
+heap: fun<main>, 2, 3, 
+env: main: fun<main>, 
+}
+--- handle value auto: x with (0 = auto: x, 1 = auto: y)<1>(auto: x,) --->
+{
+stack: main{auto: y<-1> :: (0 = auto: x, 1 = auto: y)<1>(auto: x,) :: var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<1>((0 = 2@1, 1 = 3@2),) :: return ((y - x) - 1);<-1>} :: top{}
+heap: fun<main>, 2, 3, 
+env: main: fun<main>, 
+}
+--- step exp auto: y --->
+{
+stack: main{auto<-1> :: auto: y<0> :: (0 = auto: x, 1 = auto: y)<1>(auto: x,) :: var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<1>((0 = 2@1, 1 = 3@2),) :: return ((y - x) - 1);<-1>} :: top{}
+heap: fun<main>, 2, 3, 
+env: main: fun<main>, 
+}
+--- step exp auto --->
+{
+stack: main{auto<-1> :: auto: y<0> :: (0 = auto: x, 1 = auto: y)<1>(auto: x,) :: var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<1>((0 = 2@1, 1 = 3@2),) :: return ((y - x) - 1);<-1>} :: top{}
+heap: fun<main>, 2, 3, 
+env: main: fun<main>, 
+}
+--- handle value auto with auto: y<1>(auto,) --->
+{
+stack: main{auto: y<-1> :: (0 = auto: x, 1 = auto: y)<1>(auto: x,) :: var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<1>((0 = 2@1, 1 = 3@2),) :: return ((y - x) - 1);<-1>} :: top{}
+heap: fun<main>, 2, 3, 
+env: main: fun<main>, 
+}
+--- handle value auto: y with (0 = auto: x, 1 = auto: y)<2>(auto: x,auto: y,) --->
+{
+stack: main{(0 = auto: x@3, 1 = auto: y@4)<-1> :: var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<1>((0 = 2@1, 1 = 3@2),) :: return ((y - x) - 1);<-1>} :: top{}
+heap: fun<main>, 2, 3, auto: x, auto: y, 
+env: main: fun<main>, 
+}
+--- handle value (0 = auto: x@3, 1 = auto: y@4) with var (0 = auto: x, 1 = auto: y) = (0 = 2, 1 = 3);<2>((0 = 2@1, 1 = 3@2),(0 = auto: x@3, 1 = auto: y@4),) --->
+pattern_match((0 = auto: x@3, 1 = auto: y@4), (0 = 2@1, 1 = 3@2))
+pattern_match(auto: x, 2)
+pattern_match(auto: y, 3)
+{
+stack: main{return ((y - x) - 1);<-1>} :: top{}
+heap: fun<main>, 2, 3, auto: x, auto: y, 2, 3, 
+env: y: 3, x: 2, main: fun<main>, 
+}
+--- step stmt return ((y - x) - 1); --->
+{
+stack: main{((y - x) - 1)<-1> :: return ((y - x) - 1);<0>} :: top{}
+heap: fun<main>, 2, 3, auto: x, auto: y, 2, 3, 
+env: y: 3, x: 2, main: fun<main>, 
+}
+--- step exp ((y - x) - 1) --->
+{
+stack: main{(y - x)<-1> :: ((y - x) - 1)<0> :: return ((y - x) - 1);<0>} :: top{}
+heap: fun<main>, 2, 3, auto: x, auto: y, 2, 3, 
+env: y: 3, x: 2, main: fun<main>, 
+}
+--- step exp (y - x) --->
+{
+stack: main{y<-1> :: (y - x)<0> :: ((y - x) - 1)<0> :: return ((y - x) - 1);<0>} :: top{}
+heap: fun<main>, 2, 3, auto: x, auto: y, 2, 3, 
+env: y: 3, x: 2, main: fun<main>, 
+}
+--- step exp y --->
+{
+stack: main{3<-1> :: (y - x)<0> :: ((y - x) - 1)<0> :: return ((y - x) - 1);<0>} :: top{}
+heap: fun<main>, 2, 3, auto: x, auto: y, 2, 3, 
+env: y: 3, x: 2, main: fun<main>, 
+}
+--- handle value 3 with (y - x)<1>(3,) --->
+{
+stack: main{x<-1> :: (y - x)<1>(3,) :: ((y - x) - 1)<0> :: return ((y - x) - 1);<0>} :: top{}
+heap: fun<main>, 2, 3, auto: x, auto: y, 2, 3, 
+env: y: 3, x: 2, main: fun<main>, 
+}
+--- step exp x --->
+{
+stack: main{2<-1> :: (y - x)<1>(3,) :: ((y - x) - 1)<0> :: return ((y - x) - 1);<0>} :: top{}
+heap: fun<main>, 2, 3, auto: x, auto: y, 2, 3, 
+env: y: 3, x: 2, main: fun<main>, 
+}
+--- handle value 2 with (y - x)<2>(3,2,) --->
+{
+stack: main{1<-1> :: ((y - x) - 1)<0> :: return ((y - x) - 1);<0>} :: top{}
+heap: fun<main>, 2, 3, auto: x, auto: y, 2, 3, 
+env: y: 3, x: 2, main: fun<main>, 
+}
+--- handle value 1 with ((y - x) - 1)<1>(1,) --->
+{
+stack: main{1<-1> :: ((y - x) - 1)<1>(1,) :: return ((y - x) - 1);<0>} :: top{}
+heap: fun<main>, 2, 3, auto: x, auto: y, 2, 3, 
+env: y: 3, x: 2, main: fun<main>, 
+}
+--- step exp 1 --->
+{
+stack: main{1<-1> :: ((y - x) - 1)<1>(1,) :: return ((y - x) - 1);<0>} :: top{}
+heap: fun<main>, 2, 3, auto: x, auto: y, 2, 3, 
+env: y: 3, x: 2, main: fun<main>, 
+}
+--- handle value 1 with ((y - x) - 1)<2>(1,1,) --->
+{
+stack: main{0<-1> :: return ((y - x) - 1);<0>} :: top{}
+heap: fun<main>, 2, 3, auto: x, auto: y, 2, 3, 
+env: y: 3, x: 2, main: fun<main>, 
+}
+--- handle value 0 with return ((y - x) - 1);<1>(0,) --->
+{
+stack: top{0<-1>}
+heap: fun<main>, 2, 3, auto: x, auto: y, !!2, !!3, 
+env: main: fun<main>, 
+}
 result: 0

+ 297 - 0
executable_semantics/testdata/record1.golden

@@ -1 +1,298 @@
+********** source program **********
+fn main () -> Int {
+var (x = Int, y = Int): t2 = (y = 5, x = 2);
+t2.y = 3;
+return ((t2.y - t2.x) - 1);
+
+}
+********** type checking **********
+--- step exp Int --->
+--- step exp Int --->
+--- step exp (x = Int, y = Int) --->
+--- step exp Int --->
+--- handle value Int with (x = Int, y = Int)<1>(Int,) --->
+--- step exp Int --->
+--- handle value Int with (x = Int, y = Int)<2>(Int,Int,) --->
+
+********** type checking complete **********
+fn main () -> Int {
+var (x = Int, y = Int): t2 = (y = 5, x = 2);
+t2.y = 3;
+return ((t2.y - t2.x) - 1);
+}
+********** starting execution **********
+********** initializing globals **********
+--- step exp () --->
+********** calling main function **********
+{
+stack: top{main()<-1>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main() --->
+{
+stack: top{main<-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main --->
+{
+stack: top{fun<main><-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value fun<main> with main()<1>(fun<main>,) --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp () --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value () with main()<2>(fun<main>,(),) --->
+pattern_match((), ())
+{
+stack: main{var (x = Int, y = Int): t2 = (y = 5, x = 2); ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt var (x = Int, y = Int): t2 = (y = 5, x = 2); ...  --->
+{
+stack: main{var (x = Int, y = Int): t2 = (y = 5, x = 2);<-1> :: t2.y = 3; ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt var (x = Int, y = Int): t2 = (y = 5, x = 2); --->
+{
+stack: main{(y = 5, x = 2)<-1> :: var (x = Int, y = Int): t2 = (y = 5, x = 2);<0> :: t2.y = 3; ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp (y = 5, x = 2) --->
+{
+stack: main{5<-1> :: (y = 5, x = 2)<0> :: var (x = Int, y = Int): t2 = (y = 5, x = 2);<0> :: t2.y = 3; ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 5 --->
+{
+stack: main{5<-1> :: (y = 5, x = 2)<0> :: var (x = Int, y = Int): t2 = (y = 5, x = 2);<0> :: t2.y = 3; ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 5 with (y = 5, x = 2)<1>(5,) --->
+{
+stack: main{2<-1> :: (y = 5, x = 2)<1>(5,) :: var (x = Int, y = Int): t2 = (y = 5, x = 2);<0> :: t2.y = 3; ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 2 --->
+{
+stack: main{2<-1> :: (y = 5, x = 2)<1>(5,) :: var (x = Int, y = Int): t2 = (y = 5, x = 2);<0> :: t2.y = 3; ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 2 with (y = 5, x = 2)<2>(5,2,) --->
+{
+stack: main{(y = 5@1, x = 2@2)<-1> :: var (x = Int, y = Int): t2 = (y = 5, x = 2);<0> :: t2.y = 3; ... <-1>} :: top{}
+heap: fun<main>, 5, 2, 
+env: main: fun<main>, 
+}
+--- handle value (y = 5@1, x = 2@2) with var (x = Int, y = Int): t2 = (y = 5, x = 2);<1>((y = 5@1, x = 2@2),) --->
+{
+stack: main{(x = Int, y = Int): t2<-1> :: var (x = Int, y = Int): t2 = (y = 5, x = 2);<1>((y = 5@1, x = 2@2),) :: t2.y = 3; ... <-1>} :: top{}
+heap: fun<main>, 5, 2, 
+env: main: fun<main>, 
+}
+--- step exp (x = Int, y = Int): t2 --->
+{
+stack: main{(x = Int, y = Int)<-1> :: (x = Int, y = Int): t2<0> :: var (x = Int, y = Int): t2 = (y = 5, x = 2);<1>((y = 5@1, x = 2@2),) :: t2.y = 3; ... <-1>} :: top{}
+heap: fun<main>, 5, 2, 
+env: main: fun<main>, 
+}
+--- step exp (x = Int, y = Int) --->
+{
+stack: main{Int<-1> :: (x = Int, y = Int)<0> :: (x = Int, y = Int): t2<0> :: var (x = Int, y = Int): t2 = (y = 5, x = 2);<1>((y = 5@1, x = 2@2),) :: t2.y = 3; ... <-1>} :: top{}
+heap: fun<main>, 5, 2, 
+env: main: fun<main>, 
+}
+--- step exp Int --->
+{
+stack: main{Int<-1> :: (x = Int, y = Int)<0> :: (x = Int, y = Int): t2<0> :: var (x = Int, y = Int): t2 = (y = 5, x = 2);<1>((y = 5@1, x = 2@2),) :: t2.y = 3; ... <-1>} :: top{}
+heap: fun<main>, 5, 2, 
+env: main: fun<main>, 
+}
+--- handle value Int with (x = Int, y = Int)<1>(Int,) --->
+{
+stack: main{Int<-1> :: (x = Int, y = Int)<1>(Int,) :: (x = Int, y = Int): t2<0> :: var (x = Int, y = Int): t2 = (y = 5, x = 2);<1>((y = 5@1, x = 2@2),) :: t2.y = 3; ... <-1>} :: top{}
+heap: fun<main>, 5, 2, 
+env: main: fun<main>, 
+}
+--- step exp Int --->
+{
+stack: main{Int<-1> :: (x = Int, y = Int)<1>(Int,) :: (x = Int, y = Int): t2<0> :: var (x = Int, y = Int): t2 = (y = 5, x = 2);<1>((y = 5@1, x = 2@2),) :: t2.y = 3; ... <-1>} :: top{}
+heap: fun<main>, 5, 2, 
+env: main: fun<main>, 
+}
+--- handle value Int with (x = Int, y = Int)<2>(Int,Int,) --->
+{
+stack: main{(x = Int@3, y = Int@4)<-1> :: (x = Int, y = Int): t2<0> :: var (x = Int, y = Int): t2 = (y = 5, x = 2);<1>((y = 5@1, x = 2@2),) :: t2.y = 3; ... <-1>} :: top{}
+heap: fun<main>, 5, 2, Int, Int, 
+env: main: fun<main>, 
+}
+--- handle value (x = Int@3, y = Int@4) with (x = Int, y = Int): t2<1>((x = Int@3, y = Int@4),) --->
+{
+stack: main{(x = Int@3, y = Int@4): t2<-1> :: var (x = Int, y = Int): t2 = (y = 5, x = 2);<1>((y = 5@1, x = 2@2),) :: t2.y = 3; ... <-1>} :: top{}
+heap: fun<main>, 5, 2, Int, Int, 
+env: main: fun<main>, 
+}
+--- handle value (x = Int@3, y = Int@4): t2 with var (x = Int, y = Int): t2 = (y = 5, x = 2);<2>((y = 5@1, x = 2@2),(x = Int@3, y = Int@4): t2,) --->
+pattern_match((x = Int@3, y = Int@4): t2, (y = 5@1, x = 2@2))
+{
+stack: main{t2.y = 3; ... <-1>} :: top{}
+heap: fun<main>, 5, 2, Int, Int, 5, 2, (y = 5@5, x = 2@6), 
+env: t2: (y = 5@5, x = 2@6), main: fun<main>, 
+}
+--- step stmt t2.y = 3; ...  --->
+{
+stack: main{t2.y = 3;<-1> :: return ((t2.y - t2.x) - 1);<-1>} :: top{}
+heap: fun<main>, 5, 2, Int, Int, 5, 2, (y = 5@5, x = 2@6), 
+env: t2: (y = 5@5, x = 2@6), main: fun<main>, 
+}
+--- step stmt t2.y = 3; --->
+{
+stack: main{t2.y<-1> :: t2.y = 3;<0> :: return ((t2.y - t2.x) - 1);<-1>} :: top{}
+heap: fun<main>, 5, 2, Int, Int, 5, 2, (y = 5@5, x = 2@6), 
+env: t2: (y = 5@5, x = 2@6), main: fun<main>, 
+}
+--- step lvalue t2.y --->
+{
+stack: main{t2<-1> :: t2.y<0> :: t2.y = 3;<0> :: return ((t2.y - t2.x) - 1);<-1>} :: top{}
+heap: fun<main>, 5, 2, Int, Int, 5, 2, (y = 5@5, x = 2@6), 
+env: t2: (y = 5@5, x = 2@6), main: fun<main>, 
+}
+--- step lvalue t2 --->
+{
+stack: main{ptr<7><-1> :: t2.y<0> :: t2.y = 3;<0> :: return ((t2.y - t2.x) - 1);<-1>} :: top{}
+heap: fun<main>, 5, 2, Int, Int, 5, 2, (y = 5@5, x = 2@6), 
+env: t2: (y = 5@5, x = 2@6), main: fun<main>, 
+}
+--- handle value ptr<7> with t2.y<1>(ptr<7>,) --->
+{
+stack: main{ptr<5><-1> :: t2.y = 3;<0> :: return ((t2.y - t2.x) - 1);<-1>} :: top{}
+heap: fun<main>, 5, 2, Int, Int, 5, 2, (y = 5@5, x = 2@6), 
+env: t2: (y = 5@5, x = 2@6), main: fun<main>, 
+}
+--- handle value ptr<5> with t2.y = 3;<1>(ptr<5>,) --->
+{
+stack: main{3<-1> :: t2.y = 3;<1>(ptr<5>,) :: return ((t2.y - t2.x) - 1);<-1>} :: top{}
+heap: fun<main>, 5, 2, Int, Int, 5, 2, (y = 5@5, x = 2@6), 
+env: t2: (y = 5@5, x = 2@6), main: fun<main>, 
+}
+--- step exp 3 --->
+{
+stack: main{3<-1> :: t2.y = 3;<1>(ptr<5>,) :: return ((t2.y - t2.x) - 1);<-1>} :: top{}
+heap: fun<main>, 5, 2, Int, Int, 5, 2, (y = 5@5, x = 2@6), 
+env: t2: (y = 5@5, x = 2@6), main: fun<main>, 
+}
+--- handle value 3 with t2.y = 3;<2>(ptr<5>,3,) --->
+{
+stack: main{return ((t2.y - t2.x) - 1);<-1>} :: top{}
+heap: fun<main>, 5, 2, Int, Int, 3, 2, (y = 3@5, x = 2@6), 
+env: t2: (y = 3@5, x = 2@6), main: fun<main>, 
+}
+--- step stmt return ((t2.y - t2.x) - 1); --->
+{
+stack: main{((t2.y - t2.x) - 1)<-1> :: return ((t2.y - t2.x) - 1);<0>} :: top{}
+heap: fun<main>, 5, 2, Int, Int, 3, 2, (y = 3@5, x = 2@6), 
+env: t2: (y = 3@5, x = 2@6), main: fun<main>, 
+}
+--- step exp ((t2.y - t2.x) - 1) --->
+{
+stack: main{(t2.y - t2.x)<-1> :: ((t2.y - t2.x) - 1)<0> :: return ((t2.y - t2.x) - 1);<0>} :: top{}
+heap: fun<main>, 5, 2, Int, Int, 3, 2, (y = 3@5, x = 2@6), 
+env: t2: (y = 3@5, x = 2@6), main: fun<main>, 
+}
+--- step exp (t2.y - t2.x) --->
+{
+stack: main{t2.y<-1> :: (t2.y - t2.x)<0> :: ((t2.y - t2.x) - 1)<0> :: return ((t2.y - t2.x) - 1);<0>} :: top{}
+heap: fun<main>, 5, 2, Int, Int, 3, 2, (y = 3@5, x = 2@6), 
+env: t2: (y = 3@5, x = 2@6), main: fun<main>, 
+}
+--- step exp t2.y --->
+{
+stack: main{t2<-1> :: t2.y<0> :: (t2.y - t2.x)<0> :: ((t2.y - t2.x) - 1)<0> :: return ((t2.y - t2.x) - 1);<0>} :: top{}
+heap: fun<main>, 5, 2, Int, Int, 3, 2, (y = 3@5, x = 2@6), 
+env: t2: (y = 3@5, x = 2@6), main: fun<main>, 
+}
+--- step lvalue t2 --->
+{
+stack: main{ptr<7><-1> :: t2.y<0> :: (t2.y - t2.x)<0> :: ((t2.y - t2.x) - 1)<0> :: return ((t2.y - t2.x) - 1);<0>} :: top{}
+heap: fun<main>, 5, 2, Int, Int, 3, 2, (y = 3@5, x = 2@6), 
+env: t2: (y = 3@5, x = 2@6), main: fun<main>, 
+}
+--- handle value ptr<7> with t2.y<1>(ptr<7>,) --->
+{
+stack: main{3<-1> :: (t2.y - t2.x)<0> :: ((t2.y - t2.x) - 1)<0> :: return ((t2.y - t2.x) - 1);<0>} :: top{}
+heap: fun<main>, 5, 2, Int, Int, 3, 2, (y = 3@5, x = 2@6), 
+env: t2: (y = 3@5, x = 2@6), main: fun<main>, 
+}
+--- handle value 3 with (t2.y - t2.x)<1>(3,) --->
+{
+stack: main{t2.x<-1> :: (t2.y - t2.x)<1>(3,) :: ((t2.y - t2.x) - 1)<0> :: return ((t2.y - t2.x) - 1);<0>} :: top{}
+heap: fun<main>, 5, 2, Int, Int, 3, 2, (y = 3@5, x = 2@6), 
+env: t2: (y = 3@5, x = 2@6), main: fun<main>, 
+}
+--- step exp t2.x --->
+{
+stack: main{t2<-1> :: t2.x<0> :: (t2.y - t2.x)<1>(3,) :: ((t2.y - t2.x) - 1)<0> :: return ((t2.y - t2.x) - 1);<0>} :: top{}
+heap: fun<main>, 5, 2, Int, Int, 3, 2, (y = 3@5, x = 2@6), 
+env: t2: (y = 3@5, x = 2@6), main: fun<main>, 
+}
+--- step lvalue t2 --->
+{
+stack: main{ptr<7><-1> :: t2.x<0> :: (t2.y - t2.x)<1>(3,) :: ((t2.y - t2.x) - 1)<0> :: return ((t2.y - t2.x) - 1);<0>} :: top{}
+heap: fun<main>, 5, 2, Int, Int, 3, 2, (y = 3@5, x = 2@6), 
+env: t2: (y = 3@5, x = 2@6), main: fun<main>, 
+}
+--- handle value ptr<7> with t2.x<1>(ptr<7>,) --->
+{
+stack: main{2<-1> :: (t2.y - t2.x)<1>(3,) :: ((t2.y - t2.x) - 1)<0> :: return ((t2.y - t2.x) - 1);<0>} :: top{}
+heap: fun<main>, 5, 2, Int, Int, 3, 2, (y = 3@5, x = 2@6), 
+env: t2: (y = 3@5, x = 2@6), main: fun<main>, 
+}
+--- handle value 2 with (t2.y - t2.x)<2>(3,2,) --->
+{
+stack: main{1<-1> :: ((t2.y - t2.x) - 1)<0> :: return ((t2.y - t2.x) - 1);<0>} :: top{}
+heap: fun<main>, 5, 2, Int, Int, 3, 2, (y = 3@5, x = 2@6), 
+env: t2: (y = 3@5, x = 2@6), main: fun<main>, 
+}
+--- handle value 1 with ((t2.y - t2.x) - 1)<1>(1,) --->
+{
+stack: main{1<-1> :: ((t2.y - t2.x) - 1)<1>(1,) :: return ((t2.y - t2.x) - 1);<0>} :: top{}
+heap: fun<main>, 5, 2, Int, Int, 3, 2, (y = 3@5, x = 2@6), 
+env: t2: (y = 3@5, x = 2@6), main: fun<main>, 
+}
+--- step exp 1 --->
+{
+stack: main{1<-1> :: ((t2.y - t2.x) - 1)<1>(1,) :: return ((t2.y - t2.x) - 1);<0>} :: top{}
+heap: fun<main>, 5, 2, Int, Int, 3, 2, (y = 3@5, x = 2@6), 
+env: t2: (y = 3@5, x = 2@6), main: fun<main>, 
+}
+--- handle value 1 with ((t2.y - t2.x) - 1)<2>(1,1,) --->
+{
+stack: main{0<-1> :: return ((t2.y - t2.x) - 1);<0>} :: top{}
+heap: fun<main>, 5, 2, Int, Int, 3, 2, (y = 3@5, x = 2@6), 
+env: t2: (y = 3@5, x = 2@6), main: fun<main>, 
+}
+--- handle value 0 with return ((t2.y - t2.x) - 1);<1>(0,) --->
+{
+stack: top{0<-1>}
+heap: fun<main>, 5, 2, Int, Int, !!3, !!2, !!(y = !!3@5, x = !!2@6), 
+env: main: fun<main>, 
+}
 result: 0

+ 255 - 0
executable_semantics/testdata/struct1.golden

@@ -1 +1,256 @@
+********** source program **********
+struct Point {
+var x : Int;
+var y : Int;
+}
+fn main () -> Int {
+var auto: p = Point(x = 1, y = 2);
+return ((p.y - p.x) - 1);
+
+}
+********** type checking **********
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+--- step exp auto --->
+
+********** type checking complete **********
+struct Point {
+var x : Int;
+var y : Int;
+}
+fn main () -> Int {
+var auto: p = Point(x = 1, y = 2);
+return ((p.y - p.x) - 1);
+}
+********** starting execution **********
+********** initializing globals **********
+--- step exp Int --->
+--- step exp Int --->
+--- step exp () --->
+********** calling main function **********
+{
+stack: top{main()<-1>}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step exp main() --->
+{
+stack: top{main<-1> :: main()<0>}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step exp main --->
+{
+stack: top{fun<main><-1> :: main()<0>}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- handle value fun<main> with main()<1>(fun<main>,) --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step exp () --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- handle value () with main()<2>(fun<main>,(),) --->
+pattern_match((), ())
+{
+stack: main{var auto: p = Point(x = 1, y = 2); ... <-1>} :: top{}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step stmt var auto: p = Point(x = 1, y = 2); ...  --->
+{
+stack: main{var auto: p = Point(x = 1, y = 2);<-1> :: return ((p.y - p.x) - 1);<-1>} :: top{}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step stmt var auto: p = Point(x = 1, y = 2); --->
+{
+stack: main{Point(x = 1, y = 2)<-1> :: var auto: p = Point(x = 1, y = 2);<0> :: return ((p.y - p.x) - 1);<-1>} :: top{}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step exp Point(x = 1, y = 2) --->
+{
+stack: main{Point<-1> :: Point(x = 1, y = 2)<0> :: var auto: p = Point(x = 1, y = 2);<0> :: return ((p.y - p.x) - 1);<-1>} :: top{}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step exp Point --->
+{
+stack: main{struct Point<-1> :: Point(x = 1, y = 2)<0> :: var auto: p = Point(x = 1, y = 2);<0> :: return ((p.y - p.x) - 1);<-1>} :: top{}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- handle value struct Point with Point(x = 1, y = 2)<1>(struct Point,) --->
+{
+stack: main{(x = 1, y = 2)<-1> :: Point(x = 1, y = 2)<1>(struct Point,) :: var auto: p = Point(x = 1, y = 2);<0> :: return ((p.y - p.x) - 1);<-1>} :: top{}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step exp (x = 1, y = 2) --->
+{
+stack: main{1<-1> :: (x = 1, y = 2)<0> :: Point(x = 1, y = 2)<1>(struct Point,) :: var auto: p = Point(x = 1, y = 2);<0> :: return ((p.y - p.x) - 1);<-1>} :: top{}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step exp 1 --->
+{
+stack: main{1<-1> :: (x = 1, y = 2)<0> :: Point(x = 1, y = 2)<1>(struct Point,) :: var auto: p = Point(x = 1, y = 2);<0> :: return ((p.y - p.x) - 1);<-1>} :: top{}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- handle value 1 with (x = 1, y = 2)<1>(1,) --->
+{
+stack: main{2<-1> :: (x = 1, y = 2)<1>(1,) :: Point(x = 1, y = 2)<1>(struct Point,) :: var auto: p = Point(x = 1, y = 2);<0> :: return ((p.y - p.x) - 1);<-1>} :: top{}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step exp 2 --->
+{
+stack: main{2<-1> :: (x = 1, y = 2)<1>(1,) :: Point(x = 1, y = 2)<1>(struct Point,) :: var auto: p = Point(x = 1, y = 2);<0> :: return ((p.y - p.x) - 1);<-1>} :: top{}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- handle value 2 with (x = 1, y = 2)<2>(1,2,) --->
+{
+stack: main{(x = 1@2, y = 2@3)<-1> :: Point(x = 1, y = 2)<1>(struct Point,) :: var auto: p = Point(x = 1, y = 2);<0> :: return ((p.y - p.x) - 1);<-1>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- handle value (x = 1@2, y = 2@3) with Point(x = 1, y = 2)<2>(struct Point,(x = 1@2, y = 2@3),) --->
+{
+stack: main{Point(x = 1@4, y = 2@5)<-1> :: var auto: p = Point(x = 1, y = 2);<0> :: return ((p.y - p.x) - 1);<-1>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- handle value Point(x = 1@4, y = 2@5) with var auto: p = Point(x = 1, y = 2);<1>(Point(x = 1@4, y = 2@5),) --->
+{
+stack: main{auto: p<-1> :: var auto: p = Point(x = 1, y = 2);<1>(Point(x = 1@4, y = 2@5),) :: return ((p.y - p.x) - 1);<-1>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step exp auto: p --->
+{
+stack: main{auto<-1> :: auto: p<0> :: var auto: p = Point(x = 1, y = 2);<1>(Point(x = 1@4, y = 2@5),) :: return ((p.y - p.x) - 1);<-1>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step exp auto --->
+{
+stack: main{auto<-1> :: auto: p<0> :: var auto: p = Point(x = 1, y = 2);<1>(Point(x = 1@4, y = 2@5),) :: return ((p.y - p.x) - 1);<-1>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- handle value auto with auto: p<1>(auto,) --->
+{
+stack: main{auto: p<-1> :: var auto: p = Point(x = 1, y = 2);<1>(Point(x = 1@4, y = 2@5),) :: return ((p.y - p.x) - 1);<-1>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- handle value auto: p with var auto: p = Point(x = 1, y = 2);<2>(Point(x = 1@4, y = 2@5),auto: p,) --->
+pattern_match(auto: p, Point(x = 1@4, y = 2@5))
+{
+stack: main{return ((p.y - p.x) - 1);<-1>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 
+env: p: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- step stmt return ((p.y - p.x) - 1); --->
+{
+stack: main{((p.y - p.x) - 1)<-1> :: return ((p.y - p.x) - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 
+env: p: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- step exp ((p.y - p.x) - 1) --->
+{
+stack: main{(p.y - p.x)<-1> :: ((p.y - p.x) - 1)<0> :: return ((p.y - p.x) - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 
+env: p: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- step exp (p.y - p.x) --->
+{
+stack: main{p.y<-1> :: (p.y - p.x)<0> :: ((p.y - p.x) - 1)<0> :: return ((p.y - p.x) - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 
+env: p: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- step exp p.y --->
+{
+stack: main{p<-1> :: p.y<0> :: (p.y - p.x)<0> :: ((p.y - p.x) - 1)<0> :: return ((p.y - p.x) - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 
+env: p: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- step lvalue p --->
+{
+stack: main{ptr<8><-1> :: p.y<0> :: (p.y - p.x)<0> :: ((p.y - p.x) - 1)<0> :: return ((p.y - p.x) - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 
+env: p: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- handle value ptr<8> with p.y<1>(ptr<8>,) --->
+{
+stack: main{2<-1> :: (p.y - p.x)<0> :: ((p.y - p.x) - 1)<0> :: return ((p.y - p.x) - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 
+env: p: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- handle value 2 with (p.y - p.x)<1>(2,) --->
+{
+stack: main{p.x<-1> :: (p.y - p.x)<1>(2,) :: ((p.y - p.x) - 1)<0> :: return ((p.y - p.x) - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 
+env: p: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- step exp p.x --->
+{
+stack: main{p<-1> :: p.x<0> :: (p.y - p.x)<1>(2,) :: ((p.y - p.x) - 1)<0> :: return ((p.y - p.x) - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 
+env: p: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- step lvalue p --->
+{
+stack: main{ptr<8><-1> :: p.x<0> :: (p.y - p.x)<1>(2,) :: ((p.y - p.x) - 1)<0> :: return ((p.y - p.x) - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 
+env: p: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- handle value ptr<8> with p.x<1>(ptr<8>,) --->
+{
+stack: main{1<-1> :: (p.y - p.x)<1>(2,) :: ((p.y - p.x) - 1)<0> :: return ((p.y - p.x) - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 
+env: p: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- handle value 1 with (p.y - p.x)<2>(2,1,) --->
+{
+stack: main{1<-1> :: ((p.y - p.x) - 1)<0> :: return ((p.y - p.x) - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 
+env: p: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- handle value 1 with ((p.y - p.x) - 1)<1>(1,) --->
+{
+stack: main{1<-1> :: ((p.y - p.x) - 1)<1>(1,) :: return ((p.y - p.x) - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 
+env: p: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- step exp 1 --->
+{
+stack: main{1<-1> :: ((p.y - p.x) - 1)<1>(1,) :: return ((p.y - p.x) - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 
+env: p: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- handle value 1 with ((p.y - p.x) - 1)<2>(1,1,) --->
+{
+stack: main{0<-1> :: return ((p.y - p.x) - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 
+env: p: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- handle value 0 with return ((p.y - p.x) - 1);<1>(0,) --->
+{
+stack: top{0<-1>}
+heap: struct Point, fun<main>, 1, 2, 1, 2, !!1, !!2, !!Point!!(x = !!1@6, y = !!2@7), 
+env: main: fun<main>, Point: struct Point, 
+}
 result: 0

+ 321 - 0
executable_semantics/testdata/struct2.golden

@@ -1 +1,322 @@
+********** source program **********
+struct Point {
+var x : Int;
+var y : Int;
+}
+fn main () -> Int {
+var auto: p1 = Point(x = 1, y = 2);
+var auto: p2 = p1;
+p2.x = 3;
+return (p1.x - 1);
+
+}
+********** type checking **********
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+--- step exp auto --->
+--- step exp auto --->
+
+********** type checking complete **********
+struct Point {
+var x : Int;
+var y : Int;
+}
+fn main () -> Int {
+var auto: p1 = Point(x = 1, y = 2);
+var auto: p2 = p1;
+p2.x = 3;
+return (p1.x - 1);
+}
+********** starting execution **********
+********** initializing globals **********
+--- step exp Int --->
+--- step exp Int --->
+--- step exp () --->
+********** calling main function **********
+{
+stack: top{main()<-1>}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step exp main() --->
+{
+stack: top{main<-1> :: main()<0>}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step exp main --->
+{
+stack: top{fun<main><-1> :: main()<0>}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- handle value fun<main> with main()<1>(fun<main>,) --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step exp () --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- handle value () with main()<2>(fun<main>,(),) --->
+pattern_match((), ())
+{
+stack: main{var auto: p1 = Point(x = 1, y = 2); ... <-1>} :: top{}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step stmt var auto: p1 = Point(x = 1, y = 2); ...  --->
+{
+stack: main{var auto: p1 = Point(x = 1, y = 2);<-1> :: var auto: p2 = p1; ... <-1>} :: top{}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step stmt var auto: p1 = Point(x = 1, y = 2); --->
+{
+stack: main{Point(x = 1, y = 2)<-1> :: var auto: p1 = Point(x = 1, y = 2);<0> :: var auto: p2 = p1; ... <-1>} :: top{}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step exp Point(x = 1, y = 2) --->
+{
+stack: main{Point<-1> :: Point(x = 1, y = 2)<0> :: var auto: p1 = Point(x = 1, y = 2);<0> :: var auto: p2 = p1; ... <-1>} :: top{}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step exp Point --->
+{
+stack: main{struct Point<-1> :: Point(x = 1, y = 2)<0> :: var auto: p1 = Point(x = 1, y = 2);<0> :: var auto: p2 = p1; ... <-1>} :: top{}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- handle value struct Point with Point(x = 1, y = 2)<1>(struct Point,) --->
+{
+stack: main{(x = 1, y = 2)<-1> :: Point(x = 1, y = 2)<1>(struct Point,) :: var auto: p1 = Point(x = 1, y = 2);<0> :: var auto: p2 = p1; ... <-1>} :: top{}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step exp (x = 1, y = 2) --->
+{
+stack: main{1<-1> :: (x = 1, y = 2)<0> :: Point(x = 1, y = 2)<1>(struct Point,) :: var auto: p1 = Point(x = 1, y = 2);<0> :: var auto: p2 = p1; ... <-1>} :: top{}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step exp 1 --->
+{
+stack: main{1<-1> :: (x = 1, y = 2)<0> :: Point(x = 1, y = 2)<1>(struct Point,) :: var auto: p1 = Point(x = 1, y = 2);<0> :: var auto: p2 = p1; ... <-1>} :: top{}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- handle value 1 with (x = 1, y = 2)<1>(1,) --->
+{
+stack: main{2<-1> :: (x = 1, y = 2)<1>(1,) :: Point(x = 1, y = 2)<1>(struct Point,) :: var auto: p1 = Point(x = 1, y = 2);<0> :: var auto: p2 = p1; ... <-1>} :: top{}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step exp 2 --->
+{
+stack: main{2<-1> :: (x = 1, y = 2)<1>(1,) :: Point(x = 1, y = 2)<1>(struct Point,) :: var auto: p1 = Point(x = 1, y = 2);<0> :: var auto: p2 = p1; ... <-1>} :: top{}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- handle value 2 with (x = 1, y = 2)<2>(1,2,) --->
+{
+stack: main{(x = 1@2, y = 2@3)<-1> :: Point(x = 1, y = 2)<1>(struct Point,) :: var auto: p1 = Point(x = 1, y = 2);<0> :: var auto: p2 = p1; ... <-1>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- handle value (x = 1@2, y = 2@3) with Point(x = 1, y = 2)<2>(struct Point,(x = 1@2, y = 2@3),) --->
+{
+stack: main{Point(x = 1@4, y = 2@5)<-1> :: var auto: p1 = Point(x = 1, y = 2);<0> :: var auto: p2 = p1; ... <-1>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- handle value Point(x = 1@4, y = 2@5) with var auto: p1 = Point(x = 1, y = 2);<1>(Point(x = 1@4, y = 2@5),) --->
+{
+stack: main{auto: p1<-1> :: var auto: p1 = Point(x = 1, y = 2);<1>(Point(x = 1@4, y = 2@5),) :: var auto: p2 = p1; ... <-1>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step exp auto: p1 --->
+{
+stack: main{auto<-1> :: auto: p1<0> :: var auto: p1 = Point(x = 1, y = 2);<1>(Point(x = 1@4, y = 2@5),) :: var auto: p2 = p1; ... <-1>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step exp auto --->
+{
+stack: main{auto<-1> :: auto: p1<0> :: var auto: p1 = Point(x = 1, y = 2);<1>(Point(x = 1@4, y = 2@5),) :: var auto: p2 = p1; ... <-1>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- handle value auto with auto: p1<1>(auto,) --->
+{
+stack: main{auto: p1<-1> :: var auto: p1 = Point(x = 1, y = 2);<1>(Point(x = 1@4, y = 2@5),) :: var auto: p2 = p1; ... <-1>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- handle value auto: p1 with var auto: p1 = Point(x = 1, y = 2);<2>(Point(x = 1@4, y = 2@5),auto: p1,) --->
+pattern_match(auto: p1, Point(x = 1@4, y = 2@5))
+{
+stack: main{var auto: p2 = p1; ... <-1>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 
+env: p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- step stmt var auto: p2 = p1; ...  --->
+{
+stack: main{var auto: p2 = p1;<-1> :: p2.x = 3; ... <-1>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 
+env: p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- step stmt var auto: p2 = p1; --->
+{
+stack: main{p1<-1> :: var auto: p2 = p1;<0> :: p2.x = 3; ... <-1>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 
+env: p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- step exp p1 --->
+{
+stack: main{Point(x = 1@6, y = 2@7)<-1> :: var auto: p2 = p1;<0> :: p2.x = 3; ... <-1>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 
+env: p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- handle value Point(x = 1@6, y = 2@7) with var auto: p2 = p1;<1>(Point(x = 1@6, y = 2@7),) --->
+{
+stack: main{auto: p2<-1> :: var auto: p2 = p1;<1>(Point(x = 1@6, y = 2@7),) :: p2.x = 3; ... <-1>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 
+env: p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- step exp auto: p2 --->
+{
+stack: main{auto<-1> :: auto: p2<0> :: var auto: p2 = p1;<1>(Point(x = 1@6, y = 2@7),) :: p2.x = 3; ... <-1>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 
+env: p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- step exp auto --->
+{
+stack: main{auto<-1> :: auto: p2<0> :: var auto: p2 = p1;<1>(Point(x = 1@6, y = 2@7),) :: p2.x = 3; ... <-1>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 
+env: p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- handle value auto with auto: p2<1>(auto,) --->
+{
+stack: main{auto: p2<-1> :: var auto: p2 = p1;<1>(Point(x = 1@6, y = 2@7),) :: p2.x = 3; ... <-1>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 
+env: p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- handle value auto: p2 with var auto: p2 = p1;<2>(Point(x = 1@6, y = 2@7),auto: p2,) --->
+pattern_match(auto: p2, Point(x = 1@6, y = 2@7))
+{
+stack: main{p2.x = 3; ... <-1>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 1, 2, Point(x = 1@9, y = 2@10), 
+env: p2: Point(x = 1@9, y = 2@10), p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- step stmt p2.x = 3; ...  --->
+{
+stack: main{p2.x = 3;<-1> :: return (p1.x - 1);<-1>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 1, 2, Point(x = 1@9, y = 2@10), 
+env: p2: Point(x = 1@9, y = 2@10), p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- step stmt p2.x = 3; --->
+{
+stack: main{p2.x<-1> :: p2.x = 3;<0> :: return (p1.x - 1);<-1>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 1, 2, Point(x = 1@9, y = 2@10), 
+env: p2: Point(x = 1@9, y = 2@10), p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- step lvalue p2.x --->
+{
+stack: main{p2<-1> :: p2.x<0> :: p2.x = 3;<0> :: return (p1.x - 1);<-1>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 1, 2, Point(x = 1@9, y = 2@10), 
+env: p2: Point(x = 1@9, y = 2@10), p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- step lvalue p2 --->
+{
+stack: main{ptr<11><-1> :: p2.x<0> :: p2.x = 3;<0> :: return (p1.x - 1);<-1>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 1, 2, Point(x = 1@9, y = 2@10), 
+env: p2: Point(x = 1@9, y = 2@10), p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- handle value ptr<11> with p2.x<1>(ptr<11>,) --->
+{
+stack: main{ptr<9><-1> :: p2.x = 3;<0> :: return (p1.x - 1);<-1>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 1, 2, Point(x = 1@9, y = 2@10), 
+env: p2: Point(x = 1@9, y = 2@10), p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- handle value ptr<9> with p2.x = 3;<1>(ptr<9>,) --->
+{
+stack: main{3<-1> :: p2.x = 3;<1>(ptr<9>,) :: return (p1.x - 1);<-1>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 1, 2, Point(x = 1@9, y = 2@10), 
+env: p2: Point(x = 1@9, y = 2@10), p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- step exp 3 --->
+{
+stack: main{3<-1> :: p2.x = 3;<1>(ptr<9>,) :: return (p1.x - 1);<-1>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 1, 2, Point(x = 1@9, y = 2@10), 
+env: p2: Point(x = 1@9, y = 2@10), p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- handle value 3 with p2.x = 3;<2>(ptr<9>,3,) --->
+{
+stack: main{return (p1.x - 1);<-1>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 3, 2, Point(x = 3@9, y = 2@10), 
+env: p2: Point(x = 3@9, y = 2@10), p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- step stmt return (p1.x - 1); --->
+{
+stack: main{(p1.x - 1)<-1> :: return (p1.x - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 3, 2, Point(x = 3@9, y = 2@10), 
+env: p2: Point(x = 3@9, y = 2@10), p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- step exp (p1.x - 1) --->
+{
+stack: main{p1.x<-1> :: (p1.x - 1)<0> :: return (p1.x - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 3, 2, Point(x = 3@9, y = 2@10), 
+env: p2: Point(x = 3@9, y = 2@10), p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- step exp p1.x --->
+{
+stack: main{p1<-1> :: p1.x<0> :: (p1.x - 1)<0> :: return (p1.x - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 3, 2, Point(x = 3@9, y = 2@10), 
+env: p2: Point(x = 3@9, y = 2@10), p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- step lvalue p1 --->
+{
+stack: main{ptr<8><-1> :: p1.x<0> :: (p1.x - 1)<0> :: return (p1.x - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 3, 2, Point(x = 3@9, y = 2@10), 
+env: p2: Point(x = 3@9, y = 2@10), p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- handle value ptr<8> with p1.x<1>(ptr<8>,) --->
+{
+stack: main{1<-1> :: (p1.x - 1)<0> :: return (p1.x - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 3, 2, Point(x = 3@9, y = 2@10), 
+env: p2: Point(x = 3@9, y = 2@10), p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- handle value 1 with (p1.x - 1)<1>(1,) --->
+{
+stack: main{1<-1> :: (p1.x - 1)<1>(1,) :: return (p1.x - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 3, 2, Point(x = 3@9, y = 2@10), 
+env: p2: Point(x = 3@9, y = 2@10), p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- step exp 1 --->
+{
+stack: main{1<-1> :: (p1.x - 1)<1>(1,) :: return (p1.x - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 3, 2, Point(x = 3@9, y = 2@10), 
+env: p2: Point(x = 3@9, y = 2@10), p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- handle value 1 with (p1.x - 1)<2>(1,1,) --->
+{
+stack: main{0<-1> :: return (p1.x - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 1, 2, Point(x = 1@6, y = 2@7), 3, 2, Point(x = 3@9, y = 2@10), 
+env: p2: Point(x = 3@9, y = 2@10), p1: Point(x = 1@6, y = 2@7), main: fun<main>, Point: struct Point, 
+}
+--- handle value 0 with return (p1.x - 1);<1>(0,) --->
+{
+stack: top{0<-1>}
+heap: struct Point, fun<main>, 1, 2, 1, 2, !!1, !!2, !!Point!!(x = !!1@6, y = !!2@7), !!3, !!2, !!Point!!(x = !!3@9, y = !!2@10), 
+env: main: fun<main>, Point: struct Point, 
+}
 result: 0

+ 185 - 0
executable_semantics/testdata/struct3.golden

@@ -1 +1,186 @@
+********** source program **********
+struct Point {
+var x : Int;
+var y : Int;
+}
+fn main () -> Int {
+return (Point(x = 1, y = 2).x - 1);
+
+}
+********** type checking **********
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+
+********** type checking complete **********
+struct Point {
+var x : Int;
+var y : Int;
+}
+fn main () -> Int {
+return (Point(x = 1, y = 2).x - 1);
+}
+********** starting execution **********
+********** initializing globals **********
+--- step exp Int --->
+--- step exp Int --->
+--- step exp () --->
+********** calling main function **********
+{
+stack: top{main()<-1>}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step exp main() --->
+{
+stack: top{main<-1> :: main()<0>}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step exp main --->
+{
+stack: top{fun<main><-1> :: main()<0>}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- handle value fun<main> with main()<1>(fun<main>,) --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step exp () --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- handle value () with main()<2>(fun<main>,(),) --->
+pattern_match((), ())
+{
+stack: main{return (Point(x = 1, y = 2).x - 1);<-1>} :: top{}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step stmt return (Point(x = 1, y = 2).x - 1); --->
+{
+stack: main{(Point(x = 1, y = 2).x - 1)<-1> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step exp (Point(x = 1, y = 2).x - 1) --->
+{
+stack: main{Point(x = 1, y = 2).x<-1> :: (Point(x = 1, y = 2).x - 1)<0> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step exp Point(x = 1, y = 2).x --->
+{
+stack: main{Point(x = 1, y = 2)<-1> :: Point(x = 1, y = 2).x<0> :: (Point(x = 1, y = 2).x - 1)<0> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step lvalue Point(x = 1, y = 2) --->
+{
+stack: main{Point(x = 1, y = 2)<-1> :: exp=>lval<-1> :: Point(x = 1, y = 2).x<0> :: (Point(x = 1, y = 2).x - 1)<0> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step exp Point(x = 1, y = 2) --->
+{
+stack: main{Point<-1> :: Point(x = 1, y = 2)<0> :: exp=>lval<-1> :: Point(x = 1, y = 2).x<0> :: (Point(x = 1, y = 2).x - 1)<0> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step exp Point --->
+{
+stack: main{struct Point<-1> :: Point(x = 1, y = 2)<0> :: exp=>lval<-1> :: Point(x = 1, y = 2).x<0> :: (Point(x = 1, y = 2).x - 1)<0> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- handle value struct Point with Point(x = 1, y = 2)<1>(struct Point,) --->
+{
+stack: main{(x = 1, y = 2)<-1> :: Point(x = 1, y = 2)<1>(struct Point,) :: exp=>lval<-1> :: Point(x = 1, y = 2).x<0> :: (Point(x = 1, y = 2).x - 1)<0> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step exp (x = 1, y = 2) --->
+{
+stack: main{1<-1> :: (x = 1, y = 2)<0> :: Point(x = 1, y = 2)<1>(struct Point,) :: exp=>lval<-1> :: Point(x = 1, y = 2).x<0> :: (Point(x = 1, y = 2).x - 1)<0> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step exp 1 --->
+{
+stack: main{1<-1> :: (x = 1, y = 2)<0> :: Point(x = 1, y = 2)<1>(struct Point,) :: exp=>lval<-1> :: Point(x = 1, y = 2).x<0> :: (Point(x = 1, y = 2).x - 1)<0> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- handle value 1 with (x = 1, y = 2)<1>(1,) --->
+{
+stack: main{2<-1> :: (x = 1, y = 2)<1>(1,) :: Point(x = 1, y = 2)<1>(struct Point,) :: exp=>lval<-1> :: Point(x = 1, y = 2).x<0> :: (Point(x = 1, y = 2).x - 1)<0> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step exp 2 --->
+{
+stack: main{2<-1> :: (x = 1, y = 2)<1>(1,) :: Point(x = 1, y = 2)<1>(struct Point,) :: exp=>lval<-1> :: Point(x = 1, y = 2).x<0> :: (Point(x = 1, y = 2).x - 1)<0> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- handle value 2 with (x = 1, y = 2)<2>(1,2,) --->
+{
+stack: main{(x = 1@2, y = 2@3)<-1> :: Point(x = 1, y = 2)<1>(struct Point,) :: exp=>lval<-1> :: Point(x = 1, y = 2).x<0> :: (Point(x = 1, y = 2).x - 1)<0> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- handle value (x = 1@2, y = 2@3) with Point(x = 1, y = 2)<2>(struct Point,(x = 1@2, y = 2@3),) --->
+{
+stack: main{Point(x = 1@4, y = 2@5)<-1> :: exp=>lval<-1> :: Point(x = 1, y = 2).x<0> :: (Point(x = 1, y = 2).x - 1)<0> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, 
+env: main: fun<main>, Point: struct Point, 
+}
+--- handle value Point(x = 1@4, y = 2@5) with exp=>lval<0>(Point(x = 1@4, y = 2@5),) --->
+{
+stack: main{ptr<6><-1> :: Point(x = 1, y = 2).x<0> :: (Point(x = 1, y = 2).x - 1)<0> :: delete_tmp(6)<-1> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, Point(x = 1@4, y = 2@5), 
+env: main: fun<main>, Point: struct Point, 
+}
+--- handle value ptr<6> with Point(x = 1, y = 2).x<1>(ptr<6>,) --->
+{
+stack: main{1<-1> :: (Point(x = 1, y = 2).x - 1)<0> :: delete_tmp(6)<-1> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, Point(x = 1@4, y = 2@5), 
+env: main: fun<main>, Point: struct Point, 
+}
+--- handle value 1 with (Point(x = 1, y = 2).x - 1)<1>(1,) --->
+{
+stack: main{1<-1> :: (Point(x = 1, y = 2).x - 1)<1>(1,) :: delete_tmp(6)<-1> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, Point(x = 1@4, y = 2@5), 
+env: main: fun<main>, Point: struct Point, 
+}
+--- step exp 1 --->
+{
+stack: main{1<-1> :: (Point(x = 1, y = 2).x - 1)<1>(1,) :: delete_tmp(6)<-1> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, Point(x = 1@4, y = 2@5), 
+env: main: fun<main>, Point: struct Point, 
+}
+--- handle value 1 with (Point(x = 1, y = 2).x - 1)<2>(1,1,) --->
+{
+stack: main{0<-1> :: delete_tmp(6)<-1> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 1, 2, 1, 2, Point(x = 1@4, y = 2@5), 
+env: main: fun<main>, Point: struct Point, 
+}
+--- handle value 0 with delete_tmp(6)<0>(0,) --->
+{
+stack: main{0<-1> :: return (Point(x = 1, y = 2).x - 1);<0>} :: top{}
+heap: struct Point, fun<main>, 1, 2, !!1, !!2, !!Point!!(x = !!1@4, y = !!2@5), 
+env: main: fun<main>, Point: struct Point, 
+}
+--- handle value 0 with return (Point(x = 1, y = 2).x - 1);<1>(0,) --->
+{
+stack: top{0<-1>}
+heap: struct Point, fun<main>, 1, 2, !!1, !!2, !!Point!!(x = !!1@4, y = !!2@5), 
+env: main: fun<main>, Point: struct Point, 
+}
 result: 0

+ 388 - 0
executable_semantics/testdata/tuple1.golden

@@ -1 +1,389 @@
+********** source program **********
+fn main () -> Int {
+var Int: x = 1;
+var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);
+t2[0] = 3;
+return ((t2[0] - t2[1]) - x);
+
+}
+********** type checking **********
+--- step exp Int --->
+--- step exp Int --->
+--- step exp Int --->
+--- step exp (0 = Int, 1 = Int) --->
+--- step exp Int --->
+--- handle value Int with (0 = Int, 1 = Int)<1>(Int,) --->
+--- step exp Int --->
+--- handle value Int with (0 = Int, 1 = Int)<2>(Int,Int,) --->
+--- step exp 0 --->
+--- step exp 0 --->
+--- step exp 1 --->
+
+********** type checking complete **********
+fn main () -> Int {
+var Int: x = 1;
+var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);
+t2[0] = 3;
+return ((t2[0] - t2[1]) - x);
+}
+********** starting execution **********
+********** initializing globals **********
+--- step exp () --->
+********** calling main function **********
+{
+stack: top{main()<-1>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main() --->
+{
+stack: top{main<-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main --->
+{
+stack: top{fun<main><-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value fun<main> with main()<1>(fun<main>,) --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp () --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value () with main()<2>(fun<main>,(),) --->
+pattern_match((), ())
+{
+stack: main{var Int: x = 1; ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt var Int: x = 1; ...  --->
+{
+stack: main{var Int: x = 1;<-1> :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2); ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt var Int: x = 1; --->
+{
+stack: main{1<-1> :: var Int: x = 1;<0> :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2); ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 1 --->
+{
+stack: main{1<-1> :: var Int: x = 1;<0> :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2); ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 1 with var Int: x = 1;<1>(1,) --->
+{
+stack: main{Int: x<-1> :: var Int: x = 1;<1>(1,) :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2); ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp Int: x --->
+{
+stack: main{Int<-1> :: Int: x<0> :: var Int: x = 1;<1>(1,) :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2); ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp Int --->
+{
+stack: main{Int<-1> :: Int: x<0> :: var Int: x = 1;<1>(1,) :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2); ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value Int with Int: x<1>(Int,) --->
+{
+stack: main{Int: x<-1> :: var Int: x = 1;<1>(1,) :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2); ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value Int: x with var Int: x = 1;<2>(1,Int: x,) --->
+pattern_match(Int: x, 1)
+{
+stack: main{var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2); ... <-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step stmt var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2); ...  --->
+{
+stack: main{var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);<-1> :: t2[0] = 3; ... <-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step stmt var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2); --->
+{
+stack: main{(0 = 5, 1 = 2)<-1> :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);<0> :: t2[0] = 3; ... <-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step exp (0 = 5, 1 = 2) --->
+{
+stack: main{5<-1> :: (0 = 5, 1 = 2)<0> :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);<0> :: t2[0] = 3; ... <-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step exp 5 --->
+{
+stack: main{5<-1> :: (0 = 5, 1 = 2)<0> :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);<0> :: t2[0] = 3; ... <-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- handle value 5 with (0 = 5, 1 = 2)<1>(5,) --->
+{
+stack: main{2<-1> :: (0 = 5, 1 = 2)<1>(5,) :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);<0> :: t2[0] = 3; ... <-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step exp 2 --->
+{
+stack: main{2<-1> :: (0 = 5, 1 = 2)<1>(5,) :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);<0> :: t2[0] = 3; ... <-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- handle value 2 with (0 = 5, 1 = 2)<2>(5,2,) --->
+{
+stack: main{(0 = 5@2, 1 = 2@3)<-1> :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);<0> :: t2[0] = 3; ... <-1>} :: top{}
+heap: fun<main>, 1, 5, 2, 
+env: x: 1, main: fun<main>, 
+}
+--- handle value (0 = 5@2, 1 = 2@3) with var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);<1>((0 = 5@2, 1 = 2@3),) --->
+{
+stack: main{(0 = Int, 1 = Int): t2<-1> :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);<1>((0 = 5@2, 1 = 2@3),) :: t2[0] = 3; ... <-1>} :: top{}
+heap: fun<main>, 1, 5, 2, 
+env: x: 1, main: fun<main>, 
+}
+--- step exp (0 = Int, 1 = Int): t2 --->
+{
+stack: main{(0 = Int, 1 = Int)<-1> :: (0 = Int, 1 = Int): t2<0> :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);<1>((0 = 5@2, 1 = 2@3),) :: t2[0] = 3; ... <-1>} :: top{}
+heap: fun<main>, 1, 5, 2, 
+env: x: 1, main: fun<main>, 
+}
+--- step exp (0 = Int, 1 = Int) --->
+{
+stack: main{Int<-1> :: (0 = Int, 1 = Int)<0> :: (0 = Int, 1 = Int): t2<0> :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);<1>((0 = 5@2, 1 = 2@3),) :: t2[0] = 3; ... <-1>} :: top{}
+heap: fun<main>, 1, 5, 2, 
+env: x: 1, main: fun<main>, 
+}
+--- step exp Int --->
+{
+stack: main{Int<-1> :: (0 = Int, 1 = Int)<0> :: (0 = Int, 1 = Int): t2<0> :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);<1>((0 = 5@2, 1 = 2@3),) :: t2[0] = 3; ... <-1>} :: top{}
+heap: fun<main>, 1, 5, 2, 
+env: x: 1, main: fun<main>, 
+}
+--- handle value Int with (0 = Int, 1 = Int)<1>(Int,) --->
+{
+stack: main{Int<-1> :: (0 = Int, 1 = Int)<1>(Int,) :: (0 = Int, 1 = Int): t2<0> :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);<1>((0 = 5@2, 1 = 2@3),) :: t2[0] = 3; ... <-1>} :: top{}
+heap: fun<main>, 1, 5, 2, 
+env: x: 1, main: fun<main>, 
+}
+--- step exp Int --->
+{
+stack: main{Int<-1> :: (0 = Int, 1 = Int)<1>(Int,) :: (0 = Int, 1 = Int): t2<0> :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);<1>((0 = 5@2, 1 = 2@3),) :: t2[0] = 3; ... <-1>} :: top{}
+heap: fun<main>, 1, 5, 2, 
+env: x: 1, main: fun<main>, 
+}
+--- handle value Int with (0 = Int, 1 = Int)<2>(Int,Int,) --->
+{
+stack: main{(0 = Int@4, 1 = Int@5)<-1> :: (0 = Int, 1 = Int): t2<0> :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);<1>((0 = 5@2, 1 = 2@3),) :: t2[0] = 3; ... <-1>} :: top{}
+heap: fun<main>, 1, 5, 2, Int, Int, 
+env: x: 1, main: fun<main>, 
+}
+--- handle value (0 = Int@4, 1 = Int@5) with (0 = Int, 1 = Int): t2<1>((0 = Int@4, 1 = Int@5),) --->
+{
+stack: main{(0 = Int@4, 1 = Int@5): t2<-1> :: var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);<1>((0 = 5@2, 1 = 2@3),) :: t2[0] = 3; ... <-1>} :: top{}
+heap: fun<main>, 1, 5, 2, Int, Int, 
+env: x: 1, main: fun<main>, 
+}
+--- handle value (0 = Int@4, 1 = Int@5): t2 with var (0 = Int, 1 = Int): t2 = (0 = 5, 1 = 2);<2>((0 = 5@2, 1 = 2@3),(0 = Int@4, 1 = Int@5): t2,) --->
+pattern_match((0 = Int@4, 1 = Int@5): t2, (0 = 5@2, 1 = 2@3))
+{
+stack: main{t2[0] = 3; ... <-1>} :: top{}
+heap: fun<main>, 1, 5, 2, Int, Int, 5, 2, (0 = 5@6, 1 = 2@7), 
+env: t2: (0 = 5@6, 1 = 2@7), x: 1, main: fun<main>, 
+}
+--- step stmt t2[0] = 3; ...  --->
+{
+stack: main{t2[0] = 3;<-1> :: return ((t2[0] - t2[1]) - x);<-1>} :: top{}
+heap: fun<main>, 1, 5, 2, Int, Int, 5, 2, (0 = 5@6, 1 = 2@7), 
+env: t2: (0 = 5@6, 1 = 2@7), x: 1, main: fun<main>, 
+}
+--- step stmt t2[0] = 3; --->
+{
+stack: main{t2[0]<-1> :: t2[0] = 3;<0> :: return ((t2[0] - t2[1]) - x);<-1>} :: top{}
+heap: fun<main>, 1, 5, 2, Int, Int, 5, 2, (0 = 5@6, 1 = 2@7), 
+env: t2: (0 = 5@6, 1 = 2@7), x: 1, main: fun<main>, 
+}
+--- step lvalue t2[0] --->
+{
+stack: main{t2<-1> :: t2[0]<0> :: t2[0] = 3;<0> :: return ((t2[0] - t2[1]) - x);<-1>} :: top{}
+heap: fun<main>, 1, 5, 2, Int, Int, 5, 2, (0 = 5@6, 1 = 2@7), 
+env: t2: (0 = 5@6, 1 = 2@7), x: 1, main: fun<main>, 
+}
+--- step exp t2 --->
+{
+stack: main{(0 = 5@6, 1 = 2@7)<-1> :: t2[0]<0> :: t2[0] = 3;<0> :: return ((t2[0] - t2[1]) - x);<-1>} :: top{}
+heap: fun<main>, 1, 5, 2, Int, Int, 5, 2, (0 = 5@6, 1 = 2@7), 
+env: t2: (0 = 5@6, 1 = 2@7), x: 1, main: fun<main>, 
+}
+--- handle value (0 = 5@6, 1 = 2@7) with t2[0]<1>((0 = 5@6, 1 = 2@7),) --->
+{
+stack: main{0<-1> :: t2[0]<1>((0 = 5@6, 1 = 2@7),) :: t2[0] = 3;<0> :: return ((t2[0] - t2[1]) - x);<-1>} :: top{}
+heap: fun<main>, 1, 5, 2, Int, Int, 5, 2, (0 = 5@6, 1 = 2@7), 
+env: t2: (0 = 5@6, 1 = 2@7), x: 1, main: fun<main>, 
+}
+--- step exp 0 --->
+{
+stack: main{0<-1> :: t2[0]<1>((0 = 5@6, 1 = 2@7),) :: t2[0] = 3;<0> :: return ((t2[0] - t2[1]) - x);<-1>} :: top{}
+heap: fun<main>, 1, 5, 2, Int, Int, 5, 2, (0 = 5@6, 1 = 2@7), 
+env: t2: (0 = 5@6, 1 = 2@7), x: 1, main: fun<main>, 
+}
+--- handle value 0 with t2[0]<2>((0 = 5@6, 1 = 2@7),0,) --->
+{
+stack: main{ptr<6><-1> :: t2[0] = 3;<0> :: return ((t2[0] - t2[1]) - x);<-1>} :: top{}
+heap: fun<main>, 1, 5, 2, Int, Int, 5, 2, (0 = 5@6, 1 = 2@7), 
+env: t2: (0 = 5@6, 1 = 2@7), x: 1, main: fun<main>, 
+}
+--- handle value ptr<6> with t2[0] = 3;<1>(ptr<6>,) --->
+{
+stack: main{3<-1> :: t2[0] = 3;<1>(ptr<6>,) :: return ((t2[0] - t2[1]) - x);<-1>} :: top{}
+heap: fun<main>, 1, 5, 2, Int, Int, 5, 2, (0 = 5@6, 1 = 2@7), 
+env: t2: (0 = 5@6, 1 = 2@7), x: 1, main: fun<main>, 
+}
+--- step exp 3 --->
+{
+stack: main{3<-1> :: t2[0] = 3;<1>(ptr<6>,) :: return ((t2[0] - t2[1]) - x);<-1>} :: top{}
+heap: fun<main>, 1, 5, 2, Int, Int, 5, 2, (0 = 5@6, 1 = 2@7), 
+env: t2: (0 = 5@6, 1 = 2@7), x: 1, main: fun<main>, 
+}
+--- handle value 3 with t2[0] = 3;<2>(ptr<6>,3,) --->
+{
+stack: main{return ((t2[0] - t2[1]) - x);<-1>} :: top{}
+heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7), 
+env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>, 
+}
+--- step stmt return ((t2[0] - t2[1]) - x); --->
+{
+stack: main{((t2[0] - t2[1]) - x)<-1> :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
+heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7), 
+env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>, 
+}
+--- step exp ((t2[0] - t2[1]) - x) --->
+{
+stack: main{(t2[0] - t2[1])<-1> :: ((t2[0] - t2[1]) - x)<0> :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
+heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7), 
+env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>, 
+}
+--- step exp (t2[0] - t2[1]) --->
+{
+stack: main{t2[0]<-1> :: (t2[0] - t2[1])<0> :: ((t2[0] - t2[1]) - x)<0> :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
+heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7), 
+env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>, 
+}
+--- step exp t2[0] --->
+{
+stack: main{t2<-1> :: t2[0]<0> :: (t2[0] - t2[1])<0> :: ((t2[0] - t2[1]) - x)<0> :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
+heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7), 
+env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>, 
+}
+--- step exp t2 --->
+{
+stack: main{(0 = 3@6, 1 = 2@7)<-1> :: t2[0]<0> :: (t2[0] - t2[1])<0> :: ((t2[0] - t2[1]) - x)<0> :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
+heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7), 
+env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>, 
+}
+--- handle value (0 = 3@6, 1 = 2@7) with t2[0]<1>((0 = 3@6, 1 = 2@7),) --->
+{
+stack: main{0<-1> :: t2[0]<1>((0 = 3@6, 1 = 2@7),) :: (t2[0] - t2[1])<0> :: ((t2[0] - t2[1]) - x)<0> :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
+heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7), 
+env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>, 
+}
+--- step exp 0 --->
+{
+stack: main{0<-1> :: t2[0]<1>((0 = 3@6, 1 = 2@7),) :: (t2[0] - t2[1])<0> :: ((t2[0] - t2[1]) - x)<0> :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
+heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7), 
+env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>, 
+}
+--- handle value 0 with t2[0]<2>((0 = 3@6, 1 = 2@7),0,) --->
+{
+stack: main{3<-1> :: (t2[0] - t2[1])<0> :: ((t2[0] - t2[1]) - x)<0> :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
+heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7), 
+env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>, 
+}
+--- handle value 3 with (t2[0] - t2[1])<1>(3,) --->
+{
+stack: main{t2[1]<-1> :: (t2[0] - t2[1])<1>(3,) :: ((t2[0] - t2[1]) - x)<0> :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
+heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7), 
+env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>, 
+}
+--- step exp t2[1] --->
+{
+stack: main{t2<-1> :: t2[1]<0> :: (t2[0] - t2[1])<1>(3,) :: ((t2[0] - t2[1]) - x)<0> :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
+heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7), 
+env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>, 
+}
+--- step exp t2 --->
+{
+stack: main{(0 = 3@6, 1 = 2@7)<-1> :: t2[1]<0> :: (t2[0] - t2[1])<1>(3,) :: ((t2[0] - t2[1]) - x)<0> :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
+heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7), 
+env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>, 
+}
+--- handle value (0 = 3@6, 1 = 2@7) with t2[1]<1>((0 = 3@6, 1 = 2@7),) --->
+{
+stack: main{1<-1> :: t2[1]<1>((0 = 3@6, 1 = 2@7),) :: (t2[0] - t2[1])<1>(3,) :: ((t2[0] - t2[1]) - x)<0> :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
+heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7), 
+env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>, 
+}
+--- step exp 1 --->
+{
+stack: main{1<-1> :: t2[1]<1>((0 = 3@6, 1 = 2@7),) :: (t2[0] - t2[1])<1>(3,) :: ((t2[0] - t2[1]) - x)<0> :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
+heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7), 
+env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>, 
+}
+--- handle value 1 with t2[1]<2>((0 = 3@6, 1 = 2@7),1,) --->
+{
+stack: main{2<-1> :: (t2[0] - t2[1])<1>(3,) :: ((t2[0] - t2[1]) - x)<0> :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
+heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7), 
+env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>, 
+}
+--- handle value 2 with (t2[0] - t2[1])<2>(3,2,) --->
+{
+stack: main{1<-1> :: ((t2[0] - t2[1]) - x)<0> :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
+heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7), 
+env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>, 
+}
+--- handle value 1 with ((t2[0] - t2[1]) - x)<1>(1,) --->
+{
+stack: main{x<-1> :: ((t2[0] - t2[1]) - x)<1>(1,) :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
+heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7), 
+env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>, 
+}
+--- step exp x --->
+{
+stack: main{1<-1> :: ((t2[0] - t2[1]) - x)<1>(1,) :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
+heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7), 
+env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>, 
+}
+--- handle value 1 with ((t2[0] - t2[1]) - x)<2>(1,1,) --->
+{
+stack: main{0<-1> :: return ((t2[0] - t2[1]) - x);<0>} :: top{}
+heap: fun<main>, 1, 5, 2, Int, Int, 3, 2, (0 = 3@6, 1 = 2@7), 
+env: t2: (0 = 3@6, 1 = 2@7), x: 1, main: fun<main>, 
+}
+--- handle value 0 with return ((t2[0] - t2[1]) - x);<1>(0,) --->
+{
+stack: top{0<-1>}
+heap: fun<main>, !!1, 5, 2, Int, Int, !!3, !!2, !!(0 = !!3@6, 1 = !!2@7), 
+env: main: fun<main>, 
+}
 result: 0

+ 198 - 0
executable_semantics/testdata/tuple2.golden

@@ -1 +1,199 @@
+********** source program **********
+fn main () -> Int {
+var (0 = Int): t = (0 = 5);
+return (t[0] - 5);
+
+}
+********** type checking **********
+--- step exp Int --->
+--- step exp Int --->
+--- step exp (0 = Int) --->
+--- step exp Int --->
+--- handle value Int with (0 = Int)<1>(Int,) --->
+--- step exp 0 --->
+
+********** type checking complete **********
+fn main () -> Int {
+var (0 = Int): t = (0 = 5);
+return (t[0] - 5);
+}
+********** starting execution **********
+********** initializing globals **********
+--- step exp () --->
+********** calling main function **********
+{
+stack: top{main()<-1>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main() --->
+{
+stack: top{main<-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main --->
+{
+stack: top{fun<main><-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value fun<main> with main()<1>(fun<main>,) --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp () --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value () with main()<2>(fun<main>,(),) --->
+pattern_match((), ())
+{
+stack: main{var (0 = Int): t = (0 = 5); ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt var (0 = Int): t = (0 = 5); ...  --->
+{
+stack: main{var (0 = Int): t = (0 = 5);<-1> :: return (t[0] - 5);<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt var (0 = Int): t = (0 = 5); --->
+{
+stack: main{(0 = 5)<-1> :: var (0 = Int): t = (0 = 5);<0> :: return (t[0] - 5);<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp (0 = 5) --->
+{
+stack: main{5<-1> :: (0 = 5)<0> :: var (0 = Int): t = (0 = 5);<0> :: return (t[0] - 5);<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 5 --->
+{
+stack: main{5<-1> :: (0 = 5)<0> :: var (0 = Int): t = (0 = 5);<0> :: return (t[0] - 5);<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 5 with (0 = 5)<1>(5,) --->
+{
+stack: main{(0 = 5@1)<-1> :: var (0 = Int): t = (0 = 5);<0> :: return (t[0] - 5);<-1>} :: top{}
+heap: fun<main>, 5, 
+env: main: fun<main>, 
+}
+--- handle value (0 = 5@1) with var (0 = Int): t = (0 = 5);<1>((0 = 5@1),) --->
+{
+stack: main{(0 = Int): t<-1> :: var (0 = Int): t = (0 = 5);<1>((0 = 5@1),) :: return (t[0] - 5);<-1>} :: top{}
+heap: fun<main>, 5, 
+env: main: fun<main>, 
+}
+--- step exp (0 = Int): t --->
+{
+stack: main{(0 = Int)<-1> :: (0 = Int): t<0> :: var (0 = Int): t = (0 = 5);<1>((0 = 5@1),) :: return (t[0] - 5);<-1>} :: top{}
+heap: fun<main>, 5, 
+env: main: fun<main>, 
+}
+--- step exp (0 = Int) --->
+{
+stack: main{Int<-1> :: (0 = Int)<0> :: (0 = Int): t<0> :: var (0 = Int): t = (0 = 5);<1>((0 = 5@1),) :: return (t[0] - 5);<-1>} :: top{}
+heap: fun<main>, 5, 
+env: main: fun<main>, 
+}
+--- step exp Int --->
+{
+stack: main{Int<-1> :: (0 = Int)<0> :: (0 = Int): t<0> :: var (0 = Int): t = (0 = 5);<1>((0 = 5@1),) :: return (t[0] - 5);<-1>} :: top{}
+heap: fun<main>, 5, 
+env: main: fun<main>, 
+}
+--- handle value Int with (0 = Int)<1>(Int,) --->
+{
+stack: main{(0 = Int@2)<-1> :: (0 = Int): t<0> :: var (0 = Int): t = (0 = 5);<1>((0 = 5@1),) :: return (t[0] - 5);<-1>} :: top{}
+heap: fun<main>, 5, Int, 
+env: main: fun<main>, 
+}
+--- handle value (0 = Int@2) with (0 = Int): t<1>((0 = Int@2),) --->
+{
+stack: main{(0 = Int@2): t<-1> :: var (0 = Int): t = (0 = 5);<1>((0 = 5@1),) :: return (t[0] - 5);<-1>} :: top{}
+heap: fun<main>, 5, Int, 
+env: main: fun<main>, 
+}
+--- handle value (0 = Int@2): t with var (0 = Int): t = (0 = 5);<2>((0 = 5@1),(0 = Int@2): t,) --->
+pattern_match((0 = Int@2): t, (0 = 5@1))
+{
+stack: main{return (t[0] - 5);<-1>} :: top{}
+heap: fun<main>, 5, Int, 5, (0 = 5@3), 
+env: t: (0 = 5@3), main: fun<main>, 
+}
+--- step stmt return (t[0] - 5); --->
+{
+stack: main{(t[0] - 5)<-1> :: return (t[0] - 5);<0>} :: top{}
+heap: fun<main>, 5, Int, 5, (0 = 5@3), 
+env: t: (0 = 5@3), main: fun<main>, 
+}
+--- step exp (t[0] - 5) --->
+{
+stack: main{t[0]<-1> :: (t[0] - 5)<0> :: return (t[0] - 5);<0>} :: top{}
+heap: fun<main>, 5, Int, 5, (0 = 5@3), 
+env: t: (0 = 5@3), main: fun<main>, 
+}
+--- step exp t[0] --->
+{
+stack: main{t<-1> :: t[0]<0> :: (t[0] - 5)<0> :: return (t[0] - 5);<0>} :: top{}
+heap: fun<main>, 5, Int, 5, (0 = 5@3), 
+env: t: (0 = 5@3), main: fun<main>, 
+}
+--- step exp t --->
+{
+stack: main{(0 = 5@3)<-1> :: t[0]<0> :: (t[0] - 5)<0> :: return (t[0] - 5);<0>} :: top{}
+heap: fun<main>, 5, Int, 5, (0 = 5@3), 
+env: t: (0 = 5@3), main: fun<main>, 
+}
+--- handle value (0 = 5@3) with t[0]<1>((0 = 5@3),) --->
+{
+stack: main{0<-1> :: t[0]<1>((0 = 5@3),) :: (t[0] - 5)<0> :: return (t[0] - 5);<0>} :: top{}
+heap: fun<main>, 5, Int, 5, (0 = 5@3), 
+env: t: (0 = 5@3), main: fun<main>, 
+}
+--- step exp 0 --->
+{
+stack: main{0<-1> :: t[0]<1>((0 = 5@3),) :: (t[0] - 5)<0> :: return (t[0] - 5);<0>} :: top{}
+heap: fun<main>, 5, Int, 5, (0 = 5@3), 
+env: t: (0 = 5@3), main: fun<main>, 
+}
+--- handle value 0 with t[0]<2>((0 = 5@3),0,) --->
+{
+stack: main{5<-1> :: (t[0] - 5)<0> :: return (t[0] - 5);<0>} :: top{}
+heap: fun<main>, 5, Int, 5, (0 = 5@3), 
+env: t: (0 = 5@3), main: fun<main>, 
+}
+--- handle value 5 with (t[0] - 5)<1>(5,) --->
+{
+stack: main{5<-1> :: (t[0] - 5)<1>(5,) :: return (t[0] - 5);<0>} :: top{}
+heap: fun<main>, 5, Int, 5, (0 = 5@3), 
+env: t: (0 = 5@3), main: fun<main>, 
+}
+--- step exp 5 --->
+{
+stack: main{5<-1> :: (t[0] - 5)<1>(5,) :: return (t[0] - 5);<0>} :: top{}
+heap: fun<main>, 5, Int, 5, (0 = 5@3), 
+env: t: (0 = 5@3), main: fun<main>, 
+}
+--- handle value 5 with (t[0] - 5)<2>(5,5,) --->
+{
+stack: main{0<-1> :: return (t[0] - 5);<0>} :: top{}
+heap: fun<main>, 5, Int, 5, (0 = 5@3), 
+env: t: (0 = 5@3), main: fun<main>, 
+}
+--- handle value 0 with return (t[0] - 5);<1>(0,) --->
+{
+stack: top{0<-1>}
+heap: fun<main>, 5, Int, !!5, !!(0 = !!5@3), 
+env: main: fun<main>, 
+}
 result: 0

+ 297 - 0
executable_semantics/testdata/tuple_assign.golden

@@ -1 +1,298 @@
+********** source program **********
+fn main () -> Int {
+var auto: x = 0;
+var auto: y = 1;
+(0 = x, 1 = y) = (0 = 5, 1 = (- 5));
+return (x + y);
+
+}
+********** type checking **********
+--- step exp Int --->
+--- step exp Int --->
+--- step exp auto --->
+--- step exp auto --->
+
+********** type checking complete **********
+fn main () -> Int {
+var auto: x = 0;
+var auto: y = 1;
+(0 = x, 1 = y) = (0 = 5, 1 = (- 5));
+return (x + y);
+}
+********** starting execution **********
+********** initializing globals **********
+--- step exp () --->
+********** calling main function **********
+{
+stack: top{main()<-1>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main() --->
+{
+stack: top{main<-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main --->
+{
+stack: top{fun<main><-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value fun<main> with main()<1>(fun<main>,) --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp () --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value () with main()<2>(fun<main>,(),) --->
+pattern_match((), ())
+{
+stack: main{var auto: x = 0; ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt var auto: x = 0; ...  --->
+{
+stack: main{var auto: x = 0;<-1> :: var auto: y = 1; ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt var auto: x = 0; --->
+{
+stack: main{0<-1> :: var auto: x = 0;<0> :: var auto: y = 1; ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 0 --->
+{
+stack: main{0<-1> :: var auto: x = 0;<0> :: var auto: y = 1; ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 0 with var auto: x = 0;<1>(0,) --->
+{
+stack: main{auto: x<-1> :: var auto: x = 0;<1>(0,) :: var auto: y = 1; ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp auto: x --->
+{
+stack: main{auto<-1> :: auto: x<0> :: var auto: x = 0;<1>(0,) :: var auto: y = 1; ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp auto --->
+{
+stack: main{auto<-1> :: auto: x<0> :: var auto: x = 0;<1>(0,) :: var auto: y = 1; ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value auto with auto: x<1>(auto,) --->
+{
+stack: main{auto: x<-1> :: var auto: x = 0;<1>(0,) :: var auto: y = 1; ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value auto: x with var auto: x = 0;<2>(0,auto: x,) --->
+pattern_match(auto: x, 0)
+{
+stack: main{var auto: y = 1; ... <-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step stmt var auto: y = 1; ...  --->
+{
+stack: main{var auto: y = 1;<-1> :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5)); ... <-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step stmt var auto: y = 1; --->
+{
+stack: main{1<-1> :: var auto: y = 1;<0> :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5)); ... <-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step exp 1 --->
+{
+stack: main{1<-1> :: var auto: y = 1;<0> :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5)); ... <-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- handle value 1 with var auto: y = 1;<1>(1,) --->
+{
+stack: main{auto: y<-1> :: var auto: y = 1;<1>(1,) :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5)); ... <-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step exp auto: y --->
+{
+stack: main{auto<-1> :: auto: y<0> :: var auto: y = 1;<1>(1,) :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5)); ... <-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step exp auto --->
+{
+stack: main{auto<-1> :: auto: y<0> :: var auto: y = 1;<1>(1,) :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5)); ... <-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- handle value auto with auto: y<1>(auto,) --->
+{
+stack: main{auto: y<-1> :: var auto: y = 1;<1>(1,) :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5)); ... <-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- handle value auto: y with var auto: y = 1;<2>(1,auto: y,) --->
+pattern_match(auto: y, 1)
+{
+stack: main{(0 = x, 1 = y) = (0 = 5, 1 = (- 5)); ... <-1>} :: top{}
+heap: fun<main>, 0, 1, 
+env: y: 1, x: 0, main: fun<main>, 
+}
+--- step stmt (0 = x, 1 = y) = (0 = 5, 1 = (- 5)); ...  --->
+{
+stack: main{(0 = x, 1 = y) = (0 = 5, 1 = (- 5));<-1> :: return (x + y);<-1>} :: top{}
+heap: fun<main>, 0, 1, 
+env: y: 1, x: 0, main: fun<main>, 
+}
+--- step stmt (0 = x, 1 = y) = (0 = 5, 1 = (- 5)); --->
+{
+stack: main{(0 = x, 1 = y)<-1> :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5));<0> :: return (x + y);<-1>} :: top{}
+heap: fun<main>, 0, 1, 
+env: y: 1, x: 0, main: fun<main>, 
+}
+--- step lvalue (0 = x, 1 = y) --->
+{
+stack: main{x<-1> :: (0 = x, 1 = y)<0> :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5));<0> :: return (x + y);<-1>} :: top{}
+heap: fun<main>, 0, 1, 
+env: y: 1, x: 0, main: fun<main>, 
+}
+--- step lvalue x --->
+{
+stack: main{ptr<1><-1> :: (0 = x, 1 = y)<0> :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5));<0> :: return (x + y);<-1>} :: top{}
+heap: fun<main>, 0, 1, 
+env: y: 1, x: 0, main: fun<main>, 
+}
+--- handle value ptr<1> with (0 = x, 1 = y)<1>(ptr<1>,) --->
+{
+stack: main{y<-1> :: (0 = x, 1 = y)<1>(ptr<1>,) :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5));<0> :: return (x + y);<-1>} :: top{}
+heap: fun<main>, 0, 1, 
+env: y: 1, x: 0, main: fun<main>, 
+}
+--- step lvalue y --->
+{
+stack: main{ptr<2><-1> :: (0 = x, 1 = y)<1>(ptr<1>,) :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5));<0> :: return (x + y);<-1>} :: top{}
+heap: fun<main>, 0, 1, 
+env: y: 1, x: 0, main: fun<main>, 
+}
+--- handle value ptr<2> with (0 = x, 1 = y)<2>(ptr<1>,ptr<2>,) --->
+{
+stack: main{(0 = ptr<1>@3, 1 = ptr<2>@4)<-1> :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5));<0> :: return (x + y);<-1>} :: top{}
+heap: fun<main>, 0, 1, ptr<1>, ptr<2>, 
+env: y: 1, x: 0, main: fun<main>, 
+}
+--- handle value (0 = ptr<1>@3, 1 = ptr<2>@4) with (0 = x, 1 = y) = (0 = 5, 1 = (- 5));<1>((0 = ptr<1>@3, 1 = ptr<2>@4),) --->
+{
+stack: main{(0 = 5, 1 = (- 5))<-1> :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5));<1>((0 = ptr<1>@3, 1 = ptr<2>@4),) :: return (x + y);<-1>} :: top{}
+heap: fun<main>, 0, 1, ptr<1>, ptr<2>, 
+env: y: 1, x: 0, main: fun<main>, 
+}
+--- step exp (0 = 5, 1 = (- 5)) --->
+{
+stack: main{5<-1> :: (0 = 5, 1 = (- 5))<0> :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5));<1>((0 = ptr<1>@3, 1 = ptr<2>@4),) :: return (x + y);<-1>} :: top{}
+heap: fun<main>, 0, 1, ptr<1>, ptr<2>, 
+env: y: 1, x: 0, main: fun<main>, 
+}
+--- step exp 5 --->
+{
+stack: main{5<-1> :: (0 = 5, 1 = (- 5))<0> :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5));<1>((0 = ptr<1>@3, 1 = ptr<2>@4),) :: return (x + y);<-1>} :: top{}
+heap: fun<main>, 0, 1, ptr<1>, ptr<2>, 
+env: y: 1, x: 0, main: fun<main>, 
+}
+--- handle value 5 with (0 = 5, 1 = (- 5))<1>(5,) --->
+{
+stack: main{(- 5)<-1> :: (0 = 5, 1 = (- 5))<1>(5,) :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5));<1>((0 = ptr<1>@3, 1 = ptr<2>@4),) :: return (x + y);<-1>} :: top{}
+heap: fun<main>, 0, 1, ptr<1>, ptr<2>, 
+env: y: 1, x: 0, main: fun<main>, 
+}
+--- step exp (- 5) --->
+{
+stack: main{5<-1> :: (- 5)<0> :: (0 = 5, 1 = (- 5))<1>(5,) :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5));<1>((0 = ptr<1>@3, 1 = ptr<2>@4),) :: return (x + y);<-1>} :: top{}
+heap: fun<main>, 0, 1, ptr<1>, ptr<2>, 
+env: y: 1, x: 0, main: fun<main>, 
+}
+--- step exp 5 --->
+{
+stack: main{5<-1> :: (- 5)<0> :: (0 = 5, 1 = (- 5))<1>(5,) :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5));<1>((0 = ptr<1>@3, 1 = ptr<2>@4),) :: return (x + y);<-1>} :: top{}
+heap: fun<main>, 0, 1, ptr<1>, ptr<2>, 
+env: y: 1, x: 0, main: fun<main>, 
+}
+--- handle value 5 with (- 5)<1>(5,) --->
+{
+stack: main{-5<-1> :: (0 = 5, 1 = (- 5))<1>(5,) :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5));<1>((0 = ptr<1>@3, 1 = ptr<2>@4),) :: return (x + y);<-1>} :: top{}
+heap: fun<main>, 0, 1, ptr<1>, ptr<2>, 
+env: y: 1, x: 0, main: fun<main>, 
+}
+--- handle value -5 with (0 = 5, 1 = (- 5))<2>(5,-5,) --->
+{
+stack: main{(0 = 5@5, 1 = -5@6)<-1> :: (0 = x, 1 = y) = (0 = 5, 1 = (- 5));<1>((0 = ptr<1>@3, 1 = ptr<2>@4),) :: return (x + y);<-1>} :: top{}
+heap: fun<main>, 0, 1, ptr<1>, ptr<2>, 5, -5, 
+env: y: 1, x: 0, main: fun<main>, 
+}
+--- handle value (0 = 5@5, 1 = -5@6) with (0 = x, 1 = y) = (0 = 5, 1 = (- 5));<2>((0 = ptr<1>@3, 1 = ptr<2>@4),(0 = 5@5, 1 = -5@6),) --->
+{
+stack: main{return (x + y);<-1>} :: top{}
+heap: fun<main>, 5, -5, ptr<1>, ptr<2>, 5, -5, 
+env: y: -5, x: 5, main: fun<main>, 
+}
+--- step stmt return (x + y); --->
+{
+stack: main{(x + y)<-1> :: return (x + y);<0>} :: top{}
+heap: fun<main>, 5, -5, ptr<1>, ptr<2>, 5, -5, 
+env: y: -5, x: 5, main: fun<main>, 
+}
+--- step exp (x + y) --->
+{
+stack: main{x<-1> :: (x + y)<0> :: return (x + y);<0>} :: top{}
+heap: fun<main>, 5, -5, ptr<1>, ptr<2>, 5, -5, 
+env: y: -5, x: 5, main: fun<main>, 
+}
+--- step exp x --->
+{
+stack: main{5<-1> :: (x + y)<0> :: return (x + y);<0>} :: top{}
+heap: fun<main>, 5, -5, ptr<1>, ptr<2>, 5, -5, 
+env: y: -5, x: 5, main: fun<main>, 
+}
+--- handle value 5 with (x + y)<1>(5,) --->
+{
+stack: main{y<-1> :: (x + y)<1>(5,) :: return (x + y);<0>} :: top{}
+heap: fun<main>, 5, -5, ptr<1>, ptr<2>, 5, -5, 
+env: y: -5, x: 5, main: fun<main>, 
+}
+--- step exp y --->
+{
+stack: main{-5<-1> :: (x + y)<1>(5,) :: return (x + y);<0>} :: top{}
+heap: fun<main>, 5, -5, ptr<1>, ptr<2>, 5, -5, 
+env: y: -5, x: 5, main: fun<main>, 
+}
+--- handle value -5 with (x + y)<2>(5,-5,) --->
+{
+stack: main{0<-1> :: return (x + y);<0>} :: top{}
+heap: fun<main>, 5, -5, ptr<1>, ptr<2>, 5, -5, 
+env: y: -5, x: 5, main: fun<main>, 
+}
+--- handle value 0 with return (x + y);<1>(0,) --->
+{
+stack: top{0<-1>}
+heap: fun<main>, !!5, !!-5, ptr<1>, ptr<2>, !!5, !!-5, 
+env: main: fun<main>, 
+}
 result: 0

+ 317 - 0
executable_semantics/testdata/tuple_match.golden

@@ -1 +1,318 @@
+********** source program **********
+fn main () -> Int {
+var auto: t = (0 = 5, 1 = 2);
+match (t) {
+case (0 = auto: a, 1 = auto: b) =>
+return ((a + b) - 7);
+}
+
+}
+********** type checking **********
+--- step exp Int --->
+--- step exp Int --->
+--- step exp auto --->
+--- step exp auto --->
+--- step exp auto --->
+
+********** type checking complete **********
+fn main () -> Int {
+var auto: t = (0 = 5, 1 = 2);
+match (t) {
+case (0 = auto: a, 1 = auto: b) =>
+return ((a + b) - 7);
+}
+}
+********** starting execution **********
+********** initializing globals **********
+--- step exp () --->
+********** calling main function **********
+{
+stack: top{main()<-1>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main() --->
+{
+stack: top{main<-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main --->
+{
+stack: top{fun<main><-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value fun<main> with main()<1>(fun<main>,) --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp () --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value () with main()<2>(fun<main>,(),) --->
+pattern_match((), ())
+{
+stack: main{var auto: t = (0 = 5, 1 = 2); ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt var auto: t = (0 = 5, 1 = 2); ...  --->
+{
+stack: main{var auto: t = (0 = 5, 1 = 2);<-1> :: match (t) {...}<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt var auto: t = (0 = 5, 1 = 2); --->
+{
+stack: main{(0 = 5, 1 = 2)<-1> :: var auto: t = (0 = 5, 1 = 2);<0> :: match (t) {...}<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp (0 = 5, 1 = 2) --->
+{
+stack: main{5<-1> :: (0 = 5, 1 = 2)<0> :: var auto: t = (0 = 5, 1 = 2);<0> :: match (t) {...}<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 5 --->
+{
+stack: main{5<-1> :: (0 = 5, 1 = 2)<0> :: var auto: t = (0 = 5, 1 = 2);<0> :: match (t) {...}<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 5 with (0 = 5, 1 = 2)<1>(5,) --->
+{
+stack: main{2<-1> :: (0 = 5, 1 = 2)<1>(5,) :: var auto: t = (0 = 5, 1 = 2);<0> :: match (t) {...}<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 2 --->
+{
+stack: main{2<-1> :: (0 = 5, 1 = 2)<1>(5,) :: var auto: t = (0 = 5, 1 = 2);<0> :: match (t) {...}<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 2 with (0 = 5, 1 = 2)<2>(5,2,) --->
+{
+stack: main{(0 = 5@1, 1 = 2@2)<-1> :: var auto: t = (0 = 5, 1 = 2);<0> :: match (t) {...}<-1>} :: top{}
+heap: fun<main>, 5, 2, 
+env: main: fun<main>, 
+}
+--- handle value (0 = 5@1, 1 = 2@2) with var auto: t = (0 = 5, 1 = 2);<1>((0 = 5@1, 1 = 2@2),) --->
+{
+stack: main{auto: t<-1> :: var auto: t = (0 = 5, 1 = 2);<1>((0 = 5@1, 1 = 2@2),) :: match (t) {...}<-1>} :: top{}
+heap: fun<main>, 5, 2, 
+env: main: fun<main>, 
+}
+--- step exp auto: t --->
+{
+stack: main{auto<-1> :: auto: t<0> :: var auto: t = (0 = 5, 1 = 2);<1>((0 = 5@1, 1 = 2@2),) :: match (t) {...}<-1>} :: top{}
+heap: fun<main>, 5, 2, 
+env: main: fun<main>, 
+}
+--- step exp auto --->
+{
+stack: main{auto<-1> :: auto: t<0> :: var auto: t = (0 = 5, 1 = 2);<1>((0 = 5@1, 1 = 2@2),) :: match (t) {...}<-1>} :: top{}
+heap: fun<main>, 5, 2, 
+env: main: fun<main>, 
+}
+--- handle value auto with auto: t<1>(auto,) --->
+{
+stack: main{auto: t<-1> :: var auto: t = (0 = 5, 1 = 2);<1>((0 = 5@1, 1 = 2@2),) :: match (t) {...}<-1>} :: top{}
+heap: fun<main>, 5, 2, 
+env: main: fun<main>, 
+}
+--- handle value auto: t with var auto: t = (0 = 5, 1 = 2);<2>((0 = 5@1, 1 = 2@2),auto: t,) --->
+pattern_match(auto: t, (0 = 5@1, 1 = 2@2))
+{
+stack: main{match (t) {...}<-1>} :: top{}
+heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), 
+env: t: (0 = 5@3, 1 = 2@4), main: fun<main>, 
+}
+--- step stmt match (t) {...} --->
+{
+stack: main{t<-1> :: match (t) {...}<0>} :: top{}
+heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), 
+env: t: (0 = 5@3, 1 = 2@4), main: fun<main>, 
+}
+--- step exp t --->
+{
+stack: main{(0 = 5@3, 1 = 2@4)<-1> :: match (t) {...}<0>} :: top{}
+heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), 
+env: t: (0 = 5@3, 1 = 2@4), main: fun<main>, 
+}
+--- handle value (0 = 5@3, 1 = 2@4) with match (t) {...}<1>((0 = 5@3, 1 = 2@4),) --->
+{
+stack: main{(0 = auto: a, 1 = auto: b)<-1> :: match (t) {...}<1>((0 = 5@3, 1 = 2@4),)} :: top{}
+heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), 
+env: t: (0 = 5@3, 1 = 2@4), main: fun<main>, 
+}
+--- step exp (0 = auto: a, 1 = auto: b) --->
+{
+stack: main{auto: a<-1> :: (0 = auto: a, 1 = auto: b)<0> :: match (t) {...}<1>((0 = 5@3, 1 = 2@4),)} :: top{}
+heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), 
+env: t: (0 = 5@3, 1 = 2@4), main: fun<main>, 
+}
+--- step exp auto: a --->
+{
+stack: main{auto<-1> :: auto: a<0> :: (0 = auto: a, 1 = auto: b)<0> :: match (t) {...}<1>((0 = 5@3, 1 = 2@4),)} :: top{}
+heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), 
+env: t: (0 = 5@3, 1 = 2@4), main: fun<main>, 
+}
+--- step exp auto --->
+{
+stack: main{auto<-1> :: auto: a<0> :: (0 = auto: a, 1 = auto: b)<0> :: match (t) {...}<1>((0 = 5@3, 1 = 2@4),)} :: top{}
+heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), 
+env: t: (0 = 5@3, 1 = 2@4), main: fun<main>, 
+}
+--- handle value auto with auto: a<1>(auto,) --->
+{
+stack: main{auto: a<-1> :: (0 = auto: a, 1 = auto: b)<0> :: match (t) {...}<1>((0 = 5@3, 1 = 2@4),)} :: top{}
+heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), 
+env: t: (0 = 5@3, 1 = 2@4), main: fun<main>, 
+}
+--- handle value auto: a with (0 = auto: a, 1 = auto: b)<1>(auto: a,) --->
+{
+stack: main{auto: b<-1> :: (0 = auto: a, 1 = auto: b)<1>(auto: a,) :: match (t) {...}<1>((0 = 5@3, 1 = 2@4),)} :: top{}
+heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), 
+env: t: (0 = 5@3, 1 = 2@4), main: fun<main>, 
+}
+--- step exp auto: b --->
+{
+stack: main{auto<-1> :: auto: b<0> :: (0 = auto: a, 1 = auto: b)<1>(auto: a,) :: match (t) {...}<1>((0 = 5@3, 1 = 2@4),)} :: top{}
+heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), 
+env: t: (0 = 5@3, 1 = 2@4), main: fun<main>, 
+}
+--- step exp auto --->
+{
+stack: main{auto<-1> :: auto: b<0> :: (0 = auto: a, 1 = auto: b)<1>(auto: a,) :: match (t) {...}<1>((0 = 5@3, 1 = 2@4),)} :: top{}
+heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), 
+env: t: (0 = 5@3, 1 = 2@4), main: fun<main>, 
+}
+--- handle value auto with auto: b<1>(auto,) --->
+{
+stack: main{auto: b<-1> :: (0 = auto: a, 1 = auto: b)<1>(auto: a,) :: match (t) {...}<1>((0 = 5@3, 1 = 2@4),)} :: top{}
+heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), 
+env: t: (0 = 5@3, 1 = 2@4), main: fun<main>, 
+}
+--- handle value auto: b with (0 = auto: a, 1 = auto: b)<2>(auto: a,auto: b,) --->
+{
+stack: main{(0 = auto: a@6, 1 = auto: b@7)<-1> :: match (t) {...}<1>((0 = 5@3, 1 = 2@4),)} :: top{}
+heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), auto: a, auto: b, 
+env: t: (0 = 5@3, 1 = 2@4), main: fun<main>, 
+}
+--- handle value (0 = auto: a@6, 1 = auto: b@7) with match (t) {...}<2>((0 = 5@3, 1 = 2@4),(0 = auto: a@6, 1 = auto: b@7),) --->
+pattern_match((0 = auto: a@6, 1 = auto: b@7), (0 = 5@3, 1 = 2@4))
+pattern_match(auto: a, 5)
+pattern_match(auto: b, 2)
+{
+stack: main{return ((a + b) - 7);<-1> :: {
+ ... 
+}
+<0>} :: top{}
+heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), auto: a, auto: b, 5, 2, 
+env: b: 2, a: 5, t: (0 = 5@3, 1 = 2@4), main: fun<main>, 
+}
+--- step stmt return ((a + b) - 7); --->
+{
+stack: main{((a + b) - 7)<-1> :: return ((a + b) - 7);<0> :: {
+ ... 
+}
+<0>} :: top{}
+heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), auto: a, auto: b, 5, 2, 
+env: b: 2, a: 5, t: (0 = 5@3, 1 = 2@4), main: fun<main>, 
+}
+--- step exp ((a + b) - 7) --->
+{
+stack: main{(a + b)<-1> :: ((a + b) - 7)<0> :: return ((a + b) - 7);<0> :: {
+ ... 
+}
+<0>} :: top{}
+heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), auto: a, auto: b, 5, 2, 
+env: b: 2, a: 5, t: (0 = 5@3, 1 = 2@4), main: fun<main>, 
+}
+--- step exp (a + b) --->
+{
+stack: main{a<-1> :: (a + b)<0> :: ((a + b) - 7)<0> :: return ((a + b) - 7);<0> :: {
+ ... 
+}
+<0>} :: top{}
+heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), auto: a, auto: b, 5, 2, 
+env: b: 2, a: 5, t: (0 = 5@3, 1 = 2@4), main: fun<main>, 
+}
+--- step exp a --->
+{
+stack: main{5<-1> :: (a + b)<0> :: ((a + b) - 7)<0> :: return ((a + b) - 7);<0> :: {
+ ... 
+}
+<0>} :: top{}
+heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), auto: a, auto: b, 5, 2, 
+env: b: 2, a: 5, t: (0 = 5@3, 1 = 2@4), main: fun<main>, 
+}
+--- handle value 5 with (a + b)<1>(5,) --->
+{
+stack: main{b<-1> :: (a + b)<1>(5,) :: ((a + b) - 7)<0> :: return ((a + b) - 7);<0> :: {
+ ... 
+}
+<0>} :: top{}
+heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), auto: a, auto: b, 5, 2, 
+env: b: 2, a: 5, t: (0 = 5@3, 1 = 2@4), main: fun<main>, 
+}
+--- step exp b --->
+{
+stack: main{2<-1> :: (a + b)<1>(5,) :: ((a + b) - 7)<0> :: return ((a + b) - 7);<0> :: {
+ ... 
+}
+<0>} :: top{}
+heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), auto: a, auto: b, 5, 2, 
+env: b: 2, a: 5, t: (0 = 5@3, 1 = 2@4), main: fun<main>, 
+}
+--- handle value 2 with (a + b)<2>(5,2,) --->
+{
+stack: main{7<-1> :: ((a + b) - 7)<0> :: return ((a + b) - 7);<0> :: {
+ ... 
+}
+<0>} :: top{}
+heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), auto: a, auto: b, 5, 2, 
+env: b: 2, a: 5, t: (0 = 5@3, 1 = 2@4), main: fun<main>, 
+}
+--- handle value 7 with ((a + b) - 7)<1>(7,) --->
+{
+stack: main{7<-1> :: ((a + b) - 7)<1>(7,) :: return ((a + b) - 7);<0> :: {
+ ... 
+}
+<0>} :: top{}
+heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), auto: a, auto: b, 5, 2, 
+env: b: 2, a: 5, t: (0 = 5@3, 1 = 2@4), main: fun<main>, 
+}
+--- step exp 7 --->
+{
+stack: main{7<-1> :: ((a + b) - 7)<1>(7,) :: return ((a + b) - 7);<0> :: {
+ ... 
+}
+<0>} :: top{}
+heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), auto: a, auto: b, 5, 2, 
+env: b: 2, a: 5, t: (0 = 5@3, 1 = 2@4), main: fun<main>, 
+}
+--- handle value 7 with ((a + b) - 7)<2>(7,7,) --->
+{
+stack: main{0<-1> :: return ((a + b) - 7);<0> :: {
+ ... 
+}
+<0>} :: top{}
+heap: fun<main>, 5, 2, 5, 2, (0 = 5@3, 1 = 2@4), auto: a, auto: b, 5, 2, 
+env: b: 2, a: 5, t: (0 = 5@3, 1 = 2@4), main: fun<main>, 
+}
+--- handle value 0 with return ((a + b) - 7);<1>(0,) --->
+{
+stack: top{0<-1>}
+heap: fun<main>, 5, 2, !!5, !!2, !!(0 = !!5@3, 1 = !!2@4), auto: a, auto: b, !!5, !!2, 
+env: main: fun<main>, 
+}
 result: 0

+ 18 - 0
executable_semantics/testdata/undef1.6c

@@ -0,0 +1,18 @@
+// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+// The behavior of this program is undefined because it tries to
+// access a local variable after its lifetime is over.
+
+fn f() -> Int* {
+  var int: x;
+  x = 0;
+  return &x;
+}
+
+fn main() -> int {
+  var Ptr(int): p;
+  p = f();
+  return *p;
+}

+ 2 - 0
executable_semantics/testdata/undef1.golden

@@ -0,0 +1,2 @@
+executable_semantics/testdata/undef1.6c:8: syntax error
+EXIT CODE: 255

+ 13 - 0
executable_semantics/testdata/undef2.6c

@@ -0,0 +1,13 @@
+// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+// Use-after-free.
+
+fun main() -> Int {
+  var Ptr(int): p;
+  p = malloc(Int);
+  *p = 0;
+  free(p);
+  return *p;
+}

+ 4 - 0
executable_semantics/testdata/undef2.golden

@@ -0,0 +1,4 @@
+********** source program **********
+********** type checking **********
+error, program must contain a function named `main`
+EXIT CODE: 255

+ 463 - 0
executable_semantics/testdata/while1.golden

@@ -1 +1,464 @@
+********** source program **********
+fn main () -> Int {
+var auto: x = 2;
+while ((! (x == 0)))
+x = (x - 1);
+return x;
+
+}
+********** type checking **********
+--- step exp Int --->
+--- step exp Int --->
+--- step exp auto --->
+
+********** type checking complete **********
+fn main () -> Int {
+var auto: x = 2;
+while ((! (x == 0)))
+x = (x - 1);
+return x;
+}
+********** starting execution **********
+********** initializing globals **********
+--- step exp () --->
+********** calling main function **********
+{
+stack: top{main()<-1>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main() --->
+{
+stack: top{main<-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main --->
+{
+stack: top{fun<main><-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value fun<main> with main()<1>(fun<main>,) --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp () --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value () with main()<2>(fun<main>,(),) --->
+pattern_match((), ())
+{
+stack: main{var auto: x = 2; ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt var auto: x = 2; ...  --->
+{
+stack: main{var auto: x = 2;<-1> :: while ((! (x == 0)))
+ ...  ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt var auto: x = 2; --->
+{
+stack: main{2<-1> :: var auto: x = 2;<0> :: while ((! (x == 0)))
+ ...  ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 2 --->
+{
+stack: main{2<-1> :: var auto: x = 2;<0> :: while ((! (x == 0)))
+ ...  ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 2 with var auto: x = 2;<1>(2,) --->
+{
+stack: main{auto: x<-1> :: var auto: x = 2;<1>(2,) :: while ((! (x == 0)))
+ ...  ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp auto: x --->
+{
+stack: main{auto<-1> :: auto: x<0> :: var auto: x = 2;<1>(2,) :: while ((! (x == 0)))
+ ...  ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp auto --->
+{
+stack: main{auto<-1> :: auto: x<0> :: var auto: x = 2;<1>(2,) :: while ((! (x == 0)))
+ ...  ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value auto with auto: x<1>(auto,) --->
+{
+stack: main{auto: x<-1> :: var auto: x = 2;<1>(2,) :: while ((! (x == 0)))
+ ...  ... <-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value auto: x with var auto: x = 2;<2>(2,auto: x,) --->
+pattern_match(auto: x, 2)
+{
+stack: main{while ((! (x == 0)))
+ ...  ... <-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step stmt while ((! (x == 0)))
+ ...  ...  --->
+{
+stack: main{while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step stmt while ((! (x == 0)))
+ ...  --->
+{
+stack: main{(! (x == 0))<-1> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step exp (! (x == 0)) --->
+{
+stack: main{(x == 0)<-1> :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step exp (x == 0) --->
+{
+stack: main{x<-1> :: (x == 0)<0> :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step exp x --->
+{
+stack: main{2<-1> :: (x == 0)<0> :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- handle value 2 with (x == 0)<1>(2,) --->
+{
+stack: main{0<-1> :: (x == 0)<1>(2,) :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step exp 0 --->
+{
+stack: main{0<-1> :: (x == 0)<1>(2,) :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- handle value 0 with (x == 0)<2>(2,0,) --->
+{
+stack: main{false<-1> :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- handle value false with (! (x == 0))<1>(false,) --->
+{
+stack: main{true<-1> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- handle value true with while ((! (x == 0)))
+ ... <1>(true,) --->
+{
+stack: main{x = (x - 1);<-1> :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step stmt x = (x - 1); --->
+{
+stack: main{x<-1> :: x = (x - 1);<0> :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step lvalue x --->
+{
+stack: main{ptr<1><-1> :: x = (x - 1);<0> :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- handle value ptr<1> with x = (x - 1);<1>(ptr<1>,) --->
+{
+stack: main{(x - 1)<-1> :: x = (x - 1);<1>(ptr<1>,) :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step exp (x - 1) --->
+{
+stack: main{x<-1> :: (x - 1)<0> :: x = (x - 1);<1>(ptr<1>,) :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step exp x --->
+{
+stack: main{2<-1> :: (x - 1)<0> :: x = (x - 1);<1>(ptr<1>,) :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- handle value 2 with (x - 1)<1>(2,) --->
+{
+stack: main{1<-1> :: (x - 1)<1>(2,) :: x = (x - 1);<1>(ptr<1>,) :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- step exp 1 --->
+{
+stack: main{1<-1> :: (x - 1)<1>(2,) :: x = (x - 1);<1>(ptr<1>,) :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- handle value 1 with (x - 1)<2>(2,1,) --->
+{
+stack: main{1<-1> :: x = (x - 1);<1>(ptr<1>,) :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 2, 
+env: x: 2, main: fun<main>, 
+}
+--- handle value 1 with x = (x - 1);<2>(ptr<1>,1,) --->
+{
+stack: main{while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step stmt while ((! (x == 0)))
+ ...  --->
+{
+stack: main{(! (x == 0))<-1> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step exp (! (x == 0)) --->
+{
+stack: main{(x == 0)<-1> :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step exp (x == 0) --->
+{
+stack: main{x<-1> :: (x == 0)<0> :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step exp x --->
+{
+stack: main{1<-1> :: (x == 0)<0> :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- handle value 1 with (x == 0)<1>(1,) --->
+{
+stack: main{0<-1> :: (x == 0)<1>(1,) :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step exp 0 --->
+{
+stack: main{0<-1> :: (x == 0)<1>(1,) :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- handle value 0 with (x == 0)<2>(1,0,) --->
+{
+stack: main{false<-1> :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- handle value false with (! (x == 0))<1>(false,) --->
+{
+stack: main{true<-1> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- handle value true with while ((! (x == 0)))
+ ... <1>(true,) --->
+{
+stack: main{x = (x - 1);<-1> :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step stmt x = (x - 1); --->
+{
+stack: main{x<-1> :: x = (x - 1);<0> :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step lvalue x --->
+{
+stack: main{ptr<1><-1> :: x = (x - 1);<0> :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- handle value ptr<1> with x = (x - 1);<1>(ptr<1>,) --->
+{
+stack: main{(x - 1)<-1> :: x = (x - 1);<1>(ptr<1>,) :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step exp (x - 1) --->
+{
+stack: main{x<-1> :: (x - 1)<0> :: x = (x - 1);<1>(ptr<1>,) :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step exp x --->
+{
+stack: main{1<-1> :: (x - 1)<0> :: x = (x - 1);<1>(ptr<1>,) :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- handle value 1 with (x - 1)<1>(1,) --->
+{
+stack: main{1<-1> :: (x - 1)<1>(1,) :: x = (x - 1);<1>(ptr<1>,) :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- step exp 1 --->
+{
+stack: main{1<-1> :: (x - 1)<1>(1,) :: x = (x - 1);<1>(ptr<1>,) :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- handle value 1 with (x - 1)<2>(1,1,) --->
+{
+stack: main{0<-1> :: x = (x - 1);<1>(ptr<1>,) :: while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 1, 
+env: x: 1, main: fun<main>, 
+}
+--- handle value 0 with x = (x - 1);<2>(ptr<1>,0,) --->
+{
+stack: main{while ((! (x == 0)))
+ ... <-1> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step stmt while ((! (x == 0)))
+ ...  --->
+{
+stack: main{(! (x == 0))<-1> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step exp (! (x == 0)) --->
+{
+stack: main{(x == 0)<-1> :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step exp (x == 0) --->
+{
+stack: main{x<-1> :: (x == 0)<0> :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step exp x --->
+{
+stack: main{0<-1> :: (x == 0)<0> :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- handle value 0 with (x == 0)<1>(0,) --->
+{
+stack: main{0<-1> :: (x == 0)<1>(0,) :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step exp 0 --->
+{
+stack: main{0<-1> :: (x == 0)<1>(0,) :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- handle value 0 with (x == 0)<2>(0,0,) --->
+{
+stack: main{true<-1> :: (! (x == 0))<0> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- handle value true with (! (x == 0))<1>(true,) --->
+{
+stack: main{false<-1> :: while ((! (x == 0)))
+ ... <0> :: return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- handle value false with while ((! (x == 0)))
+ ... <1>(false,) --->
+{
+stack: main{return x;<-1>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step stmt return x; --->
+{
+stack: main{x<-1> :: return x;<0>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- step exp x --->
+{
+stack: main{0<-1> :: return x;<0>} :: top{}
+heap: fun<main>, 0, 
+env: x: 0, main: fun<main>, 
+}
+--- handle value 0 with return x;<1>(0,) --->
+{
+stack: top{0<-1>}
+heap: fun<main>, !!0, 
+env: main: fun<main>, 
+}
 result: 0

+ 71 - 0
executable_semantics/testdata/zero.golden

@@ -1 +1,72 @@
+********** source program **********
+fn main () -> Int {
+return 0;
+
+}
+********** type checking **********
+--- step exp Int --->
+--- step exp Int --->
+
+********** type checking complete **********
+fn main () -> Int {
+return 0;
+}
+********** starting execution **********
+********** initializing globals **********
+--- step exp () --->
+********** calling main function **********
+{
+stack: top{main()<-1>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main() --->
+{
+stack: top{main<-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp main --->
+{
+stack: top{fun<main><-1> :: main()<0>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value fun<main> with main()<1>(fun<main>,) --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp () --->
+{
+stack: top{()<-1> :: main()<1>(fun<main>,)}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value () with main()<2>(fun<main>,(),) --->
+pattern_match((), ())
+{
+stack: main{return 0;<-1>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step stmt return 0; --->
+{
+stack: main{0<-1> :: return 0;<0>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- step exp 0 --->
+{
+stack: main{0<-1> :: return 0;<0>} :: top{}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
+--- handle value 0 with return 0;<1>(0,) --->
+{
+stack: top{0<-1>}
+heap: fun<main>, 
+env: main: fun<main>, 
+}
 result: 0