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

Merge branch 'master' of gitlab.control.lth.se:anders_blomdell/labcomm

parents f9ba2767 373eac7b
AST
AST/*
LabComm.class
labComm.jar
lib/java/se/lth/control/labcomm/LabComm.class
lib/java/se/lth/control/labcomm/LabCommDecoderChannel.class
lib/java/se/lth/control/labcomm/LabCommDecoder.class
lib/java/se/lth/control/labcomm/LabCommDecoderRegistry.class
lib/java/se/lth/control/labcomm/LabCommDecoderRegistry$Entry.class
lib/java/se/lth/control/labcomm/LabCommDispatcher.class
lib/java/se/lth/control/labcomm/LabCommEncoderChannel.class
lib/java/se/lth/control/labcomm/LabCommEncoder.class
lib/java/se/lth/control/labcomm/LabCommEncoderRegistry.class
lib/java/se/lth/control/labcomm/LabCommEncoderRegistry$Entry.class
lib/java/se/lth/control/labcomm/LabCommHandler.class
lib/java/se/lth/control/labcomm/LabCommReader.class
lib/java/se/lth/control/labcomm/LabCommSample.class
lib/java/se/lth/control/labcomm/LabCommType.class
lib/java/se/lth/control/labcomm/LabCommWriter.class
gen
labcomm.dll
labcomm.jar
example.c
example.h
example.py
examples/wiki_example/example.encoded
example.encoded
examples/simple/*.class
examples/simple/encoded_data
examples/simple/example_decoder
examples/simple/example_encoder
lib/c/test/test_labcomm_basic_type_encoding
lib/c/test/test_labcomm_generated_encoding
lib/java/se/lth/control/labcomm/WriterWrapper.class
lib/c/liblabcomm.so.1
lib/c/test/test_labcomm_pthread_scheduler
lib/c/liblabcomm_plain_c.so.1
lib/c/test/test_signature_plain_c
test/test_signature_numbers
lib/c/test/test_signature_numbers
lib/c/test/test_labcomm
SUBDIRS=compiler lib test examples packaging
export LABCOMM_JAR=$(shell pwd)/compiler/labcomm_compiler.jar
export LABCOMM_JAR=$(shell pwd)/compiler/labcomm2014_compiler.jar
export LABCOMM=java -jar $(LABCOMM_JAR)
.PHONY: all
......
gen
labcomm2006_compiler.jar
labcomm2014_compiler.jar
labcomm_compiler.jar
labcomm2014_compiler.jar
aspect ArrayRewrite {
syn boolean Dim.isVariable() {
for (int i = 0 ; i < getNumExp() ; i++) {
if (getExp(i) instanceof VariableSize) {
return true;
}
}
return false;
}
rewrite ParseArrayType {
when (! getDim(0).isVariable())
to FixedArrayType {
if (getNumDim() == 1) {
return new FixedArrayType(getType(),
getDim(0).getExpList());
} else {
List l = new List();
for (int i = 1 ; i < getNumDim() ; i++) {
l.add(getDim(i));
}
return new FixedArrayType(new ParseArrayType(getType(), l),
getDim(0).getExpList());
}
}
when (getDim(0).isVariable())
to VariableArrayType {
if (getNumDim() == 1) {
return new VariableArrayType(getType(),
getDim(0).getExpList());
} else {
List l = new List();
for (int i = 1 ; i < getNumDim() ; i++) {
l.add(getDim(i));
}
return new VariableArrayType(new ParseArrayType(getType(), l),
getDim(0).getExpList());
}
}
}
}
import java.io.*;
import java.util.*;
aspect CS_CodeGenEnv {
// Environment wrapper for CS-code generation
// handles indentation, file writing,
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();
final private static 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, int version) {
this.version = version;
this.indent = indent;
this.printer = printer;
this.verStr = LabCommVersion.versionString(version);
}
public CS_env(File f, int version) {
this(0, new CS_printer(f), version);
}
public CS_env(PrintStream out, int version) {
this(0, new CS_printer(out), version);
}
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;
if (indent < 0) {
throw new Error("Negative indent level");
}
}
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 UserType.CS_isVoid() = decl().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, int version) throws IOException {
// Registration class
CS_env env = new CS_env(new File(file), version);
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) {
}
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 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){
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(t.getName()+".register(e);");
} else { // Just output a comment
String refpath = (via == null) ? "directly" : "indirectly via "+via;
env.println(" //Depends ("+refpath+") on "+t.getName() );
}
}
}
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);");
env.unindent();
env.println("}");
env.println("public static void registerSampleRef(Encoder e) {");
env.indent();
env.println("e.registerSampleRef(dispatcher);");
env.unindent();
env.println("}");
env.println();
}
public void Decl.CS_emitRegisterDecoder(CS_env env) {
env.println("public static void register(Decoder d, Handler h) {");
env.indent();
env.println("d.register(dispatcher, h);");
env.unindent();
env.println("}");
env.println();
env.println("public static void registerSampleRef(Decoder d) {");
env.indent();
env.println("d.registerSampleRef(dispatcher);");
env.unindent();
env.println("}");
env.println();
}
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() + " : SampleType {");
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();
env.println("}");
}
}
public void SampleDecl.CS_emitClass(CS_env env) {
env.println("/* ");
pp(env.getPrintStream());
env.println("*/");
env.println();
env.println("public class " + getName() + " : Sample {");
env.println();
env.indent();
getType().CS_emitInstance(env);
env.println("public interface Handler : SampleHandler {");
env.print(" void handle(");
if (!isVoid()) {
getType().CS_emitType(env);
env.print(" value");
}
env.println(");");
env.println("}");
env.println();
CS_emitDispatcher(env,true);
CS_emitRegisterEncoder(env);
CS_emitRegisterDecoder(env);
CS_emitEncoder(env);
CS_emitDecoder(env);
CS_emitSignature(env);
env.println("}");
}
public void Decl.CS_emitSignature(CS_env env) {
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.print(String.format("0x%02X, ", 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 static Dispatcher dispatcher = new Dispatcher();");
env.println();
env.println("public SampleDispatcher getDispatcher() {");
env.indent();
env.println("return dispatcher;");
env.unindent();
env.println("}");
env.println();
env.println("private class Dispatcher : SampleDispatcher{");
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 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("/** return the flat signature. */");
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()) {
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(Encoder 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;