Forked from
Anders Blomdell / LabComm
598 commits behind the upstream repository.
-
Sven Robertz authoredSven Robertz authored
CS_CodeGen.jrag 20.15 KiB
import java.io.*;
import java.util.*;
aspect CS_CodeGenEnv {
// Environment wrapper for CS-code generation
// handles indentation, file writing,
public class CS_env {
private int indent;
private int depth;
private CS_printer printer;
private HashMap unique = new HashMap();
final private class CS_printer {
private boolean newline = true;
private File file;
private PrintStream out;
private IOException exception;
public CS_printer(File f) {
file = f;
File parentFile = f.getParentFile();
if(parentFile != null) {
parentFile.mkdirs();
}
}
public CS_printer(PrintStream out) {
this.out = out;
}
public void close() throws IOException {
if (out != null) {
out.close();
}
if (exception != null) {
throw exception;
}
}
public PrintStream getPrintStream() {
return(out);
}
public void checkOpen() {
if (out == null && exception == null) {
try {
out = new PrintStream(new FileOutputStream(file));
} catch (IOException e) {
exception = e;
}
}
}
public void print(CS_env env, String s) {
checkOpen();
if (newline) {
newline = false;
for (int i = 0 ; i < env.indent ; i++) {
out.print(" ");
}
}
out.print(s);
}
public void println(CS_env env, String s) {
checkOpen();
print(env, s);
out.println();
newline = true;
}
}
private CS_env(int indent, CS_printer printer) {
this.indent = indent;
this.printer = printer;
}
public CS_env(File f) {
this.indent = 0;
this.printer = new CS_printer(f);
}
public CS_env(PrintStream out) {
this.indent = 0;
this.printer = new CS_printer(out);
}
public void close() throws IOException {
printer.close();
}
public PrintStream getPrintStream() {
return printer.getPrintStream();
}
public void indent(int amount) {
indent += amount;
}
public void indent() {
indent(1);
}
public void unindent(int amount) {
indent -= amount;
}
public void unindent() {
unindent(1);
}
public void print(String s) {
printer.print(this, s);
}
public void println(String s) {
printer.println(this, s);
}
public void println() {
printer.println(this, "");
}
public int getDepth() {
return depth;
}
public String print_for_begin(String limit) {
print("for (int i_" + depth + " = 0 ; ");
print("i_" + depth + " < " + limit + " ; ");
println("i_" + depth + "++) {");
indent();
depth++;
return "i_" + (depth - 1);
}
public void print_for_end() {
depth--;
unindent();
println("}");
}
public void print_block_begin() {
println("{");
indent();
}
public void print_block_end() {
unindent();
println("}");
}
public String getUnique(Object o) {
String result = (String)unique.get(o);
if (result == null) {
result = "_" + (unique.size() + 1) + "_";
}
unique.put(o, result);
return result;
}
}
}
aspect CS_StructName {
inh int Decl.CS_Depth();
inh int Type.CS_Depth();
eq Program.getDecl(int i).CS_Depth() = 0;
eq StructType.getField(int i).CS_Depth() = CS_Depth() + 1;
inh String Type.CS_structName();
eq Program.getDecl(int i).CS_structName() = getDecl(i).getName();
eq StructType.getField(int i).CS_structName() {
if (CS_Depth() == 0) {
return "struct_" + getField(i).getName();
} else {
return CS_structName() + "_" + getField(i).getName();
}
}
}
aspect CS_Void {
syn boolean Decl.CS_isVoid() = getType().CS_isVoid();
syn boolean Type.CS_isVoid() = false;
syn boolean VoidType.CS_isVoid() = true;
}
aspect CS_CodeGen {
public void Program.CS_gen(String file,
String namespace) throws IOException {
// Registration class
CS_env env = new CS_env(new File(file));
if (namespace != null && namespace.length() > 0) {
env.println("namespace " + namespace + "{");
env.indent();
}
env.println("using System;");
env.println("using se.lth.control.labcomm;");
for (int i = 0; i < getNumDecl(); i++) {
Decl d = getDecl(i);
try {
d.CS_emitClass(env);
} catch (Error e) {
System.err.println(d.getName());
throw e;
}
}
if (namespace != null && namespace.length() > 0) {
env.unindent();
env.println("}");
}
}
}
aspect CS_Register {
public void Program.CS_emitTypeRegister(CS_env env) {
/*
env.println("static void register(LabCommChannel c) {");
env.indent();
for (int i = 0; i < getNumDecl(); i++) {
getDecl(i).CS_emitTypeRegister(env);
}
env.unindent();
env.println("}");
*/
}
public void Decl.CS_emitTypeRegister(CS_env env) {
throw new Error(this.getClass().getName() +
".CS_emitTypeRegister(CS_env env)" +
" not declared");
}
public void SampleDecl.CS_emitTypeRegister(CS_env env) {
env.println(getName() + ".register(c);");
}
public void TypeDecl.CS_emitTypeRegister(CS_env env) {
// TODO
}
}
aspect CS_Class {
public void Decl.CS_emitClass(CS_env env) {
throw new Error(this.getClass().getName() +
".CS_emitClass(CS_env env)" +
" not declared");
}
public void TypeDecl.CS_emitClass(CS_env env) {
if (getType().CS_needInstance()) {
// Hackish prettyprint preamble
env.println("/* ");
pp(env.getPrintStream());
env.println("*/");
env.println();
env.println("public class " + getName() + " : LabCommType {");
env.println();
env.indent();
getType().CS_emitInstance(env);
CS_emitEncoder(env);
CS_emitDecoder(env);
env.unindent();
env.println("}");
}
}
public void SampleDecl.CS_emitClass(CS_env env) {
env.println("/* ");
pp(env.getPrintStream());
env.println("*/");
env.println();
env.println("public class " + getName() + " : LabCommSample {");
env.println();
env.indent();
getType().CS_emitInstance(env);
env.println("public interface Handler : LabCommHandler {");
env.print(" void handle(");
if (!isVoid()) {
getType().CS_emitType(env);
env.print(" value");
}
env.println(");");
env.println("}");
env.println();
env.println("public static void register(LabCommDecoder d, Handler h) {");
env.indent();
env.println("d.register(new Dispatcher(), h);");
env.unindent();
env.println("}");
env.println();
env.println("public static void register(LabCommEncoder e) {");
env.indent();
env.println("e.register(new Dispatcher());");
env.unindent();
env.println("}");
env.println();
env.println("private class Dispatcher : LabCommDispatcher {");
env.indent();
env.println();
env.println("public Type getSampleClass() {");
env.indent();
env.println("return typeof(" + getName() + ");");
env.unindent();
env.println("}");
env.println();
env.println("public String getName() {");
env.indent();
env.println("return \"" + getName() + "\";");
env.unindent();
env.println("}");
env.println();
env.println("public byte[] getSignature() {");
env.indent();
env.println("return signature;");
env.unindent();
env.println("}");
env.println();
env.println("public void decodeAndHandle(LabCommDecoder d, LabCommHandler h) {");
env.indent();
if (isVoid()) {
env.println(getName() + ".decode(d);");
env.println("((Handler)h).handle();");
} else {
env.println("((Handler)h).handle(" + getName() + ".decode(d));");
}
env.unindent();
env.println("}");
env.println("");
env.unindent();
env.println("}");
env.println("");
CS_emitEncoder(env);
CS_emitDecoder(env);
env.println("private static byte[] signature = new byte[] {");
env.indent();
SignatureList signature = signature();
for (int i = 0 ; i < signature.size() ; i++) {
String comment = signature.getComment(i);
if (comment != null) {
env.println(signature.getIndent(i) + "// " + comment);
}
byte[] data = signature.getData(i);
if (data != null) {
env.print(signature.getIndent(i));
for (int j = 0 ; j < data.length ; j++) {
env.print(data[j] + ", ");
}
env.println();
}
}
env.unindent();
env.println("};");
env.unindent();
env.println();
env.println("}");
}
public void TypeDecl.CS_emitEncoder(CS_env env) {
env.print("public static void encode(LabCommEncoder e");
if (!isVoid()) {
env.print(", ");
getType().CS_emitType(env);
env.print(" value");
}
env.println(") {");
env.indent();
getType().CS_emitEncoder(env, "value");
env.unindent();
env.println("}");
env.println();
}
public void SampleDecl.CS_emitEncoder(CS_env env) {
env.print("public static void encode(LabCommEncoder e");
if (!isVoid()) {
env.print(", ");
getType().CS_emitType(env);
env.print(" value");
}
env.println(") {");
env.indent();
env.println("e.begin(typeof(" + getName() + "));");
getType().CS_emitEncoder(env, "value");
env.println("e.end(typeof(" + getName() + "));");
env.unindent();
env.println("}");
env.println();
}
public void Type.CS_emitEncoder(CS_env env, String name) {
throw new Error(this.getClass().getName() +
".CS_emitEncoder(CS_env env, String name)" +
" not declared");
}
public void VoidType.CS_emitEncoder(CS_env env, String name) {
}
public void PrimType.CS_emitEncoder(CS_env env, String name) {
switch (getToken()) {
case LABCOMM_BOOLEAN: { env.print("e.encodeBoolean"); } break;
case LABCOMM_BYTE: { env.print("e.encodeByte"); } break;
case LABCOMM_SHORT: { env.print("e.encodeShort"); } break;
case LABCOMM_INT: { env.print("e.encodeInt"); } break;
case LABCOMM_LONG: { env.print("e.encodeLong"); } break;
case LABCOMM_FLOAT: { env.print("e.encodeFloat"); } break;
case LABCOMM_DOUBLE: { env.print("e.encodeDouble"); } break;
case LABCOMM_STRING: { env.print("e.encodeString"); } break;
}
env.println("(" + name + ");");
}
public void ArrayType.CS_emitEncoder(CS_env env, String name) {
int baseDepth = env.getDepth();
for (int i = 0 ; i < getNumExp() ; i++) {
String limit = getExp(i).CS_emitEncoder(env,
name + ".GetLength(" + i + ")");
env.print_block_begin();
env.println("int i_" + (baseDepth + i) + "_max = " + limit + ";");
}
String index = null;
for (int i = 0 ; i < getNumExp() ; i++) {
String limit = "i_" + (baseDepth + i) + "_max";
if (i == 0) {
index = env.print_for_begin(limit);
} else {
index = index + ", " + env.print_for_begin(limit);
}
}
getType().CS_emitEncoder(env, name + "[" + index + "]");
for (int i = 0 ; i < getNumExp() ; i++) {
env.print_for_end();
env.print_block_end();
}
}
public String Exp.CS_emitEncoder(CS_env env, String name) {
throw new Error(this.getClass().getName() +
".CS_emitEncoder(CS_env env, String name)" +
" not declared");
}
public String IntegerLiteral.CS_emitEncoder(CS_env env, String name) {
return getValue();
}
public String VariableSize.CS_emitEncoder(CS_env env, String name) {
env.println("e.encodeInt(" + name + ");");
return name;
}
public void StructType.CS_emitEncoder(CS_env env, String name) {
for (int i = 0 ; i < getNumField() ; i++) {
Field f = getField(i);
f.getType().CS_emitEncoder(env, name + "." + f.getName());
}
}
public void UserType.CS_emitEncoder(CS_env env, String name) {
if (CS_needInstance()) {
env.println(getName() + ".encode(e, " + name + ");");
} else {
decl().getType().CS_emitEncoder(env, name);
}
}
public void Decl.CS_emitDecoder(CS_env env) {
env.print("public static ");
getType().CS_emitType(env);
env.println(" decode(LabCommDecoder d) {");
env.indent();
if (!isVoid()) {
getType().CS_emitType(env);
env.println(" result;");
getType().CS_emitDecoder(env, "result");
env.println("return result;");
}
env.unindent();
env.println("}");
env.println();
}
public void Type.CS_emitDecoder(CS_env env, String name) {
throw new Error(this.getClass().getName() +
".CS_emitDecoder(CS_env env, String name)" +
" not declared");
}
public void VoidType.CS_emitDecoder(CS_env env, String name) {
}
public void PrimType.CS_emitDecoder(CS_env env, String name) {
env.print(name + " = ");
switch (getToken()) {
case LABCOMM_BOOLEAN: { env.println("d.decodeBoolean();"); } break;
case LABCOMM_BYTE: { env.println("d.decodeByte();"); } break;
case LABCOMM_SHORT: { env.println("d.decodeShort();"); } break;
case LABCOMM_INT: { env.println("d.decodeInt();"); } break;
case LABCOMM_LONG: { env.println("d.decodeLong();"); } break;
case LABCOMM_FLOAT: { env.println("d.decodeFloat();"); } break;
case LABCOMM_DOUBLE: { env.println("d.decodeDouble();"); } break;
case LABCOMM_STRING: { env.println("d.decodeString();"); } break;
}
}
public void ArrayType.CS_emitDecoder(CS_env env, String name) {
env.println("{");
env.indent();
int baseDepth = env.getDepth();
for (int i = 0 ; i < getNumExp() ; i++) {
env.print("int i_" + (baseDepth + i) + "_max = ");
getExp(i).CS_emitDecoder(env);
env.println(";");
}
env.print(name + " = new ");
getType().CS_emitTypePrefix(env);
env.print("[");
for (int i = 0 ; i < getNumExp() ; i++) {
if (i > 0) {
env.print(", ");
}
env.print("i_" + (baseDepth + i) + "_max");
}
env.println("]");
getType().CS_emitTypeSuffix(env);
env.println(";");
String index = null;
for (int i = 0 ; i < getNumExp() ; i++) {
String limit = "i_" + (baseDepth + i) + "_max";
if (i == 0) {
index = env.print_for_begin(limit);
} else {
index = index + ", " + env.print_for_begin(limit);
}
}
getType().CS_emitDecoder(env, name + "[" + index + "]");
for (int i = 0 ; i < getNumExp() ; i++) {
env.print_for_end();
}
env.unindent();
env.println("}");
}
public void Exp.CS_emitDecoder(CS_env env) {
throw new Error(this.getClass().getName() +
".CS_emitDecoder(CS_env env)" +
" not declared");
}
public void IntegerLiteral.CS_emitDecoder(CS_env env) {
env.print(getValue());
}
public void VariableSize.CS_emitDecoder(CS_env env) {
env.print("d.decodeInt()");
}
public void StructType.CS_emitDecoder(CS_env env, String name) {
env.print(name + " = new ");
CS_emitType(env);
env.println("();");
for (int i = 0 ; i < getNumField() ; i++) {
Field f = getField(i);
f.getType().CS_emitDecoder(env, name + "." + f.getName());
}
}
public void UserType.CS_emitDecoder(CS_env env, String name) {
if (CS_needInstance()) {
env.println(name + " = " + getName() + ".decode(d);");
} else {
decl().getType().CS_emitDecoder(env, name);
}
}
public void Type.CS_emitNew(CS_env env, String size) {
throw new Error(this.getClass().getName() +
".CS_emitNew(CS_env env, String size)" +
" not declared");
}
public void ArrayType.CS_emitNew(CS_env env, String size, int depth) {
env.print("new ");
getType().CS_emitTypePrefix(env);
env.print("[" + size + "]");
getType().CS_emitTypeSuffix(env);
for (int i = 1 ; i < depth ; i++) {
env.print("[]");
}
}
public void Type.CS_emitTypePrefix(CS_env env) {
throw new Error(this.getClass().getName() +
".CS_emitTypePrefix(CS_env env)" +
" not declared");
}
public void PrimType.CS_emitTypePrefix(CS_env env) {
switch (getToken()) {
case LABCOMM_STRING: { env.print("String"); } break;
default: { env.print(getName()); } break;
}
}
public void UserType.CS_emitTypePrefix(CS_env env) {
if (CS_needInstance()) {
env.print(getName());
} else {
decl().getType().CS_emitTypePrefix(env);
}
}
public void ArrayType.CS_emitTypePrefix(CS_env env){
getType().CS_emitTypePrefix(env);
}
public void StructType.CS_emitTypePrefix(CS_env env){
env.print(CS_structName());
}
public void Type.CS_emitTypeSuffix(CS_env env) {
}
public void UserType.CS_emitTypeSuffix(CS_env env) {
if (! CS_needInstance()) {
decl().getType().CS_emitTypeSuffix(env);
}
}
public void ArrayType.CS_emitTypeSuffix(CS_env env){
getType().CS_emitTypeSuffix(env);
env.print("[");
for (int i = 1 ; i < getNumExp() ; i++) {
env.print(",");
}
env.print("]");
}
public boolean Type.CS_needInstance() {
throw new Error(this.getClass().getName() +
".CS_needInstance()" +
" not declared");
}
public boolean PrimType.CS_needInstance() {
return false;
}
public boolean UserType.CS_needInstance() {
return decl().getType().CS_needInstance();
}
public boolean StructType.CS_needInstance() {
return true;
}
public boolean ArrayType.CS_needInstance() {
return getType().CS_needInstance();
}
public boolean Type.CS_isPrimitive() {
return false;
}
public boolean PrimType.CS_isPrimitive() {
return true;
}
public void Type.CS_emitInstance(CS_env env) {
throw new Error(this.getClass().getName() +
".CS_emitInstance(CS_env env)" +
" not declared");
}
public void VoidType.CS_emitInstance(CS_env env) {
}
public void PrimType.CS_emitInstance(CS_env env) {
}
public void ArrayType.CS_emitInstance(CS_env env) {
getType().CS_emitInstance(env);
}
public void StructType.CS_emitInstance(CS_env env) {
if (CS_Depth() > 0) {
env.println("public static class " + CS_structName() + " {");
env.indent();
}
for (int i = 0 ; i < getNumField() ; i++) {
getField(i).getType().CS_emitInstance(env);
}
for (int i = 0 ; i < getNumField() ; i++) {
getField(i).CS_emitField(env);
}
if (CS_Depth() > 0) {
env.unindent();
env.println("}");
}
env.println();
}
public void UserType.CS_emitInstance(CS_env env) {
}
public void Field.CS_emitField(CS_env env) {
env.print("public ");
getType().CS_emitType(env);
env.println(" " + getName() + ";");
}
public void Type.CS_emitType(CS_env env) {
throw new Error(this.getClass().getName() +
".CS_emitType(CS_env env)" +
" not declared");
}
public void VoidType.CS_emitType(CS_env env) {
env.print("void");
}
public void PrimType.CS_emitType(CS_env env) {
switch (getToken()) {
case LABCOMM_STRING: { env.print("String"); } break;
case LABCOMM_BOOLEAN: { env.print("bool"); } break;
default: { env.print(getName()); } break;
}
}
public void UserType.CS_emitType(CS_env env) {
decl().getType().CS_emitType(env);
}
public void ArrayType.CS_emitType(CS_env env){
getType().CS_emitType(env);
env.print("[");
for (int i = 1 ; i < getNumExp() ; i++) {
env.print(",");
}
env.print("]");
}
public void StructType.CS_emitType(CS_env env){
env.print(CS_structName());
}
}
aspect CS_Info {
public void Program.CS_info(PrintStream out, String namespace) {
CS_env env = new CS_env(out);
if (namespace == null) {
namespace = "";
} else {
namespace = namespace + ".";
}
for (int i = 0; i < getNumDecl(); i++) {
getDecl(i).CS_info(env, namespace);
}
}
public void Decl.CS_info(CS_env env, String namespace) {
throw new Error(this.getClass().getName() +
".CS_info(CS_env env)" +
" not declared");
}
public void TypeDecl.CS_info(CS_env env, String namespace) {
env.print("C#,typedef," + namespace + getName() + ",");
getType().CS_emitType(env);
env.println();
}
public void SampleDecl.CS_info(CS_env env, String namespace) {
env.print("C#,sample," + namespace + getName() + ",");
getType().CS_emitType(env);
env.println();
}
}