Browse Source

One generated class per script file + classes

kindlich 6 years ago
parent
commit
e09877d432
No known key found for this signature in database

+ 35
- 10
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaCompiler.java View File

6
 package org.openzen.zenscript.javabytecode;
6
 package org.openzen.zenscript.javabytecode;
7
 
7
 
8
 import java.util.ArrayList;
8
 import java.util.ArrayList;
9
+import java.util.HashMap;
9
 import java.util.List;
10
 import java.util.List;
11
+import java.util.Map;
12
+
10
 import org.objectweb.asm.ClassWriter;
13
 import org.objectweb.asm.ClassWriter;
11
 import org.objectweb.asm.Opcodes;
14
 import org.objectweb.asm.Opcodes;
12
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
15
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
15
 import org.openzen.zenscript.codemodel.statement.Statement;
18
 import org.openzen.zenscript.codemodel.statement.Statement;
16
 import static org.openzen.zenscript.codemodel.type.member.BuiltinTypeMembers.*;
19
 import static org.openzen.zenscript.codemodel.type.member.BuiltinTypeMembers.*;
17
 
20
 
21
+import org.openzen.zenscript.javabytecode.compiler.JavaClassWriter;
18
 import org.openzen.zenscript.javabytecode.compiler.definitions.JavaDefinitionVisitor;
22
 import org.openzen.zenscript.javabytecode.compiler.definitions.JavaDefinitionVisitor;
19
 import org.openzen.zenscript.javabytecode.compiler.JavaStatementVisitor;
23
 import org.openzen.zenscript.javabytecode.compiler.JavaStatementVisitor;
20
 import org.openzen.zenscript.javabytecode.compiler.JavaWriter;
24
 import org.openzen.zenscript.javabytecode.compiler.JavaWriter;
127
 	}
131
 	}
128
 	
132
 	
129
 	private final JavaModule target;
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
 	private int generatedScriptBlockCounter = 0;
136
 	private int generatedScriptBlockCounter = 0;
133
 	private boolean finished = false;
137
 	private boolean finished = false;
134
 	
138
 	
139
 	public JavaCompiler(boolean debug) {
143
 	public JavaCompiler(boolean debug) {
140
 		target = new JavaModule();
144
 		target = new JavaModule();
141
 		
145
 		
142
-		scriptsClassWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
146
+		scriptsClassWriter = new JavaClassWriter(ClassWriter.COMPUTE_FRAMES, true);
143
 		scriptsClassWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, "Scripts", null, "java/lang/Object", null);
147
 		scriptsClassWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, "Scripts", null, "java/lang/Object", null);
144
 	}
148
 	}
145
 	
149
 	
146
 	public void addDefinition(HighLevelDefinition definition) {
150
 	public void addDefinition(HighLevelDefinition definition) {
147
 		// convert definition into java class
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
 	public void addScriptBlock(ScriptBlock script) {
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
 		if (sourceFile == null) {
169
 		if (sourceFile == null) {
156
 			methodName = "generatedBlock" + (generatedScriptBlockCounter++);
170
 			methodName = "generatedBlock" + (generatedScriptBlockCounter++);
157
 		} else {
171
 		} else {
160
 			methodName = sourceFile.filename.substring(0, sourceFile.filename.lastIndexOf('.')).replace("/", "_");
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
 		// convert scripts into methods (add them to a Scripts class?)
183
 		// convert scripts into methods (add them to a Scripts class?)
166
 		// (TODO: can we break very long scripts into smaller methods? for the extreme scripts)
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
 		statementVisitor.start();
188
 		statementVisitor.start();
169
 		for (Statement statement : script.statements) {
189
 		for (Statement statement : script.statements) {
170
 			statement.accept(statementVisitor);
190
 			statement.accept(statementVisitor);
180
 		
200
 		
181
 		final JavaWriter runWriter = new JavaWriter(scriptsClassWriter, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "run", "()V", null, null);
201
 		final JavaWriter runWriter = new JavaWriter(scriptsClassWriter, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "run", "()V", null, null);
182
 		runWriter.start();
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
 		runWriter.ret();
211
 		runWriter.ret();
187
 		runWriter.end();
212
 		runWriter.end();

+ 4
- 13
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaModule.java View File

17
  * @author Hoofdgebruiker
17
  * @author Hoofdgebruiker
18
  */
18
  */
19
 public class JavaModule {
19
 public class JavaModule {
20
-	private Map<String, byte[]> classes = new HashMap<>();
20
+	private final Map<String, byte[]> classes = new HashMap<>();
21
 	
21
 	
22
 	public JavaModule() {
22
 	public JavaModule() {
23
 		
23
 		
24
 	}
24
 	}
25
 	
25
 	
26
 	public void register(String classname, byte[] bytecode) {
26
 	public void register(String classname, byte[] bytecode) {
27
+		if(bytecode == null) return;
27
 		classes.put(classname, bytecode);
28
 		classes.put(classname, bytecode);
28
 		try(FileOutputStream writer = new FileOutputStream(new File(classname + ".class"))) {
29
 		try(FileOutputStream writer = new FileOutputStream(new File(classname + ".class"))) {
29
 			writer.write(bytecode);
30
 			writer.write(bytecode);
37
 		
38
 		
38
 		try {
39
 		try {
39
 			classLoader.loadClass("Scripts").getMethod("run").invoke(null);
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
 			Logger.getLogger(JavaModule.class.getName()).log(Level.SEVERE, null, ex);
42
 			Logger.getLogger(JavaModule.class.getName()).log(Level.SEVERE, null, ex);
52
 		}
43
 		}
53
 	}
44
 	}
54
 	
45
 	
55
 	private class ScriptClassLoader extends ClassLoader {
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
 		@Override
49
 		@Override
59
 		public Class<?> loadClass(String name) throws ClassNotFoundException {
50
 		public Class<?> loadClass(String name) throws ClassNotFoundException {

+ 18
- 0
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaClassWriter.java View File

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 View File

21
 public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
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
     @Override
31
     @Override
25
     public byte[] visitClass(ClassDefinition definition) {
32
     public byte[] visitClass(ClassDefinition definition) {
26
-
33
+        //Classes will always be created in a new File/Class
27
 
34
 
28
         final Type superType;
35
         final Type superType;
29
         if (definition.superType == null)
36
         if (definition.superType == null)

+ 58
- 0
ScriptingExample/scripts/conditionals.zs View File

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 View File

61
 
61
 
62
 println("");
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
 	println(item);
67
 	println(item);
68
 }
68
 }
69
 
69
 

Loading…
Cancel
Save