Bladeren bron

Functions in Java

kindlich 6 jaren geleden
bovenliggende
commit
1126c8370c
Geen bekende sleutel gevonden voor deze handtekening in de database

+ 1
- 1
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaCompiler.java Bestand weergeven

@@ -159,7 +159,7 @@ public class JavaCompiler {
159 159
 			scriptBlocks.put(methodName, scriptFileWriter);
160 160
 		}
161 161
 
162
-		target.register(definition.name, definition.accept(new JavaDefinitionVisitor(scriptBlocks.get(definition.position.filename))));
162
+		target.register(definition.name, definition.accept(new JavaDefinitionVisitor(scriptBlocks.get(methodName))));
163 163
 
164 164
 	}
165 165
 	

+ 9
- 0
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/TestIsStaticInfo.java Bestand weergeven

@@ -0,0 +1,9 @@
1
+package org.openzen.zenscript.javabytecode;
2
+
3
+public class TestIsStaticInfo {
4
+    public final boolean isStatic;
5
+
6
+    public TestIsStaticInfo(boolean isStatic) {
7
+        this.isStatic = isStatic;
8
+    }
9
+}

+ 26
- 2
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/CompilerUtils.java Bestand weergeven

@@ -1,15 +1,18 @@
1 1
 package org.openzen.zenscript.javabytecode.compiler;
2 2
 
3
+import org.objectweb.asm.Opcodes;
3 4
 import org.objectweb.asm.Type;
4 5
 import org.openzen.zenscript.codemodel.FunctionHeader;
5 6
 import org.openzen.zenscript.codemodel.FunctionParameter;
7
+import org.openzen.zenscript.codemodel.Modifiers;
6 8
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
7 9
 import org.openzen.zenscript.codemodel.type.ITypeID;
10
+import org.openzen.zenscript.shared.CodePosition;
8 11
 
9 12
 public class CompilerUtils {
10 13
     public static String calcDesc(FunctionHeader header, boolean isEnum) {
11 14
         StringBuilder descBuilder = new StringBuilder("(");
12
-        if(isEnum)
15
+        if (isEnum)
13 16
             descBuilder.append("Ljava/lang/String;I");
14 17
         for (FunctionParameter parameter : header.parameters) {
15 18
             descBuilder.append(Type.getDescriptor(parameter.type.accept(JavaTypeClassVisitor.INSTANCE)));
@@ -29,7 +32,7 @@ public class CompilerUtils {
29 32
     }
30 33
 
31 34
     public static boolean isPrimitive(ITypeID id) {
32
-        if(id instanceof BasicTypeID) {
35
+        if (id instanceof BasicTypeID) {
33 36
             switch ((BasicTypeID) id) {
34 37
                 case BOOL:
35 38
                 case BYTE:
@@ -48,4 +51,25 @@ public class CompilerUtils {
48 51
         }
49 52
         return false;
50 53
     }
54
+
55
+    public static int calcAccess(int modifiers) {
56
+        int out = 0;
57
+        if (Modifiers.isStatic(modifiers))
58
+            out |= Opcodes.ACC_STATIC;
59
+        if (Modifiers.isFinal(modifiers))
60
+            out |= Opcodes.ACC_FINAL;
61
+        if (Modifiers.isPublic(modifiers))
62
+            out |= Opcodes.ACC_PUBLIC;
63
+        if (Modifiers.isPrivate(modifiers))
64
+            out |= Opcodes.ACC_PRIVATE;
65
+        if (Modifiers.isProtected(modifiers))
66
+            out |= Opcodes.ACC_PROTECTED;
67
+        if (Modifiers.isAbstract(modifiers))
68
+            out |= Opcodes.ACC_ABSTRACT;
69
+        return out;
70
+    }
71
+
72
+    public static String calcClasName(CodePosition position) {
73
+        return position.filename.substring(0, position.filename.lastIndexOf('.')).replace("/", "_");
74
+    }
51 75
 }

+ 3
- 1
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaExpressionVisitor.java Bestand weergeven

@@ -317,7 +317,9 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
317 317
 
318 318
     @Override
319 319
     public Void visitGetFunctionParameter(GetFunctionParameterExpression expression) {
320
-        javaWriter.load(Type.getType(expression.parameter.type.accept(JavaTypeClassVisitor.INSTANCE)), expression.parameter.index + 1);
320
+        //TODO is Static?
321
+        final boolean isStatic = false;
322
+        javaWriter.load(Type.getType(expression.parameter.type.accept(JavaTypeClassVisitor.INSTANCE)), isStatic ? expression.parameter.index : expression.parameter.index + 1);
321 323
         return null;
322 324
     }
323 325
 

+ 45
- 8
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/definitions/JavaDefinitionVisitor.java Bestand weergeven

@@ -3,27 +3,34 @@ package org.openzen.zenscript.javabytecode.compiler.definitions;
3 3
 import org.objectweb.asm.ClassWriter;
4 4
 import org.objectweb.asm.Opcodes;
5 5
 import org.objectweb.asm.Type;
6
+import org.openzen.zenscript.codemodel.FunctionParameter;
6 7
 import org.openzen.zenscript.codemodel.definition.*;
7 8
 import org.openzen.zenscript.codemodel.expression.Expression;
8 9
 import org.openzen.zenscript.codemodel.expression.ExpressionVisitor;
10
+import org.openzen.zenscript.codemodel.generic.TypeParameter;
9 11
 import org.openzen.zenscript.codemodel.member.ConstructorMember;
10 12
 import org.openzen.zenscript.codemodel.member.EnumConstantMember;
11 13
 import org.openzen.zenscript.codemodel.member.FieldMember;
12 14
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
13 15
 import org.openzen.zenscript.codemodel.statement.ExpressionStatement;
16
+import org.openzen.zenscript.codemodel.statement.ReturnStatement;
17
+import org.openzen.zenscript.codemodel.statement.Statement;
14 18
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
19
+import org.openzen.zenscript.codemodel.type.ITypeID;
20
+import org.openzen.zenscript.javabytecode.JavaClassInfo;
15 21
 import org.openzen.zenscript.javabytecode.JavaEnumInfo;
16
-import org.openzen.zenscript.javabytecode.compiler.JavaExpressionVisitor;
17
-import org.openzen.zenscript.javabytecode.compiler.JavaStatementVisitor;
18
-import org.openzen.zenscript.javabytecode.compiler.JavaTypeClassVisitor;
19
-import org.openzen.zenscript.javabytecode.compiler.JavaWriter;
22
+import org.openzen.zenscript.javabytecode.JavaMethodInfo;
23
+import org.openzen.zenscript.javabytecode.TestIsStaticInfo;
24
+import org.openzen.zenscript.javabytecode.compiler.*;
25
+
26
+import java.util.Iterator;
20 27
 
21 28
 public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
22 29
 
23 30
 
24
-    private final ClassWriter outerWriter;
31
+    private final JavaClassWriter outerWriter;
25 32
 
26
-    public JavaDefinitionVisitor(ClassWriter outerWriter) {
33
+    public JavaDefinitionVisitor(JavaClassWriter outerWriter) {
27 34
 
28 35
         this.outerWriter = outerWriter;
29 36
     }
@@ -38,7 +45,7 @@ public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
38 45
         else
39 46
             superType = Type.getType(definition.superType.accept(JavaTypeClassVisitor.INSTANCE));
40 47
 
41
-        ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
48
+        JavaClassWriter writer = new JavaClassWriter(ClassWriter.COMPUTE_FRAMES);
42 49
 
43 50
         //TODO: Calculate signature from generic parameters
44 51
         //TODO: Interfaces?
@@ -151,7 +158,7 @@ public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
151 158
         clinitWriter.newArray(Type.getType("L" + definition.name + ";"));
152 159
 
153 160
         for (IDefinitionMember member : definition.members) {
154
-            if(!(member instanceof EnumConstantMember)) continue;
161
+            if (!(member instanceof EnumConstantMember)) continue;
155 162
             final EnumConstantMember constantMember = (EnumConstantMember) member;
156 163
             clinitWriter.dup();
157 164
             clinitWriter.constant(constantMember.value);
@@ -194,6 +201,36 @@ public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
194 201
 
195 202
     @Override
196 203
     public byte[] visitFunction(FunctionDefinition definition) {
204
+        final String signature = CompilerUtils.calcSign(definition.header, false);
205
+        final JavaWriter writer = new JavaWriter(outerWriter, true, CompilerUtils.calcAccess(definition.modifiers) | Opcodes.ACC_STATIC, definition.name, CompilerUtils.calcDesc(definition.header, false), signature, null);
206
+        final JavaStatementVisitor statementVisitor = new JavaStatementVisitor(writer);
207
+        statementVisitor.start();
208
+        final Iterator<Statement> statementIterator = definition.statements.iterator();
209
+
210
+        //TODO this is dirty, fix when there is a way of knowing if a parameter is static or not
211
+        for (FunctionParameter parameter : definition.header.parameters) {
212
+            parameter.index -= 1;
213
+        }
214
+        while (statementIterator.hasNext()) {
215
+            final Statement statement = statementIterator.next();
216
+            statement.accept(statementVisitor);
217
+            if (!statementIterator.hasNext() && !(statement instanceof ReturnStatement)) {
218
+                ITypeID type = definition.header.returnType;
219
+                if (CompilerUtils.isPrimitive(type))
220
+                    writer.iConst0();
221
+                else if (type != BasicTypeID.VOID)
222
+                    writer.aConstNull();
223
+                writer.returnType(type.accept(JavaTypeVisitor.INSTANCE));
224
+            }
225
+
226
+        }
227
+
228
+        statementVisitor.end();
229
+
230
+        final JavaMethodInfo methodInfo = new JavaMethodInfo(new JavaClassInfo(CompilerUtils.calcClasName(definition.position)), definition.name, signature, true);
231
+
232
+        definition.setTag(JavaMethodInfo.class, methodInfo);
233
+        definition.caller.setTag(JavaMethodInfo.class, methodInfo);
197 234
         return null;
198 235
     }
199 236
 

+ 20
- 0
ScriptingExample/scripts/functions.zs Bestand weergeven

@@ -0,0 +1,20 @@
1
+function test() {
2
+	println("functions.zs; test1");
3
+}
4
+
5
+
6
+
7
+function test2() as void {
8
+	println("functions.zs; test2");
9
+}
10
+
11
+
12
+test();
13
+test2();
14
+println(test3(1, 3));
15
+
16
+
17
+function test3(a as int, b as int) as int{
18
+	println(a+b);
19
+	return a + b;
20
+}

Laden…
Annuleren
Opslaan