Commit ac1eb49e authored by Sven Robertz's avatar Sven Robertz
Browse files

a bit more polished example

parent b0357d84
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:
......
#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
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;
}###
#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
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();
......
package test;
public class HandlerContext {
public final String str="HandlerContext";
public int x, y, z, bar;
}
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();
}
}
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();
}
}
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();
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment