diff --git a/compiler/Java_CodeGen.jrag b/compiler/Java_CodeGen.jrag index 188878c639569ee8b25003db80aa3cf4aec52047..e1a6ec47aee7454b6b1fce64e8d193439bfe2cf1 100644 --- a/compiler/Java_CodeGen.jrag +++ b/compiler/Java_CodeGen.jrag @@ -195,6 +195,36 @@ aspect Java_Void { aspect Java_CodeGen { + public void Program.J_gen(PrintStream ps, String pack) throws IOException { + Java_env env; +/* + // Registration class + env = new Java_env(ps); + if (pack != null && pack.length() > 0) { + env.println("package " + pack + ";"); + } + env.println("public class LabCommRegister {"); + env.println(); + env.indent(); + Java_emitTypeRegister(env); + env.unindent(); + env.println(); + env.println("}"); +// env.close(); +*/ + env = new Java_env(ps); + for (int i = 0; i < getNumDecl(); i++) { + Decl d = getDecl(i); + try { + d.Java_emitClass(env, pack); + } catch (Error e) { + System.err.println(d.getName()); + throw e; + } + } + env.close(); + } + public void Program.J_gen(String dir, String pack) throws IOException { Java_env env; /* @@ -225,6 +255,29 @@ aspect Java_CodeGen { } } + /** Experimental method for generating code to a map <classname, source> + */ + public void Program.J_gen(Map<String,String> src, String pack) throws IOException { + Java_env env; +/* + // Registration class was commented out, so got removed in this copy +*/ + for (int i = 0; i < getNumDecl(); i++) { + Decl d = getDecl(i); + try { + ByteArrayOutputStream bs = new ByteArrayOutputStream(); + PrintStream out = new PrintStream(bs); + env = new Java_env(out); + d.Java_emitClass(env, pack); + env.close(); + src.put(d.getName(), bs.toString()); + } catch (Error e) { + System.err.println(d.getName()); + throw e; + } + } + } + } aspect Java_Register { diff --git a/examples/dynamic/DynamicPart.java b/examples/dynamic/DynamicPart.java new file mode 100644 index 0000000000000000000000000000000000000000..e8fbba0130741db6f9a9df433c53a6972ac9c9ac --- /dev/null +++ b/examples/dynamic/DynamicPart.java @@ -0,0 +1,3 @@ +public class DynamicPart { + +}; diff --git a/examples/dynamic/InRAMCompiler.java b/examples/dynamic/InRAMCompiler.java new file mode 100644 index 0000000000000000000000000000000000000000..7e19afa0cb12d0dac42a549ae19bf2597e6e92b8 --- /dev/null +++ b/examples/dynamic/InRAMCompiler.java @@ -0,0 +1,27 @@ + + +import java.lang.reflect.InvocationTargetException; + +public interface InRAMCompiler { + + /** + * Delete a class from the RAM storage, and destroy its ClassLoader, to + * allow it to be unloaded (and later replaced). + * @param className - the class to be unloaded. pkgName (as given to the constructor) is added to the name. + */ + public void deleteClass(String className); + + public void compile(String name, String srcStr) + throws ClassNotFoundException, IllegalArgumentException, + SecurityException, IllegalAccessException, + InvocationTargetException, NoSuchMethodException; + + /** + * Load className.class out of cache + * @param className + * @return the class object + * @throws ClassNotFoundException + */ + public Class<?> load(String className) throws ClassNotFoundException; + +} \ No newline at end of file diff --git a/examples/dynamic/InRAMCompilerJavax.java b/examples/dynamic/InRAMCompilerJavax.java new file mode 100644 index 0000000000000000000000000000000000000000..4a747ba84161cb43f8ccb45928bca9d987bac0ca --- /dev/null +++ b/examples/dynamic/InRAMCompilerJavax.java @@ -0,0 +1,421 @@ + + + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import javax.tools.Diagnostic; +import javax.tools.DiagnosticCollector; +import javax.tools.FileObject; +import javax.tools.ForwardingJavaFileManager; +import javax.tools.JavaCompiler; +import javax.tools.JavaCompiler.CompilationTask; +import javax.tools.JavaFileManager; +import javax.tools.JavaFileObject; +import javax.tools.JavaFileObject.Kind; +import javax.tools.SimpleJavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.StandardLocation; +import javax.tools.ToolProvider; + +/** + * On-the-fly, incremental, all-in-RAM compilation (no disk files used). + * Based on an example by Piotr Kobzda at + * http://groups.google.com/group/pl.co...7010d1cce043d0 + * + * Each class is compiled in its own compilation unit, and newer + * classes can call or reference older classes. + * + * Written and debugged against Java 1.6.0 Beta 2 build 86, in Eclipse + * 3.2 Jim Goodwin July 25 2006 + * + * Adapted to jdk 1.6.0_11 and adapted with more class loader delegation for + * working with custom class loaders (e.g., OSGi) by Sven Robertz + */ + +public class InRAMCompilerJavax implements InRAMCompiler { + + // Source for both test classes. They go in package + // "just.generated" + + private ClassLoader loader; + + private DiagnosticCollector<JavaFileObject> diagnostics; + + private JavaCompiler compiler; + + private RAMFileManager jfm; + + private Map<String, JavaFileObject> output; + + private ClassLoader providedClassLoader; + + private String pkgName; //package for the generated classes + +// private String getClassPath() +// { +// ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); +// URL[] urls = ((URLClassLoader) classLoader).getURLs(); +// StringBuilder buf = new StringBuilder(1000); +// buf.append("."); +// String separator = System.getProperty("path.separator"); +// for (URL url : urls) { +// buf.append(separator).append(url.getFile()); +// } +// return buf.toString(); +// } + + public static void main(String[] args) throws Exception { + InRAMCompiler irc = new InRAMCompilerJavax("just.generated", null); + final String SRC_HelloIf = "package just.generated;\n" + + "public class HelloIf {\n" + + " public static class Foo {\n" + + " public interface Bar {\n" + + " public String foo();\n" + + " }\n" + + " }\n" + + "}\n"; + + final String SRC_Hello1 = "package just.generated;\n" + + "public class Hello1 {\n" + + " public static void main(String... args) {\n" + + " System.out.println(new Hello2()); \n" + "}}\n"; + + final String SRC_Hello2 = "package just.generated;\n" + + "public class Hello2 implements HelloIf.Foo.Bar{\n" + + " public String foo() { return \"foo\";}\n" + + " public String toString() {\n" + + " return \"hello!\"+foo();\n}}\n"; + + irc.compile("HelloIf", SRC_HelloIf); + irc.compile("Hello2", SRC_Hello2); + irc.compile("Hello1", SRC_Hello1); + Class<?> c = irc.load("Hello1"); + // Run the 'main' method of the Hello class. + c.getMethod("main", String[].class).invoke(null, + new Object[] { new String[0] }); + } + /** + * + * @param pkgName - The package for the generated classes. The source code must only contain classes in this package. + * @param cl - An optional (i.e., may be null) classloader that is also searched + */ + public InRAMCompilerJavax(String pkgName, ClassLoader cl) { + this.pkgName = pkgName; + providedClassLoader = cl; + compiler = ToolProvider.getSystemJavaCompiler(); + + // A map of from class names to the RAMJavaFileObject that holds + // the compiled-code for that class. This is the cache of + // compiled classes. + + output = new HashMap<String, JavaFileObject>(); + + createNewClassLoader(providedClassLoader); + + } + + /* (non-Javadoc) + * @see se.lth.cs.sven.rosettaTest.cc.InRAMCompiler#deleteClass(java.lang.String) + */ + public void deleteClass(String className) { + output.remove(pkgName+"."+className); +// System.out.println("\nstored classes: " + output.keySet()); + createNewClassLoader(providedClassLoader); + } + /** + * Create a new class loader, possibly replacing the existing one. + * This method is called by the constructor, and from deleteClass, to + * allow unloading of generated classes. + * @param cl + */ + private void createNewClassLoader(ClassLoader cl) { + // A loader that searches our cache first. + + loader = new RAMClassLoader(output, cl); + + diagnostics = new DiagnosticCollector<JavaFileObject>(); + + // Create a JavaFileManager which uses our DiagnosticCollector, + // and creates a new RAMJavaFileObject for the class, and + // registers it in our cache + + StandardJavaFileManager sjfm = compiler.getStandardFileManager(diagnostics, null, null); + jfm = new RAMFileManager(sjfm, output, loader); + } + + /* + * Help routine to convert a string to a URI. + */ + static URI toURI(String name) { + try { + return new URI(name); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + } + + /* (non-Javadoc) + * @see se.lth.cs.sven.rosettaTest.cc.InRAMCompiler#compile(java.lang.String, java.lang.String) + */ + public void compile(String name, String srcStr) throws ClassNotFoundException, IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { + // TODO Auto-generated method stub + + // Create source file objects + SourceJavaFileObject src = new SourceJavaFileObject(name, + srcStr); + + // Compile source code. call() causes it to run. + + // Compiler options + // String myCP = getClassPath()+":/home/sven/eclipse/workspace_sven_test_3.4/RosettaOSGi-API/bin"; + // System.out.println("classpath: "+myCP); + List<String> options = new ArrayList<String>(); + // options.add("-classpath"); + // options.add(myCP); + // options.add(getClassPath()); + + CompilationTask task = compiler.getTask(null, jfm, + diagnostics, options, null, Arrays.asList(src)); + + jfm.isCompiling(true); + + if (!task.call()) { + for (Diagnostic<?> dm : diagnostics.getDiagnostics()) + System.err.println(dm); + throw new RuntimeException("Compilation of task "+name+" failed"); + } + + jfm.isCompiling(false); + + // Traces the classes now found in the cache + System.out.println("\nInRAMCompiler: generated classes = " + output.keySet()); + } + + /* (non-Javadoc) + * @see se.lth.cs.sven.rosettaTest.cc.InRAMCompiler#load(java.lang.String) + */ + public Class<?> load(String className) throws ClassNotFoundException { + jfm.isCompiling(false); + Class<?> c = Class.forName(pkgName+"."+className, false, + loader); + return c; + } + + /* + * A JavaFileObject class for source code, that just uses a String for + * the source code. + */ + private class SourceJavaFileObject extends SimpleJavaFileObject { + + private final String classText; + + SourceJavaFileObject(String className, final String classText) { + super(InRAMCompilerJavax.toURI(className + ".java"), + Kind.SOURCE); + this.classText = classText; + } + + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) + throws IOException, IllegalStateException, + UnsupportedOperationException { + return classText; + } + } + + /* + * A JavaFileManager that presents the contents of the cache as a file + * system to the compiler. To do this, it must do four things: + * + * It remembers our special loader and returns it from getClassLoader() + * + * It maintains our cache, adding class "files" to it when the compiler + * calls getJavaFileForOutput + * + * It implements list() to add the classes in our cache to the result + * when the compiler is asking for the classPath. This is the key +trick: + * it is what makes it possible for the second compilation task to + * compile a call to a class from the first task. + * + * It implements inferBinaryName to give the right answer for cached + * classes. + */ + + private class RAMFileManager extends + ForwardingJavaFileManager<StandardJavaFileManager> { + + private final Map<String, JavaFileObject> output; + + private final ClassLoader ldr; + + public RAMFileManager(StandardJavaFileManager sjfm, + Map<String, JavaFileObject> output, ClassLoader ldr) { + super(sjfm); + this.output = output; + this.ldr = ldr; + } + + public JavaFileObject getJavaFileForOutput(Location location, + String name, Kind kind, FileObject sibling) + throws IOException { + JavaFileObject jfo = new RAMJavaFileObject(name, kind); + output.put(name, jfo); + return jfo; + } + + public ClassLoader getClassLoader(JavaFileManager.Location + location) { + return ldr; + } + + @Override + public String inferBinaryName(Location loc, JavaFileObject jfo) { + // System.out.println("RAMFileManager.inferBinaryName:"+loc+", "+jfo); + String result; + + if (loc == StandardLocation.CLASS_PATH + && jfo instanceof RAMJavaFileObject) + result = jfo.getName(); + else + result = super.inferBinaryName(loc, jfo); + + return result; + } + + private boolean restrictPackage=true; + + public void isCompiling(boolean b) { + restrictPackage = !b; + } + + @Override + public Iterable<JavaFileObject> list(Location loc, String pkg, + Set<Kind> kind, boolean recurse) throws IOException { + + Iterable<JavaFileObject> result = super.list(loc, pkg, kind, + recurse); + + if (loc == StandardLocation.CLASS_PATH + && (!restrictPackage || pkg.equals("just.generated")) + && kind.contains(JavaFileObject.Kind.CLASS)) { + ArrayList<JavaFileObject> temp = new ArrayList<JavaFileObject>( + 3); + for (JavaFileObject jfo : result) + temp.add(jfo); + for (Entry<String, JavaFileObject> entry : output + .entrySet()) { + temp.add(entry.getValue()); + } + result = temp; + } else { + result = super.list(loc, pkg, kind, recurse); + } + return result; + } + } + + /** + * A JavaFileObject that uses RAM instead of disk to store the file. It + * gets written to by the compiler, and read from by the loader. + */ + + private class RAMJavaFileObject extends SimpleJavaFileObject { + + ByteArrayOutputStream baos; + + RAMJavaFileObject(String name, Kind kind) { + super(InRAMCompilerJavax.toURI(name), kind); + } + + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) + throws IOException, IllegalStateException, + UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + @Override + public InputStream openInputStream() throws IOException, + IllegalStateException, UnsupportedOperationException { + return new ByteArrayInputStream(baos.toByteArray()); + } + + @Override + public OutputStream openOutputStream() throws IOException, + IllegalStateException, UnsupportedOperationException { + return baos = new ByteArrayOutputStream(); + } + + } + + /** + * A class loader that loads what's in the cache by preference, and if + * it can't find the class there, loads from the standard parent. + * + * It is important that everything in the demo use the same loader, so + * we pass this to the JavaFileManager as well as calling it directly. + */ + + private final class RAMClassLoader extends ClassLoader { + private final Map<String, JavaFileObject> output; + private ClassLoader classLoader; + + RAMClassLoader(Map<String, JavaFileObject> output, ClassLoader cl) { + this.output = output; + this.classLoader = cl; + testGetResources(); + } + + private void testGetResources() { + Package[] ps = getPackages(); + for (Package package1 : ps) { + System.out.println(package1.getName()); + } + } + + @Override + protected Class<?> findClass(String name) + throws ClassNotFoundException { + JavaFileObject jfo = output.get(name); + try { + //XXX This is a hack! Look in "parent" class loader first, to find correct Service instances. + if(classLoader != null) { + System.out.println("RAMClassLoader.findClass: getResource (package): "+classLoader.getResource("se/lth/cs/sven/rosettaTest")); + System.out.println("RAMClassLoader.findClass: getResource: "+classLoader.getResource("se/lth/cs/sven/rosettaTest/Constraint.class")); + + try { + Class<?> c = classLoader.loadClass(name); + if(c != null) { + return c; + } + } catch( ClassNotFoundException ex) { + System.out.println(ex.getMessage()); + } + } + if (jfo != null) { + byte[] bytes = ((RAMJavaFileObject) jfo).baos.toByteArray(); + return defineClass(name, bytes, 0, bytes.length); + } + } catch(Exception e) { + e.printStackTrace(); + } + + return super.findClass(name); + } + } +} diff --git a/examples/dynamic/README b/examples/dynamic/README new file mode 100644 index 0000000000000000000000000000000000000000..072b74b16ec021d129380dc03daff3212920c5ac --- /dev/null +++ b/examples/dynamic/README @@ -0,0 +1,2 @@ +This directory contains an embryo of an example of how to +generate and compile a labcomm endpoint on the fly. diff --git a/examples/dynamic/StaticPart.java b/examples/dynamic/StaticPart.java new file mode 100644 index 0000000000000000000000000000000000000000..1ffe501415da2c16393c8e775079bec8a43f5d28 --- /dev/null +++ b/examples/dynamic/StaticPart.java @@ -0,0 +1,99 @@ +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 class Encoder { + + LabCommEncoderChannel encoder; + + public Encoder(OutputStream out) + throws Exception + { + encoder = new LabCommEncoderChannel(out); + theTwoInts.register(encoder); + IntString.register(encoder); + TwoArrays.register(encoder); + } + + public void doEncode() throws java.io.IOException { + TwoInts x = new TwoInts(); + x.a = 17; + x.b = 42; + + IntString y = new IntString(); + y.x = 37; + y.s = "Testing, testing"; + + System.out.println("Encoding theTwoInts, a="+x.a+", b="+x.b); + theTwoInts.encode(encoder, x); + + System.out.println("Encoding IntString, x="+y.x+", s="+y.s); + IntString.encode(encoder, y); + } + } + + public class Decoder + implements theTwoInts.Handler, anotherTwoInts.Handler, IntString.Handler + { + + LabCommDecoderChannel decoder; + + public Decoder(InputStream in) + throws Exception + { + decoder = new LabCommDecoderChannel(in); + theTwoInts.register(decoder, this); + anotherTwoInts.register(decoder, this); + IntString.register(decoder, this); + TwoArrays.register(decoder, this); + TwoFixedArrays.register(decoder, this); + + try { + System.out.println("Running decoder."); + decoder.run(); + } catch (java.io.EOFException e) { + System.out.println("Decoder reached end of file."); + } + } + + public void printTwoInts(TwoInts d) throws java.io.IOException { + System.out.println("a="+d.a+", b="+d.b); + } + + public void handle_theTwoInts(TwoInts d) throws java.io.IOException { + System.out.print("Got theTwoInts: "); + printTwoInts(d); + } + + public void handle_anotherTwoInts(TwoInts d) throws java.io.IOException { + System.out.print("Got anotherheTwoInts: "); + printTwoInts(d); + } + + public void handle_IntString(IntString d) throws java.io.IOException { + System.out.println("Got IntString, x="+d.x+", s="+d.s); + } + + } + + public static void main(String[] arg) throws Exception { + FileOutputStream fos = new FileOutputStream(arg[0]); + FileInputStream fis = new FileInputStream(new File(arg[0])) + Encoder example = new Encoder(fos); + Decoder example = new Decoder(fis); + example.doEncode(); + fos.close(); + fis.close(); + } +} + diff --git a/examples/dynamic/TestLabCommCompiler.java b/examples/dynamic/TestLabCommCompiler.java new file mode 100644 index 0000000000000000000000000000000000000000..4afe10321c47e0f87bc211a6af12568b371b1374 --- /dev/null +++ b/examples/dynamic/TestLabCommCompiler.java @@ -0,0 +1,160 @@ +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Map; + +import AST.LabCommParser; +import AST.LabCommScanner; +import AST.Program; +import beaver.Parser.Exception; + + + +public class TestLabCommCompiler { + + /** + * @param args + */ + public static void main(String[] args) { + + /* input data: */ + String prg ="sample struct { int x; int y; int z;}foo; sample int bar;"; + + HashMap <String, String> handlers = new HashMap<String, String>(); + handlers.put("foo", "public void handle_foo(foo value) {\nSystem.out.println(value.x);\nSystem.out.println(value.y);\nSystem.out.println(value.z);}"); + handlers.put("bar", "public void handle_bar(int value) {System.out.println(value);}"); + + generateCode(prg, handlers); + + } + public static void generateCode(String prg, HashMap<String, String> handlers) { + Program ast = null; + InputStream in = new ByteArrayInputStream(prg.getBytes()); + LabCommScanner scanner = new LabCommScanner(in); + LabCommParser parser = new LabCommParser(); + Collection errors = new LinkedList(); + + try { + Program p = (Program)parser.parse(scanner); + p.errorCheck(errors); + if (errors.isEmpty()) { + ast = p; + } else { + System.out.println("*** Errors:"); + for (Iterator iter = errors.iterator(); iter.hasNext(); ) { + String s = (String)iter.next(); + System.out.println(s); + } + } + } catch (IOException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } + + if (ast != null) { + InRAMCompiler irc = handleAst(ast, handlers); + dummyTest(irc); + } else { + System.err.println("compilation failed"); + } + } + /* dummy test creating instances of sample and handler, and calling handle*/ + private static void dummyTest(InRAMCompiler irc) { + try { + Class hc = irc.load("gen_fooHandler"); + Object h = hc.newInstance(); + Class fc = irc.load("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_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(); + } + } + + private static InRAMCompiler handleAst(Program ast, HashMap<String, String> handlers) { + Map<String, String> foo = new HashMap<String, String>(); + try { + ast.J_gen(foo, "labcomm.generated"); + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("Generated labcomm code:"); + + InRAMCompiler irc = new InRAMCompilerJavax("labcomm.generated", null); + + Iterator<String> i = foo.keySet().iterator(); + while(i.hasNext()){ + final String name = i.next(); + final String src = foo.get(name); + System.out.println("***"+name+"\n"+src); + StringBuilder sb = new StringBuilder(); + sb.append("package labcomm.generated;\n"); + sb.append("public class gen_"+name+"Handler implements "+name+".Handler {\n"); + sb.append(handlers.get(name)); + sb.append("}\n"); + System.out.println("-------------------------------------"); + System.out.println(sb.toString()); + try { + irc.compile(name, src); + irc.compile("gen_"+name+"Handler", sb.toString()); + } 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; + } +} diff --git a/examples/dynamic/runme.sh b/examples/dynamic/runme.sh new file mode 100644 index 0000000000000000000000000000000000000000..fed042d934f82433a3373d9ece547b38c17f1efc --- /dev/null +++ b/examples/dynamic/runme.sh @@ -0,0 +1,5 @@ +#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 TestLabCommCompiler.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 TestLabCommCompiler diff --git a/examples/dynamic/simple.lc b/examples/dynamic/simple.lc new file mode 100644 index 0000000000000000000000000000000000000000..6443d6c099cf46fdc48abda93ec59bb469343ee5 --- /dev/null +++ b/examples/dynamic/simple.lc @@ -0,0 +1,13 @@ +typedef struct { + int a; + int b; +} TwoInts; + +sample TwoInts theTwoInts; +sample TwoInts anotherTwoInts; + +sample struct { + int x; + string s; +} IntString; +