From 0a5c322f2081b25c5aa4368dd25c4fdb18f41ac9 Mon Sep 17 00:00:00 2001 From: Anders Blomdell <anders.blomdell@control.lth.se> Date: Tue, 18 Nov 2014 17:19:41 +0100 Subject: [PATCH] C# sample references implemented. --- compiler/CS_CodeGen.jrag | 39 +++++++++++-------- compiler/Java_CodeGen.jrag | 17 ++++---- lib/csharp/se/lth/control/labcomm/Constant.cs | 5 ++- lib/csharp/se/lth/control/labcomm/Decoder.cs | 3 +- .../se/lth/control/labcomm/DecoderChannel.cs | 31 ++++++++++++--- lib/csharp/se/lth/control/labcomm/Encoder.cs | 3 +- .../se/lth/control/labcomm/EncoderChannel.cs | 30 +++++++++++--- lib/csharp/se/lth/control/labcomm/Sample.cs | 8 +++- lib/java/se/lth/control/labcomm/Encoder.java | 1 + .../lth/control/labcomm/EncoderChannel.java | 3 ++ lib/java/se/lth/control/labcomm/Sample.java | 4 +- lib/python/labcomm/LabComm.py | 14 ++++++- test/ref.lc | 6 +-- test/relay_gen_cs.py | 22 ++++++++--- 14 files changed, 133 insertions(+), 53 deletions(-) diff --git a/compiler/CS_CodeGen.jrag b/compiler/CS_CodeGen.jrag index adcb0c6..e1da497 100644 --- a/compiler/CS_CodeGen.jrag +++ b/compiler/CS_CodeGen.jrag @@ -302,15 +302,27 @@ aspect CS_Class { 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.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.singleton(), h);"); + 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(); @@ -402,22 +414,17 @@ aspect CS_Class { //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("private static Dispatcher dispatcher = new Dispatcher();"); env.println(); - env.println("public static Dispatcher singleton() {"); + env.println("public SampleDispatcher getDispatcher() {"); 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.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() + ");"); @@ -546,7 +553,7 @@ aspect CS_Class { case LABCOMM_FLOAT: { env.print("e.encodeFloat"); } break; case LABCOMM_DOUBLE: { env.print("e.encodeDouble"); } break; case LABCOMM_STRING: { env.print("e.encodeString"); } break; - case LABCOMM_SAMPLE: { env.println("e.encodeSampleRef"); } break; + case LABCOMM_SAMPLE: { env.print("e.encodeSampleRef"); } break; } env.println("(" + name + ");"); } @@ -729,7 +736,7 @@ aspect CS_Class { public void PrimType.CS_emitTypePrefix(CS_env env) { switch (getToken()) { case LABCOMM_STRING: { env.print("String"); } break; - case LABCOMM_SAMPLE: { env.print("Sample"); } break; + case LABCOMM_SAMPLE: { env.print("Type"); } break; default: { env.print(getName()); } break; } } @@ -859,7 +866,7 @@ aspect CS_Class { switch (getToken()) { case LABCOMM_STRING: { env.print("String"); } break; case LABCOMM_BOOLEAN: { env.print("bool"); } break; - case LABCOMM_SAMPLE: { env.print("Sample"); } break; + case LABCOMM_SAMPLE: { env.print("Type"); } break; default: { env.print(getName()); } break; } } diff --git a/compiler/Java_CodeGen.jrag b/compiler/Java_CodeGen.jrag index db2d562..7c00bc3 100644 --- a/compiler/Java_CodeGen.jrag +++ b/compiler/Java_CodeGen.jrag @@ -338,7 +338,7 @@ aspect Java_Class { env.indent(); Java_emitUserTypeDeps(env, null, true); - env.println("e.register(Dispatcher.singleton());"); + env.println("e.register(dispatcher);"); env.unindent(); env.println("}"); env.println(); @@ -429,7 +429,7 @@ aspect Java_Class { env.println(); env.println("public static void register(Decoder d, Handler h) throws IOException {"); env.indent(); - env.println("d.register(Dispatcher.singleton(), h);"); + env.println("d.register(dispatcher, h);"); env.unindent(); env.println("}"); env.println(); @@ -490,18 +490,17 @@ aspect Java_Class { //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("private static Dispatcher singleton;"); + env.println("private static Dispatcher dispatcher = new Dispatcher();"); env.println(); - env.println("public synchronized static Dispatcher singleton() {"); + env.println("public SampleDispatcher getDispatcher() {"); env.indent(); - env.println("if(singleton==null) singleton=new Dispatcher();"); - env.println("return singleton;"); + env.println("return dispatcher;"); env.unindent(); env.println("}"); env.println(); + env.println("private static class Dispatcher implements SampleDispatcher "+genericStr+"{"); + env.indent(); + env.println(); env.println("public Class"+genericStr+" getSampleClass() {"); env.indent(); env.println("return " + getName() + ".class;"); diff --git a/lib/csharp/se/lth/control/labcomm/Constant.cs b/lib/csharp/se/lth/control/labcomm/Constant.cs index cc7deac..5b247f6 100644 --- a/lib/csharp/se/lth/control/labcomm/Constant.cs +++ b/lib/csharp/se/lth/control/labcomm/Constant.cs @@ -9,8 +9,8 @@ namespace se.lth.control.labcomm { */ public const int VERSION = 0x01; public const int SAMPLE_DEF = 0x02; - public const int TYPE_DEF = 0x03; - public const int TYPE_BINDING = 0x04; + public const int SAMPLE_REF = 0x03; + public const int TYPE_DEF = 0x04; public const int PRAGMA = 0x3f; public const int FIRST_USER_INDEX = 0x40; /* ..0xffffffff */ @@ -31,6 +31,7 @@ namespace se.lth.control.labcomm { public const int FLOAT = 0x25; public const int DOUBLE = 0x26; public const int STRING = 0x27; + public const int SAMPLE = 0x28; } diff --git a/lib/csharp/se/lth/control/labcomm/Decoder.cs b/lib/csharp/se/lth/control/labcomm/Decoder.cs index 9bdbaa3..4e8868f 100644 --- a/lib/csharp/se/lth/control/labcomm/Decoder.cs +++ b/lib/csharp/se/lth/control/labcomm/Decoder.cs @@ -6,6 +6,7 @@ namespace se.lth.control.labcomm { void register(SampleDispatcher dispatcher, SampleHandler handler); + void registerSampleRef(SampleDispatcher dispatcher); bool decodeBoolean(); byte decodeByte(); @@ -16,7 +17,7 @@ namespace se.lth.control.labcomm { double decodeDouble(); String decodeString(); int decodePacked32(); - Sample decodeSampleRef(); + Type decodeSampleRef(); } diff --git a/lib/csharp/se/lth/control/labcomm/DecoderChannel.cs b/lib/csharp/se/lth/control/labcomm/DecoderChannel.cs index 26a3e65..1185e28 100644 --- a/lib/csharp/se/lth/control/labcomm/DecoderChannel.cs +++ b/lib/csharp/se/lth/control/labcomm/DecoderChannel.cs @@ -8,7 +8,8 @@ namespace se.lth.control.labcomm { public class DecoderChannel : Decoder { private Stream stream; - private DecoderRegistry registry = new DecoderRegistry(); + private DecoderRegistry def_registry = new DecoderRegistry(); + private DecoderRegistry ref_registry = new DecoderRegistry(); byte[] buf = new byte[8]; public DecoderChannel(Stream stream) { @@ -34,10 +35,18 @@ namespace se.lth.control.labcomm { int signature_length = decodePacked32(); byte[] signature = new byte[signature_length]; ReadBytes(signature, signature_length); - registry.add(index, name, signature); + def_registry.add(index, name, signature); + } break; + case Constant.SAMPLE_REF: { + int index = decodePacked32(); + String name = decodeString(); + int signature_length = decodePacked32(); + byte[] signature = new byte[signature_length]; + ReadBytes(signature, signature_length); + ref_registry.add(index, name, signature); } break; default: { - DecoderRegistry.Entry e = registry.get(tag); + DecoderRegistry.Entry e = def_registry.get(tag); if (e == null) { throw new IOException("Unhandled tag " + tag); } @@ -64,7 +73,11 @@ namespace se.lth.control.labcomm { public void register(SampleDispatcher dispatcher, SampleHandler handler) { - registry.add(dispatcher, handler); + def_registry.add(dispatcher, handler); + } + + public void registerSampleRef(SampleDispatcher dispatcher) { + ref_registry.add(dispatcher, null); } private void ReadBytes(byte[] result, int length) { @@ -147,8 +160,14 @@ namespace se.lth.control.labcomm { return (int) (res & 0xffffffff); } - public Sample decodeSampleRef() { - return null; + public Type decodeSampleRef() { + int index = (int)ReadInt(4); + DecoderRegistry.Entry e = ref_registry.get(index); + if (e != null) { + return e.getSampleDispatcher().getSampleClass(); + } else { + return null; + } } } } diff --git a/lib/csharp/se/lth/control/labcomm/Encoder.cs b/lib/csharp/se/lth/control/labcomm/Encoder.cs index 0badded..1deb1b7 100644 --- a/lib/csharp/se/lth/control/labcomm/Encoder.cs +++ b/lib/csharp/se/lth/control/labcomm/Encoder.cs @@ -5,6 +5,7 @@ namespace se.lth.control.labcomm { public interface Encoder { void register(SampleDispatcher dispatcher); + void registerSampleRef(SampleDispatcher dispatcher); void begin(Type c); void end(Type c); @@ -17,7 +18,7 @@ namespace se.lth.control.labcomm { void encodeDouble(double value); void encodeString(String value); void encodePacked32(Int64 value); - void encodeSampleRef(Sample value); + void encodeSampleRef(Type value); } diff --git a/lib/csharp/se/lth/control/labcomm/EncoderChannel.cs b/lib/csharp/se/lth/control/labcomm/EncoderChannel.cs index 90c0ac8..2f3da1c 100644 --- a/lib/csharp/se/lth/control/labcomm/EncoderChannel.cs +++ b/lib/csharp/se/lth/control/labcomm/EncoderChannel.cs @@ -9,7 +9,8 @@ namespace se.lth.control.labcomm { private Stream writer; private MemoryStream bytes = new MemoryStream(); - private EncoderRegistry registry = new EncoderRegistry(); + private EncoderRegistry def_registry = new EncoderRegistry(); + private EncoderRegistry ref_registry = new EncoderRegistry(); byte[] buf = new byte[8]; private int current_tag; @@ -22,7 +23,7 @@ namespace se.lth.control.labcomm { } public void register(SampleDispatcher dispatcher) { - int index = registry.add(dispatcher); + int index = def_registry.add(dispatcher); begin(Constant.SAMPLE_DEF); encodePacked32(index); encodeString(dispatcher.getName()); @@ -34,13 +35,26 @@ namespace se.lth.control.labcomm { end(null); } + public void registerSampleRef(SampleDispatcher dispatcher) { + int index = ref_registry.add(dispatcher); + begin(Constant.SAMPLE_REF); + encodePacked32(index); + encodeString(dispatcher.getName()); + byte[] signature = dispatcher.getSignature(); + encodePacked32(signature.Length); + for (int i = 0 ; i < signature.Length ; i++) { + encodeByte(signature[i]); + } + end(null); + } + private void begin(int tag) { current_tag = tag; bytes.SetLength(0); } public void begin(Type c) { - begin(registry.getTag(c)); + begin(def_registry.getTag(c)); } public void end(Type c) { @@ -118,9 +132,13 @@ namespace se.lth.control.labcomm { WritePacked32(bytes, value); } - public void encodeSampleRef(Sample value) { - WriteInt(0, 4); - throw new Exception("IMPLEMENT"); + public void encodeSampleRef(Type value) { + int index = 0; + try { + index = ref_registry.getTag(value); + } catch (NullReferenceException) { + } + WriteInt(index, 4); } } diff --git a/lib/csharp/se/lth/control/labcomm/Sample.cs b/lib/csharp/se/lth/control/labcomm/Sample.cs index ac56229..c9ea7fd 100644 --- a/lib/csharp/se/lth/control/labcomm/Sample.cs +++ b/lib/csharp/se/lth/control/labcomm/Sample.cs @@ -1,3 +1,9 @@ -public interface Sample { +namespace se.lth.control.labcomm { + + public interface Sample { + + SampleDispatcher getDispatcher(); + + } } diff --git a/lib/java/se/lth/control/labcomm/Encoder.java b/lib/java/se/lth/control/labcomm/Encoder.java index 1d0f452..957447e 100644 --- a/lib/java/se/lth/control/labcomm/Encoder.java +++ b/lib/java/se/lth/control/labcomm/Encoder.java @@ -5,6 +5,7 @@ import java.io.IOException; public interface Encoder { public void register(SampleDispatcher dispatcher) throws IOException; + public void registerSampleRef(Sample sample) throws IOException; public void begin(Class<? extends Sample> c) throws IOException; public void end(Class<? extends Sample> c) throws IOException; public void encodeBoolean(boolean value) throws IOException; diff --git a/lib/java/se/lth/control/labcomm/EncoderChannel.java b/lib/java/se/lth/control/labcomm/EncoderChannel.java index 91dade4..aeeee47 100644 --- a/lib/java/se/lth/control/labcomm/EncoderChannel.java +++ b/lib/java/se/lth/control/labcomm/EncoderChannel.java @@ -41,6 +41,9 @@ public class EncoderChannel implements Encoder { end(null); } + public void registerSampleRef(Sample sample) throws IOException { + } + private void begin(int tag) { current_tag = tag; bytes.reset(); diff --git a/lib/java/se/lth/control/labcomm/Sample.java b/lib/java/se/lth/control/labcomm/Sample.java index 8210e3a..f86f486 100644 --- a/lib/java/se/lth/control/labcomm/Sample.java +++ b/lib/java/se/lth/control/labcomm/Sample.java @@ -2,4 +2,6 @@ package se.lth.control.labcomm; public interface Sample { -} \ No newline at end of file + public SampleDispatcher getDispatcher(); + +} diff --git a/lib/python/labcomm/LabComm.py b/lib/python/labcomm/LabComm.py index f22707b..c45e705 100644 --- a/lib/python/labcomm/LabComm.py +++ b/lib/python/labcomm/LabComm.py @@ -559,7 +559,17 @@ class array(object): class struct: def __init__(self, field): - self.field = field + self.field = tuple(field) + + def __eq__(self, other): + return (type(self) == type(other) and + self.field == other.field) + + def __ne__(self, other): + return not self == other + + def __hash__(self): + return hash(self.field) def encode_decl(self, encoder): encoder.encode_type(i_STRUCT) @@ -612,7 +622,7 @@ SAMPLE_DEF = sample_def() SAMPLE_REF = sample_ref() ARRAY = array(None, None) -STRUCT = struct({}) +STRUCT = struct([]) class anonymous_object(dict): def __setattr__(self, name, value): diff --git a/test/ref.lc b/test/ref.lc index 955d9a7..6fa041e 100644 --- a/test/ref.lc +++ b/test/ref.lc @@ -1,4 +1,4 @@ -sample sample usedBoth; -sample sample unusedEncoder; -sample sample unusedDecoder; +sample sample s1; +sample sample s2; +sample sample s3; sample sample sample_list[4]; diff --git a/test/relay_gen_cs.py b/test/relay_gen_cs.py index 669f5f5..8cd9043 100755 --- a/test/relay_gen_cs.py +++ b/test/relay_gen_cs.py @@ -2,6 +2,7 @@ import re import sys +import random def split_match(pattern, multiline): def match(s): @@ -11,6 +12,10 @@ def split_match(pattern, multiline): pass return filter(lambda s: s != None, map(match, multiline.split('\n'))) +def shuffle(l): + result = list(l) + random.shuffle(result) + return result if __name__ == '__main__': f = open(sys.argv[1]) @@ -58,22 +63,29 @@ if __name__ == '__main__': | FileStream InFile = new FileStream(InName, | FileMode.Open, | FileAccess.Read); - | DecoderChannel d = new DecoderChannel(InFile); + | DecoderChannel decoder = new DecoderChannel(InFile); | FileStream OutFile = new FileStream(OutName, | FileMode.OpenOrCreate, | FileAccess.Write); | encoder = new EncoderChannel(OutFile); | """)) - for func,arg in sample: - result.append(' %s.register(d, this);' % func) + for func,arg in shuffle(sample): + result.append(' %s.register(decoder, this);' % func) pass - for func,arg in sample: + for func,arg in shuffle(sample): + result.append(' %s.registerSampleRef(decoder);' % func) + pass + for func,arg in shuffle(sample): result.append(' %s.register(encoder);' % func) pass + for func,arg in shuffle(sample): + result.append(' %s.registerSampleRef(encoder);' % func) + pass + result.extend(split_match('^[^|]*\|(.*)$', """ | try { - | d.run(); + | decoder.run(); | } catch (EndOfStreamException) { | } | } -- GitLab