Skip to content
Snippets Groups Projects
Forked from Anders Blomdell / LabComm
588 commits behind the upstream repository.
Python_CodeGen.jrag 4.83 KiB
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";
  }

}