Signature.jrag 5.42 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
import java.util.*;

aspect Signature {  

  public class SignatureLine {
  
    private int indent;
    private byte[] data;
    private String comment;

    public SignatureLine(int indent, byte[] data, String comment) {
      this.indent = indent;
      this.data = data;
      this.comment = comment;
    }

    public int getIndent() {
      return indent;
    }

    public byte[] getData() {
      return data;
    }

    public String getComment() {
      return comment;
    }

  }

  public class SignatureList {

    private int indent;
34
    private final int ver;
Anders Nilsson's avatar
Anders Nilsson committed
35
36
    private ArrayList list = new ArrayList();
    
37
38
39
40
    public SignatureList(int version) {
      this.ver = version; 
    }

Anders Nilsson's avatar
Anders Nilsson committed
41
42
43
44
45
    public void add(byte[] data, String comment) {
      list.add(new SignatureLine(indent, data, comment));
    }

    public void addInt(int value, String comment) {
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
      switch(ver) {
        case 2006:             // Use old encoding with 32 bit integers
	    byte[] data = new byte[4];
	    for (int i = 0 ; i < 4 ; i++) {
	        data[3 - i] = (byte)((value >> (8 * i)) & 0xff);
	    }
	    add(data, comment);
        break;
        case 2013:             // Use new encoding with varints
	    byte[] tmp = new byte[5];
 	    long v = value & 0xffffffff;
            int i, j;
            for (i = 0 ; i == 0 || v != 0 ; i++, v = (v >> 7)) {
		tmp[i] = (byte)(v & 0x7f);
            }
	    byte[] packed = new byte[i];
            for (i = i - 1, j = 0 ; i >= 0 ; i--, j++) {
		packed[j] = (byte)(tmp[i] | (i!=0?0x80:0x00));
            }
	    add(packed, comment);
        break;
        default: 
            throw new RuntimeException("Version = "+ver+". This should never happen.");
      }
Anders Nilsson's avatar
Anders Nilsson committed
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
    }

    public void addString(String value, String comment) {
      addInt(value.length(), comment);
      byte[] data = new byte[value.length()];
      for (int i = 0 ; i < value.length() ; i++) {
        data[i] = (byte)(value.charAt(i) & 0xff);
      }
      add(data, null);
    }

    public int size() {
      return list.size();
    }

    public String getIndent(int i) {
      StringBuffer result = new StringBuffer();
      int indent = ((SignatureLine)list.get(i)).getIndent();
      for (i = 0 ; i < indent ; i++) {
        result.append("  ");
      }
      return result.toString();
    }

    public byte[] getData(int i) {
      return ((SignatureLine)list.get(i)).getData();
    }

    public String getComment(int i) {
      return ((SignatureLine)list.get(i)).getComment();
    }

    public void indent() {
      indent++;
    }

    public void unindent() {
      indent--;
    }

  }

112
113
  public SignatureList Decl.signature(int version) {
    SignatureList result = new SignatureList(version);
Anders Nilsson's avatar
Anders Nilsson committed
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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
    flatSignature(result);
    return result;
  }

  public void ASTNode.flatSignature(SignatureList list) {
    throw new Error(this.getClass().getName() + 
                    ".flatSignature(SignatureList list)" + 
                    " not declared");
  }

  public void TypeDecl.flatSignature(SignatureList list) {
    getType().flatSignature(list);
  }

  public void SampleDecl.flatSignature(SignatureList list) {
    getType().flatSignature(list);
  }

  public void VoidType.flatSignature(SignatureList list) {
    list.addInt(LABCOMM_STRUCT, "void");
    list.addInt(0, null);
  }

  public void PrimType.flatSignature(SignatureList list) {
    list.addInt(getToken(), null);
  }

  public void UserType.flatSignature(SignatureList list) {
    lookupType(getName()).flatSignature(list);
  }

  public void ArrayType.flatSignature(SignatureList list) {
    list.addInt(LABCOMM_ARRAY, signatureComment());
    list.indent();
    list.addInt(getNumExp(), null);
    for (int i = 0 ; i < getNumExp() ; i++) {
      getExp(i).flatSignature(list);
    }
    getType().flatSignature(list);
    list.unindent();
    list.add(null, "}");
  }

  public void StructType.flatSignature(SignatureList list) {
    list.addInt(LABCOMM_STRUCT, "struct { " + getNumField() + " fields");
    list.indent();
    list.addInt(getNumField(), null);
    for (int i = 0 ; i < getNumField() ; i++) {
      getField(i).flatSignature(list);
    }
    list.unindent();
    list.add(null, "}");
  }

  public void Field.flatSignature(SignatureList list) {
    list.addString(getName(), signatureComment());
    getType().flatSignature(list);
  }

  public void IntegerLiteral.flatSignature(SignatureList list) {
    list.addInt(Integer.parseInt(getValue()), null);
  }

  public void VariableSize.flatSignature(SignatureList list) {
    list.addInt(0, null);
  }

  public String ArrayType.signatureComment() {
    StringBuffer result = new StringBuffer("array [");
    for (int i = 0 ; i < getNumExp() ; i++) {
      if (i > 0) {
	result.append(", ");
      }
      result.append(getExp(i).signatureComment());
    }
    result.append("]");
    return result.toString();
  }

  public String ASTNode.signatureComment() {
    throw new Error(this.getClass().getName() + 
                    ".signatureComment()" + 
                    " not declared");
  }

  public String Field.signatureComment() {
    return getType().signatureComment() + " '" + getName() +"'";
  }

  public String PrimType.signatureComment() {
    return getName();
  }

  public String UserType.signatureComment() {
    return getName();
  }

  public String StructType.signatureComment() {
    return "struct";
  }

  public String IntegerLiteral.signatureComment() {
    return getValue();
  }

  public String VariableSize.signatureComment() {
    return "_";
  }

223
}