Skip to content
Snippets Groups Projects
Python_CodeGen.jrag 4.83 KiB
Newer Older
  • Learn to ignore specific revisions
  • Anders Nilsson's avatar
    Anders Nilsson committed
    aspect Python_CodeGenEnv {
    
      // Environment wrapper for Python code generation
      // handles qualid nesting, indentation, file writing and
      // prefix propagation
    
      public class Python_env {
    
        final private class Python_printer {
          
          private boolean newline = true;
          private PrintStream out;
    
          public Python_printer(PrintStream out) {
            this.out = out;
          }
    
          public void print(Python_env env, String s) {
            if (newline) {
              newline = false;
              for (int i = 0 ; i < env.indent ; i++) {
                out.print("    ");
              }
            }
            out.print(s);
          }
    
          public void println(Python_env env, String s) {
            print(env, s);
            out.println();
            newline = true;
          }
    
          public void println(Python_env env) {
            out.println();
            newline = true;
          }
    
        }
    
        private int indent;
        private Python_printer printer;
    
        public Python_env(PrintStream out) {
          this.indent = 0;
          this.printer = new Python_printer(out);
        }
    
        public void indent() {
          indent++;
        }
    
        public void unindent() {
          indent--;
        }
    
        public void print(String s) {
          printer.print(this, s);
        }
    
        public void println(String s) {
          printer.println(this, s);
        }
    
        public void println() {
          printer.println(this);
        }
    
      }
    
    }
    
    aspect Python_CodeGen {
    
      public void Program.Python_gen(PrintStream out, String baseName) {
        Python_env env = new Python_env(out);
        env.println("#!/usr/bin/python");
        env.println("# Auto generated " + baseName);
        env.println();
        env.println("import labcomm");
        env.println();
        Python_genTypes(env);
      }
    
    }
    
    aspect PythonTypes {
      
      public void Program.Python_genTypes(Python_env env) {
        for (int i = 0 ; i < getNumDecl() ; i++) {
          env.println("class " + getDecl(i).getName() + "(object):");
          env.indent();
          getDecl(i).Python_genSignature(env);
          env.unindent();
          env.println();
        }
      }
    
      public void Decl.Python_genSignature(Python_env env) {
        throw new Error(this.getClass().getName() + 
                        ".Python_genSignature(Python_env env)" + 
                        " not declared");
      }
    
      public void TypeDecl.Python_genSignature(Python_env env) {
        env.println("no_signature = labcomm.typedef('" + getName() + "',");
        env.indent();
        getType().Python_genSignature(env);
        env.unindent();
        env.println(")");
      }
    
      public void SampleDecl.Python_genSignature(Python_env env) {
        env.println("signature = labcomm.sample('" + getName() + "', ");
        env.indent();
        getType().Python_genSignature(env);
        env.unindent();
        env.println(")");
      }
    
      public void UserType.Python_genSignature(Python_env env) {
        lookupType(getName()).getType().Python_genSignature(env);
      }
    
      public void Type.Python_genSignature(Python_env env) {
        throw new Error(this.getClass().getName() + 
                        ".Python_genSignature(Python_env env)" + 
                        " not declared");
      }
    
      public void PrimType.Python_genSignature(Python_env env) {
        switch (getToken()) {
          case LABCOMM_BOOLEAN: { env.print("labcomm.BOOLEAN()"); } break;
          case LABCOMM_BYTE: { env.print("labcomm.BYTE()"); } break;
          case LABCOMM_SHORT: { env.print("labcomm.SHORT()"); } break;
          case LABCOMM_INT: { env.print("labcomm.INTEGER()"); } break;
          case LABCOMM_LONG: { env.print("labcomm.LONG()"); } break;
          case LABCOMM_FLOAT: { env.print("labcomm.FLOAT()"); } break;
          case LABCOMM_DOUBLE: { env.print("labcomm.DOUBLE()"); } break;
          case LABCOMM_STRING: { env.print("labcomm.STRING()"); } break;
        }
      }
    
      public void ArrayType.Python_genSignature(Python_env env) {
        env.print("labcomm.array([");
        for (int i = 0 ; i < getNumExp() ; i++) {
          if (i > 0) { env.print(", "); }
          env.print(getExp(i).Python_getValue());
        }
        env.println("],");
        env.indent();
        getType().Python_genSignature(env);
        env.print(")");
        env.unindent();
      }
    
      public void StructType.Python_genSignature(Python_env env) {
        env.println("labcomm.struct([");
        env.indent();
        for (int i = 0 ; i < getNumField() ; i++) {
          if (i > 0) { env.println(","); }
          getField(i).Python_genSignature(env);
        }
        env.print("])");
        env.unindent();
      }
    
      public void VoidType.Python_genSignature(Python_env env) {
        env.println("labcomm.struct([])");
        env.unindent();
      }
    
      public void Field.Python_genSignature(Python_env env) {
        env.print("('" + getName() + "', ");
        getType().Python_genSignature(env);
        env.print(")");
      }
    
      public String Exp.Python_getValue() {
       throw new Error(this.getClass().getName() + 
                        ".Python_getValue()" + 
                        " not declared");
      }
    
      public String IntegerLiteral.Python_getValue() {
        return getValue();
      }
    
      public String VariableSize.Python_getValue() {
        return "0";
      }
    
    }