Python_CodeGen.jrag 4.83 KB
Newer Older
Anders Nilsson's avatar
Anders Nilsson committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
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";
  }

}