diff --git a/examples/dynamic/README b/examples/dynamic/README index 5a3f11e8853e61bf365927a8f9857a66cb78bf82..26f8b7185031e71e86bb1f450ac0251de3244ef2 100644 --- a/examples/dynamic/README +++ b/examples/dynamic/README @@ -1,9 +1,13 @@ -This directory contains an embryo of an example of how to -generate and compile a labcomm endpoint on the fly. +This directory contains a small example of how to generate and compile +a labcomm endpoint on the fly. -NB! There is currently no connection to the StaticPart.java +the script static.sh builds and runs a very simple static labcomm demo -the runme.sh script builds and runs the TestLabCommGen, which illustrates the +the script dynamic.sh builds and runs an example where labcomm is generated and woven +togerther with user-defined handler code. + + +the test.sh script builds and runs the TestLabCommGen, which illustrates the on-the-fly compilation to RAM, reading the labcomm declarations and handlers from file The handlers declaration (in handlers.txt) is experimental, and has the following format: diff --git a/examples/dynamic/dynamic.sh b/examples/dynamic/dynamic.sh new file mode 100644 index 0000000000000000000000000000000000000000..77fb6bcd1779a75a4cee43b106cfdb51c54b8053 --- /dev/null +++ b/examples/dynamic/dynamic.sh @@ -0,0 +1,24 @@ +#dummy script to test the on-the-fly compilation + +java -jar ../../compiler/labComm.jar --java=gen --javapackage=gen simple.lc + +javac -cp .:gen:../../lib/java/labcomm.jar gen/*.java + +# compile static encoder and decoder +javac -cp .:gen:../../lib/java/labcomm.jar test/StaticEncoder.java +javac -cp .:gen:../../lib/java/labcomm.jar test/StaticDecoder.java + +# compile dynamic part +javac -cp .:../../compiler/labComm.jar:../../lib/java/labcomm.jar:../../lib/tools/beaver.jar:../../lib/tools/beaver-rt.jar:../../lib/tools/jastadd2.jar:../../lib/tools/JFlex.jar:../../lib/tools/proj.jar test/DynamicPart.java + +javac test/HandlerContext.java + +# run static encoder +java -cp .:gen:../../lib/java//labcomm.jar test.StaticEncoder encoded_data + +# run dynamic part +java -cp .:../../compiler/labComm.jar:../../lib/java/labcomm.jar:../../lib/tools/beaver.jar:../../lib/tools/beaver-rt.jar:../../lib/tools/jastadd2.jar:../../lib/tools/JFlex.jar:../../lib/tools/proj.jar test.DynamicPart simple.lc handlers2.txt encoded_data dynamic_out + + +# run static decoder +java -cp .:gen:../../lib/java//labcomm.jar test.StaticDecoder dynamic_out diff --git a/examples/dynamic/handlers2.txt b/examples/dynamic/handlers2.txt index fbf22463f5b4b150296a6c07402449730ea5797a..efa3f75597929363ff3a64d2f75059b2ddcd40a7 100644 --- a/examples/dynamic/handlers2.txt +++ b/examples/dynamic/handlers2.txt @@ -1,10 +1,10 @@ foo:handler(foo value) { test.HandlerContext ctx = (test.HandlerContext)context; - System.out.println("foo handler from handlers.txt"); + System.out.println("foo handler from handlers2.txt"); System.out.println("using context "+ctx.str); - ctx.x = value.x; - ctx.y = value.y; - ctx.z = value.z; + ctx.x = value.x + 1000; + ctx.y = value.y + 1000; + ctx.z = value.z + 1000; System.out.println(value.x); System.out.println(value.y); System.out.println(value.z); @@ -15,4 +15,6 @@ foo:handler(foo value) { }### bar:handler(int value) { System.out.println("bar:"+value); + test.HandlerContext ctx = (test.HandlerContext)context; + ctx.bar = value + 1000; }### diff --git a/examples/dynamic/static.sh b/examples/dynamic/static.sh new file mode 100644 index 0000000000000000000000000000000000000000..ff1b8362de6978ad252cdf047d69fcdfb4d47f15 --- /dev/null +++ b/examples/dynamic/static.sh @@ -0,0 +1,13 @@ +#dummy script to test the static part + +# run labcomm compilation + +java -jar ../../compiler/labComm.jar --java=gen --javapackage=gen simple.lc + +# compile example programs +javac -cp .:gen:../../lib/java/labcomm.jar test/StaticEncoder.java +javac -cp .:gen:../../lib/java/labcomm.jar test/StaticDecoder.java + +# run example programs +java -cp .:gen:../../lib/java//labcomm.jar test.StaticEncoder encoded_data +java -cp .:gen:../../lib/java//labcomm.jar test.StaticDecoder encoded_data diff --git a/examples/dynamic/runme.sh b/examples/dynamic/test.sh similarity index 100% rename from examples/dynamic/runme.sh rename to examples/dynamic/test.sh diff --git a/examples/dynamic/test/DynamicPart.java b/examples/dynamic/test/DynamicPart.java index 08fdd472a78207ebe85aab990f0c2dde105e8bfd..46295bef92c9d72670f2c25fafb063a09415d59a 100644 --- a/examples/dynamic/test/DynamicPart.java +++ b/examples/dynamic/test/DynamicPart.java @@ -1,4 +1,5 @@ package test; + import java.io.ByteArrayInputStream; import java.io.EOFException; import java.io.FileInputStream; @@ -6,6 +7,7 @@ import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; +import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -25,19 +27,13 @@ import AST.LabCommScanner; import AST.Program; import beaver.Parser.Exception; - - -/** Simple test class that illustrates on-the-fly generation, compilation, and loading - * of labcomm handlers. - * - * It reads, modifies and writes the "foo" and "bar" sample types - */ public class DynamicPart { private static final String SAMPLE_NAME_FOO = "foo"; private static final String SAMPLE_NAME_BAR = "bar"; - /** A class representing the source code for one Labcomm handler */ + static final String handlerClassName= "HandlerContainer"; + static class HandlerSrc { private String sampleName; private String param; @@ -57,15 +53,16 @@ public class DynamicPart { } } - public void doTest(InRAMCompiler irc, String inFile, String outFile) { - System.out.println("*** DynamicPart reading from "+inFile); - decodeTest(irc, tmpFile, SAMPLE_NAME_FOO, SAMPLE_NAME_BAR); - System.out.println("*** DynamicPart writing to "+outFile); - encodeTest(irc, tmpFile); + public void doTest(InRAMCompiler irc, String iFile, String oFile) { + HandlerContext ctxt = new HandlerContext(); + System.out.println("*** reading file "+iFile); + decodeTest(irc, ctxt, iFile, SAMPLE_NAME_FOO, SAMPLE_NAME_BAR); + System.out.println("*** writing "+oFile); + encodeTest(irc, ctxt, oFile); } /** - * @param args (types.lc, handlers.txt, inputfile, outputfile) + * @param args */ public static void main(String[] args) { @@ -90,12 +87,11 @@ public class DynamicPart { InRAMCompiler irc = generateCode(labcommStr, handlers); if(irc != null) { - String inFile = args[2]; - String outFile = args[3]; - new DynamicPart().doTest(irc, inFile, outFile); + String iFile = args[2]; + String oFile = args[3]; + new DynamicPart().doTest(irc, iFile, oFile); } } - public static void generateHandlers(String srcStr, HashMap<String,String> handlers) { int pos = 0; while(pos < srcStr.length()) { @@ -217,6 +213,78 @@ public class DynamicPart { } System.out.println("Generated labcomm code:"); + InRAMCompiler irc = new InRAMCompilerJavax("labcomm.generated", TestLabcommGen.class.getClassLoader()); + + StringBuilder handlerClass = new StringBuilder(); + StringBuilder handlerMethods = new StringBuilder(); + + handlerClass.append("package labcomm.generated;\n"); + handlerClass.append("import test.TestLabcommGen;\n"); + handlerClass.append("public class "+handlerClassName+" implements "); + + + String handlerAttributes = "Object context;\n"; + String handlerConstructor = "public "+handlerClassName+"(Object context){ this.context=context;}\n"; + + Iterator<String> i = genCode.keySet().iterator(); + try { + while(i.hasNext()){ + final String sampleName = i.next(); + final String src = genCode.get(sampleName); + handlerClass.append(sampleName+".Handler"); + if(i.hasNext()) { + handlerClass.append(", "); + } + handlerMethods.append(handlers.get(sampleName)); + handlerMethods.append("\n"); + System.out.println("***"+sampleName+"\n"+src); + irc.compile(sampleName, src); // while iterating, compile the labcomm generated code + } + handlerClass.append("{\n"); + handlerClass.append(handlerAttributes); + handlerClass.append(handlerConstructor); + handlerClass.append(handlerMethods.toString()); + handlerClass.append("}\n"); + + + System.out.println("-------------------------------------"); + + final String handlerSrc = handlerClass.toString(); + System.out.println(handlerSrc); + irc.compile(handlerClassName, handlerSrc); // compile the generated handler class + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (SecurityException e) { + e.printStackTrace(); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } + System.out.println("================================"); + + return irc; + } + + /** generate labcomm code and compile handlers. Version for separate handler classes + * + * @param lcAST - the AST of the labcomm declaration + * @param handlers - a map <name, source> of handlers for the types in ast + * @return an InRAMCompiler object containing the generated clases + */ + private static InRAMCompiler handleAstSeparate(Program lcAST, HashMap<String, String> handlers) { + Map<String, String> genCode = new HashMap<String, String>(); + try { + lcAST.J_gen(genCode, "labcomm.generated"); + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("Generated labcomm code:"); + InRAMCompiler irc = new InRAMCompilerJavax("labcomm.generated", null); Iterator<String> i = genCode.keySet().iterator(); @@ -253,18 +321,19 @@ public class DynamicPart { } /** test method */ - private void decodeTest(InRAMCompiler irc, String tmpFile, String... sampleNames) { + private void decodeTest(InRAMCompiler irc, HandlerContext ctxt, String tmpFile, String... sampleNames) { try { FileInputStream in = new FileInputStream(tmpFile); LabCommDecoderChannel dec = new LabCommDecoderChannel(in); + Class handlerClass = irc.load(handlerClassName); + Constructor hcc = handlerClass.getDeclaredConstructor(Object.class); + Object handler = hcc.newInstance(ctxt); + for (String sampleName : sampleNames) { System.out.println("registering handler for "+sampleName); Class sampleClass = irc.load(sampleName); - Class handlerClass = irc.load("gen_"+sampleName+"Handler"); Class handlerInterface = irc.load(sampleName+"$Handler"); - Object handler = handlerClass.newInstance(); - Method reg = sampleClass.getDeclaredMethod("register", LabCommDecoder.class, handlerInterface); reg.invoke(sampleClass, dec, handler); } @@ -283,21 +352,21 @@ public class DynamicPart { } /** test encoding */ - private void encodeTest(InRAMCompiler irc, String tmpFile) { + private void encodeTest(InRAMCompiler irc, HandlerContext ctxt, String tmpFile) { try { Class fc = irc.load(SAMPLE_NAME_FOO); Class bc = irc.load(SAMPLE_NAME_BAR); /* create sample class and instance objects */ Object f = fc.newInstance(); - + Field x = fc.getDeclaredField("x"); Field y = fc.getDeclaredField("y"); Field z = fc.getDeclaredField("z"); - x.setInt(f, 10); - y.setInt(f, 11); - z.setInt(f, 12); - + x.setInt(f, ctxt.x); + y.setInt(f, ctxt.y); + z.setInt(f, ctxt.z); + FileOutputStream out = new FileOutputStream(tmpFile); LabCommEncoderChannel enc = new LabCommEncoderChannel(out); @@ -314,7 +383,7 @@ public class DynamicPart { regBar.invoke(bc, enc); Method doEncodeBar = bc.getDeclaredMethod("encode", LabCommEncoder.class, Integer.TYPE); - doEncodeBar.invoke(bc, enc, 42); + doEncodeBar.invoke(bc, enc, ctxt.bar); out.close(); } catch (Throwable e) { @@ -325,6 +394,95 @@ public class DynamicPart { /** dummy test creating instances of sample and handler, and calling handle*/ private static void dummyTest(InRAMCompiler irc) { + try { + Class hc = irc.load(handlerClassName); + Constructor hcc = hc.getDeclaredConstructor(Object.class); +// Object h = hc.newInstance(); + Object h = hcc.newInstance(new HandlerContext()); + Class fc = irc.load(SAMPLE_NAME_FOO); + Object f = fc.newInstance(); + Field x = fc.getDeclaredField("x"); + Field y = fc.getDeclaredField("y"); + Field z = fc.getDeclaredField("z"); + x.setInt(f, 10); + y.setInt(f, 11); + z.setInt(f, 12); + Method m; + try { + m = hc.getDeclaredMethod("handle_"+SAMPLE_NAME_FOO, fc); + m.invoke(h, f); + } catch (SecurityException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (NoSuchMethodException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InvocationTargetException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } catch (InstantiationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalAccessException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (SecurityException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (NoSuchFieldException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InvocationTargetException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (NoSuchMethodException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + /** test method + */ + private static void decodeTestSeparate(InRAMCompiler irc, String tmpFile, String... sampleNames) { + try { + FileInputStream in = new FileInputStream(tmpFile); + LabCommDecoderChannel dec = new LabCommDecoderChannel(in); + for (String sampleName : sampleNames) { + System.out.println("registering handler for "+sampleName); + Class sampleClass = irc.load(sampleName); + Class handlerClass = irc.load("gen_"+sampleName+"Handler"); + Class handlerInterface = irc.load(sampleName+"$Handler"); + + Object handler = handlerClass.newInstance(); + + Method reg = sampleClass.getDeclaredMethod("register", LabCommDecoder.class, handlerInterface); + reg.invoke(sampleClass, dec, handler); + } + + try{ + System.out.println("*** decoding:"); + dec.run(); + } catch(EOFException e) { + System.out.println("*** reached EOF ***"); + } + in.close(); + } catch (Throwable e) { + e.printStackTrace(); + } + + } + + /** dummy test creating instances of sample and handler, and calling handle*/ + private static void dummyTestSeparate(InRAMCompiler irc) { try { Class hc = irc.load("gen_"+SAMPLE_NAME_FOO+"Handler"); Object h = hc.newInstance(); diff --git a/examples/dynamic/test/HandlerContext.java b/examples/dynamic/test/HandlerContext.java new file mode 100644 index 0000000000000000000000000000000000000000..b6f0223ac5385bacc46eb1cd92463c5399294b12 --- /dev/null +++ b/examples/dynamic/test/HandlerContext.java @@ -0,0 +1,7 @@ +package test; + +public class HandlerContext { + public final String str="HandlerContext"; + public int x, y, z, bar; +} + diff --git a/examples/dynamic/test/StaticDecoder.java b/examples/dynamic/test/StaticDecoder.java new file mode 100644 index 0000000000000000000000000000000000000000..b3d74edf4c407397f2aae315b1899303ad27d6f9 --- /dev/null +++ b/examples/dynamic/test/StaticDecoder.java @@ -0,0 +1,49 @@ +package test; + +import gen.foo; +import gen.bar; + +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import se.lth.control.labcomm.LabCommDecoderChannel; + + +public class StaticDecoder implements foo.Handler, bar.Handler +{ + + LabCommDecoderChannel decoder; + + public StaticDecoder(InputStream in) throws Exception { + decoder = new LabCommDecoderChannel(in); + foo.register(decoder, this); + bar.register(decoder, this); + + } + + public void run() throws Exception { + try { + System.out.println("Running decoder."); + decoder.run(); + } catch (java.io.EOFException e) { + System.out.println("Decoder reached end of file."); + } + } + + + public void handle_foo(foo d) throws java.io.IOException { + System.out.println("Got foo, x="+d.x+", y="+d.y+", z="+d.z); + } + + public void handle_bar(int d) throws java.io.IOException { + System.out.println("Got bar: "+d); + } + + public static void main(String[] arg) throws Exception { + FileInputStream fis = new FileInputStream(new File(arg[0])); + StaticDecoder dec = new StaticDecoder(fis); + dec.run(); + fis.close(); + } +} + diff --git a/examples/dynamic/test/StaticEncoder.java b/examples/dynamic/test/StaticEncoder.java new file mode 100644 index 0000000000000000000000000000000000000000..697f339e8335de34a4aef9f6bbdc3928d2c207f2 --- /dev/null +++ b/examples/dynamic/test/StaticEncoder.java @@ -0,0 +1,44 @@ +package test; +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; +import se.lth.control.labcomm.LabCommEncoderChannel; + +import gen.foo; +import gen.bar; + +public class StaticEncoder { + + LabCommEncoderChannel encoder; + + public StaticEncoder(OutputStream out) + throws Exception + { + encoder = new LabCommEncoderChannel(out); + foo.register(encoder); + bar.register(encoder); + } + + public void doEncode() throws java.io.IOException { + foo f = new foo(); + f.x = 17; + f.y = 42; + f.z = 37; + + int b = 13; + + System.out.println("Encoding foo, x="+f.x+", y="+f.y+", z="+f.z); + foo.encode(encoder, f); + + System.out.println("Encoding bar: "+b); + bar.encode(encoder, b); + } + + public static void main(String[] arg) throws Exception { + FileOutputStream fos = new FileOutputStream(arg[0]); + StaticEncoder enc = new StaticEncoder(fos); + enc.doEncode(); + fos.close(); + } +} + diff --git a/examples/dynamic/test/StaticPart.java b/examples/dynamic/test/StaticPart.java deleted file mode 100644 index 3ffb362f7574be569f5b60654a76bff8342983e0..0000000000000000000000000000000000000000 --- a/examples/dynamic/test/StaticPart.java +++ /dev/null @@ -1,92 +0,0 @@ -package test; -import java.io.File; -import java.io.FileOutputStream; -import java.io.OutputStream; -import se.lth.control.labcomm.LabCommEncoderChannel; - -import java.io.FileInputStream; -import java.io.InputStream; -import se.lth.control.labcomm.LabCommDecoderChannel; - - -public class StaticPart { - /** - * Simple encoder - */ - public static class Encoder { - - LabCommEncoderChannel encoder; - - public Encoder(OutputStream out) - throws Exception - { - encoder = new LabCommEncoderChannel(out); - foo.register(encoder); - bar.register(encoder); - } - - public void doEncode() throws java.io.IOException { - foo f = new foo(); - f.x = 17; - f.y = 42; - f.z = 37; - - int b = 13; - - System.out.println("Encoding foo, x="+f.x+", y="+f.y+", z="+f.z); - foo.encode(encoder, f); - - System.out.println("Encoding bar: "+b); - bar.encode(encoder, b); - } - } - - public static class Decoder - implements foo.Handler, bar.Handler - { - - LabCommDecoderChannel decoder; - - public Decoder(InputStream in) - throws Exception - { - decoder = new LabCommDecoderChannel(in); - foo.register(decoder, this); - bar.register(decoder, this); - - } - - public void doDecode() throws java.io.IOException { - try { - System.out.println("Running decoder."); - decoder.run(); - } catch (java.io.EOFException e) { - System.out.println("Decoder reached end of file."); - } catch (Exception e) { - e.printStackTrace(); - } - } - - - public void handle_foo(foo d) throws java.io.IOException { - System.out.println("Got foo, x="+d.x+", y="+d.y+", z="+d.z); - } - - public void handle_bar(int d) throws java.io.IOException { - System.out.println("Got bar: "+d); - } - - } - - public static void main(String[] arg) throws Exception { - FileOutputStream fos = new FileOutputStream(arg[0]); - FileInputStream fis = new FileInputStream(new File(arg[0])); - Encoder enc = new Encoder(fos); - Decoder dec = new Decoder(fis); - enc.doEncode(); - dec.doDecode(); - fos.close(); - fis.close(); - } -} -