RAPID_CodeGen.jrag 12 KB
Newer Older
1
2
3

aspect RAPID_env {
	public class RAPID_env {
4
                public final int version;
5
6
7
8
9
10
		private String prefix;
		private StringBuilder types;
		private StringBuilder constants;
		private StringBuilder procedures;
		private PrintStream ps;

11
		public RAPID_env(PrintStream ps, String prefix, int version)
12
		{
13
			this.version = version;
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
			this.types = new StringBuilder();
			this.constants = new StringBuilder();
			this.procedures = new StringBuilder();
			this.prefix = prefix;
			this.ps = ps;
		}

		public String prefix() { return this.prefix; }

		public String addRecord(String name, java.util.List<String> components)
		{
			String recordName = this.prefix + "_" + name;
			types.append("\tRECORD " + recordName);
			types.append("\n");
			for (String c : components) {
				types.append("\t\t" + c + "\n");
			}
			types.append("\tENDRECORD");
			types.append("\n\n");
			return recordName;
		}

		public void addConstant(String type, String name, String value) {
			this.constants.append("\tLOCAL CONST " + type + " " + name +
					" := " + value + ";\n");
		}

		public void addProc(String name, java.util.List<String> params,
					java.util.List<String> stmts)
		{
			this.procedures.append("\tLOCAL PROC " + name + "(");
			for (int i = 0; i < params.size(); i++) {
				this.procedures.append(params.get(i));
				if (i < params.size() - 1) {
					this.procedures.append(", ");
				}
			}
			this.procedures.append(")\n");
			for (String stmt : stmts) {
				this.procedures.append("\t\t" + stmt + "\n");
			}
			this.procedures.append("\tERROR\n\t\tRAISE ;\n\tENDPROC\n\n");
		}

		public void flush()
		{
			ps.println("MODULE " + prefix() + "(SYSMODULE)");
			ps.println();
			ps.print(types.toString());
			ps.println();
			ps.println("\tLOCAL CONST string prefix:=\"" + this.prefix + "\";");
			ps.print(constants.toString());
			ps.println();
			ps.print(procedures.toString());
			ps.println();
			ps.print("ENDMODULE");
		}
	}
}

aspect RAPID_CodeGen {

	public void ASTNode.RAPID_gen(RAPID_env env) {
		throw new UnsupportedOperationException();
	}

80
	public void Specification.RAPID_gen(String file, String prefix, int version)
81
82
83
			throws IOException
	{
		PrintStream ps = new PrintStream(new FileOutputStream(new File(file)));
84
		RAPID_env env = new RAPID_env(ps, prefix, version);
85
86
87
		RAPID_gen(env);
	}

88
	public void Specification.RAPID_gen(RAPID_env env)
89
90
91
92
93
94
95
96
	{
		for (int i = 0; i < getNumDecl(); i++) {
			getDecl(i).RAPID_gen(env);
		}
		env.flush();
	}

	public void Decl.RAPID_gen(RAPID_env env) {
97
		throw new UnsupportedOperationException("RAPID code generation (currently) does not support "+getClass().getSimpleName());
98
99
	}

100
101
102
103
104
105
106
107
108
	public void TypeDecl.RAPID_gen(RAPID_env env) {
		System.out.println("***WARNING! TypeDecl.RapidGen(.) a NOP after sig reorganization.");
		System.out.println("            (Tell a developer to) remove this warning when tested");
	}

	public void Decl.RAPID_emitFlatSignature(RAPID_env env, String sig_len_name, String sig_name) {
		System.out.println("***WARNING! Code not tested after reorganization of signatures.");
		System.out.println("            (Tell a developer to) remove this warning when tested");
		SignatureList sig = flatSignature(env.version);
109
110
111
112
113
		StringBuilder sb = new StringBuilder();
		sb.append("[");
		byte[] d = null;
		int sig_len = 0;
		for (int i = 0; i < sig.size(); i++) {
114
			d = sig.getData(i, env.version);
115
116
117
118
119
120
121
122
123
			for (int j = 0; d != null && j < d.length; j++) {
				sb.append(d[j] + ",");
				sig_len++;
			}
		}
		sb.delete(sb.length() - 1, sb.length());
		sb.append("]");
		env.addConstant("num", sig_len_name, "" + sig_len);
		env.addConstant("byte", sig_name + "{" + sig_len_name + "}",
124
125
126
127
128
		sb.toString());
	} 

	public void SampleDecl.RAPID_gen(RAPID_env env) {
		// Add type declarations
129
		String fullName = getDataType().RAPID_AddType(env, getName());
130
131
132
133
134
135
		// Add signature constants
		String sig_len_name = "signature_len_" + getName();
		String sig_name = "signature_" + getName();

		RAPID_emitFlatSignature(env, sig_len_name, sig_name);

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
		// Add decode procedures
		ArrayList<String> params = new ArrayList<String>();
		ArrayList<String> stmts = new ArrayList<String>();
		params.add("VAR LabComm_Decoder_Sample s");
		params.add("string handler");
		stmts.add("s.prefix := prefix;");
		stmts.add("s.name := \"" + getName() + "\";");
		stmts.add("s.handler := handler;");
		env.addProc("Dec_Reg_" + getName(), params, stmts);	

		params.clear();
		stmts.clear();
		params.add("VAR LabComm_Decoder_Sample s");
		params.add("VAR rawbytes sig");
		params.add("num user_id");
		stmts.add("VAR byte tmp_sig{" + sig_len_name + "};");
		stmts.add("IF RawBytesLen(sig)<>" + sig_len_name + " THEN");
		stmts.add("\tRETURN;");
		stmts.add("ENDIF");
		stmts.add("FOR i FROM 1 TO " + sig_len_name + " DO");
		stmts.add("\tUnpackRawBytes sig, i, tmp_sig{i}, \\Hex1;");
		stmts.add("ENDFOR");
		stmts.add("IF tmp_sig<>" + sig_name + " THEN");
		stmts.add("\tRETURN;");
		stmts.add("ENDIF");
		stmts.add("s.user_id := user_id;");
		env.addProc("Reg_If_Signature_Of_" + getName(), params, stmts);

		params.clear();
		stmts.clear();
		params.add("VAR Decoder d");
		params.add("VAR LabComm_Stream st");
		params.add("VAR LabComm_Decoder_Sample s");
		stmts.add("VAR " + fullName + " tmp;");
170
		getDataType().RAPID_AddDecodeInstr(env, stmts, "tmp", "st");
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
		stmts.add("% s.handler % tmp;");
		env.addProc("Decode_And_Handle_" + getName(), params, stmts);

		params.clear();
		stmts.clear();
		params.add("VAR Encoder e");
		params.add("VAR LabComm_Stream st");
		params.add("VAR LabComm_Encoder_Sample s");
		stmts.add("s.prefix := prefix;");
		stmts.add("s.name := \"" + getName() + "\";");
		stmts.add("Encoder_Register_Sample e, st, s;");
		env.addProc("Enc_Reg_" + getName(), params, stmts);

		params.clear();
		stmts.clear();
		params.add("VAR Encoder e");
		params.add("VAR LabComm_Stream s");
		stmts.add("VAR rawbytes buffer;");
		stmts.add("FOR i FROM 1 TO " + sig_len_name + " DO");
		stmts.add("\tPackRawBytes " + sig_name +
					"{i}, buffer, \\Network, i, \\Hex1;");
		stmts.add("ENDFOR");
		stmts.add("SocketSend s.soc, \\RawData:=buffer, \\NoOfBytes:=" +
					sig_len_name + ";");
		env.addProc("Encode_Signature_" + getName(), params, stmts);

		params.clear();
		stmts.clear();
		params.add("VAR Encoder e");
		params.add("VAR LabComm_Stream st");
		params.add("VAR LabComm_Encoder_Sample s");
		params.add("VAR " + fullName + " val");
		stmts.add("Encode_Packed st, s.user_id;");
204
		getDataType().RAPID_AddEncodeInstr(env, stmts, "val", "st");
205
206
207
		env.addProc("Encode_" + getName(), params, stmts);
	}

208
	public String DataType.RAPID_AddType(RAPID_env env, String name) {
209
		throw new UnsupportedOperationException("RAPID code generation does (currently) not support "+getClass().getSimpleName());
210
211
212
213
214
215
216
	}

	public String StructType.RAPID_AddType(RAPID_env env, String name) {
		ArrayList<String> components = new ArrayList<String>();
		for (int i = 0; i < getNumField(); i++) {
			Field f = getField(i);
			components.add(
217
					f.getDataType().RAPID_AddType(env, name + "_" + f.getName()) +
218
219
220
221
222
223
224
					" " + f.getName() + ";");
		}
		String typeName = env.addRecord(name, components);
		return typeName;
	}

	public String FixedArrayType.RAPID_AddType(RAPID_env env, String name) {
225
		String typeName = getDataType().RAPID_AddType(env, name + "_e");
226
		if (getNumExp() > 1) {
227
			throw new UnsupportedOperationException("RAPID generation only (currently) supports one-dimensional arrays");
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
		}
		ArrayList<String> components = new ArrayList<String>();
		for (int i = 1; i <= getExp(0).RAPID_getValue(); i++) {
			components.add(typeName + " e" + i + ";");
		}
		String completeName = env.addRecord("list_" + name, components);
		return completeName;
	}

	public String PrimType.RAPID_AddType(RAPID_env env, String name) {
		if (getToken() == LABCOMM_SHORT ||
			getToken() == LABCOMM_FLOAT ||
			getToken() == LABCOMM_INT) {
			return "num";
		} else if (getToken() == LABCOMM_LONG) {
			return "dnum";
		} else if (getToken() == LABCOMM_STRING) {
			return "string";
		} else if (getToken() == LABCOMM_BOOLEAN) {
			return "bool";
		} else if (getToken() == LABCOMM_BYTE) {
			return "byte";
		}
251
		throw new UnsupportedOperationException("RAPID code generation does not (currently) support "+getName());
252
253
	}

254
	public void DataType.RAPID_AddDecodeInstr(RAPID_env env,
255
256
			java.util.List<String> instrs,
			String var_name, String stream_name) {
257
		throw new UnsupportedOperationException("RAPID code generation does not (currently) support "+getClass().getSimpleName());
258
259
260
261
262
263
	}

	public void StructType.RAPID_AddDecodeInstr(RAPID_env env,
			java.util.List<String> instrs,
			String var_name, String stream_name) {
		for (int i = 0; i < getNumField(); i++) {
264
			getField(i).getDataType().RAPID_AddDecodeInstr(env, instrs,
265
266
267
268
269
270
271
272
					var_name + "." + getField(i).getName(), stream_name);
		}
	}

	public void FixedArrayType.RAPID_AddDecodeInstr(RAPID_env env,
			java.util.List<String> instrs,
			String var_name, String stream_name) {
		for (int i = 1; i <= getExp(0).RAPID_getValue(); i++) {
273
			getDataType().RAPID_AddDecodeInstr(env, instrs,
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
					var_name + ".e" + i, stream_name);
		}
	}

	public void PrimType.RAPID_AddDecodeInstr(RAPID_env env,
			java.util.List<String> instrs,
			String var_name, String stream_name) {
		switch(getToken()) {
			case LABCOMM_BYTE:
				instrs.add("Decode_Byte " + stream_name + "," + var_name + ";");
				break;
			case LABCOMM_BOOLEAN:
				instrs.add("Decode_Bool " + stream_name + "," + var_name + ";");
				break;
			case LABCOMM_SHORT:
				instrs.add("Decode_Short " + stream_name + "," + var_name + ";");
				break;
			case LABCOMM_INT:
				instrs.add("Decode_Int " + stream_name + "," + var_name + ";");
				break;
			case LABCOMM_LONG:
				instrs.add("Decode_Long " + stream_name + "," + var_name + ";");
				break;
			case LABCOMM_FLOAT:
				instrs.add("Decode_Float " + stream_name + "," + var_name + ";");
				break;
			case LABCOMM_STRING:
				instrs.add("Decode_String " + stream_name + "," + var_name + ";");
				break;
			default:
304
				throw new UnsupportedOperationException("RAPID code generation does not (currently) support "+getName());
305
306
307
		}
	}

308
	public void DataType.RAPID_AddEncodeInstr(RAPID_env env,
309
310
			java.util.List<String> instrs,
			String var_name, String stream_name) {
311
		throw new UnsupportedOperationException("RAPID code generation does not (currently) support "+getClass().getSimpleName());
312
313
314
315
316
317
	}

	public void StructType.RAPID_AddEncodeInstr(RAPID_env env,
			java.util.List<String> instrs,
			String var_name, String stream_name) {
		for (int i = 0; i < getNumField(); i++) {
318
			getField(i).getDataType().RAPID_AddEncodeInstr(env, instrs,
319
320
321
322
323
324
325
326
					var_name + "." + getField(i).getName(), stream_name);
		}
	}

	public void FixedArrayType.RAPID_AddEncodeInstr(RAPID_env env,
			java.util.List<String> instrs,
			String var_name, String stream_name) {
		for (int i = 1; i <= getExp(0).RAPID_getValue(); i++) {
327
			getDataType().RAPID_AddEncodeInstr(env, instrs,
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
					var_name + ".e" + i, stream_name);
		}
	}

	public void PrimType.RAPID_AddEncodeInstr(RAPID_env env,
			java.util.List<String> instrs,
			String var_name, String stream_name) {
		switch(getToken()) {
			case LABCOMM_BYTE:
				instrs.add("Encode_Byte " + stream_name + "," + var_name + ";");
				break;
			case LABCOMM_BOOLEAN:
				instrs.add("Encode_Bool " + stream_name + "," + var_name + ";");
				break;
			case LABCOMM_SHORT:
				instrs.add("Encode_Short " + stream_name + "," + var_name + ";");
				break;
			case LABCOMM_INT:
				instrs.add("Encode_Int " + stream_name + "," + var_name + ";");
				break;
			case LABCOMM_LONG:
				instrs.add("Encode_Long " + stream_name + "," + var_name + ";");
				break;
			case LABCOMM_FLOAT:
				instrs.add("Encode_Float " + stream_name + "," + var_name + ";");
				break;
			case LABCOMM_STRING:
				instrs.add("Encode_String " + stream_name + "," + var_name + ";");
				break;
			default:
358
				throw new UnsupportedOperationException("RAPID code generation does not (currently) support "+getName());
359
360
361
362
		}
	}

	public int Exp.RAPID_getValue() {
363
		throw new UnsupportedOperationException("RAPID code generation does not (currently) support "+getClass().getSimpleName());
364
365
366
367
368
369
	}

	public int IntegerLiteral.RAPID_getValue() {
		return Integer.parseInt(getValue());
	}
}