Mercurial Hosting > luan
annotate src/luan/impl/LuanCompiler.java @ 1561:e1a13e707bf3
start immutable
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 05 Nov 2020 20:24:09 -0700 |
parents | 6c830be6be98 |
children | 8fbcc4747091 |
rev | line source |
---|---|
166
4eaee12f6c65
move luan/interp to impl
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
165
diff
changeset
|
1 package luan.impl; |
48
64ecb7a3aad7
rename Lua to Luan
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
2 |
703
6e6e9e73abaa
cache classes in compiler
Franklin Schmidt <fschmidt@gmail.com>
parents:
694
diff
changeset
|
3 import java.lang.ref.WeakReference; |
6e6e9e73abaa
cache classes in compiler
Franklin Schmidt <fschmidt@gmail.com>
parents:
694
diff
changeset
|
4 import java.lang.reflect.InvocationTargetException; |
1496 | 5 import java.security.MessageDigest; |
6 import java.security.NoSuchAlgorithmException; | |
667
08966099aa6d
implement Closure directly
Franklin Schmidt <fschmidt@gmail.com>
parents:
649
diff
changeset
|
7 import java.util.Map; |
703
6e6e9e73abaa
cache classes in compiler
Franklin Schmidt <fschmidt@gmail.com>
parents:
694
diff
changeset
|
8 import java.util.HashMap; |
1434
56fb5cd8228d
cache compiled code in temp files
Franklin Schmidt <fschmidt@gmail.com>
parents:
1353
diff
changeset
|
9 import java.util.Base64; |
1335 | 10 import luan.Luan; |
48
64ecb7a3aad7
rename Lua to Luan
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
11 import luan.LuanFunction; |
64ecb7a3aad7
rename Lua to Luan
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
12 import luan.LuanException; |
86
6db8f286fa6c
_ENV is per module, not global
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
80
diff
changeset
|
13 import luan.LuanTable; |
1330 | 14 import luan.LuanClosure; |
321
7f7708e8fdd4
remove import statement
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
320
diff
changeset
|
15 import luan.modules.JavaLuan; |
7f7708e8fdd4
remove import statement
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
320
diff
changeset
|
16 import luan.modules.PackageLuan; |
48
64ecb7a3aad7
rename Lua to Luan
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
17 |
64ecb7a3aad7
rename Lua to Luan
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
18 |
64ecb7a3aad7
rename Lua to Luan
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
19 public final class LuanCompiler { |
703
6e6e9e73abaa
cache classes in compiler
Franklin Schmidt <fschmidt@gmail.com>
parents:
694
diff
changeset
|
20 private static final Map<String,WeakReference<Class>> map = new HashMap<String,WeakReference<Class>>(); |
48
64ecb7a3aad7
rename Lua to Luan
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
21 |
1496 | 22 public static LuanFunction compile(Luan luan,String sourceText,String sourceName,boolean persist,LuanTable env) |
23 throws LuanException | |
24 { | |
25 if( persist && env!=null ) | |
1434
56fb5cd8228d
cache compiled code in temp files
Franklin Schmidt <fschmidt@gmail.com>
parents:
1353
diff
changeset
|
26 throw new LuanException("can't persist with env"); |
56fb5cd8228d
cache compiled code in temp files
Franklin Schmidt <fschmidt@gmail.com>
parents:
1353
diff
changeset
|
27 Class fnClass = persist ? getClass(sourceText,sourceName) : getClass(sourceText,sourceName,env); |
1330 | 28 boolean javaOk = false; |
29 if( env != null && env.closure != null ) | |
30 javaOk = env.closure.javaOk; | |
31 LuanClosure closure; | |
667
08966099aa6d
implement Closure directly
Franklin Schmidt <fschmidt@gmail.com>
parents:
649
diff
changeset
|
32 try { |
1335 | 33 closure = (LuanClosure)fnClass.getConstructor(Luan.class,Boolean.TYPE,String.class).newInstance(luan,javaOk,sourceName); |
667
08966099aa6d
implement Closure directly
Franklin Schmidt <fschmidt@gmail.com>
parents:
649
diff
changeset
|
34 } catch(NoSuchMethodException e) { |
08966099aa6d
implement Closure directly
Franklin Schmidt <fschmidt@gmail.com>
parents:
649
diff
changeset
|
35 throw new RuntimeException(e); |
08966099aa6d
implement Closure directly
Franklin Schmidt <fschmidt@gmail.com>
parents:
649
diff
changeset
|
36 } catch(InstantiationException e) { |
08966099aa6d
implement Closure directly
Franklin Schmidt <fschmidt@gmail.com>
parents:
649
diff
changeset
|
37 throw new RuntimeException(e); |
08966099aa6d
implement Closure directly
Franklin Schmidt <fschmidt@gmail.com>
parents:
649
diff
changeset
|
38 } catch(IllegalAccessException e) { |
08966099aa6d
implement Closure directly
Franklin Schmidt <fschmidt@gmail.com>
parents:
649
diff
changeset
|
39 throw new RuntimeException(e); |
08966099aa6d
implement Closure directly
Franklin Schmidt <fschmidt@gmail.com>
parents:
649
diff
changeset
|
40 } catch(InvocationTargetException e) { |
08966099aa6d
implement Closure directly
Franklin Schmidt <fschmidt@gmail.com>
parents:
649
diff
changeset
|
41 throw new RuntimeException(e); |
08966099aa6d
implement Closure directly
Franklin Schmidt <fschmidt@gmail.com>
parents:
649
diff
changeset
|
42 } |
1561 | 43 closure.upValues[0].set( PackageLuan.requireFn(luan) ); |
1330 | 44 if( env != null ) { |
1561 | 45 closure.upValues[1].set(env); |
1330 | 46 env.closure = closure; |
47 } | |
670
58ebfec6178b
all luan now compiles
Franklin Schmidt <fschmidt@gmail.com>
parents:
667
diff
changeset
|
48 return closure; |
128
f0a4abe58593
minor
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
111
diff
changeset
|
49 } |
f0a4abe58593
minor
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
111
diff
changeset
|
50 |
1496 | 51 private static synchronized Class getClass(String sourceText,String sourceName) |
52 throws LuanException | |
1434
56fb5cd8228d
cache compiled code in temp files
Franklin Schmidt <fschmidt@gmail.com>
parents:
1353
diff
changeset
|
53 { |
703
6e6e9e73abaa
cache classes in compiler
Franklin Schmidt <fschmidt@gmail.com>
parents:
694
diff
changeset
|
54 String key = sourceName + "~~~" + sourceText; |
6e6e9e73abaa
cache classes in compiler
Franklin Schmidt <fschmidt@gmail.com>
parents:
694
diff
changeset
|
55 WeakReference<Class> ref = map.get(key); |
6e6e9e73abaa
cache classes in compiler
Franklin Schmidt <fschmidt@gmail.com>
parents:
694
diff
changeset
|
56 if( ref != null ) { |
6e6e9e73abaa
cache classes in compiler
Franklin Schmidt <fschmidt@gmail.com>
parents:
694
diff
changeset
|
57 Class cls = ref.get(); |
6e6e9e73abaa
cache classes in compiler
Franklin Schmidt <fschmidt@gmail.com>
parents:
694
diff
changeset
|
58 if( cls != null ) |
6e6e9e73abaa
cache classes in compiler
Franklin Schmidt <fschmidt@gmail.com>
parents:
694
diff
changeset
|
59 return cls; |
1496 | 60 } |
61 String fileName; | |
62 try { | |
63 byte[] a = MessageDigest.getInstance("MD5").digest(key.getBytes()); | |
64 String s = Base64.getUrlEncoder().encodeToString(a); | |
65 //System.err.println("qqqqqqqqqq "+s); | |
66 fileName = s + ".luanc"; | |
67 } catch(NoSuchAlgorithmException e) { | |
68 throw new RuntimeException(e); | |
69 } | |
70 Compiled compiled = Compiled.load(fileName,key); | |
71 //Compiled compiled = null; | |
72 if( compiled==null ) { | |
73 compiled = getCompiled(sourceText,sourceName,null); | |
74 compiled.save(fileName,key); | |
703
6e6e9e73abaa
cache classes in compiler
Franklin Schmidt <fschmidt@gmail.com>
parents:
694
diff
changeset
|
75 } |
1434
56fb5cd8228d
cache compiled code in temp files
Franklin Schmidt <fschmidt@gmail.com>
parents:
1353
diff
changeset
|
76 Class cls = compiled.loadClass(); |
703
6e6e9e73abaa
cache classes in compiler
Franklin Schmidt <fschmidt@gmail.com>
parents:
694
diff
changeset
|
77 map.put(key,new WeakReference<Class>(cls)); |
6e6e9e73abaa
cache classes in compiler
Franklin Schmidt <fschmidt@gmail.com>
parents:
694
diff
changeset
|
78 return cls; |
6e6e9e73abaa
cache classes in compiler
Franklin Schmidt <fschmidt@gmail.com>
parents:
694
diff
changeset
|
79 } |
6e6e9e73abaa
cache classes in compiler
Franklin Schmidt <fschmidt@gmail.com>
parents:
694
diff
changeset
|
80 |
1496 | 81 private static Class getClass(String sourceText,String sourceName,LuanTable env) |
82 throws LuanException | |
83 { | |
84 return getCompiled(sourceText,sourceName,env).loadClass(); | |
85 } | |
1434
56fb5cd8228d
cache compiled code in temp files
Franklin Schmidt <fschmidt@gmail.com>
parents:
1353
diff
changeset
|
86 |
1496 | 87 private static Compiled getCompiled(String sourceText,String sourceName,LuanTable env) |
88 throws LuanException | |
1434
56fb5cd8228d
cache compiled code in temp files
Franklin Schmidt <fschmidt@gmail.com>
parents:
1353
diff
changeset
|
89 { |
703
6e6e9e73abaa
cache classes in compiler
Franklin Schmidt <fschmidt@gmail.com>
parents:
694
diff
changeset
|
90 LuanParser parser = new LuanParser(sourceText,sourceName); |
6e6e9e73abaa
cache classes in compiler
Franklin Schmidt <fschmidt@gmail.com>
parents:
694
diff
changeset
|
91 parser.addVar( "require" ); |
6e6e9e73abaa
cache classes in compiler
Franklin Schmidt <fschmidt@gmail.com>
parents:
694
diff
changeset
|
92 if( env != null ) parser.addVar( "_ENV" ); |
6e6e9e73abaa
cache classes in compiler
Franklin Schmidt <fschmidt@gmail.com>
parents:
694
diff
changeset
|
93 try { |
6e6e9e73abaa
cache classes in compiler
Franklin Schmidt <fschmidt@gmail.com>
parents:
694
diff
changeset
|
94 return parser.RequiredModule(); |
6e6e9e73abaa
cache classes in compiler
Franklin Schmidt <fschmidt@gmail.com>
parents:
694
diff
changeset
|
95 } catch(ParseException e) { |
6e6e9e73abaa
cache classes in compiler
Franklin Schmidt <fschmidt@gmail.com>
parents:
694
diff
changeset
|
96 //e.printStackTrace(); |
6e6e9e73abaa
cache classes in compiler
Franklin Schmidt <fschmidt@gmail.com>
parents:
694
diff
changeset
|
97 throw new LuanException( e.getFancyMessage() ); |
6e6e9e73abaa
cache classes in compiler
Franklin Schmidt <fschmidt@gmail.com>
parents:
694
diff
changeset
|
98 } |
6e6e9e73abaa
cache classes in compiler
Franklin Schmidt <fschmidt@gmail.com>
parents:
694
diff
changeset
|
99 } |
6e6e9e73abaa
cache classes in compiler
Franklin Schmidt <fschmidt@gmail.com>
parents:
694
diff
changeset
|
100 |
1496 | 101 public static String toJava(String sourceText,String sourceName) |
102 throws LuanException | |
1434
56fb5cd8228d
cache compiled code in temp files
Franklin Schmidt <fschmidt@gmail.com>
parents:
1353
diff
changeset
|
103 { |
708
77e0c859c8a3
fix luan_to_java and fix line numbers
Franklin Schmidt <fschmidt@gmail.com>
parents:
703
diff
changeset
|
104 LuanParser parser = new LuanParser(sourceText,sourceName); |
678 | 105 parser.addVar( "require" ); |
106 try { | |
107 return parser.RequiredModuleSource(); | |
108 } catch(ParseException e) { | |
1496 | 109 //e.printStackTrace(); |
678 | 110 throw new LuanException( e.getFancyMessage() ); |
111 } | |
112 } | |
113 | |
703
6e6e9e73abaa
cache classes in compiler
Franklin Schmidt <fschmidt@gmail.com>
parents:
694
diff
changeset
|
114 private LuanCompiler() {} // never |
48
64ecb7a3aad7
rename Lua to Luan
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
115 } |