Browse Source

- Moved Java bytecode generation to its own project.

- Added some utility methods to ParsedFile to parse from different sources.
Stan Hebben 6 years ago
parent
commit
b8998ea1f4

+ 19
- 0
JavaBytecodeCompiler/build.gradle View File

@@ -0,0 +1,19 @@
1
+// Note: "common.gradle" in the root project contains additional initialization
2
+//   for this project. This initialization is applied in the "build.gradle"
3
+//   of the root project.
4
+
5
+// NetBeans will automatically add "run" and "debug" tasks relying on the
6
+// "mainClass" property. You may however define the property prior executing
7
+// tasks by passing a "-PmainClass=<QUALIFIED_CLASS_NAME>" argument.
8
+//
9
+// Note however, that you may define your own "run" and "debug" task if you
10
+// prefer. In this case NetBeans will not add these tasks but you may rely on
11
+// your own implementation.
12
+if (!hasProperty('mainClass')) {
13
+    ext.mainClass = ''
14
+}
15
+
16
+dependencies {
17
+	compile 'org.ow2.asm:asm-debug-all:6.0_BETA'
18
+	compile project(':CodeModel')
19
+}

ScriptingExample/src/main/java/org/openzen/zenscript/scriptingexample/JavaClassInfo.java → JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaClassInfo.java View File

@@ -3,7 +3,7 @@
3 3
  * To change this template file, choose Tools | Templates
4 4
  * and open the template in the editor.
5 5
  */
6
-package org.openzen.zenscript.scriptingexample;
6
+package org.openzen.zenscript.javabytecode;
7 7
 
8 8
 /**
9 9
  *

+ 84
- 0
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaCompiler.java View File

@@ -0,0 +1,84 @@
1
+/*
2
+ * To change this license header, choose License Headers in Project Properties.
3
+ * To change this template file, choose Tools | Templates
4
+ * and open the template in the editor.
5
+ */
6
+package org.openzen.zenscript.javabytecode;
7
+
8
+import java.util.ArrayList;
9
+import java.util.List;
10
+import org.objectweb.asm.ClassWriter;
11
+import org.objectweb.asm.Opcodes;
12
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
13
+import org.openzen.zenscript.codemodel.ScriptBlock;
14
+import org.openzen.zenscript.codemodel.statement.Statement;
15
+import org.openzen.zenscript.javabytecode.compiler.JavaStatementVisitor;
16
+import org.openzen.zenscript.javabytecode.compiler.JavaWriter;
17
+import org.openzen.zenscript.shared.SourceFile;
18
+
19
+/**
20
+ *
21
+ * @author Hoofdgebruiker
22
+ */
23
+public class JavaCompiler {
24
+	private final JavaModule target;
25
+	private final List<String> scriptBlockNames = new ArrayList<>();
26
+	private final ClassWriter scriptsClassWriter;
27
+	private int generatedScriptBlockCounter = 0;
28
+	private boolean finished = false;
29
+	
30
+	public JavaCompiler() {
31
+		this(false);
32
+	}
33
+	
34
+	public JavaCompiler(boolean debug) {
35
+		target = new JavaModule();
36
+		
37
+		scriptsClassWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
38
+		scriptsClassWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, "Scripts", null, "java/lang/Object", null);
39
+	}
40
+	
41
+	public void addDefinition(HighLevelDefinition definition) {
42
+		// convert definition into java class
43
+	}
44
+	
45
+	public void addScriptBlock(ScriptBlock script) {
46
+		SourceFile sourceFile = script.getTag(SourceFile.class);
47
+		String methodName;
48
+		if (sourceFile == null) {
49
+			methodName = "generatedBlock" + (generatedScriptBlockCounter++);
50
+		} else {
51
+			// TODO: remove special characters
52
+			methodName = sourceFile.filename.substring(0, sourceFile.filename.lastIndexOf('.')).replace("/", "_");
53
+		}
54
+
55
+		scriptBlockNames.add(methodName);
56
+
57
+		// convert scripts into methods (add them to a Scripts class?)
58
+		// (TODO: can we break very long scripts into smaller methods? for the extreme scripts)
59
+		final JavaStatementVisitor statementVisitor = new JavaStatementVisitor(new JavaWriter(scriptsClassWriter, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, methodName, "()V", null, null));
60
+		statementVisitor.start();
61
+		for (Statement statement : script.statements) {
62
+			statement.accept(statementVisitor);
63
+		}
64
+		statementVisitor.end();
65
+	}
66
+	
67
+	public JavaModule finish() {
68
+		if (finished)
69
+			throw new IllegalStateException("Already finished!");
70
+		finished = true;
71
+		
72
+		final JavaWriter runWriter = new JavaWriter(scriptsClassWriter, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "run", "()V", null, null);
73
+		runWriter.start();
74
+		for (String scriptBlockName : scriptBlockNames) {
75
+			runWriter.invokeStatic("Scripts", scriptBlockName, "()V");
76
+		}
77
+		runWriter.ret();
78
+		runWriter.end();
79
+		
80
+		target.register("Scripts", scriptsClassWriter.toByteArray());
81
+		
82
+		return target;
83
+	}
84
+}

ScriptingExample/src/main/java/org/openzen/zenscript/scriptingexample/JavaFieldInfo.java → JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaFieldInfo.java View File

@@ -3,7 +3,7 @@
3 3
  * To change this template file, choose Tools | Templates
4 4
  * and open the template in the editor.
5 5
  */
6
-package org.openzen.zenscript.scriptingexample;
6
+package org.openzen.zenscript.javabytecode;
7 7
 
8 8
 /**
9 9
  *

ScriptingExample/src/main/java/org/openzen/zenscript/scriptingexample/JavaMethodInfo.java → JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaMethodInfo.java View File

@@ -3,7 +3,7 @@
3 3
  * To change this template file, choose Tools | Templates
4 4
  * and open the template in the editor.
5 5
  */
6
-package org.openzen.zenscript.scriptingexample;
6
+package org.openzen.zenscript.javabytecode;
7 7
 
8 8
 /**
9 9
  *

ScriptingExample/src/main/java/org/openzen/zenscript/scriptingexample/JavaModule.java → JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaModule.java View File

@@ -3,7 +3,7 @@
3 3
  * To change this template file, choose Tools | Templates
4 4
  * and open the template in the editor.
5 5
  */
6
-package org.openzen.zenscript.scriptingexample;
6
+package org.openzen.zenscript.javabytecode;
7 7
 
8 8
 import java.io.*;
9 9
 import java.lang.reflect.InvocationTargetException;

ScriptingExample/src/main/java/org/openzen/zenscript/scriptingexample/writer/JavaExpressionVisitor.java → JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaExpressionVisitor.java View File

@@ -1,8 +1,8 @@
1
-package org.openzen.zenscript.scriptingexample.writer;
1
+package org.openzen.zenscript.javabytecode.compiler;
2 2
 
3 3
 import org.openzen.zenscript.codemodel.expression.*;
4
-import org.openzen.zenscript.scriptingexample.JavaFieldInfo;
5
-import org.openzen.zenscript.scriptingexample.JavaMethodInfo;
4
+import org.openzen.zenscript.javabytecode.JavaFieldInfo;
5
+import org.openzen.zenscript.javabytecode.JavaMethodInfo;
6 6
 
7 7
 public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
8 8
 

ScriptingExample/src/main/java/org/openzen/zenscript/scriptingexample/writer/JavaStatementVisitor.java → JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaStatementVisitor.java View File

@@ -1,4 +1,4 @@
1
-package org.openzen.zenscript.scriptingexample.writer;
1
+package org.openzen.zenscript.javabytecode.compiler;
2 2
 
3 3
 import org.openzen.zenscript.codemodel.statement.*;
4 4
 

ScriptingExample/src/main/java/org/openzen/zenscript/scriptingexample/writer/JavaTypeVisitor.java → JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaTypeVisitor.java View File

@@ -1,4 +1,4 @@
1
-package org.openzen.zenscript.scriptingexample.writer;
1
+package org.openzen.zenscript.javabytecode.compiler;
2 2
 
3 3
 import org.openzen.zenscript.codemodel.type.*;
4 4
 

ScriptingExample/src/main/java/org/openzen/zenscript/scriptingexample/writer/JavaWriter.java → JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaWriter.java View File

@@ -1,4 +1,4 @@
1
-package org.openzen.zenscript.scriptingexample.writer;
1
+package org.openzen.zenscript.javabytecode.compiler;
2 2
 
3 3
 import org.objectweb.asm.*;
4 4
 import org.objectweb.asm.commons.LocalVariablesSorter;

+ 51
- 37
Parser/src/main/java/org/openzen/zenscript/parser/ParsedFile.java View File

@@ -8,6 +8,8 @@ package org.openzen.zenscript.parser;
8 8
 import java.io.File;
9 9
 import java.io.FileReader;
10 10
 import java.io.IOException;
11
+import java.io.Reader;
12
+import java.io.StringReader;
11 13
 import java.util.ArrayList;
12 14
 import java.util.List;
13 15
 import java.util.Map;
@@ -39,48 +41,60 @@ import org.openzen.zenscript.shared.SourceFile;
39 41
 public class ParsedFile {
40 42
 	public static ParsedFile parse(File file) throws IOException {
41 43
 		String filename = file.toString();
42
-		ParsedFile result = new ParsedFile(file.getName());
43
-		
44 44
 		try (FileReader reader = new FileReader(file)) {
45
-			ZSTokenStream tokens = new ZSTokenStream(filename, reader);
46
-			
45
+			return parse(filename, reader);
46
+		}
47
+	}
48
+	
49
+	public static ParsedFile parse(String filename, String content) {
50
+		try (StringReader reader = new StringReader(content)) {
51
+			return parse(filename, reader);
52
+		} catch (IOException ex) {
53
+			throw new AssertionError(); // supposed to never happen in a StringReader
54
+		}
55
+	}
56
+	
57
+	public static ParsedFile parse(String filename, Reader reader) throws IOException {
58
+		ParsedFile result = new ParsedFile(filename);
59
+		
60
+		ZSTokenStream tokens = new ZSTokenStream(filename, reader);
61
+
62
+		while (true) {
63
+			CodePosition position = tokens.peek().position;
64
+			int modifiers = 0;
47 65
 			while (true) {
48
-				CodePosition position = tokens.peek().position;
49
-				int modifiers = 0;
50
-				while (true) {
51
-					if (tokens.optional(K_PUBLIC) != null) {
52
-						modifiers |= Modifiers.MODIFIER_PUBLIC;
53
-					} else if (tokens.optional(K_PRIVATE) != null) {
54
-						modifiers |= Modifiers.MODIFIER_PRIVATE;
55
-					} else if (tokens.optional(K_EXPORT) != null) {
56
-						modifiers |= Modifiers.MODIFIER_EXPORT;
57
-					} else if (tokens.optional(K_ABSTRACT) != null) {
58
-						modifiers |= Modifiers.MODIFIER_ABSTRACT;
59
-					} else if (tokens.optional(K_FINAL) != null) {
60
-						modifiers |= Modifiers.MODIFIER_FINAL;
61
-					} else if (tokens.optional(K_PROTECTED) != null) {
62
-						modifiers |= Modifiers.MODIFIER_PROTECTED;
63
-					} else if (tokens.optional(K_IMPLICIT) != null) {
64
-						modifiers |= Modifiers.MODIFIER_IMPLICIT;
65
-					} else {
66
-						break;
67
-					}
68
-				}
69
-				
70
-				if (tokens.optional(K_IMPORT) != null) {
71
-					result.imports.add(ParsedImport.parse(position, tokens));
72
-				} else if (tokens.optional(EOF) != null) {
73
-					break;
66
+				if (tokens.optional(K_PUBLIC) != null) {
67
+					modifiers |= Modifiers.MODIFIER_PUBLIC;
68
+				} else if (tokens.optional(K_PRIVATE) != null) {
69
+					modifiers |= Modifiers.MODIFIER_PRIVATE;
70
+				} else if (tokens.optional(K_EXPORT) != null) {
71
+					modifiers |= Modifiers.MODIFIER_EXPORT;
72
+				} else if (tokens.optional(K_ABSTRACT) != null) {
73
+					modifiers |= Modifiers.MODIFIER_ABSTRACT;
74
+				} else if (tokens.optional(K_FINAL) != null) {
75
+					modifiers |= Modifiers.MODIFIER_FINAL;
76
+				} else if (tokens.optional(K_PROTECTED) != null) {
77
+					modifiers |= Modifiers.MODIFIER_PROTECTED;
78
+				} else if (tokens.optional(K_IMPLICIT) != null) {
79
+					modifiers |= Modifiers.MODIFIER_IMPLICIT;
74 80
 				} else {
75
-					ParsedDefinition definition = ParsedDefinition.parse(position, modifiers, tokens, null);
76
-					if (definition == null) {
77
-						result.statements.add(ParsedStatement.parse(tokens));
78
-					} else {
79
-						result.definitions.add(definition);
80
-					}
81
+					break;
82
+				}
83
+			}
81 84
 
82
-			//tokens.required(EOF, "An import, class, interface, enum, struct, function or alias expected.");
85
+			if (tokens.optional(K_IMPORT) != null) {
86
+				result.imports.add(ParsedImport.parse(position, tokens));
87
+			} else if (tokens.optional(EOF) != null) {
88
+				break;
89
+			} else {
90
+				ParsedDefinition definition = ParsedDefinition.parse(position, modifiers, tokens, null);
91
+				if (definition == null) {
92
+					result.statements.add(ParsedStatement.parse(tokens));
93
+				} else {
94
+					result.definitions.add(definition);
83 95
 				}
96
+
97
+				//tokens.required(EOF, "An import, class, interface, enum, struct, function or alias expected.");
84 98
 			}
85 99
 		}
86 100
 		

+ 1
- 1
ScriptingExample/build.gradle View File

@@ -14,6 +14,6 @@ if (!hasProperty('mainClass')) {
14 14
 }
15 15
 
16 16
 dependencies {
17
-	compile 'org.ow2.asm:asm-debug-all:6.0_BETA'
18 17
 	compile project(':Parser')
18
+	compile project(':JavaBytecodeCompiler')
19 19
 }

+ 3
- 0
ScriptingExample/src/main/java/org/openzen/zenscript/scriptingexample/GlobalRegistry.java View File

@@ -25,6 +25,9 @@ import org.openzen.zenscript.codemodel.type.DefinitionTypeID;
25 25
 import org.openzen.zenscript.codemodel.type.FunctionTypeID;
26 26
 import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
27 27
 import org.openzen.zenscript.codemodel.type.ITypeID;
28
+import org.openzen.zenscript.javabytecode.JavaClassInfo;
29
+import org.openzen.zenscript.javabytecode.JavaFieldInfo;
30
+import org.openzen.zenscript.javabytecode.JavaMethodInfo;
28 31
 import org.openzen.zenscript.linker.symbol.ISymbol;
29 32
 import org.openzen.zenscript.shared.CodePosition;
30 33
 

+ 7
- 52
ScriptingExample/src/main/java/org/openzen/zenscript/scriptingexample/Main.java View File

@@ -6,21 +6,17 @@ import java.util.ArrayList;
6 6
 import java.util.List;
7 7
 import java.util.Map;
8 8
 import java.util.Optional;
9
-
10
-import org.objectweb.asm.ClassWriter;
11
-import org.objectweb.asm.Opcodes;
12 9
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
10
+
13 11
 import org.openzen.zenscript.codemodel.PackageDefinitions;
14 12
 import org.openzen.zenscript.codemodel.ScriptBlock;
15 13
 import org.openzen.zenscript.codemodel.definition.ExpansionDefinition;
16 14
 import org.openzen.zenscript.codemodel.definition.ZSPackage;
17
-import org.openzen.zenscript.codemodel.statement.Statement;
18 15
 import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
16
+import org.openzen.zenscript.javabytecode.JavaCompiler;
17
+import org.openzen.zenscript.javabytecode.JavaModule;
19 18
 import org.openzen.zenscript.linker.symbol.ISymbol;
20 19
 import org.openzen.zenscript.parser.ParsedFile;
21
-import org.openzen.zenscript.scriptingexample.writer.JavaStatementVisitor;
22
-import org.openzen.zenscript.scriptingexample.writer.JavaWriter;
23
-import org.openzen.zenscript.shared.SourceFile;
24 20
 
25 21
 public class Main {
26 22
     /**
@@ -85,54 +81,13 @@ public class Main {
85 81
 	}
86 82
 	
87 83
 	private static JavaModule compileSemanticToJava(SemanticModule module) {
88
-		JavaModule result = new JavaModule();
89
-		final ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
90
-		classWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, "Scripts", null, "java/lang/Object", null);
91
-
92
-		// TODO: java bytecode compilation
84
+		JavaCompiler compiler = new JavaCompiler(true);
93 85
 		for (HighLevelDefinition definition : module.definitions.getAll()) {
94
-			// convert definitions into java classes
95
-
86
+			compiler.addDefinition(definition);
96 87
 		}
97
-		int statementNo = 0;
98
-		List<String> scriptBlockNames = new ArrayList<>();
99 88
 		for (ScriptBlock script : module.scripts) {
100
-			SourceFile sourceFile = script.getTag(SourceFile.class);
101
-			String methodName;
102
-			if (sourceFile == null) {
103
-				methodName = "generatedBlock" + (statementNo++);
104
-			} else {
105
-				// TODO: remove special characters
106
-				methodName = sourceFile.filename.substring(0, sourceFile.filename.lastIndexOf('.')).replace("/", "_");
107
-			}
108
-			
109
-			scriptBlockNames.add(methodName);
110
-			
111
-			// convert scripts into methods (add them to a Scripts class?)
112
-			// (TODO: can we break very long scripts into smaller methods? for the extreme scripts)
113
-			final JavaStatementVisitor statementVisitor = new JavaStatementVisitor(new JavaWriter(classWriter, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, methodName, "()V", null, null));
114
-			statementVisitor.start();
115
-			for (Statement statement : script.statements) {
116
-				statement.accept(statementVisitor);
117
-			}
118
-			statementVisitor.end();
119
-		}
120
-
121
-		// create a Scripts.run() method to run all scripts compiled above
122
-		final JavaWriter runWriter = new JavaWriter(classWriter, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "run", "()V", null, null);
123
-		runWriter.start();
124
-		for (String scriptBlockName : scriptBlockNames) {
125
-			runWriter.invokeStatic("Scripts", scriptBlockName, "()V");
89
+			compiler.addScriptBlock(script);
126 90
 		}
127
-		runWriter.ret();
128
-		runWriter.end();
129
-		result.register("Scripts", classWriter.toByteArray());
130
-
131
-		
132
-		return result;
133
-	}
134
-
135
-	private static String makeName(int i) {
136
-    	return "scriptBlock" + i;
91
+		return compiler.finish();
137 92
 	}
138 93
 }

Loading…
Cancel
Save