diff --git a/compiler/CS_CodeGen.jrag b/compiler/CS_CodeGen.jrag index a4a42e03e44a1ce651c15299ddfb800fc77f07b2..2790335d6beb6d2618c8e92e561ef0b3b8bfb2cf 100644 --- a/compiler/CS_CodeGen.jrag +++ b/compiler/CS_CodeGen.jrag @@ -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 { } } + diff --git a/compiler/C_CodeGen.jrag b/compiler/C_CodeGen.jrag index 9064f53d7eedddfac9d8d4237a9c095cace5322b..bf701050b6f292d7489af2018f40eaf330fbccf1 100644 --- a/compiler/C_CodeGen.jrag +++ b/compiler/C_CodeGen.jrag @@ -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); +// 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.println("};"); +// env.println("struct labcomm"+env.verStr+"_signature labcomm"+env.verStr+"_signature_" + +// env.prefix + getName() + " = {"); +// env.indent(); +// env.println("LABCOMM_SAMPLE, \"" + getName() + "\","); +// env.println("(int (*)(struct labcomm"+env.verStr+"_signature *, void *))labcomm"+env.verStr+"_sizeof_" + +// env.prefix + getName() + ","); +// env.println("sizeof(signature_bytes_" + env.prefix + getName() + "),"); +// env.println("signature_bytes_" + env.prefix + getName() + ","); +// env.println("0"); +// env.unindent(); +// env.println(" };"); +// } + +} +aspect C_Constructor { public void ASTNode.C_emitConstructor(C_env env) { throw new Error(this.getClass().getName() + ".C_emitConstructor(C_env env)" + @@ -1227,7 +1417,7 @@ aspect C_Signature { public void Decl.C_emitConstructor(C_env env) { } - +//XXX public void SampleDecl.C_emitConstructor(C_env env) { env.println("labcomm"+env.verStr+"_set_local_index(&labcomm"+env.verStr+"_signature_" + env.prefix + getName() + ");"); @@ -1247,13 +1437,12 @@ aspect C_Signature { } aspect C_Sizeof { - - public void Decl.C_emitSizeofDeclaration(C_env env) { + public void Decl.C_emitSizeofDeclaration(C_env env) { } public void SampleDecl.C_emitSizeofDeclaration(C_env env) { env.println("extern int labcomm"+env.verStr+"_sizeof_" + env.prefix + getName() + - "(" + env.prefix + getName() + " *v);"); + "(" + env.prefix + getName() + " *v);"); } public int Decl.C_fixedSizeof() { @@ -1266,7 +1455,7 @@ aspect C_Sizeof { public void SampleDecl.C_emitSizeof(C_env env) { env = env.nestStruct("(*v)"); env.println("int labcomm"+env.verStr+"_sizeof_" + env.prefix + getName() + - "(" + env.prefix + getName() + " *v)"); + "(" + env.prefix + getName() + " *v)"); env.println("{"); env.indent(); env.println("return labcomm"+env.verStr+"_internal_sizeof(" + @@ -1278,8 +1467,8 @@ aspect C_Sizeof { public int Type.C_fixedSizeof() { throw new Error(this.getClass().getName() + - ".C_fixedSizeof()" + - " not declared"); + ".C_fixedSizeof()" + + " not declared"); } public int VoidType.C_fixedSizeof() { @@ -1296,9 +1485,9 @@ aspect C_Sizeof { case LABCOMM_FLOAT: { return 4; } case LABCOMM_DOUBLE: { return 8; } default: { - throw new Error(this.getClass().getName() + - ".C_fixedSizeof()" + - " unknown size (" + getName() + ")"); + throw new Error(this.getClass().getName() + + ".C_fixedSizeof()" + + " unknown size (" + getName() + ")"); } } } @@ -1346,20 +1535,20 @@ aspect C_Sizeof { public void Type.C_emitSizeof(C_env env) { throw new Error(this.getClass().getName() + - ".C_emitSizeof(C_env env)" + - " not declared"); + ".C_emitSizeof(C_env env)" + + " not declared"); } public void PrimType.C_emitSizeof(C_env env) { switch (getToken()) { case LABCOMM_STRING: { env.print("{ int l = strlen(" + env.qualid + "); "); - env.println("result += labcomm"+env.verStr+"_size_packed32(l) + l; }"); + env.println("result += labcomm"+env.verStr+"_size_packed32(l) + l; }"); } break; default: { - throw new Error(this.getClass().getName() + - ".C_emitSizeof(C_env env)" + - " known size (" + getName() + ")"); + throw new Error(this.getClass().getName() + + ".C_emitSizeof(C_env env)" + + " known size (" + getName() + ")"); } } } @@ -1372,10 +1561,10 @@ aspect C_Sizeof { int fixed = 0; for (int i = 0 ; i < getNumField() ; i++) { if (getField(i).getType().C_isDynamic()) { - getField(i).getType().C_emitSizeof( - env.nestStruct("." + getField(i).getName())); + getField(i).getType().C_emitSizeof( + env.nestStruct("." + getField(i).getName())); } else { - fixed += getField(i).getType().C_fixedSizeof(); + fixed += getField(i).getType().C_fixedSizeof(); } } if (fixed > 0) { @@ -1389,35 +1578,34 @@ aspect C_Sizeof { env.indent(); C_emitLoopVariables(env); for (int i = 0 ; i < getNumExp() ; i++) { - String iterator = "i_" + env.depth + "_" + i; - env.println("for (" + iterator + " = 0" + - " ; " + - iterator + " < " + getExp(i).C_getLimit(env, i) + - " ; " + - iterator + "++) {"); - env.indent(); + String iterator = "i_" + env.depth + "_" + i; + env.println("for (" + iterator + " = 0" + + " ; " + + iterator + " < " + getExp(i).C_getLimit(env, i) + + " ; " + + iterator + "++) {"); + env.indent(); } C_emitCalcIndex(env); getType().C_emitSizeof(C_Nest(env)); for (int i = 0 ; i < getNumExp() ; i++) { - env.unindent(); - env.println("}"); + env.unindent(); + env.println("}"); } env.unindent(); env.println("}"); } else { for (int i = 0 ; i < getNumExp() ; i++) { - env.println("result += labcomm"+env.verStr+"_size_packed32(" + - getExp(i).C_getLimit(env, i) + ");"); + env.println("result += labcomm"+env.verStr+"_size_packed32(" + + getExp(i).C_getLimit(env, i) + ");"); } env.print("result += " + getType().C_fixedSizeof()); for (int i = 0 ; i < getNumExp() ; i++) { - env.print(" * " + getExp(i).C_getLimit(env, i)); + env.print(" * " + getExp(i).C_getLimit(env, i)); } env.println(";"); } } - } aspect C_forAll { diff --git a/compiler/FlatSignature.jrag b/compiler/FlatSignature.jrag index 7af59d529e7c4877824610f1118e9e745e137187..b0bbe57ead2d2939093d96c35c32935f7ddd02b2 100644 --- a/compiler/FlatSignature.jrag +++ b/compiler/FlatSignature.jrag @@ -3,11 +3,10 @@ import java.util.*; aspect FlatSignature { public SignatureList Decl.flatSignature(int version) { - SignatureList result = new SignatureList(version); - flatSignature(result); + SignatureList result = getSignature().getFlatSignatureList(); return result; } - + public void ASTNode.flatSignature(SignatureList list) { throw new Error(this.getClass().getName() + ".flatSignature(SignatureList list)" + diff --git a/compiler/Java_CodeGen.jrag b/compiler/Java_CodeGen.jrag index 62dcd575b295b0cf2f22427a12be2638a7aab698..75913cdf89a05d6276310f945c05b57ca51a588c 100644 --- a/compiler/Java_CodeGen.jrag +++ b/compiler/Java_CodeGen.jrag @@ -4,7 +4,7 @@ import java.util.*; aspect Java_CodeGenEnv { // Environment wrapper for Java-code generation - // handles indentation, file writing, + // handles indentation, file writing, public class Java_env { @@ -15,13 +15,17 @@ aspect Java_CodeGenEnv { private Java_printer printer; private HashMap unique = new HashMap(); + public boolean versionHasMetaData() { + return version != 2006; + } + final private class Java_printer { - + private boolean newline = true; private File file; private PrintStream out; private IOException exception; - + public Java_printer(File f) { file = f; @@ -78,7 +82,7 @@ aspect Java_CodeGenEnv { } private Java_env(int version, int indent) { - this.version = version; + this.version = version; this.verStr = (version == 2006) ? "2006" : ""; this.indent = indent; } @@ -264,13 +268,10 @@ aspect Java_CodeGen { } } - /** Experimental method for generating code to a map <classname, source> + /** Experimental method for generating code to a map <classname, source> */ public void Program.J_gen(Map<String,String> src, String pack, int version) throws IOException { Java_env env; -/* - // Registration class was commented out, so got removed in this copy -*/ for (int i = 0; i < getNumDecl(); i++) { Decl d = getDecl(i); try { @@ -286,46 +287,13 @@ aspect Java_CodeGen { } } } - -} - -aspect Java_Register { - - public void Program.Java_emitTypeRegister(Java_env env) { - - env.println("static void register(Encoder e) {"); - env.indent(); - for (int i = 0; i < getNumDecl(); i++) { - getDecl(i).Java_emitTypeRegister(env); - } - env.unindent(); - env.println("}"); - - - } - - public void Decl.Java_emitTypeRegister(Java_env env) { - throw new Error(this.getClass().getName() + - ".Java_emitTypeRegister(Java_env env)" + - " not declared"); - } - - public void SampleDecl.Java_emitTypeRegister(Java_env env) { - env.println(getName() + ".register(e);"); - } - - public void TypeDecl.Java_emitTypeRegister(Java_env env) { - // TODO - env.println("//TODO " + getName() + ".register(e);"); - } - } aspect Java_Class { public void Decl.Java_emitClass(Java_env env, String pack) { - throw new Error(this.getClass().getName() + - ".Java_emitClass(Java_env env, String pack)" + + throw new Error(this.getClass().getName() + + ".Java_emitClass(Java_env env, String pack)" + " not declared"); } @@ -345,18 +313,17 @@ aspect Java_Class { Iterator<Decl> it = type_dependencies().iterator(); while(it.hasNext()) { Decl t = it.next(); - t.Java_emitUserTypeDeps(env, t.getName(), outputCode); - if(outputCode) { - env.println(t.getName()+".register(e);"); + if( outputCode){// && t.getType().isUserType() ) + //env.println(t.getName()+".register(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() ); + String refpath = (via == null) ? "directly" : "indirectly via "+via; + env.println(" //Depends ("+refpath+") on "+t.getName() ); } - } - } + } + } } + public void Decl.Java_emitUserTypeRefs(Java_env env, String via, boolean outputCode) { if( isReferenced() ) { Iterator<Decl> it = type_references().iterator(); @@ -368,19 +335,18 @@ aspect Java_Class { env.println(t.getName()+".register(e);"); } else { // Just output a comment String refpath = (via == null) ? "directly" : "indirectly via "+via; - env.println(" //Is referenced by ("+refpath+") on "+t.getName() ); + env.println(" //Is referenced ("+refpath+") by "+t.getName() ); } } - } + } } - public void Decl.Java_emitRegisterEncoder(Java_env env) { env.println("public static void register(Encoder e) throws IOException {"); env.indent(); Java_emitUserTypeDeps(env, null, false); //XXX false -> generate no code - env.println("e.register(new Dispatcher());"); + env.println("e.register(Dispatcher.singleton());"); env.unindent(); env.println("}"); env.println(); @@ -392,20 +358,21 @@ aspect Java_Class { env.println("package " + pack + ";"); } + env.println("import se.lth.control.labcomm"+env.verStr+".Constant;"); env.println("import se.lth.control.labcomm"+env.verStr+".SampleType;"); - if (getType().Java_needInstance() || hasDependencies()) { + if (getType().Java_needInstance() || hasDependencies() || isReferenced()) { env.println("import se.lth.control.labcomm"+env.verStr+".Encoder;"); env.println("import se.lth.control.labcomm"+env.verStr+".SampleDispatcher;"); env.println("import se.lth.control.labcomm"+env.verStr+".SampleHandler;"); - env.println(); - } - - if (getType().Java_needInstance()) { +// env.println(); +// } +// +// if (getType().Java_needInstance()) { env.println("import java.io.IOException;"); env.println("import se.lth.control.labcomm"+env.verStr+".Decoder;"); } - // For types without type_dependencies and not needing an instance, + // For types without type_dependencies and not needing an instance, // currently just an empty class is generated env.println("public class " + getName() + " implements SampleType {"); @@ -438,6 +405,7 @@ aspect Java_Class { } env.println("import java.io.IOException;"); + env.println("import se.lth.control.labcomm"+env.verStr+".Constant;"); env.println("import se.lth.control.labcomm"+env.verStr+".Decoder;"); env.println("import se.lth.control.labcomm"+env.verStr+".SampleDispatcher;"); env.println("import se.lth.control.labcomm"+env.verStr+".Encoder;"); @@ -446,7 +414,7 @@ aspect Java_Class { env.println(); env.print("public class " + getName()); // TODO: ? -// Code for making samples of user types extend their type +// Code for making samples of user types extend their type // currently commented out. Is this a good idea or not? // // if(getType().isUserType()) { @@ -465,9 +433,9 @@ aspect Java_Class { env.println(") throws Exception;"); env.println("}"); env.println(); - env.println("public static void register(Decoder d, SampleHandler h) throws IOException {"); + env.println("public static void register(Decoder d, Handler h) throws IOException {"); env.indent(); - env.println("d.register(new Dispatcher(), h);"); + env.println("d.register(Dispatcher.singleton(), h);"); env.unindent(); env.println("}"); env.println(); @@ -482,21 +450,37 @@ aspect Java_Class { env.println("}"); env.println(); } + //public void TypeDecl.Java_emitSignature(Java_env env) { + // Signature signature = getSignature(); + // signature.Java_emitSignature(env, true); + //} public void Decl.Java_emitSignature(Java_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 + Java_emitFlatSignature(env); + //if(isReferenced() || isSampleDecl()){ + // Signature signature = getSignature(); + // signature.Java_emitSignature(env, !isSampleDecl()); + //} + } + + public void Decl.Java_emitFlatSignature(Java_env env){ env.println("private static byte[] signature = new byte[] {"); - env.indent(); - SignatureList signature = signature(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); - if (data != null) { - env.print(signature.getIndent(i)); - for (int j = 0 ; j < data.length ; j++) { - env.print(data[j] + ", "); + 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(); } @@ -505,45 +489,101 @@ aspect Java_Class { env.println("};"); env.unindent(); env.println(); - } - public void Decl.Java_emitDispatcher(Java_env env, boolean canDecodeAndHandle) { - env.println("private static class Dispatcher implements SampleDispatcher {"); + + //XXX TODO: refactor: split into a static class ("TypeDefSingleton"?)and a (smaller) dispatcher + public void Decl.Java_emitDispatcher(Java_env env, boolean isSample) { + String genericStr = env.versionHasMetaData()?"<"+getName()+">":""; + env.println("private static class Dispatcher implements SampleDispatcher "+genericStr+"{"); env.indent(); - env.println(); - env.println("public Class getSampleClass() {"); + env.println(); + env.println("private static Dispatcher singleton;"); + env.println(); + env.println("public synchronized static Dispatcher singleton() {"); + env.indent(); + env.println("if(singleton==null) singleton=new Dispatcher();"); + env.println("return singleton;"); + env.unindent(); + env.println("}"); + env.println(); + env.println("public Class"+genericStr+" getSampleClass() {"); env.indent(); env.println("return " + getName() + ".class;"); env.unindent(); env.println("}"); - env.println(); + env.println(); env.println("public String getName() {"); env.indent(); env.println("return \"" + getName() + "\";"); env.unindent(); env.println("}"); - env.println(); + env.println(); + env.println("public byte getTypeDeclTag() {"); + env.indent(); + if(env.version == 2006) { + if(isSample) { + env.println("return Constant.SAMPLE;"); + } else { + env.println("return Constant.TYPEDEF;"); + } + } else { + if(isSample) { + env.println("return Constant.SAMPLE_DEF;"); + } else { + env.println("return Constant.TYPE_DEF;"); + } + } + env.unindent(); + env.println("}"); + env.println(); + env.println("public boolean isSample() {"); + env.indent(); + env.println("return "+isSample+";"); + env.unindent(); + env.println("}"); + env.println("public boolean 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 boolean isSample() {"); + 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) throws IOException{"); +// 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 boolean canDecodeAndHandle() {"); env.indent(); - env.println("return "+canDecodeAndHandle+";"); + env.println("return "+isSample+";"); env.unindent(); env.println("}"); - env.println(); + env.println(); env.println("public void decodeAndHandle(Decoder d,"); env.println(" SampleHandler h) throws Exception {"); env.indent(); - if( canDecodeAndHandle) { + if( isSample) { if (isVoid()) { env.println(getName() + ".decode(d);"); - env.println("((Handler)h).handle_" + getName() + "();"); + env.println("((Handler)h).handle_" + getName() + "();"); } else { - env.println("((Handler)h).handle_" + getName() + "(" + getName() + ".decode(d));"); + env.println("((Handler)h).handle_" + getName() + "(" + getName() + ".decode(d));"); } } else { env.println("throw new Exception(\"A typedef has no handler, the corresponding method on the sample class should be called.\");"); @@ -590,8 +630,8 @@ aspect Java_Class { } public void Type.Java_emitEncoder(Java_env env, String name) { - throw new Error(this.getClass().getName() + - ".Java_emitEncoder(Java_env env, String name)" + + throw new Error(this.getClass().getName() + + ".Java_emitEncoder(Java_env env, String name)" + " not declared"); } @@ -631,10 +671,10 @@ aspect Java_Class { env.print_block_end(); } } - + public String Exp.Java_emitEncoder(Java_env env, String name) { - throw new Error(this.getClass().getName() + - ".Java_emitEncoder(Java_env env, String name)" + + throw new Error(this.getClass().getName() + + ".Java_emitEncoder(Java_env env, String name)" + " not declared"); } @@ -679,8 +719,8 @@ aspect Java_Class { } public void Type.Java_emitDecoder(Java_env env, String name) { - throw new Error(this.getClass().getName() + - ".Java_emitDecoder(Java_env env, String name)" + + throw new Error(this.getClass().getName() + + ".Java_emitDecoder(Java_env env, String name)" + " not declared"); } @@ -712,7 +752,7 @@ aspect Java_Class { } for (int i = 0 ; i < getNumExp() ; i++) { String limit = "i_" + (baseDepth + i) + "_max"; - env.print(name + " = "); + env.print(name + " = "); Java_emitNew(env, limit, getNumExp() - i); env.println(";"); name = name + env.print_for_begin(limit); @@ -726,8 +766,8 @@ aspect Java_Class { } public void Exp.Java_emitDecoder(Java_env env) { - throw new Error(this.getClass().getName() + - ".Java_emitDecoder(Java_env env)" + + throw new Error(this.getClass().getName() + + ".Java_emitDecoder(Java_env env)" + " not declared"); } @@ -758,8 +798,8 @@ aspect Java_Class { } public void Type.Java_emitNew(Java_env env, String size) { - throw new Error(this.getClass().getName() + - ".Java_emitNew(Java_env env, String size)" + + throw new Error(this.getClass().getName() + + ".Java_emitNew(Java_env env, String size)" + " not declared"); } @@ -774,8 +814,8 @@ aspect Java_Class { } public void Type.Java_emitTypePrefix(Java_env env) { - throw new Error(this.getClass().getName() + - ".Java_emitTypePrefix(Java_env env)" + + throw new Error(this.getClass().getName() + + ".Java_emitTypePrefix(Java_env env)" + " not declared"); } @@ -791,7 +831,7 @@ aspect Java_Class { env.print(getName()); } else { decl().getType().Java_emitTypePrefix(env); - } + } } public void ArrayType.Java_emitTypePrefix(Java_env env){ @@ -808,7 +848,7 @@ aspect Java_Class { public void UserType.Java_emitTypeSuffix(Java_env env) { if (! Java_needInstance()) { decl().getType().Java_emitTypeSuffix(env); - } + } } public void ArrayType.Java_emitTypeSuffix(Java_env env){ @@ -819,8 +859,8 @@ aspect Java_Class { } public boolean Type.Java_needInstance() { - throw new Error(this.getClass().getName() + - ".Java_needInstance()" + + throw new Error(this.getClass().getName() + + ".Java_needInstance()" + " not declared"); } @@ -853,8 +893,8 @@ aspect Java_Class { } public void Type.Java_emitInstance(Java_env env) { - throw new Error(this.getClass().getName() + - ".Java_emitInstance(Java_env env)" + + throw new Error(this.getClass().getName() + + ".Java_emitInstance(Java_env env)" + " not declared"); } @@ -892,12 +932,12 @@ aspect Java_Class { public void Field.Java_emitField(Java_env env) { env.print("public "); getType().Java_emitType(env); - env.println(" " + getName() + ";"); + env.println(" " + getName() + ";"); } public void Type.Java_emitType(Java_env env) { - throw new Error(this.getClass().getName() + - ".Java_emitType(Java_env env)" + + throw new Error(this.getClass().getName() + + ".Java_emitType(Java_env env)" + " not declared"); } @@ -926,6 +966,53 @@ aspect Java_Class { public void StructType.Java_emitType(Java_env env){ env.print(Java_structName()); } +} + +aspect Java_Signature { + public void Signature.Java_emitSignature(Java_env env, boolean decl){ + // XXX should sendOnlyFlatSignatures be kept somewhere? + //SignatureList sl = (parentDecl().sendOnlyFlatSignatures(env)) ? getFlatSignatureList() : getSignatureList(); + SignatureList sl = getSignatureList(); + sl.Java_emitSignature(env, decl); + } + +// public void Signature.Java_emitHierarchicalSignature(Java_env env, boolean decl){ +// SignatureList sl = getSignatureList(); +// sl.Java_emitSignature(env, decl); +// } +// + public abstract void SignatureLine.Java_emitSignature(Java_env env, boolean decl); + + public void TypeRefSignatureLine.Java_emitSignature(Java_env env, boolean isDecl){ + env.print(getIndentString()); + env.println("e.encodePacked32(e.getTypeId("+decl.getName()+".class));"); + } + + public void DataSignatureLine.Java_emitSignature(Java_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.Java_emitSignature(Java_env env, boolean decl) { + env.println("private static void emitSignature(Encoder e) throws IOException{"); + 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.Java_emitSignature(env, decl); + } + env.println("}"); + env.unindent(); + } } @@ -939,14 +1026,14 @@ aspect Java_Info { } public void Decl.Java_info(Java_env env) { - throw new Error(this.getClass().getName() + - ".Java_info(Java_env env)" + + throw new Error(this.getClass().getName() + + ".Java_info(Java_env env)" + " not declared"); } public void TypeDecl.Java_info(Java_env env) { env.print(",Java,typedef," + getName() + ","); - getType().Java_emitType(env); + getType().Java_emitType(env); env.print(",not_applicable_for_Java"); env.println(); } diff --git a/compiler/LabComm.ast b/compiler/LabComm.ast index 6f290e58d497c19dc4f78ffb443fe6dd3278944a..95151ddd0dca02ee2fd5e7ae04daa645eb9972ea 100644 --- a/compiler/LabComm.ast +++ b/compiler/LabComm.ast @@ -1,6 +1,21 @@ Program ::= Decl*; -abstract Decl ::= Type <Name:String>; +//TODO: Add signatures to the abstract grammar, so that +//they can be extended and refined by more than one aspect. +//sketch: +Signature ::= SignatureList FlatSignatureList:SignatureList; +SignatureList ::= SignatureLine*; +abstract SignatureLine ::= <Indent:int> <Comment:String>; +abstract DataSignatureLine : SignatureLine; +ByteArraySignatureLine : DataSignatureLine ::= <Data:byte[]>; +IntSignatureLine : DataSignatureLine ::= <Data:int>; +StringSignatureLine : DataSignatureLine ::= <Data:String>; +TypeRefSignatureLine : SignatureLine ::= Decl; + + +//abstract Decl ::= Type <Name:String>; +// the signature list be defined as a non-terminal attribute: +abstract Decl ::= Type <Name:String> /Signature/; TypeDecl : Decl; SampleDecl : Decl; diff --git a/compiler/LabComm.java b/compiler/LabComm.java index a2250d91ad3b2d414a9134dc88d5705c0348b9a1..63373011f4baa1988b0cd514bdd62d6f48b9204f 100644 --- a/compiler/LabComm.java +++ b/compiler/LabComm.java @@ -78,6 +78,7 @@ public class LabComm { } private static void genCS(Program p, String csName, String csNamespace, int ver) { +// throw new Error("C# generation currently disabled"); try { p.CS_gen(csName, csNamespace, ver); } catch (IOException e) { diff --git a/compiler/LabCommTokens.jrag b/compiler/LabCommTokens.jrag new file mode 100644 index 0000000000000000000000000000000000000000..7b7b2e3fb37bc7adf2b6f719dd80c86678aff5d5 --- /dev/null +++ b/compiler/LabCommTokens.jrag @@ -0,0 +1,19 @@ +aspect LabCommTokens { + + public static final int ASTNode.LABCOMM_VERSION = 0x01; + public static final int ASTNode.LABCOMM_SAMPLE = 0x02; // The flat signature + public static final int ASTNode.LABCOMM_TYPE_DEF = 0x03; // and type declarations, hierarchically + + public static final int ASTNode.LABCOMM_ARRAY = 0x10; + public static final int ASTNode.LABCOMM_STRUCT = 0x11; + + public static final int ASTNode.LABCOMM_BOOLEAN = 0x20; + public static final int ASTNode.LABCOMM_BYTE = 0x21; + public static final int ASTNode.LABCOMM_SHORT = 0x22; + public static final int ASTNode.LABCOMM_INT = 0x23; + public static final int ASTNode.LABCOMM_LONG = 0x24; + public static final int ASTNode.LABCOMM_FLOAT = 0x25; + public static final int ASTNode.LABCOMM_DOUBLE = 0x26; + public static final int ASTNode.LABCOMM_STRING = 0x27; + +} diff --git a/compiler/LabCommmTokens.jrag b/compiler/LabCommmTokens.jrag deleted file mode 100644 index 351e5b4b34dfc4dd1b915018160b548605f861d8..0000000000000000000000000000000000000000 --- a/compiler/LabCommmTokens.jrag +++ /dev/null @@ -1,18 +0,0 @@ -aspect LabCommTokens { - - public static final int ASTNode.LABCOMM_TYPEDEF = 0x01; - public static final int ASTNode.LABCOMM_SAMPLE = 0x02; - - public static final int ASTNode.LABCOMM_ARRAY = 0x10; - public static final int ASTNode.LABCOMM_STRUCT = 0x11; - - public static final int ASTNode.LABCOMM_BOOLEAN = 0x20; - public static final int ASTNode.LABCOMM_BYTE = 0x21; - public static final int ASTNode.LABCOMM_SHORT = 0x22; - public static final int ASTNode.LABCOMM_INT = 0x23; - public static final int ASTNode.LABCOMM_LONG = 0x24; - public static final int ASTNode.LABCOMM_FLOAT = 0x25; - public static final int ASTNode.LABCOMM_DOUBLE = 0x26; - public static final int ASTNode.LABCOMM_STRING = 0x27; - -} \ No newline at end of file diff --git a/compiler/NameAnalysis.jrag b/compiler/NameAnalysis.jrag index e77264af0f1886fc0ff9da55029dbf5d530d8060..bf060556d7ffd2be1ca7b52ffee2ff92331093f7 100644 --- a/compiler/NameAnalysis.jrag +++ b/compiler/NameAnalysis.jrag @@ -34,7 +34,11 @@ aspect NameAnalysis { return null; } - syn TypeDecl UserType.decl() = lookupType(getName()); + //syn TypeDecl UserType.decl() = lookupType(getName()); + syn TypeDecl Type.decl(); + eq Type.decl() = null; + eq UserType.decl() = lookupType(getName()); + eq PrimType.decl() = null; //HERE BE DRAGONS XXX public void ASTNode.nameCheck() { diff --git a/compiler/PrettyPrint.jrag b/compiler/PrettyPrint.jrag index 371a76c281984c8b651e27b15fcc978cb2b531c5..405bee32ac0fcea25c7653af3ff69db4796a1322 100644 --- a/compiler/PrettyPrint.jrag +++ b/compiler/PrettyPrint.jrag @@ -68,6 +68,10 @@ aspect PrettyPrint { out.print("void"); } + public String PrimType.toString() { + return getName(); + } + public void PrimType.ppPrefix(PrintStream out) { out.print(getName()); } diff --git a/compiler/Python_CodeGen.jrag b/compiler/Python_CodeGen.jrag index 7a41813a73ccde3f497e9772c5b6ea68a8a4a6e1..4d19724b033e5e91b57e5352d2b4db948b59c502 100644 --- a/compiler/Python_CodeGen.jrag +++ b/compiler/Python_CodeGen.jrag @@ -81,17 +81,16 @@ aspect Python_CodeGen { env.println("# Auto generated " + baseName); env.println(); env.println("import labcomm"); + env.println("import StringIO"); env.println(); Python_genTypes(env); -/* Typedefs curenntly disabled - env.println("typedef = ["); - env.indent(); - for (int i = 0 ; i < getNumDecl() ; i++) { - getDecl(i).Python_genTypedefListEntry(env); - } - env.unindent(); - env.println("]"); -*/ + //env.println("typedef = ["); + //env.indent(); + //for (int i = 0 ; i < getNumDecl() ; i++) { + // getDecl(i).Python_genTypedefListEntry(env); + //} + //env.unindent(); + //env.println("]"); env.println("sample = ["); env.indent(); for (int i = 0 ; i < getNumDecl() ; i++) { @@ -229,3 +228,4 @@ aspect PythonTypes { } } + diff --git a/compiler/RAPID_CodeGen.jrag b/compiler/RAPID_CodeGen.jrag index 5e49e260fc6b4b77c3ccd7763f5883d36a7ebbd8..b367ee5720eb34ff4cd308cd4eeab56a6d1002cd 100644 --- a/compiler/RAPID_CodeGen.jrag +++ b/compiler/RAPID_CodeGen.jrag @@ -97,19 +97,21 @@ aspect RAPID_CodeGen { throw new UnsupportedOperationException("RAPID code generation (currently) does not support "+getClass().getSimpleName()); } - public void SampleDecl.RAPID_gen(RAPID_env env) { - // Add type declarations - String fullName = getType().RAPID_AddType(env, getName()); - // Add signature constants - String sig_len_name = "signature_len_" + getName(); - String sig_name = "signature_" + getName(); - SignatureList sig = signature(env.version); + 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); StringBuilder sb = new StringBuilder(); sb.append("["); byte[] d = null; int sig_len = 0; for (int i = 0; i < sig.size(); i++) { - d = sig.getData(i); + d = sig.getData(i, env.version); for (int j = 0; d != null && j < d.length; j++) { sb.append(d[j] + ","); sig_len++; @@ -119,8 +121,18 @@ aspect RAPID_CodeGen { sb.append("]"); env.addConstant("num", sig_len_name, "" + sig_len); env.addConstant("byte", sig_name + "{" + sig_len_name + "}", - sb.toString()); - + sb.toString()); + } + + public void SampleDecl.RAPID_gen(RAPID_env env) { + // Add type declarations + String fullName = getType().RAPID_AddType(env, getName()); + // Add signature constants + String sig_len_name = "signature_len_" + getName(); + String sig_name = "signature_" + getName(); + + RAPID_emitFlatSignature(env, sig_len_name, sig_name); + // Add decode procedures ArrayList<String> params = new ArrayList<String>(); ArrayList<String> stmts = new ArrayList<String>(); diff --git a/compiler/Signature.jrag b/compiler/Signature.jrag index 973afb4af13e96babc1170d6a397b7a3eca62ee1..5bb590719f29411f59f292dca0367a9cd4f0e65b 100644 --- a/compiler/Signature.jrag +++ b/compiler/Signature.jrag @@ -2,54 +2,92 @@ import java.util.*; aspect Signature { - public class SignatureLine { - - private int indent; - private byte[] data; - private String comment; + syn boolean Decl.isSampleDecl(); + eq TypeDecl.isSampleDecl() = false; + eq SampleDecl.isSampleDecl() = true; + + syn boolean Decl.sendOnlyFlatSignatures(Java_env env) = (env.version==2006); + + eq Decl.getSignature().parentDecl() = this; + eq Signature.getSignatureList().parentDecl() = parentDecl(); + + inh Decl Signature.parentDecl(); + inh Decl SignatureList.parentDecl(); + + + syn nta Signature Decl.getSignature() { + SignatureList sl = new SignatureList(); + genSigLineForDecl(sl, true); + SignatureList fsl = new SignatureList(); + flatSignature(fsl); + Signature sig = new Signature(); + sig.setSignatureList(sl); + sig.setFlatSignatureList(fsl); + // HERE BE DRAGONS. Is this correct for a NTA? + setSignature(sig); + return sig; + } - public SignatureLine(int indent, byte[] data, String comment) { - this.indent = indent; - this.data = data; - this.comment = comment; - } + //syn nta SignatureList Signature.getSignatureList() { + // SignatureList result = new SignatureList(); + // genSigLineForDecl(result, true); + // return result; + //} - public int getIndent() { - return indent; + public String SignatureLine.getIndentString() { + StringBuffer result = new StringBuffer(); + int indent = getIndent(); + for (int i = 0 ; i < indent ; i++) { + result.append(" "); + } + return result.toString(); } - public byte[] getData() { - return data; + //Very temporary kludge: the flat signature generation + //predates the SignatureLine class hierarchy. This hack + //returns size zero arrays, which doesn't break the sig + //generation + //public byte[] getData() { + syn byte[] SignatureLine.getData(int version) { + return new byte[0]; } - public String getComment() { - return comment; + private Decl TypeRefSignatureLine.decl; + public TypeRefSignatureLine.TypeRefSignatureLine(int indent, Decl decl, String comment) { + super(indent, comment); + this.decl = decl; + } + public void SignatureList.addTypeRef(Decl type, String comment) { + addSignatureLine(new TypeRefSignatureLine(indent, type, comment)); } - } + public ByteArraySignatureLine.ByteArraySignatureLine(int indent, byte[] data, String comment) { + super(indent, comment); + setData(data); + } - public class SignatureList { + public IntSignatureLine.IntSignatureLine(int indent, int data, String comment) { + super(indent, comment); + setData(data); + } - private int indent; - private final int ver; - private ArrayList list = new ArrayList(); - - public SignatureList(int version) { - this.ver = version; + public void SignatureList.add(byte[] data, String comment) { + addSignatureLine(new ByteArraySignatureLine(indent, data, comment)); } - public void add(byte[] data, String comment) { - list.add(new SignatureLine(indent, data, comment)); + public void SignatureList.addInt(int data, String comment) { + addSignatureLine(new IntSignatureLine(indent, data, comment)); } - public void addInt(int value, String comment) { - switch(ver) { + protected byte[] DataSignatureLine.getIntBytes(int value, int version) { + byte data[]; + switch(version) { case 2006: // Use old encoding with 32 bit integers - byte[] data = new byte[4]; + data = new byte[4]; for (int i = 0 ; i < 4 ; i++) { data[3 - i] = (byte)((value >> (8 * i)) & 0xff); } - add(data, comment); + //add(data, comment); break; case 2013: // Use new encoding with varints byte[] tmp = new byte[5]; @@ -62,56 +100,146 @@ aspect Signature { for (i = i - 1, j = 0 ; i >= 0 ; i--, j++) { packed[j] = (byte)(tmp[i] | (i!=0?0x80:0x00)); } - add(packed, comment); + //add(packed, comment); + data = packed; break; default: - throw new RuntimeException("Version = "+ver+". This should never happen."); + throw new RuntimeException("Unsupported version = "+version+". This should never happen."); } + return data; + } + + eq IntSignatureLine.getData(int version) { + return getIntBytes(getData(), version); + } + + public void SignatureList.addString(String data, String comment) { + addSignatureLine(new StringSignatureLine(indent, comment, data)); } + eq StringSignatureLine.getData(int version) { + byte[] lenBytes = getIntBytes(getData().length(), version); + byte[] data = new byte[lenBytes.length+getData().length()]; - 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); + // first add the encoded length + for (int i = 0 ; i < lenBytes.length ; i++) { + data[i] = lenBytes[i]; } - add(data, null); + // and then the actual chars + for (int i = 0 ; i < getData().length() ; i++) { + int idx = lenBytes.length + i; + data[idx] = (byte)(getData().charAt(i) & 0xff); + } + return data; } - public int size() { - return list.size(); + public int SignatureList.size() { + return getNumSignatureLine(); } - public String getIndent(int i) { + public String SignatureList.getIndent(int i) { StringBuffer result = new StringBuffer(); - int indent = ((SignatureLine)list.get(i)).getIndent(); + int indent = getSignatureLine(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 byte[] SignatureList.getData(int i, int version) { + return getSignatureLine(i).getData(version); } - public String getComment(int i) { - return ((SignatureLine)list.get(i)).getComment(); + public String SignatureList.getComment(int i) { + return getSignatureLine(i).getComment(); } - public void indent() { + private int SignatureList.indent; + + public void SignatureList.indent() { indent++; } - public void unindent() { + public void SignatureList.unindent() { indent--; } + + public void ASTNode.genSigLineForDecl(SignatureList list, boolean decl) { + throw new Error(this.getClass().getName() + + ".genSigLineForDecl(SignatureList list)" + + " not declared"); + } + + public void TypeDecl.genSigLineForDecl(SignatureList list, boolean decl) { + System.out.println("************ TypeDecl.genSigLine("+decl+").... for "+getName()); + if(decl){ + getType().genSigLineForDecl(list, decl); + }else{ + list.addTypeRef(this, "//TODO (from list.addTypeRef)"); + } + } + + public void SampleDecl.genSigLineForDecl(SignatureList list, boolean decl) { + System.out.println("************ SampleDecl.genSigLine("+decl+").... for "+getName()); + getType().genSigLineForDecl(list, decl); + } + + public void VoidType.genSigLineForDecl(SignatureList list, boolean decl) { + list.addInt(LABCOMM_STRUCT, "void"); + list.addInt(0, null); + } + + public void PrimType.genSigLineForDecl(SignatureList list, boolean decl) { + list.addInt(getToken(), null); + } + + public void UserType.genSigLineForDecl(SignatureList list, boolean decl) { + if(decl){ + System.out.println("************ UserType.genSigLine("+decl+").... for "+getName()); + TypeDecl thet=lookupType(getName()); + System.out.println("************ thet: "+thet.getName() +":"+thet.getType()); + thet.genSigLineForDecl(list, decl); + }else{ + //System.out.println("************ UserType.genSigLine("+decl+").... for "+getName()); + TypeDecl thet = lookupType(getName()); + // System.out.println("************ thet: "+thet.getName() +":"+thet.getType()); + list.addTypeRef(thet, null); + } + } + + public void ArrayType.genSigLineForDecl(SignatureList list, boolean decl) { + list.addInt(LABCOMM_ARRAY, signatureComment()); + list.indent(); + list.addInt(getNumExp(), null); + for (int i = 0 ; i < getNumExp() ; i++) { + getExp(i).genSigLineForDecl(list, false); + } + getType().genSigLineForDecl(list, false); + list.unindent(); + list.add(null, "}"); + } + + public void StructType.genSigLineForDecl(SignatureList list, boolean decl) { + list.addInt(LABCOMM_STRUCT, "struct { " + getNumField() + " fields"); + list.indent(); + list.addInt(getNumField(), null); + for (int i = 0 ; i < getNumField() ; i++) { + getField(i).genSigLineForDecl(list, false); + } + list.unindent(); + list.add(null, "}"); + } + + public void Field.genSigLineForDecl(SignatureList list, boolean decl) { + list.addString(getName(), signatureComment()); + getType().genSigLineForDecl(list, decl); + } + + public void IntegerLiteral.genSigLineForDecl(SignatureList list, boolean decl) { + list.addInt(Integer.parseInt(getValue()), null); } - public SignatureList Decl.signature(int version) { - SignatureList result = new SignatureList(version); - flatSignature(result); - return result; + public void VariableSize.genSigLineForDecl(SignatureList list, boolean decl) { + list.addInt(0, null); } } diff --git a/compiler/TypeCheck.jrag b/compiler/TypeCheck.jrag index a61224b070c09cc8dcdba548c198011050255acb..a640ace5098013bef6cad31767a96220aa66b8a7 100644 --- a/compiler/TypeCheck.jrag +++ b/compiler/TypeCheck.jrag @@ -9,13 +9,7 @@ aspect TypeCheck { syn boolean Type.isNull(); eq Type.isNull() = false; eq VoidType.isNull() = true; - eq UserType.isNull() { - if (decl() != null) { - return decl().isNull(); - } else { - return false; - } - } + eq UserType.isNull() = decl().isNull(); syn boolean TypeDecl.isNull(); eq TypeDecl.isNull() = getType().isNull(); diff --git a/compiler/TypeReferences.jrag b/compiler/TypeReferences.jrag index 81ca242ab0f834c01ff79f3c57e68938b56017e1..eb4c7b569d69d1da38b54bf7b1bdaa3cb11f0761 100644 --- a/compiler/TypeReferences.jrag +++ b/compiler/TypeReferences.jrag @@ -19,6 +19,16 @@ aspect Type_References { to Decl.type_dependencies() for parentDecl(); + UserType contributes decl() + when parentDecl() != null + to Decl.type_dependencies() + for parentDecl(); + /* + Field contributes getType().decl() + when parentDecl() != null && getType().isLeafType() + to Decl.type_dependencies() + for parentDecl(); + */ // The references from other type declarations to a Decl. coll Set<Decl> Decl.type_references() [new HashSet<Decl>()] with add; diff --git a/compiler/build.xml b/compiler/build.xml index b7e303599c60ffa3993180e0eb47a43578d37081..5c80942a1f610895c4703c03fef339bb328cd6a2 100644 --- a/compiler/build.xml +++ b/compiler/build.xml @@ -29,7 +29,9 @@ classpath="tools/jastadd2.jar"/> <!-- compile sources --> <target name="build" depends="gen"> <javac debug="true" nowarn="true" srcdir="." includes="**/*.java" excludes="test/** examples/**" classpath=".:${tools}/beaver-rt.jar:${tools}/junit.jar" - fork="true" memoryMaximumSize="128M"/> + fork="true" memoryMaximumSize="128M"> + <!-- compilerarg value="-Xlint"/ --> + </javac> </target> diff --git a/lib/c/labcomm_private.h b/lib/c/labcomm_private.h index f20ba0ee0f9e70a3bc037683870eb5aeac55b562..82bfc41c3315fb6b3a54154af9a3809e3401f5cd 100644 --- a/lib/c/labcomm_private.h +++ b/lib/c/labcomm_private.h @@ -46,24 +46,23 @@ #define LABCOMM_PRAGMA 0x3f #define LABCOMM_USER 0x40 /* ..0xffffffff */ - /* * Predefined aggregate type indices */ -#define LABCOMM_ARRAY 0x10 -#define LABCOMM_STRUCT 0x11 +#define LABCOMM_ARRAY 0x10 +#define LABCOMM_STRUCT 0x11 /* * Predefined primitive type indices */ -#define LABCOMM_BOOLEAN 0x20 -#define LABCOMM_BYTE 0x21 -#define LABCOMM_SHORT 0x22 -#define LABCOMM_INT 0x23 -#define LABCOMM_LONG 0x24 -#define LABCOMM_FLOAT 0x25 -#define LABCOMM_DOUBLE 0x26 -#define LABCOMM_STRING 0x27 +#define LABCOMM_BOOLEAN 0x20 +#define LABCOMM_BYTE 0x21 +#define LABCOMM_SHORT 0x22 +#define LABCOMM_INT 0x23 +#define LABCOMM_LONG 0x24 +#define LABCOMM_FLOAT 0x25 +#define LABCOMM_DOUBLE 0x26 +#define LABCOMM_STRING 0x27 /* diff --git a/lib/csharp/se/lth/control/labcomm/Constant.cs b/lib/csharp/se/lth/control/labcomm/Constant.cs index 170cb55055244cf0ccc53bc3daca5a0ecc7260cf..cc7deac9bae1a29ed7c9caa6c5fe7dd17cd079c8 100644 --- a/lib/csharp/se/lth/control/labcomm/Constant.cs +++ b/lib/csharp/se/lth/control/labcomm/Constant.cs @@ -8,7 +8,9 @@ namespace se.lth.control.labcomm { * Allowed packet tags */ public const int VERSION = 0x01; - public const int SAMPLE = 0x02; + public const int SAMPLE_DEF = 0x02; + public const int TYPE_DEF = 0x03; + public const int TYPE_BINDING = 0x04; public const int PRAGMA = 0x3f; public const int FIRST_USER_INDEX = 0x40; /* ..0xffffffff */ diff --git a/lib/csharp/se/lth/control/labcomm/DecoderChannel.cs b/lib/csharp/se/lth/control/labcomm/DecoderChannel.cs index 19e4e0db484c5c4d8cef067c0403c450d4c14fe4..60e94b12ef6a0c36d5ce16a44bc8270b19132442 100644 --- a/lib/csharp/se/lth/control/labcomm/DecoderChannel.cs +++ b/lib/csharp/se/lth/control/labcomm/DecoderChannel.cs @@ -28,7 +28,7 @@ namespace se.lth.control.labcomm { version + " != " + Constant.CURRENT_VERSION); } } break; - case Constant.SAMPLE: { + case Constant.SAMPLE_DEF: { int index = decodePacked32(); String name = decodeString(); int signature_length = decodePacked32(); diff --git a/lib/csharp/se/lth/control/labcomm/EncoderChannel.cs b/lib/csharp/se/lth/control/labcomm/EncoderChannel.cs index ca717d501dc98475145ba17c87af41ea1282c157..7ecd506bae56a06864911feb1a941040bf568113 100644 --- a/lib/csharp/se/lth/control/labcomm/EncoderChannel.cs +++ b/lib/csharp/se/lth/control/labcomm/EncoderChannel.cs @@ -23,7 +23,7 @@ namespace se.lth.control.labcomm { public void register(SampleDispatcher dispatcher) { int index = registry.add(dispatcher); - begin(Constant.SAMPLE); + begin(Constant.SAMPLE_DEF); encodePacked32(index); encodeString(dispatcher.getName()); byte[] signature = dispatcher.getSignature(); diff --git a/lib/java/se/lth/control/labcomm/DecoderChannel.java b/lib/java/se/lth/control/labcomm/DecoderChannel.java index 2539fa6f2f19cca57733d6cab4641e400c59582c..2ff5377c7eac3c4ef1e22f3b8d508b9c6e6f5703 100644 --- a/lib/java/se/lth/control/labcomm/DecoderChannel.java +++ b/lib/java/se/lth/control/labcomm/DecoderChannel.java @@ -12,11 +12,10 @@ public class DecoderChannel implements Decoder { private DataInputStream in; private DecoderRegistry registry; - public DecoderChannel(InputStream in, DecoderRegistry reg) throws IOException { + private DecoderChannel(InputStream in, DecoderRegistry reg) throws IOException { this.in = new DataInputStream(in); - this.registry = reg; + registry = reg; } - public DecoderChannel(InputStream in) throws IOException { this(in, new DecoderRegistry()); } diff --git a/lib/java/se/lth/control/labcomm/SampleDispatcher.java b/lib/java/se/lth/control/labcomm/SampleDispatcher.java index 8051296a2104ddf07522d154686221f308934605..a8788284d2c5584e8177ab09bf64d7e4e55cdb3d 100644 --- a/lib/java/se/lth/control/labcomm/SampleDispatcher.java +++ b/lib/java/se/lth/control/labcomm/SampleDispatcher.java @@ -1,6 +1,6 @@ package se.lth.control.labcomm; -public interface SampleDispatcher { +public interface SampleDispatcher <T> { public Class getSampleClass(); diff --git a/lib/python/labcomm/LabComm.py b/lib/python/labcomm/LabComm.py index cb65c2b89ad25c4171030e59251e6f54d52721aa..ba12d4cb1d7625438c9e6e5b75da4b655c7b16bb 100644 --- a/lib/python/labcomm/LabComm.py +++ b/lib/python/labcomm/LabComm.py @@ -11,7 +11,7 @@ # | ... # +----+-- # -# LabComm2014 SAMPLE: +# LabComm2014 SAMPLE_DEF: # # +----+----+----+----+ # | id = 0x02 (packed32) @@ -30,7 +30,7 @@ # +----+-- # # LabComm2014 TYPE_DEF: (as SAMPLE_DEF, but signatures are hierarchical, -# i.e., may contain references to other types +# i.e., may contain references to other types # # +----+----+----+----+ # | id = 0x03 (packed32)