Skip to content
Snippets Groups Projects
Select Git revision
  • labcomm2014_tc31
  • labcomm2014
  • master default
  • js
  • java_dyn_msg_dec
  • anders.blomdell
  • typeref
  • pragma
  • compiler-refactoring
  • labcomm2013
  • v2014.1
  • v2014.0
  • v2013.0
13 results

CS_CodeGen.jrag

Blame
  • Forked from Anders Blomdell / LabComm
    312 commits behind the upstream repository.
    CS_CodeGen.jrag 20.01 KiB
    import java.io.*;
    import java.util.*;
    
    aspect CS_CodeGenEnv {
    
      // Environment wrapper for CS-code generation
      // handles indentation, file writing, 
    
      public class CS_env {
    
        public final int version;
        private int indent;
        private int depth;
        private CS_printer printer;
        private HashMap unique = new HashMap();
    
        final private static class CS_printer {
          
          private boolean newline = true;
          private File file;
          private PrintStream out;
          private IOException exception;
          
    
          public CS_printer(File f) {
      	file = f;
            File parentFile = f.getParentFile();
            if(parentFile != null) {
                parentFile.mkdirs();
            }
          }
    
         public CS_printer(PrintStream out) {
            this.out = out;
          }
    
          public void close() throws IOException {
    	if (out != null) {
      	  out.close();
            }
    	if (exception != null) {
    	  throw exception;
            }
          }
    
          public PrintStream getPrintStream() {
    	return(out);
          }
    
          public void checkOpen() {
    	if (out == null && exception == null) {
              try {
        	    out = new PrintStream(new FileOutputStream(file));
              } catch (IOException e) {
    	    exception = e;
              }
            }
          }
    
          public void print(CS_env env, String s) {
    	checkOpen();
            if (newline) {
              newline = false;
              for (int i = 0 ; i < env.indent ; i++) {
                out.print("  ");
              }
            }
            out.print(s);
          }
    
          public void println(CS_env env, String s) {
    	checkOpen();
            print(env, s);
            out.println();
            newline = true;
          }
        }
    
        private CS_env(int indent, CS_printer printer, int version) {
          this.version = version;
          this.indent = indent;
          this.printer = printer;
        }
    
        public CS_env(File f, int version) {
          this(0, new CS_printer(f), version);
        }
    
        public CS_env(PrintStream out, int version) {
          this(0, new CS_printer(out), version);
        }
    
        public void close() throws IOException {
          printer.close();
        }
    
        public PrintStream getPrintStream() {
          return printer.getPrintStream();
        }
        public void indent(int amount) {
          indent += amount;
        }
    
        public void indent() {
          indent(1);
        }
    
        public void unindent(int amount) {
          indent -= amount;
        }
    
        public void unindent() {
          unindent(1);
        }
    
        public void print(String s) {
          printer.print(this, s);
        }
    
        public void println(String s) {
          printer.println(this, s);
        }
    
        public void println() {
          printer.println(this, "");
        }
    
        public int getDepth() {
          return depth;
        }
    
        public String print_for_begin(String limit) {
          print("for (int i_" + depth + " = 0 ; ");
          print("i_" + depth + " < " + limit + " ; ");
          println("i_" + depth + "++) {");
          indent();
          depth++;
          return "i_" + (depth - 1);
        }
    
        public void print_for_end() {
          depth--;
          unindent();
          println("}");
        }
    
        public void print_block_begin() {
          println("{");
          indent();
        }
    
        public void print_block_end() {
          unindent();
          println("}");
        }
    
        public String getUnique(Object o) {
          String result = (String)unique.get(o);
          if (result == null) {
       	result = "_" + (unique.size() + 1) + "_";
          }
          unique.put(o, result);
          return result;
        }
    
      }
    
    }
    
    aspect CS_StructName {
    
      inh int Decl.CS_Depth();
      inh int Type.CS_Depth();
      eq Program.getDecl(int i).CS_Depth() = 0;
      eq StructType.getField(int i).CS_Depth() = CS_Depth() + 1;
    
      inh String Type.CS_structName();
      eq Program.getDecl(int i).CS_structName() = getDecl(i).getName();
      eq StructType.getField(int i).CS_structName() {
        if (CS_Depth() == 0) {
          return "struct_" + getField(i).getName();
        } else {
          return CS_structName() + "_" + getField(i).getName();
        }
      }
    }
    
    aspect CS_Void {
    
      syn boolean Decl.CS_isVoid() = getType().CS_isVoid();
      syn boolean Type.CS_isVoid() = false;
      syn boolean VoidType.CS_isVoid() = true;
    
    }
    
    aspect CS_CodeGen {
    
      public void Program.CS_gen(String file, 
    			     String namespace, int version) throws IOException {
        // Registration class
        CS_env env = new CS_env(new File(file), version);
        if (namespace != null && namespace.length() > 0) {
          env.println("namespace " + namespace + "{");
          env.indent();
        }
        env.println("using System;");
        env.println("using se.lth.control.labcomm;");
        for (int i = 0; i < getNumDecl(); i++) {
          Decl d = getDecl(i);
          try {
            d.CS_emitClass(env);
          } catch (Error e) {
    	System.err.println(d.getName());
    	throw e;
          }
        }
        if (namespace != null && namespace.length() > 0) {
          env.unindent();
          env.println("}");
        }
      }
    
    }
    
    aspect CS_Register {
    
      public void Program.CS_emitTypeRegister(CS_env env) {
        /*
        env.println("static void register(LabCommChannel c) {");
        env.indent();
        for (int i = 0; i < getNumDecl(); i++) {
          getDecl(i).CS_emitTypeRegister(env);
        }
        env.unindent();
        env.println("}");
    */
    
      }
    
      public void Decl.CS_emitTypeRegister(CS_env env) {
        throw new Error(this.getClass().getName() + 
    		    ".CS_emitTypeRegister(CS_env env)" + 
    		    " not declared");
      }
    
      public void SampleDecl.CS_emitTypeRegister(CS_env env) {
        env.println(getName() + ".register(c);");
      }
    
      public void TypeDecl.CS_emitTypeRegister(CS_env env) {
        // TODO
      }
    
    }
    
    aspect CS_Class {
    
      public void Decl.CS_emitClass(CS_env env) {
        throw new Error(this.getClass().getName() + 
    		    ".CS_emitClass(CS_env env)" + 
    		    " not declared");
      }
    
      public void TypeDecl.CS_emitClass(CS_env env) {
        if (getType().CS_needInstance()) {
          // Hackish prettyprint preamble
          env.println("/* ");
          pp(env.getPrintStream());
          env.println("*/");
          env.println();
          env.println("public class " + getName() + " : LabCommType {");
          env.println();
          env.indent();
          getType().CS_emitInstance(env);
          CS_emitEncoder(env);
          CS_emitDecoder(env);
          env.unindent();
          env.println("}");
        }
      }
    
      public void SampleDecl.CS_emitClass(CS_env env) {
        env.println("/* ");
        pp(env.getPrintStream());
        env.println("*/");
        env.println();
        env.println("public class " + getName() + " : LabCommSample {");
        env.println();
        env.indent();
        getType().CS_emitInstance(env);
        env.println("public interface Handler : LabCommHandler {");
        env.print("  void handle(");
        if (!isVoid()) {
          getType().CS_emitType(env);
          env.print(" value");
        }
        env.println(");");
        env.println("}");
        env.println();
        env.println("public static void register(LabCommDecoder d, Handler h) {");
        env.indent();
        env.println("d.register(new Dispatcher(), h);");
        env.unindent();
        env.println("}");
        env.println();
    
        env.println("public static void register(LabCommEncoder e) {");
        env.indent();
        env.println("e.register(new Dispatcher());");
        env.unindent();
        env.println("}");
        env.println(); 
    
        env.println("private class Dispatcher : LabCommDispatcher {");
        env.indent();
        env.println(); 
        env.println("public Type getSampleClass() {");
        env.indent();
        env.println("return typeof(" + getName() + ");");
        env.unindent();
        env.println("}");
        env.println(); 
        env.println("public String getName() {");
        env.indent();
        env.println("return \"" + getName() + "\";");
        env.unindent();
        env.println("}");
        env.println(); 
        env.println("public byte[] getSignature() {");
        env.indent();
        env.println("return signature;");
        env.unindent();
        env.println("}");
        env.println(); 
        env.println("public void decodeAndHandle(LabCommDecoder d, LabCommHandler h) {");
        env.indent();
        if (isVoid()) {
          env.println(getName() + ".decode(d);");
          env.println("((Handler)h).handle();"); 
        } else {
          env.println("((Handler)h).handle(" + getName() + ".decode(d));"); 
        }
        env.unindent();
        env.println("}");
        env.println("");
        env.unindent();
        env.println("}");
        env.println("");
    
        CS_emitEncoder(env);
        CS_emitDecoder(env);
        env.println("private static byte[] signature = new byte[] {");
        env.indent();
        SignatureList signature = signature(env.version);
        for (int i = 0 ; i < signature.size() ; i++) {
          String comment = signature.getComment(i);
          if (comment != null) {
            env.println(signature.getIndent(i) + "// " + comment);
          }
          byte[] data = signature.getData(i);
          if (data != null) {
            env.print(signature.getIndent(i));
            for (int j = 0 ; j < data.length ; j++) {
    	  env.print(data[j] + ", ");
            }
            env.println();
          }
        }
        env.unindent();
        env.println("};");
        env.unindent();
        env.println();
        env.println("}");
      }
    
      public void TypeDecl.CS_emitEncoder(CS_env env) {
        env.print("public static void encode(LabCommEncoder e");
        if (!isVoid()) {
          env.print(", ");
          getType().CS_emitType(env);
          env.print(" value");
        }
        env.println(") {");
        env.indent();
        getType().CS_emitEncoder(env, "value");
        env.unindent();
        env.println("}");
        env.println();
      }
    
      public void SampleDecl.CS_emitEncoder(CS_env env) {
        env.print("public static void encode(LabCommEncoder e");
        if (!isVoid()) {
          env.print(", ");
          getType().CS_emitType(env);
          env.print(" value");
        }
        env.println(") {");
        env.indent();
        env.println("e.begin(typeof(" + getName() + "));");
        getType().CS_emitEncoder(env, "value");
        env.println("e.end(typeof(" + getName() + "));");
        env.unindent();
        env.println("}");
        env.println();
      }
    
      public void Type.CS_emitEncoder(CS_env env, String name) {
        throw new Error(this.getClass().getName() + 
    		    ".CS_emitEncoder(CS_env env, String name)" + 
    		    " not declared");
      }
    
      public void VoidType.CS_emitEncoder(CS_env env, String name) {
      }
    
      public void PrimType.CS_emitEncoder(CS_env env, String name) {
        switch (getToken()) {
          case LABCOMM_BOOLEAN: { env.print("e.encodeBoolean"); } break;
          case LABCOMM_BYTE: { env.print("e.encodeByte"); } break;
          case LABCOMM_SHORT: { env.print("e.encodeShort"); } break;
          case LABCOMM_INT: { env.print("e.encodeInt"); } break;
          case LABCOMM_LONG: { env.print("e.encodeLong"); } break;
          case LABCOMM_FLOAT: { env.print("e.encodeFloat"); } break;
          case LABCOMM_DOUBLE: { env.print("e.encodeDouble"); } break;
          case LABCOMM_STRING: { env.print("e.encodeString"); } break;
        }
        env.println("(" + name + ");");
      }
    
      public void ArrayType.CS_emitEncoder(CS_env env, String name) {
        env.print_block_begin();
        int baseDepth = env.getDepth();
        for (int i = 0 ; i < getNumExp() ; i++) {
          String limit = getExp(i).CS_emitEncoder(env, 
    					      name + ".GetLength(" + i + ")");
          env.println("int i_" + (baseDepth + i) + "_max = " + limit + ";");
        }
        String index = null;
        for (int i = 0 ; i < getNumExp() ; i++) {
          String limit = "i_" + (baseDepth + i) + "_max";
          if (i == 0) {
            index = env.print_for_begin(limit);
          } else {
            index = index + ", " + env.print_for_begin(limit);
          }
        }
        getType().CS_emitEncoder(env, name + "[" + index + "]");
        for (int i = 0 ; i < getNumExp() ; i++) {
          env.print_for_end();
        }
        env.print_block_end();
      }
      
      public String Exp.CS_emitEncoder(CS_env env, String name) {
        throw new Error(this.getClass().getName() + 
    		    ".CS_emitEncoder(CS_env env, String name)" + 
    		    " not declared");
      }
    
      public String IntegerLiteral.CS_emitEncoder(CS_env env, String name) {
        return getValue();
      }
    
      public String VariableSize.CS_emitEncoder(CS_env env, String name) {
        env.println("e.encodePacked32(" + name + ");");
        return name;
      }
    
      public void StructType.CS_emitEncoder(CS_env env, String name) {
        for (int i = 0 ; i < getNumField() ; i++) {
          Field f = getField(i);
          f.getType().CS_emitEncoder(env, name + "." + f.getName());
        }
      }
    
      public void UserType.CS_emitEncoder(CS_env env, String name) {
        if (CS_needInstance()) {
          env.println(getName() + ".encode(e, " + name + ");");
        } else {
          decl().getType().CS_emitEncoder(env, name);
        }
      }
    
      public void Decl.CS_emitDecoder(CS_env env) {
        env.print("public static ");
        getType().CS_emitType(env);
        env.println(" decode(LabCommDecoder d) {");
        env.indent();
        if (!isVoid()) {
          getType().CS_emitType(env);
          env.println(" result;");
          getType().CS_emitDecoder(env, "result");
          env.println("return result;");
        }
        env.unindent();
        env.println("}");
        env.println();
      }
    
      public void Type.CS_emitDecoder(CS_env env, String name) {
        throw new Error(this.getClass().getName() + 
    		    ".CS_emitDecoder(CS_env env, String name)" + 
    		    " not declared");
      }
    
      public void VoidType.CS_emitDecoder(CS_env env, String name) {
      }
    
      public void PrimType.CS_emitDecoder(CS_env env, String name) {
        env.print(name + " = ");
        switch (getToken()) {
          case LABCOMM_BOOLEAN: { env.println("d.decodeBoolean();"); } break;
          case LABCOMM_BYTE: { env.println("d.decodeByte();"); } break;
          case LABCOMM_SHORT: { env.println("d.decodeShort();"); } break;
          case LABCOMM_INT: { env.println("d.decodeInt();"); } break;
          case LABCOMM_LONG: { env.println("d.decodeLong();"); } break;
          case LABCOMM_FLOAT: { env.println("d.decodeFloat();"); } break;
          case LABCOMM_DOUBLE: { env.println("d.decodeDouble();"); } break;
          case LABCOMM_STRING: { env.println("d.decodeString();"); } break;
        }
      }
    
      public void ArrayType.CS_emitDecoder(CS_env env, String name) {
        env.println("{");
        env.indent();
        int baseDepth = env.getDepth();
        for (int i = 0 ; i < getNumExp() ; i++) {
          env.print("int i_" + (baseDepth + i) + "_max = ");
          getExp(i).CS_emitDecoder(env);
          env.println(";");
        }
        env.print(name + " = new "); 
        getType().CS_emitTypePrefix(env);
        env.print("[");
        for (int i = 0 ; i < getNumExp() ; i++) {
          if (i > 0) {
    	env.print(", ");
          }
          env.print("i_" + (baseDepth + i) + "_max");
        }
        env.print("]");
        getType().CS_emitTypeSuffix(env);
        env.println(";");
        
        String index = null;
        for (int i = 0 ; i < getNumExp() ; i++) {
          String limit = "i_" + (baseDepth + i) + "_max";
          if (i == 0) {
            index = env.print_for_begin(limit);
          } else {
            index = index + ", " + env.print_for_begin(limit);
          }
        }
        getType().CS_emitDecoder(env, name + "[" + index + "]");
        for (int i = 0 ; i < getNumExp() ; i++) {
          env.print_for_end();
        }
        env.unindent();
        env.println("}");
      }
    
      public void Exp.CS_emitDecoder(CS_env env) {
        throw new Error(this.getClass().getName() + 
    		    ".CS_emitDecoder(CS_env env)" + 
    		    " not declared");
      }
    
      public void IntegerLiteral.CS_emitDecoder(CS_env env) {
        env.print(getValue());
      }
    
      public void VariableSize.CS_emitDecoder(CS_env env) {
        env.print("d.decodePacked32()");
      }
    
      public void StructType.CS_emitDecoder(CS_env env, String name) {
        env.print(name + " = new ");
        CS_emitType(env);
        env.println("();");
        for (int i = 0 ; i < getNumField() ; i++) {
          Field f = getField(i);
          f.getType().CS_emitDecoder(env, name + "." + f.getName());
        }
      }
    
      public void UserType.CS_emitDecoder(CS_env env, String name) {
        if (CS_needInstance()) {
          env.println(name + " = " + getName() + ".decode(d);");
        } else {
          decl().getType().CS_emitDecoder(env, name);
        }
      }
    
      public void Type.CS_emitTypePrefix(CS_env env) {
        throw new Error(this.getClass().getName() + 
    		    ".CS_emitTypePrefix(CS_env env)" + 
    		    " not declared");
      }
    
      public void PrimType.CS_emitTypePrefix(CS_env env) {
        switch (getToken()) {
          case LABCOMM_STRING: { env.print("String"); } break;
          default: { env.print(getName()); } break;
        }
      }
    
      public void UserType.CS_emitTypePrefix(CS_env env) {
        if (CS_needInstance()) {
          env.print(getName());
        } else {
          decl().getType().CS_emitTypePrefix(env);
        } 
      }
    
      public void ArrayType.CS_emitTypePrefix(CS_env env){
        getType().CS_emitTypePrefix(env);
      }
    
      public void StructType.CS_emitTypePrefix(CS_env env){
        env.print(CS_structName());
      }
    
      public void Type.CS_emitTypeSuffix(CS_env env) {
      }
    
      public void UserType.CS_emitTypeSuffix(CS_env env) {
        if (! CS_needInstance()) {
          decl().getType().CS_emitTypeSuffix(env);
        } 
      }
    
      public void ArrayType.CS_emitTypeSuffix(CS_env env){
        env.print("[");
        for (int i = 1 ; i < getNumExp() ; i++) {
          env.print(",");
        }
        env.print("]");
        getType().CS_emitTypeSuffix(env);
      }
    
      public boolean Type.CS_needInstance() {
        throw new Error(this.getClass().getName() + 
    		    ".CS_needInstance()" + 
    		    " not declared");
      }
    
      public boolean VoidType.CS_needInstance() {
        return false;
      }
    
      public boolean PrimType.CS_needInstance() {
        return false;
      }
    
      public boolean UserType.CS_needInstance() {
        return decl().getType().CS_needInstance();
      }
    
      public boolean StructType.CS_needInstance() {
        return true;
      }
    
      public boolean ArrayType.CS_needInstance() {
        return getType().CS_needInstance();
      }
    
      public boolean Type.CS_isPrimitive() {
        return false;
      }
    
      public boolean PrimType.CS_isPrimitive() {
        return true;
      }
    
      public void Type.CS_emitInstance(CS_env env) {
        throw new Error(this.getClass().getName() + 
    		    ".CS_emitInstance(CS_env env)" + 
    		    " not declared");
      }
    
      public void VoidType.CS_emitInstance(CS_env env) {
      }
    
      public void PrimType.CS_emitInstance(CS_env env) {
      }
    
      public void ArrayType.CS_emitInstance(CS_env env) {
        getType().CS_emitInstance(env);
      }
    
      public void StructType.CS_emitInstance(CS_env env) {
        if (CS_Depth() > 0) {
          env.println("public class " + CS_structName() + " {");
          env.indent();
        }
        for (int i = 0 ; i < getNumField() ; i++) {
          getField(i).getType().CS_emitInstance(env);
        }
        for (int i = 0 ; i < getNumField() ; i++) {
          getField(i).CS_emitField(env);
        }
        if (CS_Depth() > 0) {
          env.unindent();
          env.println("}");
        }
        env.println();
      }
    
      public void UserType.CS_emitInstance(CS_env env) {
      }
    
      public void Field.CS_emitField(CS_env env) {
        env.print("public ");
        getType().CS_emitType(env);
        env.println(" " + getName() + ";");    
      }
    
      public void Type.CS_emitType(CS_env env) {
        throw new Error(this.getClass().getName() + 
    		    ".CS_emitType(CS_env env)" + 
    		    " not declared");
      }
    
      public void VoidType.CS_emitType(CS_env env) {
        env.print("void");
      }
    
      public void PrimType.CS_emitType(CS_env env) {
        switch (getToken()) {
          case LABCOMM_STRING: { env.print("String"); } break;
          case LABCOMM_BOOLEAN: { env.print("bool"); } break;
          default: { env.print(getName()); } break;
        }
      }
    
      public void UserType.CS_emitType(CS_env env) {
        decl().getType().CS_emitType(env);
      }
    
      public void ArrayType.CS_emitType(CS_env env){
        getType().CS_emitTypePrefix(env);
        env.print("[");
        for (int i = 1 ; i < getNumExp() ; i++) {
          env.print(",");
        }
        env.print("]");
        getType().CS_emitTypeSuffix(env);
      }
    
      public void StructType.CS_emitType(CS_env env){
        env.print(CS_structName());
      }
    
    }
    
    aspect CS_Info {
    
      public void Program.CS_info(PrintStream out, String namespace, int version) {
        CS_env env = new CS_env(out, version);
        if (namespace == null) {
          namespace = ""; 
        } else {
          namespace = namespace + "."; 
        }
        for (int i = 0; i < getNumDecl(); i++) {
          getDecl(i).CS_info(env, namespace);
        }
      }
    
      public void Decl.CS_info(CS_env env, String namespace) {
        throw new Error(this.getClass().getName() + 
    		    ".CS_info(CS_env env)" + 
    		    " not declared");
      }
    
      public void TypeDecl.CS_info(CS_env env, String namespace) {
        env.print(";C#;typedef;" + namespace + getName() + ";");
        getType().CS_emitType(env) ;
        env.print(";not_applicable_for_C#");
        env.println();
      }
    
      public void SampleDecl.CS_info(CS_env env, String namespace) {
        env.print(";C#;sample;" + namespace + getName() + ";");
        getType().CS_emitType(env);
        env.print(";not_applicable_for_C#");
        env.println();
      }
    
    }