From 9b17c42e21d466129415725bd379a10183a90b8f Mon Sep 17 00:00:00 2001
From: Philippe Suter <philippe.suter@gmail.com>
Date: Mon, 10 Dec 2012 18:17:57 +0100
Subject: [PATCH] Support for LetTuple in CodeGen.

---
 src/main/java/leon/codegen/runtime/Tuple.java  |  4 ++--
 .../scala/leon/codegen/CodeGeneration.scala    | 18 ++++++++++++++++++
 .../regression/codegen/purescala/Prog003.scala |  6 ++++++
 3 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/src/main/java/leon/codegen/runtime/Tuple.java b/src/main/java/leon/codegen/runtime/Tuple.java
index 93ed14032..c8f46923b 100644
--- a/src/main/java/leon/codegen/runtime/Tuple.java
+++ b/src/main/java/leon/codegen/runtime/Tuple.java
@@ -7,8 +7,8 @@ public final class Tuple {
   private Object[] elements;
 
   // You may think that using varargs here would show less of the internals,
-  // however the bytecode to generate is exactly the same, so let's reflect
-  // the reality instead.
+  // however the bytecode is exactly the same, so let's reflect the reality
+  // instead.
   public Tuple(int arity, Object[] elements) {
     this.arity = arity;
     this.elements = Arrays.copyOf(elements, elements.length);
diff --git a/src/main/scala/leon/codegen/CodeGeneration.scala b/src/main/scala/leon/codegen/CodeGeneration.scala
index 422e17778..b585b5b1c 100644
--- a/src/main/scala/leon/codegen/CodeGeneration.scala
+++ b/src/main/scala/leon/codegen/CodeGeneration.scala
@@ -79,6 +79,24 @@ object CodeGeneration {
         ch << instr
         mkExpr(b, ch)(env.withVars(Map(i -> slot)))
 
+      case LetTuple(is,d,b) =>
+        mkExpr(d, ch) // the tuple
+        var count = 0
+        val withSlots = is.map(i => (i, ch.getFreshVar))
+        for((i,s) <- withSlots) {
+          ch << DUP
+          ch << Ldc(count)
+          ch << InvokeVirtual(TupleClass, "get", "(I)Ljava/lang/Object;")
+          mkUnbox(i.getType, ch)
+          val instr = i.getType match {
+            case Int32Type | BooleanType => IStore(s)
+            case _ => AStore(s)
+          }
+          ch << instr
+          count += 1
+        }
+        mkExpr(b, ch)(env.withVars(withSlots.toMap))
+
       case IntLiteral(v) =>
         ch << Ldc(v)
 
diff --git a/src/test/resources/regression/codegen/purescala/Prog003.scala b/src/test/resources/regression/codegen/purescala/Prog003.scala
index 69236b64e..829583057 100644
--- a/src/test/resources/regression/codegen/purescala/Prog003.scala
+++ b/src/test/resources/regression/codegen/purescala/Prog003.scala
@@ -5,4 +5,10 @@ object Prog003 {
   def fst(t : (Int,Boolean)) : Int = t._1
 
   def snd(t : (Int,Boolean)) : Boolean = t._2
+
+  def swap(t : (Int,Boolean)) : (Boolean,Int) = {
+    val (i,b) = t
+
+    (b,i)
+  }
 }
-- 
GitLab