Selaa lähdekoodia

One generated class per script file + classes

kindlich 6 vuotta sitten
vanhempi
commit
e09877d432
No known key found for this signature in database

+ 35
- 10
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaCompiler.java Näytä tiedosto

@@ -6,7 +6,10 @@
6 6
 package org.openzen.zenscript.javabytecode;
7 7
 
8 8
 import java.util.ArrayList;
9
+import java.util.HashMap;
9 10
 import java.util.List;
11
+import java.util.Map;
12
+
10 13
 import org.objectweb.asm.ClassWriter;
11 14
 import org.objectweb.asm.Opcodes;
12 15
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
@@ -15,6 +18,7 @@ import org.openzen.zenscript.codemodel.member.DefinitionMember;
15 18
 import org.openzen.zenscript.codemodel.statement.Statement;
16 19
 import static org.openzen.zenscript.codemodel.type.member.BuiltinTypeMembers.*;
17 20
 
21
+import org.openzen.zenscript.javabytecode.compiler.JavaClassWriter;
18 22
 import org.openzen.zenscript.javabytecode.compiler.definitions.JavaDefinitionVisitor;
19 23
 import org.openzen.zenscript.javabytecode.compiler.JavaStatementVisitor;
20 24
 import org.openzen.zenscript.javabytecode.compiler.JavaWriter;
@@ -127,8 +131,8 @@ public class JavaCompiler {
127 131
 	}
128 132
 	
129 133
 	private final JavaModule target;
130
-	private final List<String> scriptBlockNames = new ArrayList<>();
131
-	private final ClassWriter scriptsClassWriter;
134
+	private final Map<String, JavaClassWriter> scriptBlocks = new HashMap<>();
135
+	private final JavaClassWriter scriptsClassWriter;
132 136
 	private int generatedScriptBlockCounter = 0;
133 137
 	private boolean finished = false;
134 138
 	
@@ -139,19 +143,29 @@ public class JavaCompiler {
139 143
 	public JavaCompiler(boolean debug) {
140 144
 		target = new JavaModule();
141 145
 		
142
-		scriptsClassWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
146
+		scriptsClassWriter = new JavaClassWriter(ClassWriter.COMPUTE_FRAMES, true);
143 147
 		scriptsClassWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, "Scripts", null, "java/lang/Object", null);
144 148
 	}
145 149
 	
146 150
 	public void addDefinition(HighLevelDefinition definition) {
147 151
 		// convert definition into java class
148
-		target.register(definition.name, definition.accept(new JavaDefinitionVisitor()));
152
+
153
+		final String methodName = definition.position.filename.substring(0, definition.position.filename.lastIndexOf('.')).replace("/", "_");
154
+
155
+
156
+		if(!scriptBlocks.containsKey(methodName)) {
157
+			JavaClassWriter scriptFileWriter = new JavaClassWriter(ClassWriter.COMPUTE_FRAMES);
158
+			scriptFileWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, methodName, null, "java/lang/Object", null);
159
+			scriptBlocks.put(methodName, scriptFileWriter);
160
+		}
161
+
162
+		target.register(definition.name, definition.accept(new JavaDefinitionVisitor(scriptBlocks.get(definition.position.filename))));
149 163
 
150 164
 	}
151 165
 	
152 166
 	public void addScriptBlock(ScriptBlock script) {
153
-		SourceFile sourceFile = script.getTag(SourceFile.class);
154
-		String methodName;
167
+		final SourceFile sourceFile = script.getTag(SourceFile.class);
168
+		final String methodName;
155 169
 		if (sourceFile == null) {
156 170
 			methodName = "generatedBlock" + (generatedScriptBlockCounter++);
157 171
 		} else {
@@ -160,11 +174,17 @@ public class JavaCompiler {
160 174
 			methodName = sourceFile.filename.substring(0, sourceFile.filename.lastIndexOf('.')).replace("/", "_");
161 175
 		}
162 176
 
163
-		scriptBlockNames.add(methodName);
177
+		if(!scriptBlocks.containsKey(methodName)) {
178
+			JavaClassWriter scriptFileWriter = new JavaClassWriter(ClassWriter.COMPUTE_FRAMES, true);
179
+			scriptFileWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, methodName, null, "java/lang/Object", null);
180
+			scriptBlocks.put(methodName, scriptFileWriter);
181
+		}
164 182
 
165 183
 		// convert scripts into methods (add them to a Scripts class?)
166 184
 		// (TODO: can we break very long scripts into smaller methods? for the extreme scripts)
167
-		final JavaStatementVisitor statementVisitor = new JavaStatementVisitor(new JavaWriter(scriptsClassWriter, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, methodName, "()V", null, null));
185
+		final JavaClassWriter visitor = scriptBlocks.get(methodName);
186
+		visitor.hasRun = true;
187
+		final JavaStatementVisitor statementVisitor = new JavaStatementVisitor(new JavaWriter(visitor, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "run", "()V", null, null));
168 188
 		statementVisitor.start();
169 189
 		for (Statement statement : script.statements) {
170 190
 			statement.accept(statementVisitor);
@@ -180,8 +200,13 @@ public class JavaCompiler {
180 200
 		
181 201
 		final JavaWriter runWriter = new JavaWriter(scriptsClassWriter, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "run", "()V", null, null);
182 202
 		runWriter.start();
183
-		for (String scriptBlockName : scriptBlockNames) {
184
-			runWriter.invokeStatic("Scripts", scriptBlockName, "()V");
203
+		for (Map.Entry<String, JavaClassWriter> entry : scriptBlocks.entrySet()) {
204
+			final String owner = entry.getKey();
205
+			final JavaClassWriter classWriter = entry.getValue();
206
+			if(classWriter.hasRun)
207
+				runWriter.invokeStatic(owner, "run", "()V");
208
+			classWriter.visitEnd();
209
+			target.register(owner, classWriter.toByteArray());
185 210
 		}
186 211
 		runWriter.ret();
187 212
 		runWriter.end();

+ 4
- 13
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaModule.java Näytä tiedosto

@@ -17,13 +17,14 @@ import java.util.logging.Logger;
17 17
  * @author Hoofdgebruiker
18 18
  */
19 19
 public class JavaModule {
20
-	private Map<String, byte[]> classes = new HashMap<>();
20
+	private final Map<String, byte[]> classes = new HashMap<>();
21 21
 	
22 22
 	public JavaModule() {
23 23
 		
24 24
 	}
25 25
 	
26 26
 	public void register(String classname, byte[] bytecode) {
27
+		if(bytecode == null) return;
27 28
 		classes.put(classname, bytecode);
28 29
 		try(FileOutputStream writer = new FileOutputStream(new File(classname + ".class"))) {
29 30
 			writer.write(bytecode);
@@ -37,23 +38,13 @@ public class JavaModule {
37 38
 		
38 39
 		try {
39 40
 			classLoader.loadClass("Scripts").getMethod("run").invoke(null);
40
-		} catch (ClassNotFoundException ex) {
41
-			Logger.getLogger(JavaModule.class.getName()).log(Level.SEVERE, null, ex);
42
-		} catch (NoSuchMethodException ex) {
43
-			Logger.getLogger(JavaModule.class.getName()).log(Level.SEVERE, null, ex);
44
-		} catch (SecurityException ex) {
45
-			Logger.getLogger(JavaModule.class.getName()).log(Level.SEVERE, null, ex);
46
-		} catch (IllegalAccessException ex) {
47
-			Logger.getLogger(JavaModule.class.getName()).log(Level.SEVERE, null, ex);
48
-		} catch (IllegalArgumentException ex) {
49
-			Logger.getLogger(JavaModule.class.getName()).log(Level.SEVERE, null, ex);
50
-		} catch (InvocationTargetException ex) {
41
+		} catch (ClassNotFoundException | InvocationTargetException | NoSuchMethodException | IllegalAccessException | SecurityException | IllegalArgumentException ex) {
51 42
 			Logger.getLogger(JavaModule.class.getName()).log(Level.SEVERE, null, ex);
52 43
 		}
53 44
 	}
54 45
 	
55 46
 	private class ScriptClassLoader extends ClassLoader {
56
-		final Map<String, Class> customClasses = new HashMap<>();
47
+		private final Map<String, Class> customClasses = new HashMap<>();
57 48
 
58 49
 		@Override
59 50
 		public Class<?> loadClass(String name) throws ClassNotFoundException {

+ 18
- 0
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaClassWriter.java Näytä tiedosto

@@ -0,0 +1,18 @@
1
+package org.openzen.zenscript.javabytecode.compiler;
2
+
3
+import org.objectweb.asm.ClassWriter;
4
+
5
+public class JavaClassWriter extends ClassWriter {
6
+
7
+    public boolean hasRun;
8
+
9
+    public JavaClassWriter(int flags) {
10
+        super(flags);
11
+        this.hasRun = false;
12
+    }
13
+
14
+    public JavaClassWriter(int flags, boolean hasRun) {
15
+        super(flags);
16
+        this.hasRun = hasRun;
17
+    }
18
+}

+ 8
- 1
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/definitions/JavaDefinitionVisitor.java Näytä tiedosto

@@ -21,9 +21,16 @@ import org.openzen.zenscript.javabytecode.compiler.JavaWriter;
21 21
 public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
22 22
 
23 23
 
24
+    private final ClassWriter outerWriter;
25
+
26
+    public JavaDefinitionVisitor(ClassWriter outerWriter) {
27
+
28
+        this.outerWriter = outerWriter;
29
+    }
30
+
24 31
     @Override
25 32
     public byte[] visitClass(ClassDefinition definition) {
26
-
33
+        //Classes will always be created in a new File/Class
27 34
 
28 35
         final Type superType;
29 36
         if (definition.superType == null)

+ 58
- 0
ScriptingExample/scripts/conditionals.zs Näytä tiedosto

@@ -0,0 +1,58 @@
1
+val ternaryOperation = true ? 100 : 222;
2
+
3
+println(ternaryOperation);
4
+
5
+
6
+
7
+var coalesce_one as string? = null;
8
+var coalesce_tow as string? = "test";
9
+
10
+
11
+var coalesce = coalesce_one ?? coalesce_tow;
12
+
13
+println(coalesce);
14
+
15
+
16
+//if(coalesce == "test123") {
17
+//	println("true");
18
+//}
19
+
20
+if(1 == 1) {
21
+	println("intCompareTrue");
22
+}
23
+
24
+//if(1 == "1") {
25
+//	println("well...");
26
+//}
27
+
28
+
29
+if("1" == 1) {
30
+	println("...");
31
+}
32
+
33
+
34
+//var coco as int? = 10;
35
+//var coal as int? = 1;
36
+//
37
+//println(coal ?? coco);
38
+
39
+
40
+println(".....");
41
+println(true ? "RR" : "TT");
42
+
43
+
44
+println((false && true && true) ? "true" : "false");
45
+println((true && true) ? "true" : "false");
46
+println((true && false) ? "true" : "false");
47
+println((false && false) ? "true" : "false");
48
+
49
+println("---");
50
+
51
+println((false || true) ? "true" : "false");
52
+println((true || true) ? "true" : "false");
53
+println((true || false) ? "true" : "false");
54
+println((false || false) ? "true" : "false");
55
+
56
+println(":::");
57
+
58
+println((1 <= 2) ? "true" : "false");

+ 2
- 2
ScriptingExample/scripts/moreHellos.zs Näytä tiedosto

@@ -61,9 +61,9 @@ for item in testArray {
61 61
 
62 62
 println("");
63 63
 
64
-var test2 = [1, 2, 3];
64
+var test3 = [1, 2, 3];
65 65
 
66
-for item in test2 {
66
+for item in test3 {
67 67
 	println(item);
68 68
 }
69 69
 

Loading…
Peruuta
Tallenna