From 25ad39c4b8fadb5e8da2e4fde0372b89e87bffa9 Mon Sep 17 00:00:00 2001
From: Sven Gestegard Robertz <sven.robertz@cs.lth.se>
Date: Mon, 22 Jun 2015 16:24:11 +0200
Subject: [PATCH] started adding type hierarchy to Java API and unifying that
 with TypeDefParser/ASTbuilder

---
 .gitignore                                    |   1 +
 compiler/2014/ArrayTypeRewrite.jrag           |   8 +-
 compiler/2014/Java_CodeGen.jrag               | 146 +++++++
 compiler/2014/LabComm.ast                     |   2 +-
 compiler/2014/Refactoring.jrag                |   3 +
 examples/user_types/Decoder.java              |   3 +-
 examples/user_types/Makefile                  |  11 +
 examples/user_types/TDDecoder.java            |  26 +-
 examples/user_types/TestDataType.java         |  39 ++
 examples/user_types/test.lc                   |  16 +
 lib/java/Makefile                             |  21 +-
 .../lth/control/labcomm2014/ASTbuilder.java   |  50 ++-
 .../se/lth/control/labcomm2014/DataType.java  | 111 +++++
 .../lth/control/labcomm2014/NameSymbol.java   |  16 +
 .../control/labcomm2014/ParsedSampleDef.java  |  21 +
 .../control/labcomm2014/ParsedTypeDef.java    |  26 ++
 .../control/labcomm2014/SampleDispatcher.java |   6 +-
 .../lth/control/labcomm2014/SampleSymbol.java |  10 +
 .../lth/control/labcomm2014/SigArrayType.java |  52 +++
 .../se/lth/control/labcomm2014/SigField.java  |  35 ++
 .../control/labcomm2014/SigPrimitiveType.java |  16 +
 .../lth/control/labcomm2014/SigSampleDef.java |  21 +
 .../control/labcomm2014/SigStructType.java    |  81 ++++
 .../lth/control/labcomm2014/SigTypeDef.java   |  87 ++++
 .../lth/control/labcomm2014/SigUserType.java  |  22 +
 .../control/labcomm2014/SignatureSymbol.java  |   6 +
 .../labcomm2014/SignatureSymbolVisitor.java   |  17 +
 .../lth/control/labcomm2014/TypeBinding.java  |  21 +
 .../se/lth/control/labcomm2014/TypeDef.java   |  21 +
 .../control/labcomm2014/TypeDefParser.java    | 407 +++---------------
 .../lth/control/labcomm2014/TypeSymbol.java   |  11 +
 .../se/lth/control/labcomm2014/VoidType.java  |  12 +
 32 files changed, 947 insertions(+), 378 deletions(-)
 create mode 100644 examples/user_types/TestDataType.java
 create mode 100644 lib/java/se/lth/control/labcomm2014/DataType.java
 create mode 100644 lib/java/se/lth/control/labcomm2014/NameSymbol.java
 create mode 100644 lib/java/se/lth/control/labcomm2014/ParsedSampleDef.java
 create mode 100644 lib/java/se/lth/control/labcomm2014/ParsedTypeDef.java
 create mode 100644 lib/java/se/lth/control/labcomm2014/SampleSymbol.java
 create mode 100644 lib/java/se/lth/control/labcomm2014/SigArrayType.java
 create mode 100644 lib/java/se/lth/control/labcomm2014/SigField.java
 create mode 100644 lib/java/se/lth/control/labcomm2014/SigPrimitiveType.java
 create mode 100644 lib/java/se/lth/control/labcomm2014/SigSampleDef.java
 create mode 100644 lib/java/se/lth/control/labcomm2014/SigStructType.java
 create mode 100644 lib/java/se/lth/control/labcomm2014/SigTypeDef.java
 create mode 100644 lib/java/se/lth/control/labcomm2014/SigUserType.java
 create mode 100644 lib/java/se/lth/control/labcomm2014/SignatureSymbol.java
 create mode 100644 lib/java/se/lth/control/labcomm2014/SignatureSymbolVisitor.java
 create mode 100644 lib/java/se/lth/control/labcomm2014/TypeSymbol.java
 create mode 100644 lib/java/se/lth/control/labcomm2014/VoidType.java

diff --git a/.gitignore b/.gitignore
index adb9932..6db511e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@
 *.class
 *.o
 *.pyc
+examples/dynamic/gen
diff --git a/compiler/2014/ArrayTypeRewrite.jrag b/compiler/2014/ArrayTypeRewrite.jrag
index 8d83ffb..0310dc8 100644
--- a/compiler/2014/ArrayTypeRewrite.jrag
+++ b/compiler/2014/ArrayTypeRewrite.jrag
@@ -14,28 +14,28 @@ aspect ArrayRewrite {
     to FixedArrayType  { 
       if (getNumDim() == 1) {
         return new FixedArrayType(getDataType(), 
-				  getDim(0).getExpList());
+				  getDim(0));
       } else {
         List l = new List();
         for (int i = 1 ; i < getNumDim() ; i++) {
 	  l.add(getDim(i));
         }
         return new FixedArrayType(new ParseArrayType(getDataType(), l), 
-				  getDim(0).getExpList());
+				  getDim(0));
       }
     }
     when (getDim(0).isVariable()) 
     to VariableArrayType  { 
       if (getNumDim() == 1) {
         return new VariableArrayType(getDataType(), 
-				     getDim(0).getExpList());
+				     getDim(0));
       } else {
         List l = new List();
         for (int i = 1 ; i < getNumDim() ; i++) {
 	  l.add(getDim(i));
         }
         return new VariableArrayType(new ParseArrayType(getDataType(), l), 
-				     getDim(0).getExpList());
+				     getDim(0));
       }
     }
   }
diff --git a/compiler/2014/Java_CodeGen.jrag b/compiler/2014/Java_CodeGen.jrag
index 0faa6c8..a955c60 100644
--- a/compiler/2014/Java_CodeGen.jrag
+++ b/compiler/2014/Java_CodeGen.jrag
@@ -170,6 +170,13 @@ aspect Java_Class {
   private void Decl.Java_declareUserTypeDeps(Java_env env) {
     int numDeps = type_dependencies().size();
     int i=0;
+    env.println("private static DataType dataType;");
+    env.println("static {");
+    env.indent();
+    Java_emitTypeTree(env);
+    env.unindent();
+    env.println("}");
+
     env.println("private Set<SampleDispatcher> typeDependencies = new HashSet<SampleDispatcher>();");
 
     env.println("public Dispatcher(){");
@@ -183,6 +190,12 @@ aspect Java_Class {
     env.unindent();
     env.println("}");
 
+    env.println("public DataType getDataType(){");
+    env.indent();
+    env.println("return dataType;");
+    env.unindent();
+    env.println("}");
+
     env.println("public Iterator<SampleDispatcher> getDependencyIterator(){");
     env.indent();
     env.println("return typeDependencies.iterator();");
@@ -274,6 +287,12 @@ aspect Java_Class {
     env.unindent();
     env.println("}");
     env.println();
+    env.println("public static DataType getDataType(){");
+    env.indent();
+    env.println("return dispatcher.getDataType();");
+    env.unindent();
+    env.println("}");
+    env.println();
   }
 
   public void TypeDecl.Java_emitClass(Java_env env, String pack) {
@@ -284,6 +303,7 @@ aspect Java_Class {
 
       env.println("import se.lth.control.labcomm"+env.verStr+".Constant;");
       env.println("import se.lth.control.labcomm"+env.verStr+".SampleType;");
+      env.println("import se.lth.control.labcomm"+env.verStr+".*;");
 
       if (getDataType().Java_needInstance() || hasDependencies() || isReferenced()) {
           env.println("import se.lth.control.labcomm"+env.verStr+".Encoder;");
@@ -340,6 +360,7 @@ aspect Java_Class {
     env.println("import se.lth.control.labcomm"+env.verStr+".Encoder;");
     env.println("import se.lth.control.labcomm"+env.verStr+".SampleHandler;");
     env.println("import se.lth.control.labcomm"+env.verStr+".Sample;");
+    env.println("import se.lth.control.labcomm"+env.verStr+".*;");
     env.println("import java.util.Set;");
     env.println("import java.util.HashSet;");
     env.println("import java.util.Iterator;");
@@ -451,6 +472,98 @@ aspect Java_Class {
       }
   }
 
+  public void TypeInstance.Java_emitTypeTree(Java_env env, String varName) {
+      getDataType().Java_emitTypeTree(env, varName);
+  }
+
+  public void TypeInstance.Java_emitTypeField(Java_env env, String struct, String name) {
+      getDataType().Java_emitTypeField(env, struct, name);
+  }
+
+  public abstract void DataType.Java_emitTypeTree(Java_env env, String name);
+  public abstract void DataType.Java_emitTypeField(Java_env env, String struct, String name);
+
+  public void PrimType.Java_emitTypeTree(Java_env env, String name) {
+      env.println("// "+name+"="+getName() + " : " + getToken());
+      env.println(name+" = new SigPrimitiveType("+getToken()+");");
+  }
+  public void PrimType.Java_emitTypeField(Java_env env, String struct, String name) {
+      //env.println("// "+struct+".addField("+name+ ", "+getName()+");");
+      env.println(struct+".addField(\""+name+ "\", new SigPrimitiveType("+getToken()+"));");
+  }
+  public void VoidType.Java_emitTypeTree(Java_env env, String name) {
+      env.println(name+"= new VoidType();");
+  }
+  public void VoidType.Java_emitTypeField(Java_env env, String struct, String name) {
+      throw new Error("Void may not be field");
+  }
+  public void ParseArrayType.Java_emitTypeTree(Java_env env, String name) {
+      String elementType = name + "_element";
+      env.println("DataType "+elementType+";");
+      getDataType().Java_emitTypeTree(env, elementType);
+      env.println("// "+name+"=  array("+elementType+");");
+  }
+
+  syn String Exp.dimArrayPart();
+  eq IntegerLiteral.dimArrayPart() = getValue();
+  eq VariableSize.dimArrayPart() = "-1";
+
+  syn String Dim.dimArrayString() {
+      StringBuilder sb = new StringBuilder();
+      sb.append("new int[] {");
+      for(int i=0; i<getNumExp(); i++) {
+            sb.append(getExp(i).dimArrayPart());
+            if(i < getNumExp()-1) {
+                sb.append(", ");
+            }
+      }
+      sb.append("}");
+
+      return sb.toString();
+  }
+
+  public void ArrayType.Java_emitTypeTree(Java_env env, String name) {
+      String elementType = name + "_element";
+      StringBuilder dim = new StringBuilder();
+      dim.append("new int[] {");
+      env.println("DataType "+elementType+";");
+      getDataType().Java_emitTypeTree(env, elementType);
+      env.println(name+"=  new SigArrayType("+elementType+","+getDim().dimArrayString()+");");
+  }
+  public void ParseArrayType.Java_emitTypeField(Java_env env, String struct, String name) {
+      env.println("// field "+name+ " = array("+getDataType().Java_getTypeName()); }
+  public void ArrayType.Java_emitTypeField(Java_env env, String struct, String name) {
+      String innerName = struct+"_"+name;
+      env.println("DataType "+innerName+";");
+      Java_emitTypeTree(env, innerName);
+      env.println(struct+".addField(\""+name+ "\", "+innerName+");");
+      //env.println(struct+".addField(\""+name+ "\", new UserType(\""+getName()+"\"));");
+  }
+  public void StructType.Java_emitTypeTree(Java_env env, String name) {
+      env.println(name+" = new SigStructType();");
+      for(Field f : getFields()) {
+          f.Java_emitTypeField(env, name, f.getName());
+      }
+  }
+  public void StructType.Java_emitTypeField(Java_env env, String struct, String name) {
+      String innerName = struct+"_"+name;
+      env.println("SigStructType "+innerName+" = new SigStructType();");
+      for(Field f : getFields()) {
+          f.Java_emitTypeField(env, innerName, f.getName());
+      }
+      env.println(struct+".addField(\""+name+ "\", "+innerName+");");
+  }
+  public void UserType.Java_emitTypeTree(Java_env env, String name) {
+      env.println(name+" = new SigUserType(\""+getName()+"\");");
+  }
+  public void UserType.Java_emitTypeField(Java_env env, String struct, String name) {
+      env.println(struct+".addField(\""+name+ "\", new SigUserType(\""+getName()+"\"));");
+  }
+
+  public void Decl.Java_emitTypeTree(Java_env env) {
+      getTypeInstance().Java_emitTypeTree(env, "dataType");
+
+  }
   //XXX TODO: refactor: split into a static class ("TypeDefSingleton"?)and a (smaller) dispatcher
   public void Decl.Java_emitDispatcher(Java_env env, boolean isSample) {
     // String genericStr = ""; //env.versionHasMetaData()?"<"+getName()+">":"";
@@ -628,6 +741,39 @@ aspect Java_Class {
   public void VoidType.Java_emitEncoder(Java_env env, String name) {
   }
 
+  public abstract String DataType.Java_getTypeName();
+
+  public String UserType.Java_getTypeName() {
+      return "UserType";
+  }
+  public String VoidType.Java_getTypeName() {
+      return "VoidType";
+  }
+  public String ArrayType.Java_getTypeName() {
+      return "SigArrayType";
+  }
+  public String ParseArrayType.Java_getTypeName() {
+      throw new Error("should not be called");
+      //return "ParseArrayType";
+  }
+  public String StructType.Java_getTypeName() {
+      return "SigStructType";
+  }
+  public String PrimType.Java_getTypeName() {
+    switch (getToken()) {
+      case LABCOMM_BOOLEAN: { return "BooleanType"; }
+      case LABCOMM_BYTE: { return "ByteType"; }
+      case LABCOMM_SHORT: { return "ShortType"; }
+      case LABCOMM_INT: { return "IntType"; }
+      case LABCOMM_LONG: { return "LongType"; }
+      case LABCOMM_FLOAT: { return "FloatType"; }
+      case LABCOMM_DOUBLE: { return "DoubleType"; }
+      case LABCOMM_STRING: { return "StringType"; }
+      case LABCOMM_SAMPLE: { return "SampleRefType"; }
+    }
+    throw new Error( "unknown primitive type ("+getToken()+")");
+  }
+
   public void PrimType.Java_emitEncoder(Java_env env, String name) {
     switch (getToken()) {
       case LABCOMM_BOOLEAN: { env.print("e.encodeBoolean"); } break;
diff --git a/compiler/2014/LabComm.ast b/compiler/2014/LabComm.ast
index 6f3c02c..b1cd4c2 100644
--- a/compiler/2014/LabComm.ast
+++ b/compiler/2014/LabComm.ast
@@ -35,7 +35,7 @@ PrimType           : DataType ::= <Name:String> <Token:int>;
 UserType           : DataType ::= <Name:String>;
 StructType         : DataType ::= Field*;
 ParseArrayType     : DataType ::= DataType Dim*;
-abstract ArrayType : DataType ::= DataType Exp*;
+abstract ArrayType : DataType ::= DataType Dim;
 VariableArrayType  : ArrayType;
 FixedArrayType     : ArrayType;
 
diff --git a/compiler/2014/Refactoring.jrag b/compiler/2014/Refactoring.jrag
index 6e2860b..95f8363 100644
--- a/compiler/2014/Refactoring.jrag
+++ b/compiler/2014/Refactoring.jrag
@@ -1,5 +1,8 @@
 /* Temporary aspect with forwarding methods */
 aspect Refactoring {
+    syn int ArrayType.getNumExp() = getDim().getNumExp();
+    syn Exp ArrayType.getExp(int i) = getDim().getExp(i);
+
     syn String Decl.getName() = getTypeInstance().getName();
     syn DataType Decl.getDataType() = getTypeInstance().getDataType();
 
diff --git a/examples/user_types/Decoder.java b/examples/user_types/Decoder.java
index 708632d..bde5a0a 100644
--- a/examples/user_types/Decoder.java
+++ b/examples/user_types/Decoder.java
@@ -6,6 +6,7 @@ import java.io.IOException;
 import se.lth.control.labcomm2014.DecoderChannel;
 import se.lth.control.labcomm2014.TypeDef;
 import se.lth.control.labcomm2014.TypeDefParser;
+import se.lth.control.labcomm2014.SigTypeDef;
 //import se.lth.control.labcomm2014.TypeBinding;
 
 public class Decoder
@@ -65,7 +66,7 @@ public class Decoder
 //    System.out.println("Got TypeBinding: "+d.getSampleIndex()+" --> "+d.getTypeIndex()+"");
 //  }
 
-  public void onTypeDef(TypeDefParser.ParsedTypeDef d) {
+  public void onTypeDef(SigTypeDef d) {
     System.out.println("ontype_def: ");
     if(d != null) {
         System.out.print((d.isSampleDef()?"sample ":"typedef ")+d);
diff --git a/examples/user_types/Makefile b/examples/user_types/Makefile
index d999b89..92e7353 100644
--- a/examples/user_types/Makefile
+++ b/examples/user_types/Makefile
@@ -4,6 +4,7 @@ LCLJAR=${LCDIR}/lib/java/labcomm2014.jar# the LabComm library
 
 EXECUTABLES=example_encoder example_decoder \
 	    Encoder.class Decoder.class TDDecoder.class \
+	    TestDataType.class \
 	    ExampleEncoder.exe ExampleDecoder.exe
 
 include ${LCDIR}/lib/c/os_compat.mk
@@ -51,6 +52,7 @@ build :
 
 	javac -cp ${LCDIR}/lib/java/labcomm2014.jar:. ${GENDIR}/*.java Encoder.java Decoder.java
 	javac -cp ${LCDIR}/lib/java/labcomm2014.jar:${LCCJAR}:${GENDIR}:. TDDecoder.java
+	javac -cp ${LCDIR}/lib/java/labcomm2014.jar:${LCCJAR}:${GENDIR}:. TestDataType.java
 
 	${CC} ${CFLAGS} ${LDFLAGS} -Wall -Werror -Wno-unused-function \
 	    -I. -I${LCDIR}/lib/c/2014 -L${LCDIR}/lib/c \
@@ -183,6 +185,15 @@ runjastadd: cleanbuild
 	@echo "************ running Java  TypeDefdecoder: *****************"
 	java -cp .:${LCDIR}/lib/java/labcomm2014.jar:${LCCJAR}:${GENDIR} TDDecoder encoded_data_j
 
+rundatatype: cleanbuild
+	@echo
+	@echo "********************************************"
+	@echo "*************** running datatype example ***"
+	@echo "********************************************"
+	@echo
+
+	@java -cp .:${LCDIR}/lib/java/labcomm2014.jar:${GENDIR} TestDataType 
+
 
 clean:
 	rm -rf ${GENDIR}
diff --git a/examples/user_types/TDDecoder.java b/examples/user_types/TDDecoder.java
index 9416ca7..e6c4ddd 100644
--- a/examples/user_types/TDDecoder.java
+++ b/examples/user_types/TDDecoder.java
@@ -6,8 +6,11 @@ import java.io.IOException;
 import se.lth.control.labcomm2014.DecoderChannel;
 import se.lth.control.labcomm2014.TypeDef;
 import se.lth.control.labcomm2014.TypeDefParser;
+import se.lth.control.labcomm2014.SigTypeDef;
+import se.lth.control.labcomm2014.ParsedSampleDef;
 import se.lth.control.labcomm2014.ASTbuilder;
 //import se.lth.control.labcomm2014.TypeBinding;
+import se.lth.control.labcomm2014.DataType;
 
 import se.lth.control.labcomm2014.compiler.Specification;
 import java.io.FileOutputStream;
@@ -75,18 +78,29 @@ public class TDDecoder
 //    System.out.println("Got TypeBinding: "+d.getSampleIndex()+" --> "+d.getTypeIndex()+"");
 //  }
 
-  public void onTypeDef(TypeDefParser.ParsedTypeDef d) {
+  public void onTypeDef(SigTypeDef d) {
     if(d != null && d.isSampleDef()){
         System.out.println("onTypeDef (sample): ");
+        //------------
+        try {
+            System.out.println("==================== DataType ======");
+            DataType.printDataType(System.out, d);
+            System.out.println();
+            System.out.println("==================== end ======");
+        } catch (IOException ioe) {
+            ioe.printStackTrace();
+        }
         ASTbuilder v = new ASTbuilder();
-        Specification p = v.makeSpecification((TypeDefParser.ParsedSampleDef) d);
+        Specification p = v.makeSpecification((ParsedSampleDef) d);
         try {
-                //FileOutputStream f = new FileOutputStream("/tmp/foopp"+d.getName()+".txt");
-                //PrintStream out = new PrintStream(f);
+                FileOutputStream f = new FileOutputStream("/tmp/foopp"+d.getName()+".txt");
+                PrintStream out = new PrintStream(f);
                 p.pp(System.out);
                 //p.C_genC(System.out, new Vector(), "lcname", "prefix", 2014);
-                //p.J_gen(out, "testpackage", 2014);
-                //out.close();
+                p.J_gen(out, "testpackage", 2014);
+                out.close();
+
+
         } catch (Throwable e) {
                 System.err.println("Exception: " + e);
                 e.printStackTrace();
diff --git a/examples/user_types/TestDataType.java b/examples/user_types/TestDataType.java
new file mode 100644
index 0000000..1df8b08
--- /dev/null
+++ b/examples/user_types/TestDataType.java
@@ -0,0 +1,39 @@
+import java.io.PrintStream;
+
+import se.lth.control.labcomm2014.*;
+
+/**
+ * Test data type tree
+ */
+public class TestDataType
+{
+
+  private PrintStream out;
+  public TestDataType(PrintStream out)
+    throws Exception
+  {
+      this.out = out;
+  }
+
+  public void doTest() throws java.io.IOException {
+    twoLines x = new twoLines();
+    DataType.printDataType(out, x.getDispatcher());
+
+    twoStructsAndInt y = new twoStructsAndInt();
+    DataType.printDataType(out, y.getDispatcher());
+
+    theFirstInt z = new theFirstInt();
+    DataType.printDataType(out, z.getDispatcher());
+
+    doavoid a = new doavoid();
+    DataType.printDataType(out, a.getDispatcher());
+
+  }
+
+  public static void main(String[] arg) throws Exception {
+    TestDataType example = new TestDataType(System.out);
+    example.doTest();
+  }
+
+}
+
diff --git a/examples/user_types/test.lc b/examples/user_types/test.lc
index fdc9d54..118546a 100644
--- a/examples/user_types/test.lc
+++ b/examples/user_types/test.lc
@@ -41,3 +41,19 @@ sample struct {
 
 sample anInt theFirstInt;
 sample anInt theSecondInt;
+
+sample struct {
+    struct {
+        int x;
+        int y;
+    } s1;
+
+    struct {
+        int a;
+        int b;
+    } s2;
+
+    int i;
+    double double_array[2,3,_][3][_];
+} twoStructsAndInt;
+
diff --git a/lib/java/Makefile b/lib/java/Makefile
index c9fd3f9..7f47f33 100644
--- a/lib/java/Makefile
+++ b/lib/java/Makefile
@@ -15,8 +15,27 @@ MODULES=Constant \
 	TypeBinding \
 	ASTbuilder \
 	TypeDefParser \
+	SigTypeDef \
+	SigSampleDef \
+	ParsedTypeDef \
+	ParsedSampleDef \
 	Writer \
-	WriterWrapper
+	WriterWrapper \
+	DataType \
+	VoidType \
+	SignatureSymbolVisitor \
+	SignatureSymbol \
+	TypeSymbol \
+	SampleSymbol \
+	NameSymbol \
+	SigPrimitiveType \
+	SigStructType \
+	SigField \
+	SigArrayType \
+	SigUserType 
+
+
+
 
 .PHONY: all
 all: labcomm2014.jar
diff --git a/lib/java/se/lth/control/labcomm2014/ASTbuilder.java b/lib/java/se/lth/control/labcomm2014/ASTbuilder.java
index 07b2d7b..1b93613 100644
--- a/lib/java/se/lth/control/labcomm2014/ASTbuilder.java
+++ b/lib/java/se/lth/control/labcomm2014/ASTbuilder.java
@@ -10,9 +10,6 @@ import java.io.DataInputStream;
 import java.io.IOException;
 import java.io.EOFException;
 
-import se.lth.control.labcomm2014.TypeDef;
-import se.lth.control.labcomm2014.TypeDefParser;
-
 import se.lth.control.labcomm2014.compiler.LabComm;
 import se.lth.control.labcomm2014.compiler.LabCommParser;
 
@@ -40,7 +37,7 @@ import se.lth.control.labcomm2014.compiler.VariableSize;
 /** A class for building a JastAdd AST from the parsed types
  *  created by a TypeDefParser. This class depends on the LabComm compiler.
  */
-public class ASTbuilder implements TypeDefParser.ParsedSymbolVisitor {
+public class ASTbuilder implements SignatureSymbolVisitor {
 
         private LinkedList<DataType> typeStack;
         private LinkedList<Field> fieldStack;
@@ -59,19 +56,19 @@ public class ASTbuilder implements TypeDefParser.ParsedSymbolVisitor {
             }
         }
 
-        public void visit(TypeDefParser.TypeSymbol s){
+        public void visit(TypeSymbol s){
             throw new Error("not implemented? needed?");
 
         }
-        public void visit(TypeDefParser.SampleSymbol s){
+        public void visit(SampleSymbol s){
             throw new Error("not implemented? needed?");
 
         }
-        public void visit(TypeDefParser.NameSymbol s){
+        public void visit(NameSymbol s){
             throw new Error("not implemented? needed?");
         }
 
-        public void visit(TypeDefParser.PrimitiveType t){
+        public void visit(SigPrimitiveType t){
             typeStack.push(new PrimType(t.getName(), t.getTag()));
         }
 
@@ -81,24 +78,24 @@ public class ASTbuilder implements TypeDefParser.ParsedSymbolVisitor {
 //            typeStack.push(new SampleRefType());
 //        }
 
-        public void visit(TypeDefParser.ParsedStructType t){
+        public void visit(SigStructType t){
             if(t.isVoid()) {
                 typeStack.push(new VoidType());
             } else {
                 List<Field> tmpF = new List<Field>();
-                for( TypeDefParser.ParsedField f : t.getFields()) {
+                for( SigField f : t.getFields()) {
                     f.accept(this);
                     tmpF.add(fieldStack.pop());
                 }
                 typeStack.push(new StructType(tmpF));
             }
         }
-        public void visit(TypeDefParser.ParsedField t){
+        public void visit(SigField t){
             t.getType().accept(this);
             fieldStack.push(new Field(new TypeInstance(typeStack.pop(),t.getName())));
 
         }
-        public void visit(TypeDefParser.ArrayType t){
+        public void visit(SigArrayType t){
             boolean isFixed = true;
             List<Exp> dim = new List<Exp>();
             for(int i : t.getIdx()) {
@@ -111,18 +108,18 @@ public class ASTbuilder implements TypeDefParser.ParsedSymbolVisitor {
             }
             t.getType().accept(this);
             if(isFixed) {
-                typeStack.push(new FixedArrayType(typeStack.pop(), dim));
+                typeStack.push(new FixedArrayType(typeStack.pop(), new Dim(dim)));
             } else {
-                typeStack.push(new VariableArrayType(typeStack.pop(), dim));
+                typeStack.push(new VariableArrayType(typeStack.pop(), new Dim(dim)));
             }
 
         }
-        public void visit(TypeDefParser.ParsedUserType t){
+        public void visit(SigUserType t){
             typeStack.push(new UserType(t.getName()));
         }
 
 
-       public Decl makeDecl(TypeDefParser.ParsedTypeDef d) {
+       public Decl makeDecl(SigTypeDef d) {
            d.getType().accept(this);
            Decl result = new TypeDecl(new TypeInstance(typeStack.pop(), d.getName()));
            return result;
@@ -146,7 +143,7 @@ public class ASTbuilder implements TypeDefParser.ParsedSymbolVisitor {
             }
        }
 
-       public Specification makeSpecification(TypeDefParser.ParsedTypeDef d) {
+       public Specification makeSpecification(SigTypeDef d) {
            assertStacksEmpty();
            List<Decl> ds = new List<Decl>();
 
@@ -155,19 +152,26 @@ public class ASTbuilder implements TypeDefParser.ParsedSymbolVisitor {
            return createAndCheckSpecification(ds);
        }
 
-       public Decl makeDecl(TypeDefParser.ParsedSampleDef d) {
+       public Decl makeDecl(SigSampleDef d) {
            d.getType().accept(this);
            Decl result = new SampleDecl(new TypeInstance(typeStack.pop(), d.getName()));
            return result;
        }
-       public Specification makeSpecification(TypeDefParser.ParsedSampleDef d) {
-           assertStacksEmpty();
-           List<Decl> ds = new List<Decl>();
 
-           Iterator<TypeDefParser.ParsedTypeDef> it = d.getDepIterator();
+       private void addAllDeps(List<Decl> ds, SigTypeDef d) {
+           Iterator<SigTypeDef> it = d.getDepIterator();
            while(it.hasNext()){
-               ds.add(makeDecl(it.next()));
+               SigTypeDef dd = it.next();
+               addAllDeps(ds,dd);
+               ds.add(makeDecl(dd));
            }
+       }
+
+       public Specification makeSpecification(ParsedSampleDef d) {
+           assertStacksEmpty();
+           List<Decl> ds = new List<Decl>();
+
+           addAllDeps(ds, d);
 
            ds.add(makeDecl(d));
 
diff --git a/lib/java/se/lth/control/labcomm2014/DataType.java b/lib/java/se/lth/control/labcomm2014/DataType.java
new file mode 100644
index 0000000..360028b
--- /dev/null
+++ b/lib/java/se/lth/control/labcomm2014/DataType.java
@@ -0,0 +1,111 @@
+package se.lth.control.labcomm2014;
+import java.io.PrintStream;
+import java.util.Iterator;
+
+public abstract class DataType implements SignatureSymbol{
+
+    private final String name;
+    private final int typeTag;
+    public static String tagName(int typeTag) {
+        switch(typeTag) {
+            case Constant.BOOLEAN : return "boolean";
+            case Constant.BYTE : return "byte";
+            case Constant.SHORT : return "short";
+            case Constant.INT : return "int";
+            case Constant.LONG : return "long";
+            case Constant.FLOAT : return "float";
+            case Constant.DOUBLE : return "double";
+            case Constant.STRING : return "string";
+            case Constant.SAMPLE : return "sample";
+        }
+        throw new Error("not primitive type tag : " +Integer.toHexString(typeTag));
+    }
+    protected DataType(String name, int typeTag) {
+        this.name = name;
+        this.typeTag = typeTag;
+    }
+
+//    protected DataType(int typeTag) {
+//        this(tagName(typeTag), typeTag);
+//    }
+//
+
+    public String getName() {
+        return name;
+    }
+
+    public int getTag() {
+        return typeTag;
+    }
+    public boolean isArray() {
+        return false;
+    }
+    public boolean isStruct(){
+        return false;
+    }
+    public boolean isUserType(){
+        return false;
+    }
+
+    public void addField(String name, DataType type) {
+        throw new Error("cannot add field to "+getClass().getSimpleName());
+    }
+
+    public final void print(PrintStream out) {
+        print(out, "");
+    }
+
+    public void print(PrintStream out, String indent) {
+        out.print(name);
+    }
+
+
+    private static void printDependencies(PrintStream out, SampleDispatcher sd, String indent) throws java.io.IOException {
+        Iterator<SampleDispatcher> it = sd.getDependencyIterator();
+        if(it.hasNext()) {
+            out.println(indent+"dependencies:");
+        }
+        while(it.hasNext()){
+            SampleDispatcher d = it.next();
+            printDataType(out, d, indent);
+            out.println(indent+"---");
+        }
+    }
+
+    public static void printDataType(PrintStream out, SampleDispatcher sd, String indent) throws java.io.IOException{
+        out.print(indent+"typedef ");
+        sd.getDataType().print(out,indent);
+        out.println(" "+sd.getName()+";");
+        printDependencies(out, sd, "...."+indent);
+    }
+
+    public static void printDataType(PrintStream out, SampleDispatcher sd) throws java.io.IOException{
+        printDataType(out, sd, "");
+    }
+    private static void printDependencies(PrintStream out, SigTypeDef td, String indent) throws java.io.IOException {
+        Iterator<SigTypeDef> it = td.getDepIterator();
+        if(it.hasNext()) {
+            out.println(indent+"dependencies:");
+        }
+        while(it.hasNext()){
+            SigTypeDef d = it.next();
+            printDataType(out, d, indent);
+            out.println(indent+"---");
+        }
+    }
+
+    public static void printDataType(PrintStream out, SigTypeDef d, String indent) throws java.io.IOException{
+        if(d==null) {
+            System.out.println("********* WARNING: printDataType(null)???");
+            return;
+        }
+        out.print(indent+d.defType()+" ");
+        d.getType().print(out,indent);
+        out.println(" "+d.getName()+";");
+        printDependencies(out, d, "...."+indent);
+    }
+    public static void printDataType(PrintStream out, SigTypeDef d) throws java.io.IOException{
+        printDataType(out, d, "");
+    }
+
+}
diff --git a/lib/java/se/lth/control/labcomm2014/NameSymbol.java b/lib/java/se/lth/control/labcomm2014/NameSymbol.java
new file mode 100644
index 0000000..96f9320
--- /dev/null
+++ b/lib/java/se/lth/control/labcomm2014/NameSymbol.java
@@ -0,0 +1,16 @@
+package se.lth.control.labcomm2014;
+public class NameSymbol implements SignatureSymbol {
+    private String name;
+
+    public NameSymbol(String name) {
+        this.name = name;
+    }
+
+    public String toString() {
+        return name;
+    }
+    public void accept(SignatureSymbolVisitor v){
+        v.visit(this);
+    }
+}
+
diff --git a/lib/java/se/lth/control/labcomm2014/ParsedSampleDef.java b/lib/java/se/lth/control/labcomm2014/ParsedSampleDef.java
new file mode 100644
index 0000000..a8d4f85
--- /dev/null
+++ b/lib/java/se/lth/control/labcomm2014/ParsedSampleDef.java
@@ -0,0 +1,21 @@
+package se.lth.control.labcomm2014;
+
+public class ParsedSampleDef extends ParsedTypeDef{
+    int idx;
+
+    ParsedSampleDef(ParsedTypeDef td) {
+        super(td);
+    }
+
+    @Override
+    public boolean isSampleDef() {
+        return true;
+    }
+
+    public String defType() {
+        return "sample";
+    }
+
+}
+
+
diff --git a/lib/java/se/lth/control/labcomm2014/ParsedTypeDef.java b/lib/java/se/lth/control/labcomm2014/ParsedTypeDef.java
new file mode 100644
index 0000000..0ff0bb8
--- /dev/null
+++ b/lib/java/se/lth/control/labcomm2014/ParsedTypeDef.java
@@ -0,0 +1,26 @@
+package se.lth.control.labcomm2014;
+
+public class ParsedTypeDef extends SigTypeDef{
+    private int idx;
+
+    ParsedTypeDef(int idx, String name){
+        super(name);
+        this.idx = idx;
+    }
+
+    ParsedTypeDef(int idx, String name, DataType type) {
+        super(name, type);
+        this.idx = idx;
+    }
+
+    ParsedTypeDef(ParsedTypeDef td) {
+        super(td);
+        this.idx = td.getIndex();
+    }
+
+    int getIndex() {
+        return idx;
+    }
+}
+
+
diff --git a/lib/java/se/lth/control/labcomm2014/SampleDispatcher.java b/lib/java/se/lth/control/labcomm2014/SampleDispatcher.java
index c9f6fe7..733a3fe 100644
--- a/lib/java/se/lth/control/labcomm2014/SampleDispatcher.java
+++ b/lib/java/se/lth/control/labcomm2014/SampleDispatcher.java
@@ -1,5 +1,5 @@
 package se.lth.control.labcomm2014;
-
+import java.util.Iterator;
 import java.io.IOException;
 
 public interface SampleDispatcher <T extends SampleType>{
@@ -31,5 +31,9 @@ public interface SampleDispatcher <T extends SampleType>{
   public byte getTypeDeclTag();
 
   public void registerTypeDeps(Encoder e) throws IOException;
+
+  public Iterator<SampleDispatcher> getDependencyIterator();
+
+  public DataType getDataType();
 }
 
diff --git a/lib/java/se/lth/control/labcomm2014/SampleSymbol.java b/lib/java/se/lth/control/labcomm2014/SampleSymbol.java
new file mode 100644
index 0000000..f8d3d5a
--- /dev/null
+++ b/lib/java/se/lth/control/labcomm2014/SampleSymbol.java
@@ -0,0 +1,10 @@
+package se.lth.control.labcomm2014;
+public class SampleSymbol implements SignatureSymbol {
+    public String toString() {
+        return "sample ";
+    }
+    public void accept(SignatureSymbolVisitor v){
+        v.visit(this);
+    }
+}
+
diff --git a/lib/java/se/lth/control/labcomm2014/SigArrayType.java b/lib/java/se/lth/control/labcomm2014/SigArrayType.java
new file mode 100644
index 0000000..d147793
--- /dev/null
+++ b/lib/java/se/lth/control/labcomm2014/SigArrayType.java
@@ -0,0 +1,52 @@
+package se.lth.control.labcomm2014;
+import java.io.PrintStream;
+
+public class SigArrayType extends DataType {
+    private int idx[];
+    private DataType type;
+
+    public SigArrayType(DataType elementType, int idx[]) {
+        super("array", Constant.ARRAY);
+        this.idx = idx;
+        this.type = elementType;
+    }
+
+    public DataType getType() {
+        return type;
+    }
+
+    public int[] getIdx() {
+        return idx;
+    }
+
+    public boolean isArray() {
+        return true;
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(type.toString());
+        for(int i : idx) {
+            sb.append("["+(i>0 ? i : "_")+"]");
+        }
+        return sb.toString();
+    }
+
+    public void accept(SignatureSymbolVisitor v) {
+        v.visit(this);
+    }
+
+    public void print(PrintStream out, String indent) {
+        type.print(out,indent);
+        out.print("[");
+        for(int i =0; i<idx.length;i++) {
+            int d = idx[i];
+            out.print( (d==-1?"-":d));
+            if(i<idx.length-1) {
+                out.print(", ");
+            }
+        }
+        out.print("]");
+    }
+}
+
diff --git a/lib/java/se/lth/control/labcomm2014/SigField.java b/lib/java/se/lth/control/labcomm2014/SigField.java
new file mode 100644
index 0000000..c67da51
--- /dev/null
+++ b/lib/java/se/lth/control/labcomm2014/SigField.java
@@ -0,0 +1,35 @@
+package se.lth.control.labcomm2014;
+import java.io.PrintStream;
+
+public class SigField implements SignatureSymbol{
+    private DataType type;
+    private String name;
+
+    SigField(String name, DataType type) {
+        this.name = name;
+        this.type = type;
+    }
+
+    public DataType getType() {
+        return type;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String toString() {
+        return type.toString() + " " + name;
+    }
+
+    public void accept(SignatureSymbolVisitor v) {
+        v.visit(this);
+    }
+
+    public void print(PrintStream out, String indent) {
+        type.print(out, indent);
+        out.println(" "+name+";");
+    }
+}
+
+
diff --git a/lib/java/se/lth/control/labcomm2014/SigPrimitiveType.java b/lib/java/se/lth/control/labcomm2014/SigPrimitiveType.java
new file mode 100644
index 0000000..ccfe408
--- /dev/null
+++ b/lib/java/se/lth/control/labcomm2014/SigPrimitiveType.java
@@ -0,0 +1,16 @@
+package se.lth.control.labcomm2014;
+
+public class SigPrimitiveType extends DataType {
+
+    public SigPrimitiveType(int tag) {
+        super(tagName(tag), tag);
+    }
+
+    public void accept(SignatureSymbolVisitor v) {
+        v.visit(this);
+    }
+
+    public String toString() {
+        return getName();}
+}
+
diff --git a/lib/java/se/lth/control/labcomm2014/SigSampleDef.java b/lib/java/se/lth/control/labcomm2014/SigSampleDef.java
new file mode 100644
index 0000000..fa53710
--- /dev/null
+++ b/lib/java/se/lth/control/labcomm2014/SigSampleDef.java
@@ -0,0 +1,21 @@
+package se.lth.control.labcomm2014;
+
+public class SigSampleDef extends SigTypeDef{
+
+
+    SigSampleDef(SigTypeDef td) {
+        super(td.getName(), td.getType());
+    }
+
+    @Override
+    public boolean isSampleDef() {
+        return true;
+    }
+
+    public String defType() {
+        return "sample";
+    }
+
+}
+
+
diff --git a/lib/java/se/lth/control/labcomm2014/SigStructType.java b/lib/java/se/lth/control/labcomm2014/SigStructType.java
new file mode 100644
index 0000000..9b7eae7
--- /dev/null
+++ b/lib/java/se/lth/control/labcomm2014/SigStructType.java
@@ -0,0 +1,81 @@
+package se.lth.control.labcomm2014;
+
+import java.io.PrintStream;
+import java.util.List;
+import java.util.LinkedList;
+import java.util.Iterator;
+
+public class SigStructType extends DataType {
+    private List<SigField> fields;
+
+    SigStructType(int nSigFields) {
+        super("struct", Constant.STRUCT);
+        this.fields = new LinkedList<SigField>();
+    }
+
+    public SigStructType() {
+        this("struct");
+    }
+
+    protected SigStructType(String name) {
+        super(name, Constant.STRUCT);
+        this.fields = new LinkedList<SigField>();
+    }
+
+    public SigField[] getFields() {
+        return fields.toArray(new SigField[0]);
+    }
+
+    public Iterator<SigField> getFieldIterator() {
+        return fields.iterator();
+    }
+
+    public void addField(String name, DataType type) {
+        fields.add(new SigField(name, type));
+    }
+
+    public void addField(SigField f) {
+        fields.add(f);
+    }
+
+    public boolean isStruct() {
+        return true;
+    }
+
+    public boolean isVoid() {
+        return fields.size() == 0;
+    }
+
+    public String toString() {
+        if(isVoid()) { //void type is empty struct
+            return "void";
+        } else {
+            StringBuilder sb = new StringBuilder();
+            sb.append("struct {\n");
+            for(SigField f : fields) {
+                sb.append(f.toString());
+                sb.append(";\n");
+            }
+            sb.append("}");
+            return sb.toString();
+        }
+    }
+
+    public void accept(SignatureSymbolVisitor v) {
+        v.visit(this);
+    }
+    public void print(PrintStream out, String indent) {
+        out.println("struct {");
+        String newIndent=indent+"    ";
+        out.print(newIndent);
+        Iterator<SigField> it = getFieldIterator();
+        while(it.hasNext()) {
+            it.next().print(out, newIndent);
+            if(it.hasNext()) {
+                out.print(newIndent);
+            }
+        }
+        out.print(indent+"}");
+    }
+}
+
diff --git a/lib/java/se/lth/control/labcomm2014/SigTypeDef.java b/lib/java/se/lth/control/labcomm2014/SigTypeDef.java
new file mode 100644
index 0000000..381ebdf
--- /dev/null
+++ b/lib/java/se/lth/control/labcomm2014/SigTypeDef.java
@@ -0,0 +1,87 @@
+package se.lth.control.labcomm2014;
+import java.util.HashSet;
+import java.util.Iterator;
+
+public class SigTypeDef{
+    private String name;
+    private DataType type;
+    protected HashSet<SigTypeDef> deps;
+
+    SigTypeDef(SigTypeDef td) {
+        this(td.getName(), td.getType());
+        this.deps = new HashSet<SigTypeDef>(td.deps);
+    }
+
+    SigTypeDef( String name){
+        this.name = name;
+        this.deps = new HashSet<SigTypeDef>();
+    }
+
+    SigTypeDef(String name, DataType type) {
+        this(name);
+        this.type = type;
+    }
+
+    void addDependency(SigTypeDef d) {
+        deps.add(d);
+    }
+
+    HashSet<SigTypeDef> getDependencies() {
+        return deps;
+    }
+
+    Iterator<SigTypeDef> getDepIterator() {
+        return deps.iterator();
+    }
+    /** To be overridden in SigSampleDef
+    */
+    public boolean isSampleDef() {
+        return false;
+    }
+
+    public String defType() {
+        return "typedef";
+    }
+
+    void setType(DataType type) {
+        this.type = type;
+    }
+
+    public DataType getType() {
+        if(type==null) {
+            System.out.println("******** WARNING! SigTypeDef.getType returning null");
+        }
+        return type;
+    }
+
+    int getIndex() {
+        return 0;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String toString() {
+        return type.toString();
+    }
+
+    public int hashCode() {
+        return name.hashCode();
+    }
+
+    public boolean equals(Object o) {
+        if(! (o instanceof SigTypeDef)){
+            return false;
+        } else {
+            SigTypeDef other = (SigTypeDef) o;
+            return other.getIndex() == getIndex() && other.name.equals(name);
+        }
+    }
+
+    public void accept(SignatureSymbolVisitor v) {
+        type.accept(v);
+    }
+}
+
+
diff --git a/lib/java/se/lth/control/labcomm2014/SigUserType.java b/lib/java/se/lth/control/labcomm2014/SigUserType.java
new file mode 100644
index 0000000..2742749
--- /dev/null
+++ b/lib/java/se/lth/control/labcomm2014/SigUserType.java
@@ -0,0 +1,22 @@
+package se.lth.control.labcomm2014;
+
+public class SigUserType extends DataType {
+
+    public String toString() {
+        return getName();
+    }
+
+    public SigUserType(String name) {
+        super(name, 0);
+    }
+
+    public boolean isUserType() {
+        return true;
+    }
+
+    public void accept(SignatureSymbolVisitor v) {
+        v.visit(this);
+    }
+}
+
+
diff --git a/lib/java/se/lth/control/labcomm2014/SignatureSymbol.java b/lib/java/se/lth/control/labcomm2014/SignatureSymbol.java
new file mode 100644
index 0000000..46f8425
--- /dev/null
+++ b/lib/java/se/lth/control/labcomm2014/SignatureSymbol.java
@@ -0,0 +1,6 @@
+package se.lth.control.labcomm2014;
+
+public interface SignatureSymbol{
+    public void accept(SignatureSymbolVisitor v);
+}
+
diff --git a/lib/java/se/lth/control/labcomm2014/SignatureSymbolVisitor.java b/lib/java/se/lth/control/labcomm2014/SignatureSymbolVisitor.java
new file mode 100644
index 0000000..bb72518
--- /dev/null
+++ b/lib/java/se/lth/control/labcomm2014/SignatureSymbolVisitor.java
@@ -0,0 +1,17 @@
+package se.lth.control.labcomm2014;
+    /* An interface for using Visitor pattern to traverse
+     * the type tree
+     */
+    public interface SignatureSymbolVisitor {
+        void visit(TypeSymbol s);
+        void visit(SampleSymbol s);
+        void visit(NameSymbol s);
+        void visit(SigPrimitiveType t);
+        //sampleRefs are sent as primitive types
+        //Put this back if that is changed to SampleRefType
+        //void visit(SampleRefType t);
+        void visit(SigStructType t);
+        void visit(SigField t);
+        void visit(SigArrayType t);
+        void visit(SigUserType t);
+    }
diff --git a/lib/java/se/lth/control/labcomm2014/TypeBinding.java b/lib/java/se/lth/control/labcomm2014/TypeBinding.java
index 52f1e5b..300834f 100644
--- a/lib/java/se/lth/control/labcomm2014/TypeBinding.java
+++ b/lib/java/se/lth/control/labcomm2014/TypeBinding.java
@@ -3,6 +3,8 @@ package se.lth.control.labcomm2014;
 import java.io.IOException;
 import java.io.ByteArrayOutputStream;
 import java.io.ByteArrayInputStream;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
 import se.lth.control.labcomm2014.Decoder;
 import se.lth.control.labcomm2014.DecoderChannel;
 import se.lth.control.labcomm2014.SampleDispatcher;
@@ -101,6 +103,25 @@ public class TypeBinding implements BuiltinType {
     public boolean hasDependencies() {
         return false;
     }
+
+    public Iterator<SampleDispatcher> getDependencyIterator() {
+        return new Iterator<SampleDispatcher>() {
+            public boolean hasNext() {
+                return false;
+            }
+
+            public SampleDispatcher next() throws NoSuchElementException {
+                throw new NoSuchElementException();
+            }
+            public void remove() throws UnsupportedOperationException {
+                throw new UnsupportedOperationException();
+            }
+        };
+    }
+
+    public DataType getDataType() {
+        throw new Error("not implemented");
+    }
   }
 
   public static void encode(Encoder e, TypeBinding value) throws IOException {
diff --git a/lib/java/se/lth/control/labcomm2014/TypeDef.java b/lib/java/se/lth/control/labcomm2014/TypeDef.java
index f4a608c..02287fc 100644
--- a/lib/java/se/lth/control/labcomm2014/TypeDef.java
+++ b/lib/java/se/lth/control/labcomm2014/TypeDef.java
@@ -3,6 +3,8 @@ package se.lth.control.labcomm2014;
 import java.io.IOException;
 import java.io.ByteArrayOutputStream;
 import java.io.ByteArrayInputStream;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
 import se.lth.control.labcomm2014.Decoder;
 import se.lth.control.labcomm2014.DecoderChannel;
 import se.lth.control.labcomm2014.SampleDispatcher;
@@ -113,6 +115,25 @@ public class TypeDef implements BuiltinType {
     public boolean hasDependencies() {
         return false;
     }
+
+    public Iterator<SampleDispatcher> getDependencyIterator() {
+        return new Iterator<SampleDispatcher>() {
+            public boolean hasNext() {
+                return false;
+            }
+
+            public SampleDispatcher next() throws NoSuchElementException {
+                throw new NoSuchElementException();
+            }
+            public void remove() throws UnsupportedOperationException {
+                throw new UnsupportedOperationException();
+            }
+        };
+    }
+
+    public DataType getDataType() {
+        throw new Error("not implemented");
+    }
   }
 
   public static void encode(Encoder e, TypeDef value) throws IOException {
diff --git a/lib/java/se/lth/control/labcomm2014/TypeDefParser.java b/lib/java/se/lth/control/labcomm2014/TypeDefParser.java
index 4a0cce1..5acca27 100644
--- a/lib/java/se/lth/control/labcomm2014/TypeDefParser.java
+++ b/lib/java/se/lth/control/labcomm2014/TypeDefParser.java
@@ -49,13 +49,14 @@ public class TypeDefParser implements TypeDef.Handler, TypeBinding.Handler {
     }
 
     public interface TypeDefListener {
-        void onTypeDef(ParsedTypeDef d);
+        void onTypeDef(SigTypeDef d);
     }
 
     private HashMap<Integer,TypeDef> typeDefs;
     private HashMap<Integer,Integer> typeBindings;
     private HashSet<TypeDefListener> listeners;
     private LinkedList<ParsedSampleDef> sampleDefs;
+    private HashMap<Integer,ParsedTypeDef> pts;
     private Decoder decoder;
 
     protected TypeDefParser(Decoder d) {
@@ -64,6 +65,7 @@ public class TypeDefParser implements TypeDef.Handler, TypeBinding.Handler {
         typeBindings = new HashMap<Integer,Integer>();
         listeners = new HashSet<TypeDefListener>();
         sampleDefs = new LinkedList<ParsedSampleDef>();
+        pts = new HashMap<Integer,ParsedTypeDef>();
     }
 
     public void addListener(TypeDefListener l) {
@@ -78,6 +80,8 @@ public class TypeDefParser implements TypeDef.Handler, TypeBinding.Handler {
     public void handle_TypeDef(TypeDef d) throws java.io.IOException {
         System.out.println("handle_TypeDef: "+d.getIndex());
         typeDefs.put(d.getIndex(), d);
+        ParsedTypeDef td = parseSignatureTD(d);
+        pts.put(d.getIndex(), td);
     }
 
     public void handle_TypeBinding(TypeBinding d) throws java.io.IOException {
@@ -102,7 +106,7 @@ public class TypeDefParser implements TypeDef.Handler, TypeBinding.Handler {
     private void notifyListener(TypeDefListener l, ParsedTypeDef d) {
         l.onTypeDef(d);
         if(d instanceof ParsedSampleDef) {
-            for(ParsedTypeDef dep : ((ParsedSampleDef)d).getDependencies()) {
+            for(SigTypeDef dep : ((ParsedSampleDef)d).getDependencies()) {
                 //do we want to change ParseTypeDef to have dependencies,
                 //and do recursion here?
                 //if so, do notifyListener(l, dep);
@@ -132,21 +136,21 @@ public class TypeDefParser implements TypeDef.Handler, TypeBinding.Handler {
         return res;
     }
 
-    public LinkedList<ParsedSymbol> symbolify() {
+    public LinkedList<SignatureSymbol> symbolify() {
 
-        LinkedList<ParsedSymbol> result = new LinkedList<ParsedSymbol>();
+        LinkedList<SignatureSymbol> result = new LinkedList<SignatureSymbol>();
 
         Iterator<ParsedSampleDef> sdi = sampleDefIterator();
 
         while(sdi.hasNext()) {
-            ParsedSampleDef sd = sdi.next();
+            SigTypeDef sd = sdi.next();
             result.add(new SampleSymbol());
             result.add(sd.getType());
             result.add(new NameSymbol(sd.getName()));
 
-            Iterator<ParsedTypeDef> di = sd.getDepIterator();
+            Iterator<SigTypeDef> di = sd.getDepIterator();
             while(di.hasNext()) {
-                ParsedTypeDef d = di.next();
+                SigTypeDef d = di.next();
                 result.add(new TypeSymbol());
                 result.add(d.getType());
                 result.add(new NameSymbol(d.getName()));
@@ -156,7 +160,7 @@ public class TypeDefParser implements TypeDef.Handler, TypeBinding.Handler {
     }
 
     public String symbolString() {
-        Iterator<ParsedSymbol> i = symbolify().iterator();
+        Iterator<SignatureSymbol> i = symbolify().iterator();
 
         StringBuilder sb = new StringBuilder();
 
@@ -166,65 +170,9 @@ public class TypeDefParser implements TypeDef.Handler, TypeBinding.Handler {
         return sb.toString();
     }
 
-    /* An interface for using Visitor pattern to traverse
-     * ParsedTypeDefs
-     */
-    public interface ParsedSymbolVisitor {
-        void visit(TypeSymbol s);
-        void visit(SampleSymbol s);
-        void visit(NameSymbol s);
-        void visit(PrimitiveType t);
-        //sampleRefs are sent as primitive types
-        //Put this back if that is changed to SampleRefType
-        //void visit(SampleRefType t);
-        void visit(ParsedStructType t);
-        void visit(ParsedField t);
-        void visit(ArrayType t);
-        void visit(ParsedUserType t);
-    }
-    public abstract class ParsedSymbol{
-        public abstract void accept(ParsedSymbolVisitor v);
-    }
-
-    public class TypeSymbol extends ParsedSymbol {
-        public String toString() {
-            return "typedef ";
-        }
-        public void accept(ParsedSymbolVisitor v){
-            v.visit(this);
-        }
-    }
-
-    public class SampleSymbol extends ParsedSymbol {
-        public String toString() {
-            return "sample ";
-        }
-        public void accept(ParsedSymbolVisitor v){
-            v.visit(this);
-        }
-    }
-
-    public class NameSymbol extends ParsedSymbol {
-        private String name;
-
-        public NameSymbol(String name) {
-            this.name = name;
-        }
-
-        public String toString() {
-            return name;
-        }
-        public void accept(ParsedSymbolVisitor v){
-            v.visit(this);
-        }
-    }
-
-    public abstract class ParsedType extends ParsedSymbol{
-    }
-
 // SampleRefType currently not sent, se above
-//    public class SampleRefType extends ParsedType {
-//        public void accept(ParsedSymbolVisitor v) {
+//    public class SampleRefType extends DataType {
+//        public void accept(SignatureSymbolVisitor v) {
 //            v.visit(this);
 //        }
 //
@@ -232,259 +180,6 @@ public class TypeDefParser implements TypeDef.Handler, TypeBinding.Handler {
 //            return "sample";}
 //    }
 
-    public class PrimitiveType extends ParsedType {
-        private final String name;
-        private int tag;
-
-        String getName() {
-            return name;
-        }
-
-        int getTag() {
-            return tag;
-        }
-        PrimitiveType(int tag) {
-            this.tag = tag;
-            switch(tag) {
-                case Constant.BOOLEAN:
-                    this.name = "boolean";
-                    break;
-                case Constant.BYTE:
-                    this.name = "byte";
-                    break;
-                case Constant.SHORT:
-                    this.name = "short";
-                    break;
-                case Constant.INT:
-                    this.name = "int";
-                    break;
-                case Constant.LONG:
-                    this.name = "long";
-                    break;
-                case Constant.FLOAT:
-                    this.name = "float";
-                    break;
-                case Constant.DOUBLE:
-                    this.name = "double";
-                    break;
-                case Constant.STRING:
-                    this.name = "string";
-                    break;
-                case Constant.SAMPLE:
-                    this.name = "sample";
-                    break;
-                default:
-                    this.name = "??? unknown tag 0x"+Integer.toHexString(tag);
-            }
-        }
-
-        public void accept(ParsedSymbolVisitor v) {
-            v.visit(this);
-        }
-
-        public String toString() {
-            return name;}
-    }
-
-    public class ParsedStructType extends ParsedType {
-        private ParsedField fields[];
-
-        ParsedStructType(int nParsedFields) {
-            this.fields = new ParsedField[nParsedFields];
-        }
-
-        public ParsedField[] getFields() {
-            return fields;
-        }
-
-        void setParsedField(int idx, ParsedField f) {
-            fields[idx] = f;
-        }
-
-        public boolean isVoid() {
-            return fields.length == 0;
-        }
-
-        public String toString() {
-            if(isVoid()) { //void type is empty struct
-                return "void";
-            } else {
-                StringBuilder sb = new StringBuilder();
-                sb.append("struct {\n");
-                for(ParsedField f : fields) {
-                    sb.append(f.toString());
-                    sb.append(";\n");
-                }
-                sb.append("}");
-                return sb.toString();
-            }
-        }
-
-        public void accept(ParsedSymbolVisitor v) {
-            v.visit(this);
-        }
-    }
-
-    public class ParsedField extends ParsedSymbol{
-        private ParsedType type;
-        private String name;
-
-        ParsedField(String name, ParsedType type) {
-            this.name = name;
-            this.type = type;
-        }
-
-        public ParsedType getType() {
-            return type;
-        }
-
-        public String getName() {
-            return name;
-        }
-
-        public String toString() {
-            return type.toString() + " " + name;
-        }
-
-        public void accept(ParsedSymbolVisitor v) {
-            v.visit(this);
-        }
-    }
-
-    public class ArrayType extends ParsedType {
-        private int idx[];
-        private ParsedType type;
-
-        ArrayType(int idx[], ParsedType elementType) {
-            this.idx = idx;
-            this.type = elementType;
-        }
-
-        public ParsedType getType() {
-            return type;
-        }
-
-        public int[] getIdx() {
-            return idx;
-        }
-
-        public String toString() {
-            StringBuilder sb = new StringBuilder();
-            sb.append(type.toString());
-            for(int i : idx) {
-                sb.append("["+(i>0 ? i : "_")+"]");
-            }
-            return sb.toString();
-        }
-
-        public void accept(ParsedSymbolVisitor v) {
-            v.visit(this);
-        }
-    }
-
-    public class ParsedUserType extends ParsedType {
-        private String name;
-        public String getName() {
-            return name;
-        }
-
-        public String toString() {
-            return name;
-        }
-
-        ParsedUserType(String name) {
-            this.name = name;
-        }
-
-        public void accept(ParsedSymbolVisitor v) {
-            v.visit(this);
-        }
-    }
-
-    public class ParsedTypeDef{
-       private int idx;
-       private String name;
-       private ParsedType type;
-
-       ParsedTypeDef(int idx, String name){
-            this.idx = idx;
-            this.name = name;
-       }
-
-       ParsedTypeDef(int idx, String name, ParsedType type) {
-           this(idx, name);
-           this.type = type;
-       }
-
-       /** To be overridden in ParsedSampleDef
-        */
-       public boolean isSampleDef() {
-           return false;
-       }
-
-       void setType(ParsedType type) {
-           this.type = type;
-       }
-
-       ParsedType getType() {
-           return type;
-       }
-
-       int getIndex() {
-           return idx;
-       }
-
-       public String getName() {
-            return name;
-       }
-
-       public String toString() {
-          return type.toString();
-       }
-
-       public int hashCode() {
-           return name.hashCode();
-       }
-
-       public boolean equals(Object o) {
-            if(! (o instanceof ParsedTypeDef)){
-                return false;
-            } else {
-                ParsedTypeDef other = (ParsedTypeDef) o;
-                return other.idx == idx && other.name.equals(name);
-            }
-       }
-
-       public void accept(ParsedSymbolVisitor v) {
-            type.accept(v);
-       }
-    }
-
-    public class ParsedSampleDef extends ParsedTypeDef{
-
-        private HashSet<ParsedTypeDef> deps;
-        ParsedSampleDef(ParsedTypeDef td) {
-            super(td.getIndex(), td.getName(), td.getType());
-            this.deps = new HashSet<ParsedTypeDef>();
-        }
-
-        void addDependency(ParsedTypeDef d) {
-            deps.add(d);
-        }
-
-        @Override
-        public boolean isSampleDef() {
-            return true;
-        }
-        private HashSet<ParsedTypeDef> getDependencies() {
-            return deps;
-        }
-
-        Iterator<ParsedTypeDef> getDepIterator() {
-            return deps.iterator();
-        }
-    }
-
     private class ParserState {
         private ByteArrayInputStream bis;
         private DataInputStream in;
@@ -548,6 +243,14 @@ public class TypeDefParser implements TypeDef.Handler, TypeBinding.Handler {
             return current.getName();
         }
 
+        void addTypeUse(int tag) {
+            SigTypeDef td = pts.get(tag);
+            if(td != null) {
+                currentParsed.addDependency(td);
+            } else {
+                System.out.println("******* WARNING: TypeDefParser:addTypeUse ("+tag+"): null???");
+            }
+        }
         /** return name, (if any, or "") for now */
         String decodeIntentions() throws IOException {
             int n = decodePacked32() & 0xffffffff;
@@ -605,63 +308,76 @@ public class TypeDefParser implements TypeDef.Handler, TypeBinding.Handler {
         }
     }
 
+    private ParsedTypeDef parseSignatureTD(TypeDef td) throws IOException{
+        return parseSignatureTD(td, new ParserState(td));
+    }
+
+    private ParsedTypeDef parseSignatureTD(TypeDef td, ParserState s) throws IOException{
+
+        ParsedTypeDef result=null;
+        s.popType();
+        result = parseTypeDef(s);
+        return result;
+    }
+
     public ParsedSampleDef parseSignature(TypeDef td) throws IOException{
         ParserState s = new ParserState(td);
 
         ParsedSampleDef result=null;
         try {
-            s.popType();
-            result = parseSampleTypeDef(s);
-            while(s.moreTypes()) {
-                s.popType();
-                result.addDependency(parseTypeDef(s));
-            }
+            result = new ParsedSampleDef(parseSignatureTD(td,s));
+
+//            while(s.moreTypes()) {
+//                s.popType();
+//                result.addDependency(parseTypeDef(s));
+//            }
         } catch(java.io.EOFException ex) {
             System.out.println("EOF: self_binding");
         }
         return result;
     }
 
-    private ArrayType  parseArray(ParserState in) throws IOException {
+    private SigArrayType  parseArray(ParserState in) throws IOException {
         int numIdx = in.decodePacked32();
         int idx[] = new int[numIdx];
         for(int i=0; i<numIdx; i++){
             idx[i] = in.decodePacked32();
         }
         int type = in.decodePacked32();
-        ParsedType elementType = lookupType(type, in);
-        ArrayType result = new ArrayType(idx, elementType);
+        DataType elementType = lookupType(type, in);
+        SigArrayType result = new SigArrayType(elementType, idx);
         for(int i=0; i<numIdx; i++){
             idx[i] = in.decodePacked32();
         }
         return result;
     }
 
-    private ParsedStructType parseStruct(ParserState in) throws IOException {
-        int numParsedFields = in.decodePacked32();
-        ParsedStructType result = new ParsedStructType(numParsedFields);
-        for(int i=0; i<numParsedFields; i++) {
-            result.setParsedField(i, parseParsedField(in));
+    private SigStructType parseStruct(ParserState in) throws IOException {
+        int numSigFields = in.decodePacked32();
+        SigStructType result = new SigStructType(numSigFields);
+        for(int i=0; i<numSigFields; i++) {
+            result.addField(parseSigField(in));
         }
         return result;
     }
 
-    private ParsedField parseParsedField(ParserState in) throws IOException {
+    private SigField parseSigField(ParserState in) throws IOException {
         String name = in.decodeIntentions();
-        return new ParsedField(name, parseType(in, false));
+        return new SigField(name, parseType(in, false));
     }
 
-    private ParsedType lookupType(int tag, ParserState in) {
-        ParsedType result;
+    private DataType lookupType(int tag, ParserState in) {
+        DataType result;
         if(tag >= Constant.FIRST_USER_INDEX) {
                 TypeDef td = typeDefs.get(tag);
-                result = new ParsedUserType(td.getName());
+                result = new SigUserType(td.getName());
+                in.addTypeUse(tag);
                 in.pushType(tag);
 // sampleRefs are sent as primitive types, see above
 //        } else if(tag == Constant.SAMPLE) {
 //                result = new SampleRefType();
         } else {
-                result = new PrimitiveType(tag);
+                result = new SigPrimitiveType(tag);
         }
         return result;
     }
@@ -673,13 +389,22 @@ public class TypeDefParser implements TypeDef.Handler, TypeBinding.Handler {
     private ParsedTypeDef parseTypeDef(ParserState in) throws IOException {
         return parseTypeDef(in, false);
     }
+
+    private void addParsedTypeDef(ParsedTypeDef td) {
+        int idx = td.getIndex();
+        if(idx>=0x40) {
+            pts.put(idx, td);
+        }
+    }
+
     private ParsedTypeDef parseTypeDef(ParserState in, boolean parseIntentions) throws IOException {
         ParsedTypeDef result = in.newTypeDef();
         result.setType(parseType(in, false));
+        addParsedTypeDef(result);
         return result;
     }
 
-    private ParsedType parseType(ParserState in, boolean parseIntentions) throws IOException {
+    private DataType parseType(ParserState in, boolean parseIntentions) throws IOException {
         if(parseIntentions) {
             String intentions = in.decodeIntentions();
             if(intentions.length()>0) {
@@ -692,7 +417,7 @@ public class TypeDefParser implements TypeDef.Handler, TypeBinding.Handler {
         }
 
         int tag = in.decodePacked32();
-        ParsedType result = null;
+        DataType result = null;
         switch(tag) {
             case 0:
                 System.out.println("SELF");
diff --git a/lib/java/se/lth/control/labcomm2014/TypeSymbol.java b/lib/java/se/lth/control/labcomm2014/TypeSymbol.java
new file mode 100644
index 0000000..f607183
--- /dev/null
+++ b/lib/java/se/lth/control/labcomm2014/TypeSymbol.java
@@ -0,0 +1,11 @@
+package se.lth.control.labcomm2014;
+
+public class TypeSymbol implements SignatureSymbol {
+    public String toString() {
+        return "typedef ";
+    }
+    public void accept(SignatureSymbolVisitor v){
+        v.visit(this);
+    }
+}
+
diff --git a/lib/java/se/lth/control/labcomm2014/VoidType.java b/lib/java/se/lth/control/labcomm2014/VoidType.java
new file mode 100644
index 0000000..c7c607e
--- /dev/null
+++ b/lib/java/se/lth/control/labcomm2014/VoidType.java
@@ -0,0 +1,12 @@
+package se.lth.control.labcomm2014;
+import java.io.PrintStream;
+
+public class VoidType extends SigStructType{
+    public VoidType() {
+        super("void");
+    }
+
+    public void print(PrintStream out, String indent) {
+        out.print("void");
+    }
+}
-- 
GitLab