浏览代码

Merge branch 'development_kindlich' into development

# Conflicts:
#	JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaExpressionVisitor.java
#	JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaWriter.java
Stan Hebben 6 年前
父节点
当前提交
b553e18993

+ 2
- 2
CodeFormatter/src/main/java/org/openzen/zenscript/formatter/ExpressionFormatter.java 查看文件

@@ -556,8 +556,8 @@ public class ExpressionFormatter implements ExpressionVisitor<ExpressionString>
556 556
 		result.append("match ");
557 557
 		result.append(expression.value.accept(this));
558 558
 		result.append(" {\n");
559
-		
560
-		throw new UnsupportedOperationException();
559
+
560
+		return new ExpressionString(result.toString(), ZenScriptOperator.PRIMARY);
561 561
 	}
562 562
 
563 563
 	@Override

+ 29
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/DummyExpression.java 查看文件

@@ -0,0 +1,29 @@
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.codemodel.expression;
7
+
8
+import org.openzen.zencode.shared.CodePosition;
9
+import org.openzen.zenscript.codemodel.type.ITypeID;
10
+
11
+/**
12
+ *
13
+ * @author Hoofdgebruiker
14
+ */
15
+public class DummyExpression extends Expression {
16
+	public DummyExpression(ITypeID type) {
17
+		super(CodePosition.BUILTIN, type, null);
18
+	}
19
+
20
+	@Override
21
+	public <T> T accept(ExpressionVisitor<T> visitor) {
22
+		throw new UnsupportedOperationException("This is a dummy expression");
23
+	}
24
+
25
+	@Override
26
+	public Expression transform(ExpressionTransformer transformer) {
27
+		throw new UnsupportedOperationException("This is a dummy expression");
28
+	}
29
+}

+ 1
- 1
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaModule.java 查看文件

@@ -17,7 +17,7 @@ import java.util.logging.Logger;
17 17
  * @author Hoofdgebruiker
18 18
  */
19 19
 public class JavaModule {
20
-	private final Map<String, byte[]> classes = new HashMap<>();
20
+	public static final Map<String, byte[]> classes = new HashMap<>();
21 21
 	
22 22
 	public JavaModule() {
23 23
 		

+ 39
- 0
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaCapturedExpressionVisitor.java 查看文件

@@ -0,0 +1,39 @@
1
+package org.openzen.zenscript.javabytecode.compiler;
2
+
3
+import org.openzen.zenscript.codemodel.expression.*;
4
+
5
+public class JavaCapturedExpressionVisitor implements CapturedExpressionVisitor<Void> {
6
+
7
+    public final JavaExpressionVisitor expressionVisitor;
8
+
9
+    public JavaCapturedExpressionVisitor(JavaExpressionVisitor expressionVisitor) {
10
+        this.expressionVisitor = expressionVisitor;
11
+    }
12
+
13
+    @Override
14
+    public Void visitCapturedThis(CapturedThisExpression expression) {
15
+        return null;
16
+    }
17
+
18
+    @Override
19
+    public Void visitCapturedParameter(CapturedParameterExpression expression) {
20
+        return null;
21
+    }
22
+
23
+    @Override
24
+    public Void visitCapturedLocal(CapturedLocalVariableExpression expression) {
25
+        new GetLocalVariableExpression(expression.position, expression.variable)
26
+                .accept(expressionVisitor);
27
+        return null;
28
+    }
29
+
30
+    @Override
31
+    public Void visitCapturedDirect(CapturedDirectExpression expression) {
32
+        return expression.value.accept(expressionVisitor);
33
+    }
34
+
35
+    @Override
36
+    public Void visitRecaptured(CapturedClosureExpression expression) {
37
+        return expression.value.accept(this);
38
+    }
39
+}

+ 172
- 65
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaExpressionVisitor.java 查看文件

@@ -2,26 +2,24 @@ package org.openzen.zenscript.javabytecode.compiler;
2 2
 
3 3
 import java.util.Arrays;
4 4
 import java.util.Collection;
5
-import org.objectweb.asm.Label;
6
-import org.objectweb.asm.Type;
7
-import org.openzen.zenscript.codemodel.CompareType;
8
-import org.openzen.zenscript.codemodel.expression.*;
9
-import org.openzen.zenscript.codemodel.type.DefinitionTypeID;
10
-import org.openzen.zenscript.codemodel.type.ITypeID;
11
-import org.openzen.zenscript.implementations.IntRange;
12
-import org.openzen.zenscript.javabytecode.*;
13
-
5
+import java.util.Comparator;
14 6
 import java.util.Map;
7
+import java.util.StringJoiner;
8
+import org.objectweb.asm.Label;
15 9
 import org.objectweb.asm.Opcodes;
10
+import org.objectweb.asm.Type;
16 11
 import org.openzen.zencode.shared.CompileException;
17 12
 import org.openzen.zencode.shared.CompileExceptionCode;
13
+import org.openzen.zenscript.codemodel.CompareType;
14
+import org.openzen.zenscript.codemodel.expression.*;
18 15
 import org.openzen.zenscript.codemodel.member.ref.ConstMemberRef;
19 16
 import org.openzen.zenscript.codemodel.member.ref.DefinitionMemberRef;
20 17
 import org.openzen.zenscript.codemodel.member.ref.FieldMemberRef;
21
-import org.openzen.zenscript.codemodel.type.ArrayTypeID;
22
-import org.openzen.zenscript.codemodel.type.AssocTypeID;
23
-import org.openzen.zenscript.codemodel.type.BasicTypeID;
18
+import org.openzen.zenscript.codemodel.statement.ReturnStatement;
19
+import org.openzen.zenscript.codemodel.type.*;
24 20
 import org.openzen.zenscript.codemodel.type.member.BuiltinID;
21
+import org.openzen.zenscript.implementations.IntRange;
22
+import org.openzen.zenscript.javabytecode.*;
25 23
 
26 24
 public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
27 25
 	private static final int PUBLIC = Opcodes.ACC_PUBLIC;
@@ -156,9 +154,10 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
156 154
 	private static final JavaClassInfo COLLECTION = JavaClassInfo.get(Collection.class);
157 155
 	private static final JavaMethodInfo COLLECTION_SIZE = new JavaMethodInfo(COLLECTION, "size", "()I", PUBLIC);
158 156
 	private static final JavaMethodInfo COLLECTION_TOARRAY = new JavaMethodInfo(COLLECTION, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", PUBLIC);
159
-	
157
+
160 158
     private final JavaWriter javaWriter;
161
-	
159
+    private final JavaCapturedExpressionVisitor capturedExpressionVisitor = new JavaCapturedExpressionVisitor(this);
160
+
162 161
     public JavaExpressionVisitor(JavaWriter javaWriter) {
163 162
         this.javaWriter = javaWriter;
164 163
     }
@@ -929,27 +928,27 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
929 928
 
930 929
     @Override
931 930
     public Void visitCapturedClosure(CapturedClosureExpression expression) {
932
-        return null;
931
+        return expression.accept(capturedExpressionVisitor);
933 932
     }
934 933
 
935 934
     @Override
936 935
     public Void visitCapturedDirect(CapturedDirectExpression expression) {
937
-        return null;
936
+        return expression.accept(capturedExpressionVisitor);
938 937
     }
939 938
 
940 939
     @Override
941 940
     public Void visitCapturedLocalVariable(CapturedLocalVariableExpression expression) {
942
-        return null;
941
+        return expression.accept(capturedExpressionVisitor);
943 942
     }
944 943
 
945 944
     @Override
946 945
     public Void visitCapturedParameter(CapturedParameterExpression expression) {
947
-        return null;
948
-    }
946
+        return expression.accept(capturedExpressionVisitor);
947
+	}
949 948
 
950 949
     @Override
951 950
     public Void visitCapturedThis(CapturedThisExpression expression) {
952
-        return null;
951
+        return expression.accept(capturedExpressionVisitor);
953 952
     }
954 953
 
955 954
     @Override
@@ -1511,15 +1510,13 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
1511 1510
     @Override
1512 1511
     public Void visitConstructorThisCall(ConstructorThisCallExpression expression) {
1513 1512
         Type type = expression.objectType.accept(JavaTypeVisitor.INSTANCE);
1514
-		
1515
-		if (javaWriter.method.javaClass.isEnum) {
1516
-			javaWriter.loadObject(0);
1517
-			javaWriter.loadObject(1);
1518
-			javaWriter.loadInt(2);
1519
-		} else {
1520
-			javaWriter.loadObject(0);
1521
-		}
1522
-		
1513
+
1514
+        javaWriter.loadObject(0);
1515
+        if (javaWriter.method.javaClass.isEnum) {
1516
+            javaWriter.loadObject(1);
1517
+            javaWriter.loadInt(2);
1518
+        }
1519
+
1523 1520
         for (Expression argument : expression.arguments.arguments) {
1524 1521
             argument.accept(this);
1525 1522
         }
@@ -1535,8 +1532,8 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
1535 1532
         }
1536 1533
         //No super calls in enums possible, and that's already handled in the enum constructor itself.
1537 1534
         javaWriter.invokeSpecial(expression.objectType.accept(JavaTypeClassVisitor.INSTANCE), "<init>", CompilerUtils.calcDesc(expression.constructor.header, false));
1538
-		
1539
-		CompilerUtils.writeDefaultFieldInitializers(javaWriter, javaWriter.forDefinition, false);
1535
+
1536
+        CompilerUtils.writeDefaultFieldInitializers(javaWriter, javaWriter.forDefinition, false);
1540 1537
         return null;
1541 1538
     }
1542 1539
 
@@ -1549,12 +1546,67 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
1549 1546
 
1550 1547
     @Override
1551 1548
     public Void visitFunction(FunctionExpression expression) {
1549
+        if (expression.header.parameters.length == 0 && expression.body instanceof ReturnStatement && expression.body.hasTag(MatchExpression.class) && expression.closure.captures.isEmpty()) {
1550
+            ((ReturnStatement) expression.body).value.accept(this);
1551
+            return null;
1552
+        }
1553
+        final String signature = calcFunctionSignature(expression.closure, expression.header.returnType);
1554
+        final String name = "lambda" + expression.hashCode();
1555
+
1556
+        final JavaMethodInfo methodInfo = new JavaMethodInfo(javaWriter.method.javaClass, name, signature, Opcodes.ACC_STATIC | Opcodes.ACC_PRIVATE);
1557
+        JavaWriter functionWriter = new JavaWriter(javaWriter.clazzVisitor, methodInfo, null, signature, null);
1558
+
1559
+        for (CapturedExpression capture : expression.closure.captures) {
1560
+            capture.accept(new JavaCapturedExpressionVisitor(this));
1561
+        }
1562
+
1563
+        javaWriter.invokeStatic(methodInfo);
1564
+
1565
+        functionWriter.start();
1566
+        expression.body.accept(new JavaStatementVisitor(new JavaExpressionVisitor(functionWriter) {
1567
+            @Override
1568
+            public Void visitGetLocalVariable(GetLocalVariableExpression varExpression) {
1569
+                final int position = calculateMemberPosition(varExpression, expression);
1570
+                if (position < 0)
1571
+                    throw new CompileException(varExpression.position, CompileExceptionCode.INTERNAL_ERROR, "Captured Statement error");
1572
+                functionWriter.load(varExpression.variable.type.accept(JavaTypeVisitor.INSTANCE), position);
1573
+                return null;
1574
+            }
1575
+        }));
1576
+
1577
+
1578
+        functionWriter.ret();
1579
+        functionWriter.end();
1580
+
1552 1581
         return null;
1553 1582
     }
1554 1583
 
1584
+    //TODO replace with visitor?
1585
+    private static int calculateMemberPosition(GetLocalVariableExpression localVariableExpression, FunctionExpression expression) {
1586
+        int h = expression.header.parameters.length;
1587
+        for (CapturedExpression capture : expression.closure.captures) {
1588
+            if (capture instanceof CapturedLocalVariableExpression && ((CapturedLocalVariableExpression) capture).variable == localVariableExpression.variable)
1589
+                return h;
1590
+            if (capture instanceof CapturedClosureExpression && ((CapturedClosureExpression) capture).value instanceof CapturedLocalVariableExpression && ((CapturedLocalVariableExpression) ((CapturedClosureExpression) capture).value).variable == localVariableExpression.variable)
1591
+                return h;
1592
+            h++;
1593
+        }
1594
+        return -1;
1595
+    }
1596
+
1597
+    private String calcFunctionSignature(LambdaClosure closure, ITypeID type) {
1598
+        StringJoiner joiner = new StringJoiner("", "(", ")");
1599
+
1600
+        for (CapturedExpression capture : closure.captures) {
1601
+            String descriptor = capture.type.accept(JavaTypeVisitor.INSTANCE).getDescriptor();
1602
+            joiner.add(descriptor);
1603
+        }
1604
+        return joiner.toString() + type.accept(JavaTypeVisitor.INSTANCE).getDescriptor();
1605
+    }
1606
+
1555 1607
     @Override
1556 1608
     public Void visitGetField(GetFieldExpression expression) {
1557
-		expression.accept(this);
1609
+        expression.accept(this);
1558 1610
         if (!checkAndGetFieldInfo(expression.field, false))
1559 1611
             throw new IllegalStateException("Missing field info on a field member!");
1560 1612
         return null;
@@ -1562,7 +1614,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
1562 1614
 
1563 1615
     @Override
1564 1616
     public Void visitGetFunctionParameter(GetFunctionParameterExpression expression) {
1565
-		JavaParameterInfo parameter = expression.parameter.getTag(JavaParameterInfo.class);
1617
+        JavaParameterInfo parameter = expression.parameter.getTag(JavaParameterInfo.class);
1566 1618
         javaWriter.load(Type.getType(expression.parameter.type.accept(JavaTypeClassVisitor.INSTANCE)), parameter.index);
1567 1619
         return null;
1568 1620
     }
@@ -1772,7 +1824,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
1772 1824
 				javaWriter.getField(IntRange.class, "to", int.class);
1773 1825
 				break;
1774 1826
 		}
1775
-		
1827
+
1776 1828
         return null;
1777 1829
     }
1778 1830
 
@@ -1819,11 +1871,65 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
1819 1871
         }
1820 1872
         return null;
1821 1873
     }
1822
-	
1823
-	@Override
1824
-	public Void visitMatch(MatchExpression expression) {
1825
-		throw new UnsupportedOperationException();
1826
-	}
1874
+
1875
+    @Override
1876
+    public Void visitMatch(MatchExpression expression) {
1877
+
1878
+        final Label start = new Label();
1879
+        final Label end = new Label();
1880
+
1881
+
1882
+        javaWriter.label(start);
1883
+        expression.value.accept(this);
1884
+        if (expression.value.type == BasicTypeID.STRING)
1885
+            javaWriter.invokeVirtual(new JavaMethodInfo(new JavaClassInfo("java/lang/Object"), "hashCode", "()I", 0));
1886
+
1887
+        final boolean hasNoDefault = hasNoDefault(expression);
1888
+
1889
+        final MatchExpression.Case[] cases = expression.cases;
1890
+        final JavaSwitchLabel[] switchLabels = new JavaSwitchLabel[hasNoDefault ? cases.length : cases.length - 1];
1891
+        final Label defaultLabel = new Label();
1892
+
1893
+        int i = 0;
1894
+        for (final MatchExpression.Case matchCase : cases) {
1895
+            if (matchCase.key != null) {
1896
+                switchLabels[i++] = new JavaSwitchLabel(CompilerUtils.getKeyForSwitch(matchCase.key), new Label());
1897
+            }
1898
+        }
1899
+
1900
+        JavaSwitchLabel[] sortedSwitchLabels = Arrays.copyOf(switchLabels, switchLabels.length);
1901
+        Arrays.sort(sortedSwitchLabels, Comparator.comparingInt(a -> a.key));
1902
+
1903
+        javaWriter.lookupSwitch(defaultLabel, sortedSwitchLabels);
1904
+
1905
+        i = 0;
1906
+        for (final MatchExpression.Case switchCase : cases) {
1907
+            if (hasNoDefault || switchCase.key != null) {
1908
+                javaWriter.label(switchLabels[i++].label);
1909
+            } else {
1910
+                javaWriter.label(defaultLabel);
1911
+            }
1912
+            //switchCase.value.body.setTag(MatchExpression.class, expression);
1913
+            switchCase.value.accept(this);
1914
+            javaWriter.goTo(end);
1915
+        }
1916
+
1917
+        if (hasNoDefault) {
1918
+            javaWriter.label(defaultLabel);
1919
+        }
1920
+
1921
+        javaWriter.label(end);
1922
+
1923
+
1924
+        //throw new UnsupportedOperationException("Not yet implemented!");
1925
+        return null;
1926
+    }
1927
+
1928
+    private static boolean hasNoDefault(MatchExpression switchStatement) {
1929
+        for (MatchExpression.Case switchCase : switchStatement.cases)
1930
+            if (switchCase.key == null) return false;
1931
+        return true;
1932
+    }
1827 1933
 
1828 1934
     @Override
1829 1935
     public Void visitNew(NewExpression expression) {
@@ -1889,16 +1995,16 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
1889 1995
 		javaWriter.dup(expression.type.accept(new JavaTypeVisitor()));
1890 1996
         if (!checkAndExecuteByteCodeImplementation(expression.member) && !checkAndExecuteMethodInfo(expression.member))
1891 1997
             throw new IllegalStateException("Call target has no method info!");
1892
-		
1893
-		return null;
1894
-	}
1998
+
1999
+        return null;
2000
+    }
1895 2001
 
1896 2002
     @Override
1897 2003
     public Void visitRange(RangeExpression expression) {
1898
-		// TODO: there are other kinds of ranges also; there should be a Range<T, T> type with creation of synthetic types
2004
+        // TODO: there are other kinds of ranges also; there should be a Range<T, T> type with creation of synthetic types
1899 2005
         if (expression.from.type.accept(JavaTypeClassVisitor.INSTANCE) != int.class)
1900 2006
             throw new CompileException(expression.position, CompileExceptionCode.INTERNAL_ERROR, "Only integer ranges supported");
1901
-		
2007
+
1902 2008
         javaWriter.newObject(IntRange.class);
1903 2009
         javaWriter.dup();
1904 2010
         expression.from.accept(this);
@@ -1908,6 +2014,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
1908 2014
 
1909 2015
         return null;
1910 2016
     }
2017
+
1911 2018
 	
1912 2019
 	@Override
1913 2020
 	public Void visitSameObject(SameObjectExpression expression) {
@@ -1942,7 +2049,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
1942 2049
     @Override
1943 2050
     public Void visitSetFunctionParameter(SetFunctionParameterExpression expression) {
1944 2051
         expression.value.accept(this);
1945
-		JavaParameterInfo parameter = expression.parameter.getTag(JavaParameterInfo.class);
2052
+        JavaParameterInfo parameter = expression.parameter.getTag(JavaParameterInfo.class);
1946 2053
         javaWriter.store(expression.type.accept(JavaTypeVisitor.INSTANCE), parameter.index);
1947 2054
         return null;
1948 2055
     }
@@ -2070,11 +2177,11 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
2070 2177
     public Void visitStaticSetter(StaticSetterExpression expression) {
2071 2178
         return null;
2072 2179
     }
2073
-	
2074
-	@Override
2075
-	public Void visitSupertypeCast(SupertypeCastExpression expression) {
2076
-		return null; // nothing to do
2077
-	}
2180
+
2181
+    @Override
2182
+    public Void visitSupertypeCast(SupertypeCastExpression expression) {
2183
+        return null; // nothing to do
2184
+    }
2078 2185
 
2079 2186
     @Override
2080 2187
     public Void visitThis(ThisExpression expression) {
@@ -2094,25 +2201,25 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
2094 2201
 		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
2095 2202
 	}
2096 2203
 
2097
-	@Override
2098
-	public Void visitTryRethrowAsException(TryRethrowAsExceptionExpression expression) {
2099
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
2100
-	}
2204
+    @Override
2205
+    public Void visitTryRethrowAsException(TryRethrowAsExceptionExpression expression) {
2206
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
2207
+    }
2101 2208
 
2102
-	@Override
2103
-	public Void visitTryRethrowAsResult(TryRethrowAsResultExpression expression) {
2104
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
2105
-	}
2106
-	
2107
-	@Override
2108
-	public Void visitVariantValue(VariantValueExpression expression) {
2109
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
2110
-	}
2209
+    @Override
2210
+    public Void visitTryRethrowAsResult(TryRethrowAsResultExpression expression) {
2211
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
2212
+    }
2213
+
2214
+    @Override
2215
+    public Void visitVariantValue(VariantValueExpression expression) {
2216
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
2217
+    }
2111 2218
 
2112 2219
     @Override
2113 2220
     public Void visitWrapOptional(WrapOptionalExpression expression) {
2114
-		// TODO: convert basic types (char, int, float, ...) to their boxed (Character, Integer, Float, ...) counterparts
2115
-		// -- any object type values can just be passed as-is
2221
+        // TODO: convert basic types (char, int, float, ...) to their boxed (Character, Integer, Float, ...) counterparts
2222
+        // -- any object type values can just be passed as-is
2116 2223
         expression.value.accept(this);
2117 2224
         return null;
2118 2225
     }

+ 17
- 12
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaStatementVisitor.java 查看文件

@@ -13,7 +13,7 @@ import java.util.List;
13 13
 
14 14
 public class JavaStatementVisitor implements StatementVisitor<Boolean> {
15 15
     private final JavaWriter javaWriter;
16
-    public final JavaExpressionVisitor expressionVisitor;
16
+    public JavaExpressionVisitor expressionVisitor;
17 17
 
18 18
     /**
19 19
      * @param javaWriter the method writer that compiles the statement
@@ -23,6 +23,11 @@ public class JavaStatementVisitor implements StatementVisitor<Boolean> {
23 23
         this.expressionVisitor = new JavaExpressionVisitor(javaWriter);
24 24
     }
25 25
 
26
+    public JavaStatementVisitor(JavaExpressionVisitor expressionVisitor) {
27
+        this.javaWriter = expressionVisitor.getJavaWriter();
28
+        this.expressionVisitor = expressionVisitor;
29
+    }
30
+
26 31
     @Override
27 32
     public Boolean visitBlock(BlockStatement statement) {
28 33
         Boolean returns = false;
@@ -156,25 +161,25 @@ public class JavaStatementVisitor implements StatementVisitor<Boolean> {
156 161
 
157 162
         javaWriter.label(start);
158 163
         statement.value.accept(expressionVisitor);
159
-        if(statement.value.type == BasicTypeID.STRING)
164
+        if (statement.value.type == BasicTypeID.STRING)
160 165
             javaWriter.invokeVirtual(new JavaMethodInfo(new JavaClassInfo("java/lang/Object"), "hashCode", "()I", 0));
161 166
         boolean out = false;
162 167
 
163 168
         final boolean hasNoDefault = hasNoDefault(statement);
164 169
 
165 170
         final List<SwitchCase> cases = statement.cases;
166
-		final JavaSwitchLabel[] switchLabels = new JavaSwitchLabel[hasNoDefault ? cases.size() : cases.size() - 1];
171
+        final JavaSwitchLabel[] switchLabels = new JavaSwitchLabel[hasNoDefault ? cases.size() : cases.size() - 1];
167 172
         final Label defaultLabel = new Label();
168
-		
173
+
169 174
         int i = 0;
170 175
         for (final SwitchCase switchCase : cases) {
171 176
             if (switchCase.value != null) {
172
-				switchLabels[i++] = new JavaSwitchLabel(CompilerUtils.getKeyForSwitch(switchCase.value), new Label());
173
-			}
174
-		}
175
-		
176
-		JavaSwitchLabel[] sortedSwitchLabels = Arrays.copyOf(switchLabels, switchLabels.length);
177
-		Arrays.sort(sortedSwitchLabels, (a, b) -> a.key - b.key);
177
+                switchLabels[i++] = new JavaSwitchLabel(CompilerUtils.getKeyForSwitch(switchCase.value), new Label());
178
+            }
179
+        }
180
+
181
+        JavaSwitchLabel[] sortedSwitchLabels = Arrays.copyOf(switchLabels, switchLabels.length);
182
+        Arrays.sort(sortedSwitchLabels, (a, b) -> a.key - b.key);
178 183
 
179 184
         javaWriter.lookupSwitch(defaultLabel, sortedSwitchLabels);
180 185
 
@@ -190,7 +195,7 @@ public class JavaStatementVisitor implements StatementVisitor<Boolean> {
190 195
             }
191 196
         }
192 197
 
193
-        if(hasNoDefault)
198
+        if (hasNoDefault)
194 199
             javaWriter.label(defaultLabel);
195 200
 
196 201
         javaWriter.label(end);
@@ -204,7 +209,7 @@ public class JavaStatementVisitor implements StatementVisitor<Boolean> {
204 209
         for (SwitchCase switchCase : switchStatement.cases)
205 210
             if (switchCase.value == null) return false;
206 211
         return true;
207
-	}
212
+    }
208 213
 
209 214
     @Override
210 215
     public Boolean visitThrow(ThrowStatement statement) {

+ 56
- 57
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaWriter.java 查看文件

@@ -1,53 +1,52 @@
1 1
 package org.openzen.zenscript.javabytecode.compiler;
2 2
 
3
-import org.objectweb.asm.*;
4
-import org.objectweb.asm.commons.LocalVariablesSorter;
5
-import org.openzen.zenscript.javabytecode.JavaLocalVariableInfo;
6
-
7 3
 import java.lang.reflect.Field;
8 4
 import java.util.ArrayList;
9 5
 import java.util.HashMap;
10 6
 import java.util.List;
11 7
 import java.util.Map;
12
-
8
+import org.objectweb.asm.*;
13 9
 import static org.objectweb.asm.Opcodes.*;
10
+import org.objectweb.asm.commons.LocalVariablesSorter;
14 11
 import org.openzen.zencode.shared.CodePosition;
15 12
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
16 13
 import org.openzen.zenscript.javabytecode.JavaClassInfo;
17 14
 import org.openzen.zenscript.javabytecode.JavaFieldInfo;
15
+import org.openzen.zenscript.javabytecode.JavaLocalVariableInfo;
18 16
 import org.openzen.zenscript.javabytecode.JavaMethodInfo;
19 17
 import org.openzen.zenscript.javabytecode.JavaParameterInfo;
20 18
 
21 19
 public class JavaWriter {
22
-	private static final JavaClassInfo T_STRING = new JavaClassInfo("java/lang/String");
23
-	private static final JavaMethodInfo STRING_CONCAT = new JavaMethodInfo(
24
-			T_STRING,
25
-			"concat",
26
-			"(Ljava/lang/String;)Ljava/lang/String;",
27
-			Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC);
28
-	
29
-	public final JavaMethodInfo method;
30
-	public final HighLevelDefinition forDefinition;
31
-	
20
+    private static final JavaClassInfo T_STRING = new JavaClassInfo("java/lang/String");
21
+    private static final JavaMethodInfo STRING_CONCAT = new JavaMethodInfo(
22
+            T_STRING,
23
+            "concat",
24
+            "(Ljava/lang/String;)Ljava/lang/String;",
25
+            Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC);
26
+
27
+    public final JavaMethodInfo method;
28
+    public final HighLevelDefinition forDefinition;
29
+
32 30
     private final LocalVariablesSorter visitor;
33 31
     private final List<JavaLocalVariableInfo> localVariableInfos = new ArrayList<>();
32
+    public final ClassVisitor clazzVisitor;
34 33
     private boolean debug = true;
35 34
     private boolean nameVariables = true;
36 35
     private int labelIndex = 1;
37 36
     private Map<Label, String> labelNames = new HashMap<>();
38 37
 
39 38
     public JavaWriter(
40
-			ClassVisitor visitor,
41
-			boolean nameVariables,
42
-			JavaMethodInfo method,
43
-			HighLevelDefinition forDefinition,
44
-			String signature,
45
-			String[] exceptions,
46
-			String... annotations)
47
-	{
48
-		this.method = method;
49
-		this.forDefinition = forDefinition;
50
-		
39
+            ClassVisitor visitor,
40
+            boolean nameVariables,
41
+            JavaMethodInfo method,
42
+            HighLevelDefinition forDefinition,
43
+            String signature,
44
+            String[] exceptions,
45
+            String... annotations) {
46
+        this.clazzVisitor = visitor;
47
+        this.method = method;
48
+        this.forDefinition = forDefinition;
49
+
51 50
         final MethodVisitor methodVisitor = visitor.visitMethod(method.modifiers, method.name, method.descriptor, signature, exceptions);
52 51
 
53 52
         for (String annotation : annotations) {
@@ -178,13 +177,13 @@ public class JavaWriter {
178 177
 
179 178
         visitor.visitInsn(DUP);
180 179
     }
181
-	
182
-	public void dup(Type type) {
180
+
181
+    public void dup(Type type) {
183 182
         if (debug)
184 183
             System.out.println("dup");
185
-		
186
-		visitor.visitInsn(type.getSize() == 2 ? DUP2 : DUP);
187
-	}
184
+
185
+        visitor.visitInsn(type.getSize() == 2 ? DUP2 : DUP);
186
+    }
188 187
 
189 188
     public void dup(boolean large) {
190 189
         if (debug)
@@ -241,34 +240,34 @@ public class JavaWriter {
241 240
 
242 241
         visitor.visitVarInsn(type.getOpcode(ILOAD), local);
243 242
     }
244
-	
245
-	public void load(JavaParameterInfo parameter) {
243
+
244
+    public void load(JavaParameterInfo parameter) {
246 245
         if (debug)
247 246
             System.out.println("load " + parameter.index);
248 247
 
249 248
         visitor.visitVarInsn(parameter.type.getOpcode(ILOAD), parameter.index);
250
-	}
251
-	
252
-	public void load(JavaLocalVariableInfo localVariable) {
249
+    }
250
+
251
+    public void load(JavaLocalVariableInfo localVariable) {
253 252
         if (debug)
254 253
             System.out.println("load " + localVariable.local);
255 254
 
256 255
         visitor.visitVarInsn(localVariable.type.getOpcode(ILOAD), localVariable.local);
257
-	}
258
-	
259
-	public void store(JavaParameterInfo parameter) {
256
+    }
257
+
258
+    public void store(JavaParameterInfo parameter) {
260 259
         if (debug)
261 260
             System.out.println("store " + parameter.index);
262 261
 
263 262
         visitor.visitVarInsn(parameter.type.getOpcode(ISTORE), parameter.index);
264
-	}
265
-	
266
-	public void store(JavaLocalVariableInfo localVariable) {
263
+    }
264
+
265
+    public void store(JavaLocalVariableInfo localVariable) {
267 266
         if (debug)
268 267
             System.out.println("store " + localVariable.local);
269 268
 
270 269
         visitor.visitVarInsn(localVariable.type.getOpcode(ISTORE), localVariable.local);
271
-	}
270
+    }
272 271
 
273 272
     public void storeInt(int local) {
274 273
         if (debug)
@@ -666,10 +665,10 @@ public class JavaWriter {
666 665
     public void iinc(int local) {
667 666
         iinc(local, 1);
668 667
     }
669
-	
670
-	public void idec(int local) {
671
-		iinc(local, -1);
672
-	}
668
+
669
+    public void idec(int local) {
670
+        iinc(local, -1);
671
+    }
673 672
 
674 673
     public void iinc(int local, int increment) {
675 674
         if (debug)
@@ -830,13 +829,13 @@ public class JavaWriter {
830 829
     public void invokeSpecial(Class owner, String name, String descriptor) {
831 830
         invokeSpecial(Type.getInternalName(owner), name, descriptor);
832 831
     }
833
-	
834
-	public void invokeVirtual(JavaMethodInfo method) {
832
+
833
+    public void invokeVirtual(JavaMethodInfo method) {
835 834
         if (debug)
836 835
             System.out.println("invokeVirtual " + method.javaClass.internalClassName + '.' + method.name + method.descriptor);
837 836
 
838 837
         visitor.visitMethodInsn(INVOKEVIRTUAL, method.javaClass.internalClassName, method.name, method.descriptor, false);
839
-	}
838
+    }
840 839
 
841 840
     public void invokeInterface(JavaMethodInfo method) {
842 841
         if (debug)
@@ -1182,13 +1181,13 @@ public class JavaWriter {
1182 1181
     }
1183 1182
 
1184 1183
     public void lookupSwitch(Label defaultLabel, JavaSwitchLabel[] switchLabels) {
1185
-		int[] keys = new int[switchLabels.length];
1186
-		Label[] labels = new Label[switchLabels.length];
1187
-		for (int i = 0; i < switchLabels.length; i++) {
1188
-			keys[i] = switchLabels[i].key;
1189
-			labels[i] = switchLabels[i].label;
1190
-		}
1191
-		
1184
+        int[] keys = new int[switchLabels.length];
1185
+        Label[] labels = new Label[switchLabels.length];
1186
+        for (int i = 0; i < switchLabels.length; i++) {
1187
+            keys[i] = switchLabels[i].key;
1188
+            labels[i] = switchLabels[i].label;
1189
+        }
1190
+
1192 1191
         visitor.visitLookupSwitchInsn(defaultLabel, keys, labels);
1193 1192
     }
1194 1193
 

+ 3
- 1
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/definitions/JavaDefinitionVisitor.java 查看文件

@@ -9,6 +9,7 @@ import org.openzen.zenscript.codemodel.type.BasicTypeID;
9 9
 import org.openzen.zenscript.codemodel.type.ITypeID;
10 10
 import org.openzen.zenscript.javabytecode.JavaClassInfo;
11 11
 import org.openzen.zenscript.javabytecode.JavaMethodInfo;
12
+import org.openzen.zenscript.javabytecode.JavaModule;
12 13
 import org.openzen.zenscript.javabytecode.compiler.*;
13 14
 
14 15
 
@@ -172,7 +173,8 @@ public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
172 173
 
173 174
     @Override
174 175
     public byte[] visitAlias(AliasDefinition definition) {
175
-        return null;
176
+        //TODO would that work?
177
+        return JavaModule.classes.get(definition.name);
176 178
     }
177 179
 
178 180
 	@Override

+ 9
- 2
Parser/src/main/java/org/openzen/zenscript/parser/definitions/ParsedFunction.java 查看文件

@@ -7,6 +7,8 @@
7 7
 package org.openzen.zenscript.parser.definitions;
8 8
 
9 9
 import org.openzen.zencode.shared.CodePosition;
10
+import org.openzen.zencode.shared.CompileException;
11
+import org.openzen.zencode.shared.CompileExceptionCode;
10 12
 import static org.openzen.zenscript.lexer.ZSTokenType.*;
11 13
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
12 14
 import org.openzen.zenscript.codemodel.definition.FunctionDefinition;
@@ -15,6 +17,7 @@ import org.openzen.zenscript.lexer.ZSTokenParser;
15 17
 import org.openzen.zenscript.codemodel.scope.BaseScope;
16 18
 import org.openzen.zenscript.codemodel.scope.FunctionScope;
17 19
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
20
+import org.openzen.zenscript.codemodel.type.ITypeID;
18 21
 import org.openzen.zenscript.parser.ParsedAnnotation;
19 22
 import org.openzen.zenscript.parser.ParsedDefinition;
20 23
 import org.openzen.zenscript.parser.PrecompilationState;
@@ -72,7 +75,11 @@ public class ParsedFunction extends ParsedDefinition {
72 75
 		FunctionScope innerScope = new FunctionScope(scope, compiled.header);
73 76
 		compiled.setCode(body.compile(innerScope, compiled.header));
74 77
 		
75
-		if (compiled.header.returnType == BasicTypeID.UNDETERMINED)
76
-			compiled.header = compiled.header.withReturnType(body.precompileForResultType(new FunctionScope(scope, compiled.header), state));
78
+		if (compiled.header.returnType == BasicTypeID.UNDETERMINED) {
79
+			ITypeID result = body.precompileForResultType(new FunctionScope(scope, compiled.header), state);
80
+			if (result == null)
81
+				throw new CompileException(position, CompileExceptionCode.PRECOMPILE_FAILED, "Could not determine return type for method " + compiled.name);
82
+			compiled.header = compiled.header.withReturnType(result);
83
+		}
77 84
 	}
78 85
 }

+ 1
- 1
ScriptingExample/scripts/functions.zs 查看文件

@@ -1,4 +1,4 @@
1
-function test() {
1
+function test() as void {
2 2
 	println("functions.zs; test1");
3 3
 }
4 4
 

+ 26
- 0
ScriptingExample/scripts/match.zs 查看文件

@@ -0,0 +1,26 @@
1
+val test as int = 10;
2
+val tt1 = "tt";
3
+val tt2 = "tt3";
4
+val tt4 = "tt5";
5
+
6
+
7
+println(match 10 {
8
+	1 => "one",
9
+	10 => "yo",
10
+	//tt1 === "tt1" for some compiler issue it takes the variable as string input?
11
+	100 => match tt1 {
12
+		"10" => "t",
13
+		"tt1" => tt1,
14
+		"tt2" => tt1 + tt4,
15
+		default => tt4
16
+	},
17
+	default => tt2
18
+});
19
+
20
+
21
+println(tt1);
22
+
23
+//println(match test {
24
+//	case 1 : "tt",
25
+//	default : "kk"
26
+//});

正在加载...
取消
保存