Mercurial Hosting > luan
annotate core/src/luan/impl/LuanJavaCompiler.java @ 652:067d9470184d
compile SetStmt and ForStmt
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Mon, 04 Apr 2016 23:26:06 -0600 |
parents | d658eab7bf4c |
children | e038905512d3 |
rev | line source |
---|---|
648
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1 package luan.impl; |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
2 |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
3 import java.io.OutputStream; |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
4 import java.io.ByteArrayOutputStream; |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
5 import java.io.StringWriter; |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
6 import java.io.IOException; |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
7 import java.net.URI; |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
8 import java.util.Collections; |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
9 import javax.tools.FileObject; |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
10 import javax.tools.JavaFileObject; |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
11 import javax.tools.SimpleJavaFileObject; |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
12 import javax.tools.JavaCompiler; |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
13 import javax.tools.ToolProvider; |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
14 import javax.tools.JavaFileManager; |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
15 import javax.tools.StandardJavaFileManager; |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
16 import javax.tools.ForwardingJavaFileManager; |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
17 |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
18 |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
19 public final class LuanJavaCompiler { |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
20 private LuanJavaCompiler() {} // never |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
21 |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
22 public static Class compile(final String className,final String sourceName,final String code) throws ClassNotFoundException { |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
23 final int len = sourceName.length(); |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
24 StringBuilder sb = new StringBuilder(sourceName); |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
25 for( int i=0; i<len; i++ ) |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
26 sb.setCharAt(i,'$'); |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
27 JavaFileObject sourceFile = new SimpleJavaFileObject(URI.create(sb.toString()),JavaFileObject.Kind.SOURCE) { |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
28 @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) { |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
29 return code; |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
30 } |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
31 @Override public String getName() { |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
32 return sourceName; |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
33 } |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
34 @Override public boolean isNameCompatible(String simpleName,JavaFileObject.Kind kind) { |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
35 return true; |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
36 } |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
37 }; |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
38 ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
39 JavaFileObject classFile = new SimpleJavaFileObject(URI.create("whatever"),JavaFileObject.Kind.CLASS) { |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
40 @Override public OutputStream openOutputStream() { |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
41 return baos; |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
42 } |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
43 }; |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
44 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
45 StandardJavaFileManager sjfm = compiler.getStandardFileManager(null,null,null); |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
46 ForwardingJavaFileManager fjfm = new ForwardingJavaFileManager(sjfm) { |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
47 @Override public JavaFileObject getJavaFileForOutput(JavaFileManager.Location location, String className, JavaFileObject.Kind kind, FileObject sibling) throws IOException { |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
48 return classFile; |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
49 } |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
50 }; |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
51 StringWriter out = new StringWriter(); |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
52 boolean b = compiler.getTask(out, fjfm, null, null, null, Collections.singletonList(sourceFile)).call(); |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
53 if( !b ) |
652
067d9470184d
compile SetStmt and ForStmt
Franklin Schmidt <fschmidt@gmail.com>
parents:
650
diff
changeset
|
54 throw new RuntimeException("\n"+out+"\ncode:\n"+code+"\n"); |
648
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
55 byte[] byteCode = baos.toByteArray(); |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
56 int max = byteCode.length-len-3; |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
57 outer: |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
58 for( int i=0; true; i++ ) { |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
59 if( i > max ) |
650
d658eab7bf4c
finish compiling operators
Franklin Schmidt <fschmidt@gmail.com>
parents:
648
diff
changeset
|
60 throw new RuntimeException("len="+len); |
d658eab7bf4c
finish compiling operators
Franklin Schmidt <fschmidt@gmail.com>
parents:
648
diff
changeset
|
61 if( byteCode[i]==1 && (byteCode[i+1] << 8 | 0xFF & byteCode[i+2]) == len ) { |
648
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
62 for( int j=i+3; j<i+3+len; j++ ) { |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
63 if( byteCode[j] != '$' ) |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
64 continue outer; |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
65 } |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
66 System.arraycopy(sourceName.getBytes(),0,byteCode,i+3,len); |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
67 break; |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
68 } |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
69 } |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
70 ClassLoader cl = new ClassLoader() { |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
71 @Override protected Class<?> findClass(String name) throws ClassNotFoundException { |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
72 if( name.equals(className) ) { |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
73 return defineClass(name, byteCode, 0, byteCode.length); |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
74 } |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
75 return super.findClass(name); |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
76 } |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
77 }; |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
78 return cl.loadClass(className); |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
79 } |
e387e4021afe
start compiler with len operator
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
80 } |