Commit 59a49855 authored by Sven Gestegård Robertz's avatar Sven Gestegård Robertz
Browse files

pruned and grafted the refactored compiler from the metadata branch. Tests...

pruned and grafted the refactored compiler from the metadata branch. Tests run, but code needs cleanup
parent 177c6703
......@@ -9,11 +9,15 @@ aspect CS_CodeGenEnv {
public class CS_env {
public final int version;
public final String verStr;
private int indent;
private int depth;
private CS_printer printer;
private HashMap unique = new HashMap();
// public boolean versionHasMetaData() {
// return version != 2006;
// }
final private static class CS_printer {
private boolean newline = true;
......@@ -80,6 +84,7 @@ aspect CS_CodeGenEnv {
this.version = version;
this.indent = indent;
this.printer = printer;
this.verStr = (version == 2006) ? "2006" : "";
}
public CS_env(File f, int version) {
......@@ -107,6 +112,9 @@ aspect CS_CodeGenEnv {
public void unindent(int amount) {
indent -= amount;
if (indent < 0) {
throw new Error("Negative indent level");
}
}
public void unindent() {
......@@ -188,6 +196,7 @@ aspect CS_StructName {
aspect CS_Void {
syn boolean Decl.CS_isVoid() = getType().CS_isVoid();
syn boolean UserType.CS_isVoid() = decl().CS_isVoid();
syn boolean Type.CS_isVoid() = false;
syn boolean VoidType.CS_isVoid() = true;
......@@ -261,6 +270,84 @@ aspect CS_Class {
" not declared");
}
public void Decl.CS_emitDeclPP(CS_env env){
env.println("/* ");
pp(env.getPrintStream());
CS_emitUserTypeDeps(env,null,false);
CS_emitUserTypeRefs(env,null,false);
env.println("*/");
}
public void Decl.CS_emitUserTypeDeps(CS_env env, String via, boolean outputCode){
// if(env.versionHasMetaData() && hasDependencies() || isReferenced() ) {
// if(env.versionHasMetaData() && isSampleDecl() && outputCode) {
// env.println("if(sendMetaData){");
// env.indent();
// }
// Iterator<Decl> it = type_dependencies().iterator();
// while(it.hasNext()) {
// Decl t = it.next();
//
// t.CS_emitUserTypeDeps(env, t.getName(), outputCode);
// if( outputCode && t.getType().isUserType() ) {
// //env.println("/* FIXME: " + t.getName() + " does not exist");
// env.println(t.getName()+".register(e, sendMetaData);");
// //env.println("*/");
// } else { // Just output a comment
// String refpath = (via == null) ? "directly" : "indirectly via "+via;
// //env.println(" //Depends ("+refpath+") on "+t.getName() + " (" + t +") " );
// //env.println(" //Depends ("+refpath+") on "+t.getName() );
// env.println(" //Depends ("+refpath+") on "+t.getName()+" -- "+t.getType() );
// }
// }
// if(env.versionHasMetaData() && isSampleDecl() && outputCode) {
// env.unindent();
// env.println("}");
// }
// }
}
public void Decl.CS_emitUserTypeRefs(CS_env env, String via, boolean outputCode){
if( isReferenced() ) {
Iterator<Decl> it = type_references().iterator();
while(it.hasNext()) {
Decl t = it.next();
t.CS_emitUserTypeRefs(env, t.getName(), outputCode);
if(outputCode) {
env.println(t.getName()+".register(e);");
} else { // Just output a comment
String refpath = (via == null) ? "directly" : "indirectly via "+via;
env.println(" //Is referenced ("+refpath+") by "+t.getName() );
}
}
}
}
public void Decl.CS_emitRegisterEncoder(CS_env env) {
env.println("public static void register(Encoder e){");
env.indent();
env.println("e.register(Dispatcher.singleton());");
env.unindent();
env.println("}");
// env.println();
// env.println("public static void register(Encoder e, bool sendMetaData){");
// env.indent();
//
// CS_emitUserTypeDeps(env, null, true);
// if(env.versionHasMetaData()) {
// env.println("e.register(Dispatcher.singleton(), sendMetaData);");
// } else {
// env.println("e.register(Dispatcher.singleton());");
// }
// env.unindent();
// env.println("}");
// env.println();
}
public void TypeDecl.CS_emitClass(CS_env env) {
if (getType().CS_needInstance()) {
// Hackish prettyprint preamble
......@@ -272,6 +359,11 @@ aspect CS_Class {
env.println();
env.indent();
getType().CS_emitInstance(env);
if( isReferenced()) {
CS_emitRegisterEncoder(env);
CS_emitDispatcher(env,false);
}
CS_emitSignature(env);
CS_emitEncoder(env);
CS_emitDecoder(env);
env.unindent();
......@@ -303,15 +395,17 @@ aspect CS_Class {
env.unindent();
env.println("}");
env.println();
/*
env.println("public static void register(Encoder e) {");
env.indent();
env.println("e.register(new Dispatcher());");
env.unindent();
env.println("}");
env.println();
env.println(); */
CS_emitRegisterEncoder(env);
env.println("private class Dispatcher : SampleDispatcher {");
/*env.println("private class Dispatcher : LabCommDispatcher {");
env.indent();
env.println();
env.println("public Type getSampleClass() {");
......@@ -345,19 +439,20 @@ aspect CS_Class {
env.println("");
env.unindent();
env.println("}");
env.println("");
env.println("");*/
CS_emitDispatcher(env,true);
CS_emitEncoder(env);
CS_emitDecoder(env);
env.println("private static byte[] signature = new byte[] {");
/*env.println("private static byte[] signature = new byte[] {");
env.indent();
SignatureList signature = signature(env.version);
SignatureList signature = flatSignature(env.version);
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);
byte[] data = signature.getData(i, env.version);
if (data != null) {
env.print(signature.getIndent(i));
for (int j = 0 ; j < data.length ; j++) {
......@@ -369,10 +464,148 @@ aspect CS_Class {
env.unindent();
env.println("};");
env.unindent();
env.println();
env.println();*/
CS_emitSignature(env);
env.println("}");
}
public void Decl.CS_emitSignature(CS_env env) {
//always emit the flat signature, as it is needed
//for matching at the decoder side (which cannot know
//the type_ids of dependent types. Therefore, flat sigs
//are used for matching
CS_emitFlatSignature(env);
// if(isReferenced() || isSampleDecl()){
// Signature signature = getSignature();
// signature.CS_emitSignature(env, !isSampleDecl());
// }
}
public void Decl.CS_emitFlatSignature(CS_env env){
env.println("private static byte[] signature = new byte[] {");
env.indent();
SignatureList signature = flatSignature(env.version);
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, env.version);
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.println();
}
//XXX TODO: refactor: split into a static class ("TypeDefSingleton"?)and a (smaller) dispatcher
public void Decl.CS_emitDispatcher(CS_env env, boolean isSample) {
String genericStr = ""; //env.versionHasMetaData()?"<"+getName()+">":"";
env.println("private class Dispatcher : SampleDispatcher{");
env.indent();
env.println();
env.println("private static Dispatcher single;");
env.println();
env.println("public static Dispatcher singleton() {");
env.indent();
env.println("lock(typeof(Dispatcher)) {");
env.indent();
env.println("if( single == null ) single = new Dispatcher();");
env.println("return single;");
env.unindent();
env.println("}");
env.unindent();
env.println("}");
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 getTypeDeclTag() {");
env.indent();
if(isSample) {
env.println("return Constant.SAMPLE_DEF;");
} else {
env.println("return Constant.TYPE_DEF;");
}
env.unindent();
env.println("}");
env.println();
env.println("public bool isSample() {");
env.indent();
env.println("return "+isSample+";");
env.unindent();
env.println("}");
env.println("public bool hasStaticSignature() {");
env.indent();
env.println("return "+!hasDependencies()+";");
env.unindent();
env.println("}");
env.println();
env.println("/** return the flat signature. Intended use is on decoder side */");
env.println("public byte[] getSignature() {");
env.indent();
env.println("return signature;");
env.unindent();
env.println("}");
env.println();
// env.println("public void encodeSignature(Encoder e) throws IOException{");
// env.indent();
// env.println("emitSignature(e);");
// env.unindent();
// env.println("}");
// env.println();
// env.println("public void encodeSignatureMetadata(Encoder e, int index){");
// env.indent();
// env.println("e.encodePacked32(Constant.TYPE_DEF);");
// env.println("e.encodePacked32(index);");
// env.println("e.encodeString(getName());");
// env.println("emitSignature(e);");
// env.unindent();
// env.println("}");
// env.println();
env.println("public bool canDecodeAndHandle() {");
env.indent();
env.println("return "+isSample+";");
env.unindent();
env.println("}");
env.println();
env.println("public void decodeAndHandle(Decoder d,");
env.println(" SampleHandler h) {");
env.indent();
if( isSample) {
if (isVoid()) {
env.println(getName() + ".decode(d);");
env.println("((Handler)h).handle();");
} else {
env.println("((Handler)h).handle(" + getName() + ".decode(d));");
}
} else {
env.println("throw new Exception(\"A typedef has no handler, the corresponding method on the sample class should be called.\");");
}
env.unindent();
env.println("}");
env.println("");
env.unindent();
env.println("}");
env.println("");
} //TODO, fix above method
public void TypeDecl.CS_emitEncoder(CS_env env) {
env.print("public static void encode(Encoder e");
if (!isVoid()) {
......@@ -754,6 +987,48 @@ aspect CS_Class {
}
aspect CS_Signature {
public void Signature.CS_emitSignature(CS_env env, boolean decl){
SignatureList sl = getSignatureList();
sl.CS_emitSignature(env, decl);
}
public abstract void SignatureLine.CS_emitSignature(CS_env env, boolean decl);
public void TypeRefSignatureLine.CS_emitSignature(CS_env env, boolean isDecl){
env.print(getIndentString());
env.println("e.encodePacked32(e.getTypeId( typeof("+decl.getName()+")));");
}
public void DataSignatureLine.CS_emitSignature(CS_env env, boolean decl){
byte[] data = getData(env.version);
if (data != null) {
env.print(getIndentString());
for (int j = 0 ; j < data.length ; j++) {
//env.print("e.encodeByte((byte)"+data[j]+");");
env.print("e.encodeByte((byte)"+ String.format("0x%02X ", data[j]) +"); ");
}
env.println();
}
}
public void SignatureList.CS_emitSignature(CS_env env, boolean decl) {
env.println("private static void emitSignature(Encoder e){");
env.indent();
for (int i = 0 ; i < size() ; i++) {
String comment = getComment(i);
if (comment != null && comment.length() > 0) {
env.println(getIndent(i) + "// " + comment);
}
SignatureLine l = getSignatureLine(i);
l.CS_emitSignature(env, decl);
}
env.println("}");
env.unindent();
}
}
aspect CS_Info {
public void Program.CS_info(PrintStream out, String namespace, int version) {
......@@ -789,3 +1064,4 @@ aspect CS_Info {
}
}
......@@ -47,6 +47,10 @@ aspect C_CodeGenEnv {
private boolean rootIsPointer;
private int rootLevel;
public boolean versionHasMetaData() {
return version != 2006;
}
private C_env(String qualid, String lcName, String rawPrefix,
int indent, int depth, C_printer printer,
int nestedLevel, int version)
......@@ -107,6 +111,10 @@ aspect C_CodeGenEnv {
printer.print(this, s);
}
public void println() {
printer.println(this, "");
}
public void println(String s) {
printer.println(this, s);
}
......@@ -392,7 +400,7 @@ aspect C_Declarations {
public void Decl.C_emitEncoderDeclaration(C_env env) {
}
//
public void SampleDecl.C_emitEncoderDeclaration(C_env env) {
env.println("int labcomm"+env.verStr+"_encoder_register_" +
env.prefix + getName() + "(");
......@@ -978,13 +986,13 @@ aspect C_DecoderIoctl {
aspect C_Encoder {
public void Decl.C_emitEncoder(C_env env) {
throw new Error(this.getClass().getName() +
".C_emitEncoder()" +
" not declared");
//XXX throw new Error(this.getClass().getName() +
// ".C_emitEncoder()" +
// " not declared");
}
public void TypeDecl.C_emitEncoder(C_env env) {
}
// public void TypeDecl.C_emitEncoder(C_env env) {
// }
public void SampleDecl.C_emitEncoder(C_env env) {
env = env.nestStruct("(*v)");
......@@ -1091,14 +1099,15 @@ aspect C_Encoder {
}
public void Decl.C_emitEncoderRegisterHandler(C_env env) {
throw new Error(this.getClass().getName() +
".C_emitEncoderRegisterHandler(C_env env)" +
" not declared");
}
public void TypeDecl.C_emitEncoderRegisterHandler(C_env env) {
}
//XXX
// throw new Error(this.getClass().getName() +
// ".C_emitEncoderRegisterHandler(C_env env)" +
// " not declared");
}
//
//public void TypeDecl.C_emitEncoderRegisterHandler(C_env env) {
//}
//
public void SampleDecl.C_emitEncoderRegisterHandler(C_env env) {
env.println("int labcomm"+env.verStr+"_encoder_register_" +
env.prefix + getName() + "(");
......@@ -1108,6 +1117,9 @@ aspect C_Encoder {
env.println(")");
env.println("{");
env.indent();
C_emitUserTypeDeps(env, null, false); //XXX HERE BE DRAGONS
//set to false to turn off
//outputting of code
env.println("return labcomm"+env.verStr+"_internal_encoder_register(");
env.indent();
env.println("e,");
......@@ -1158,6 +1170,43 @@ aspect C_EncoderIoctl {
}
aspect C_TypeDependencies {
public void Decl.C_emitUserTypeDeps(C_env env, String via, boolean outputCode) {
if( hasDependencies() ) {
Iterator<Decl> it = type_dependencies().iterator();
while(it.hasNext()) {
Decl t = it.next();
t.C_emitUserTypeDeps(env, t.getName(), outputCode);
if(outputCode) {
System.out.println("Decl.C_emitUserTypeDeps registering "+t.getName());
env.println("labcomm"+env.verStr+"_encoder_register_"+env.prefix + t.getName()+"(e);");
} else { // Just output a comment
String refpath = (via == null) ? "directly" : "indirectly via "+via;
//env.println(" //Depends ("+refpath+") on "+t.getName() + " (" + t +") " );
env.println(" //Depends ("+refpath+") on "+t.getName() );
}
}
}
}
public void Decl.C_emitUserTypeRefs(C_env env, String via, boolean outputCode) {
if( isReferenced() ) {
Iterator<Decl> it = type_references().iterator();
while(it.hasNext()) {
Decl t = it.next();
t.C_emitUserTypeRefs(env, t.getName(), outputCode);
if(outputCode) {
env.println("labcomm"+env.verStr+"_encoder_register_"+env.prefix + t.getName()+"(e);");
} else { // Just output a comment
String refpath = (via == null) ? "directly" : "indirectly via "+via;
env.println(" //Is referenced ("+refpath+") by "+t.getName() );
}
}
}
}
}
aspect C_Signature {
public void ASTNode.C_emitSignature(C_env env) {
......@@ -1166,19 +1215,56 @@ aspect C_Signature {
" not declared");
}
syn String Decl.C_DeclTypeString();
eq SampleDecl.C_DeclTypeString() = "LABCOMM_SAMPLE";
eq TypeDecl.C_DeclTypeString() = "LABCOMM_TYPEDEF";
public void Decl.C_emitSignature(C_env env) {
//always emit the flat signature, as it is needed
//for matching at the decoder side (which cannot know
//the type_ids of dependent types. Therefore, flat sigs
//are used for matching
C_emitFlatSignature(env);
/*
if( false && (isReferenced() || isSampleDecl())){
Signature signature = getSignature();
signature.C_emitSignature(env, !isSampleDecl());
} else {
env.println("// not emitting signature for "+getName()+isReferenced()+isSampleDecl());
}
if(env.versionHasMetaData()) {
if(isReferenced() || isSampleDecl()){
env.println("(int (*)(void *))labcomm"+env.verStr+"_signature_" +
env.prefix + getName() + "_emit_signature");
} else {
env.println("NULL"); // HERE BE DRAGONS! Is it worth the size saving to skip emitting the emit_signature function for unused types?
// The code won't likely end up in a target system anyway?
}
}
env.unindent();
env.println(" };");
*/
}
public void ASTNode.C_emitFlatSignature(C_env env) {
throw new Error(this.getClass().getName() +
".C_emitFlatSignature(C_env env)" +
" not declared");
}
public void SampleDecl.C_emitSignature(C_env env) {
public void Decl.C_emitFlatSignature(C_env env) {
}
public void SampleDecl.C_emitFlatSignature(C_env env){
env.println("static unsigned char signature_bytes_" +
env.prefix + getName() + "[] = {");
SignatureList signature = signature(env.version);
env.prefix + getName() + "[] = {");
SignatureList signature = flatSignature(env.version);
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);
byte[] data = signature.getData(i, env.version);
if (data != null) {
env.print(signature.getIndent(i));
for (int j = 0 ; j < data.length ; j++) {
......@@ -1188,9 +1274,10 @@ aspect C_Signature {
}
}
env.println("};");
C_emitSizeofValue(env);
env.println("struct labcomm"+env.verStr+"_signature labcomm"+env.verStr+"_signature_" +
env.prefix + getName() + " = {");
env.prefix + getName() + " = {");
env.indent();
env.println("\"" + getName() + "\",");
env.println("sizeof_" + env.prefix + getName() + ",");
......@@ -1201,6 +1288,109 @@ aspect C_Signature {
env.println(" };");
}
public void Signature.C_emitSignature(C_env env, boolean decl){
getSignatureList().C_emitSignature(env, decl);
}
public abstract void SignatureLine.C_emitSignature(C_env env, boolean decl);
public void TypeRefSignatureLine.C_emitSignature(C_env env, boolean isDecl){
//env.print(getIndentString());
//env.println("LABCOMM_SIGDEF_SIGNATURE(labcomm"+env.verStr+"_signature_" + env.prefix + decl.getName() +"),");
}
public void DataSignatureLine.C_emitSignature(C_env env, boolean decl){
// String comment = getComment();
// if (comment != null && comment.length() > 0) {
// env.println(getIndentString() + "// " + comment);
// }
// byte[] data = getData(env.version);
// if (data != null && data.length > 0) {
// env.print(getIndentString());
// env.print("LABCOMM_SIGDEF_BYTES("+data.length+", \"");
// for (int j = 0 ; j < data.length ; j++) {
// byte d = data[j];
// //if(d>='a'&&d<='z' || d>='A'&&d<='Z'|| d>='0'&&d<='9' )
// // env.print(""+(char)d);
// //else
// env.print("\\x"+Integer.toHexString(d));
// }
// env.println("\"),");
// }
}
/*
byte[] data = getData(env.version);
if (data != null) {
for (int j = 0 ; j < data.length ; j++) {
env.print(getIndentString());
//env.print("printf(\"labcomm"+env.verStr+"_write_byte( w, (unsigned char)"+ String.format("0x%02X ", data[j]) +")\\n\"); ");
env.print("labcomm"+env.verStr+"_write_byte( w, (unsigned char)"+ String.format("0x%02X ", data[j]) +"); ");
env.println("if (result != 0) { return result; }");
}
env.println();
}
*/
//}
/**
static int encode_test_twoLines(
struct labcomm_writer *w
, test_twoLines *v
)
{
result = labcomm_write_int(w, (*v).l1.start.x.val);
**/
public void SignatureList.C_emitSignature(C_env env, boolean decl) {
env.println("static struct labcomm_signature_data signature_tree_" +
env.prefix + parentDecl().getName() + "[] = {");
env.indent();
for (int i = 0 ; i < size() ; i++) {
SignatureLine l = getSignatureLine(i);
l.C_emitSignature(env, decl);
}
env.println("LABCOMM_SIGDEF_END");
env.println("};");
env.unindent();
env.println();
}
// public void SampleDecl.C_emitSignature(C_env env) {
// env.println("static unsigned char signature_bytes_" +
// env.prefix + getName() + "[] = {");
// SignatureList signature = signature(env.version);