From b0357d84042db6f8578658a7a8b62bc6545d127b Mon Sep 17 00:00:00 2001
From: Sven Robertz <sven@cs.lth.se>
Date: Tue, 23 Jul 2013 14:01:34 +0200
Subject: [PATCH] WIP: towards adding an external context to the handlers

---
 examples/dynamic/handlers.txt             |  13 ++
 examples/dynamic/handlers2.txt            |  18 +++
 examples/dynamic/runme.sh                 |   6 +-
 examples/dynamic/test/TestLabcommGen.java | 183 +++++++++++++++++++++-
 4 files changed, 210 insertions(+), 10 deletions(-)
 create mode 100644 examples/dynamic/handlers.txt
 create mode 100644 examples/dynamic/handlers2.txt

diff --git a/examples/dynamic/handlers.txt b/examples/dynamic/handlers.txt
new file mode 100644
index 0000000..323a87d
--- /dev/null
+++ b/examples/dynamic/handlers.txt
@@ -0,0 +1,13 @@
+foo:handler(foo value) {
+	System.out.println("foo handler from handlers.txt");
+	System.out.println(value.x);
+	System.out.println(value.y);
+	System.out.println(value.z);
+	for(int i=0; i<value.x; i++){
+		System.out.print("."+(value.x-i));
+	}
+	System.out.println();
+}###
+bar:handler(int value) {
+	System.out.println("bar:"+value);
+}###
diff --git a/examples/dynamic/handlers2.txt b/examples/dynamic/handlers2.txt
new file mode 100644
index 0000000..fbf2246
--- /dev/null
+++ b/examples/dynamic/handlers2.txt
@@ -0,0 +1,18 @@
+foo:handler(foo value) {
+	test.HandlerContext ctx = (test.HandlerContext)context;
+	System.out.println("foo handler from handlers.txt");
+	System.out.println("using context "+ctx.str);
+        ctx.x = value.x;
+	ctx.y = value.y;
+	ctx.z = value.z;
+	System.out.println(value.x);
+	System.out.println(value.y);
+	System.out.println(value.z);
+	for(int i=0; i<value.x; i++){
+		System.out.print("."+(value.x-i));
+	}
+	System.out.println();
+}###
+bar:handler(int value) {
+	System.out.println("bar:"+value);
+}###
diff --git a/examples/dynamic/runme.sh b/examples/dynamic/runme.sh
index acf9924..7890716 100644
--- a/examples/dynamic/runme.sh
+++ b/examples/dynamic/runme.sh
@@ -1,5 +1,7 @@
 #dummy script to test the on-the-fly compilation
 
-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/TestLabcommGen.java
+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/TestLabcommGen.java 
 
-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.TestLabcommGen simple.lc handlers.txt encoded_data
+javac test/HandlerContext.java
+
+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.TestLabcommGen simple.lc handlers2.txt encoded_data
diff --git a/examples/dynamic/test/TestLabcommGen.java b/examples/dynamic/test/TestLabcommGen.java
index 839124e..47e4c31 100644
--- a/examples/dynamic/test/TestLabcommGen.java
+++ b/examples/dynamic/test/TestLabcommGen.java
@@ -7,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;
@@ -26,14 +27,13 @@ import AST.LabCommScanner;
 import AST.Program;
 import beaver.Parser.Exception;
 
-
-
 public class TestLabcommGen {
 
 	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;
@@ -208,6 +208,78 @@ public class TestLabcommGen {
 		}
 		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();
@@ -248,14 +320,17 @@ public class TestLabcommGen {
 		try {
 			FileInputStream in = new FileInputStream(tmpFile);
 			LabCommDecoderChannel dec = new LabCommDecoderChannel(in);
+			Class handlerClass =  irc.load(handlerClassName);
+			Constructor hcc = handlerClass.getDeclaredConstructor(Object.class);
+//			Object handler = handlerClass.newInstance(); 
+			HandlerContext ctxt = new HandlerContext();
+			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);
 			}
@@ -267,6 +342,9 @@ public class TestLabcommGen {
 				System.out.println("*** reached EOF ***");
 			}
 			in.close();
+			System.out.println("ctxt.x = "+ctxt.x);
+			System.out.println("ctxt.y = "+ctxt.y);
+			System.out.println("ctxt.z = "+ctxt.z);
 		} catch (Throwable e) {
 			e.printStackTrace();
 		}
@@ -281,14 +359,14 @@ public class TestLabcommGen {
 
 			/* 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);
-			
+
 
 			FileOutputStream out = new FileOutputStream(tmpFile);
 			LabCommEncoderChannel enc = new LabCommEncoderChannel(out);
@@ -316,6 +394,95 @@ public class TestLabcommGen {
 
 	/** 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(); 
-- 
GitLab