Browse Source

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 years ago
parent
commit
b553e18993

+ 2
- 2
CodeFormatter/src/main/java/org/openzen/zenscript/formatter/ExpressionFormatter.java View File

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

+ 29
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/DummyExpression.java View File

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

17
  * @author Hoofdgebruiker
17
  * @author Hoofdgebruiker
18
  */
18
  */
19
 public class JavaModule {
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
 	public JavaModule() {
22
 	public JavaModule() {
23
 		
23
 		

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

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

2
 
2
 
3
 import java.util.Arrays;
3
 import java.util.Arrays;
4
 import java.util.Collection;
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
 import java.util.Map;
6
 import java.util.Map;
7
+import java.util.StringJoiner;
8
+import org.objectweb.asm.Label;
15
 import org.objectweb.asm.Opcodes;
9
 import org.objectweb.asm.Opcodes;
10
+import org.objectweb.asm.Type;
16
 import org.openzen.zencode.shared.CompileException;
11
 import org.openzen.zencode.shared.CompileException;
17
 import org.openzen.zencode.shared.CompileExceptionCode;
12
 import org.openzen.zencode.shared.CompileExceptionCode;
13
+import org.openzen.zenscript.codemodel.CompareType;
14
+import org.openzen.zenscript.codemodel.expression.*;
18
 import org.openzen.zenscript.codemodel.member.ref.ConstMemberRef;
15
 import org.openzen.zenscript.codemodel.member.ref.ConstMemberRef;
19
 import org.openzen.zenscript.codemodel.member.ref.DefinitionMemberRef;
16
 import org.openzen.zenscript.codemodel.member.ref.DefinitionMemberRef;
20
 import org.openzen.zenscript.codemodel.member.ref.FieldMemberRef;
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
 import org.openzen.zenscript.codemodel.type.member.BuiltinID;
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
 public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
24
 public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
27
 	private static final int PUBLIC = Opcodes.ACC_PUBLIC;
25
 	private static final int PUBLIC = Opcodes.ACC_PUBLIC;
156
 	private static final JavaClassInfo COLLECTION = JavaClassInfo.get(Collection.class);
154
 	private static final JavaClassInfo COLLECTION = JavaClassInfo.get(Collection.class);
157
 	private static final JavaMethodInfo COLLECTION_SIZE = new JavaMethodInfo(COLLECTION, "size", "()I", PUBLIC);
155
 	private static final JavaMethodInfo COLLECTION_SIZE = new JavaMethodInfo(COLLECTION, "size", "()I", PUBLIC);
158
 	private static final JavaMethodInfo COLLECTION_TOARRAY = new JavaMethodInfo(COLLECTION, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", PUBLIC);
156
 	private static final JavaMethodInfo COLLECTION_TOARRAY = new JavaMethodInfo(COLLECTION, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", PUBLIC);
159
-	
157
+
160
     private final JavaWriter javaWriter;
158
     private final JavaWriter javaWriter;
161
-	
159
+    private final JavaCapturedExpressionVisitor capturedExpressionVisitor = new JavaCapturedExpressionVisitor(this);
160
+
162
     public JavaExpressionVisitor(JavaWriter javaWriter) {
161
     public JavaExpressionVisitor(JavaWriter javaWriter) {
163
         this.javaWriter = javaWriter;
162
         this.javaWriter = javaWriter;
164
     }
163
     }
929
 
928
 
930
     @Override
929
     @Override
931
     public Void visitCapturedClosure(CapturedClosureExpression expression) {
930
     public Void visitCapturedClosure(CapturedClosureExpression expression) {
932
-        return null;
931
+        return expression.accept(capturedExpressionVisitor);
933
     }
932
     }
934
 
933
 
935
     @Override
934
     @Override
936
     public Void visitCapturedDirect(CapturedDirectExpression expression) {
935
     public Void visitCapturedDirect(CapturedDirectExpression expression) {
937
-        return null;
936
+        return expression.accept(capturedExpressionVisitor);
938
     }
937
     }
939
 
938
 
940
     @Override
939
     @Override
941
     public Void visitCapturedLocalVariable(CapturedLocalVariableExpression expression) {
940
     public Void visitCapturedLocalVariable(CapturedLocalVariableExpression expression) {
942
-        return null;
941
+        return expression.accept(capturedExpressionVisitor);
943
     }
942
     }
944
 
943
 
945
     @Override
944
     @Override
946
     public Void visitCapturedParameter(CapturedParameterExpression expression) {
945
     public Void visitCapturedParameter(CapturedParameterExpression expression) {
947
-        return null;
948
-    }
946
+        return expression.accept(capturedExpressionVisitor);
947
+	}
949
 
948
 
950
     @Override
949
     @Override
951
     public Void visitCapturedThis(CapturedThisExpression expression) {
950
     public Void visitCapturedThis(CapturedThisExpression expression) {
952
-        return null;
951
+        return expression.accept(capturedExpressionVisitor);
953
     }
952
     }
954
 
953
 
955
     @Override
954
     @Override
1511
     @Override
1510
     @Override
1512
     public Void visitConstructorThisCall(ConstructorThisCallExpression expression) {
1511
     public Void visitConstructorThisCall(ConstructorThisCallExpression expression) {
1513
         Type type = expression.objectType.accept(JavaTypeVisitor.INSTANCE);
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
         for (Expression argument : expression.arguments.arguments) {
1520
         for (Expression argument : expression.arguments.arguments) {
1524
             argument.accept(this);
1521
             argument.accept(this);
1525
         }
1522
         }
1535
         }
1532
         }
1536
         //No super calls in enums possible, and that's already handled in the enum constructor itself.
1533
         //No super calls in enums possible, and that's already handled in the enum constructor itself.
1537
         javaWriter.invokeSpecial(expression.objectType.accept(JavaTypeClassVisitor.INSTANCE), "<init>", CompilerUtils.calcDesc(expression.constructor.header, false));
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
         return null;
1537
         return null;
1541
     }
1538
     }
1542
 
1539
 
1549
 
1546
 
1550
     @Override
1547
     @Override
1551
     public Void visitFunction(FunctionExpression expression) {
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
         return null;
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
     @Override
1607
     @Override
1556
     public Void visitGetField(GetFieldExpression expression) {
1608
     public Void visitGetField(GetFieldExpression expression) {
1557
-		expression.accept(this);
1609
+        expression.accept(this);
1558
         if (!checkAndGetFieldInfo(expression.field, false))
1610
         if (!checkAndGetFieldInfo(expression.field, false))
1559
             throw new IllegalStateException("Missing field info on a field member!");
1611
             throw new IllegalStateException("Missing field info on a field member!");
1560
         return null;
1612
         return null;
1562
 
1614
 
1563
     @Override
1615
     @Override
1564
     public Void visitGetFunctionParameter(GetFunctionParameterExpression expression) {
1616
     public Void visitGetFunctionParameter(GetFunctionParameterExpression expression) {
1565
-		JavaParameterInfo parameter = expression.parameter.getTag(JavaParameterInfo.class);
1617
+        JavaParameterInfo parameter = expression.parameter.getTag(JavaParameterInfo.class);
1566
         javaWriter.load(Type.getType(expression.parameter.type.accept(JavaTypeClassVisitor.INSTANCE)), parameter.index);
1618
         javaWriter.load(Type.getType(expression.parameter.type.accept(JavaTypeClassVisitor.INSTANCE)), parameter.index);
1567
         return null;
1619
         return null;
1568
     }
1620
     }
1772
 				javaWriter.getField(IntRange.class, "to", int.class);
1824
 				javaWriter.getField(IntRange.class, "to", int.class);
1773
 				break;
1825
 				break;
1774
 		}
1826
 		}
1775
-		
1827
+
1776
         return null;
1828
         return null;
1777
     }
1829
     }
1778
 
1830
 
1819
         }
1871
         }
1820
         return null;
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
     @Override
1934
     @Override
1829
     public Void visitNew(NewExpression expression) {
1935
     public Void visitNew(NewExpression expression) {
1889
 		javaWriter.dup(expression.type.accept(new JavaTypeVisitor()));
1995
 		javaWriter.dup(expression.type.accept(new JavaTypeVisitor()));
1890
         if (!checkAndExecuteByteCodeImplementation(expression.member) && !checkAndExecuteMethodInfo(expression.member))
1996
         if (!checkAndExecuteByteCodeImplementation(expression.member) && !checkAndExecuteMethodInfo(expression.member))
1891
             throw new IllegalStateException("Call target has no method info!");
1997
             throw new IllegalStateException("Call target has no method info!");
1892
-		
1893
-		return null;
1894
-	}
1998
+
1999
+        return null;
2000
+    }
1895
 
2001
 
1896
     @Override
2002
     @Override
1897
     public Void visitRange(RangeExpression expression) {
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
         if (expression.from.type.accept(JavaTypeClassVisitor.INSTANCE) != int.class)
2005
         if (expression.from.type.accept(JavaTypeClassVisitor.INSTANCE) != int.class)
1900
             throw new CompileException(expression.position, CompileExceptionCode.INTERNAL_ERROR, "Only integer ranges supported");
2006
             throw new CompileException(expression.position, CompileExceptionCode.INTERNAL_ERROR, "Only integer ranges supported");
1901
-		
2007
+
1902
         javaWriter.newObject(IntRange.class);
2008
         javaWriter.newObject(IntRange.class);
1903
         javaWriter.dup();
2009
         javaWriter.dup();
1904
         expression.from.accept(this);
2010
         expression.from.accept(this);
1908
 
2014
 
1909
         return null;
2015
         return null;
1910
     }
2016
     }
2017
+
1911
 	
2018
 	
1912
 	@Override
2019
 	@Override
1913
 	public Void visitSameObject(SameObjectExpression expression) {
2020
 	public Void visitSameObject(SameObjectExpression expression) {
1942
     @Override
2049
     @Override
1943
     public Void visitSetFunctionParameter(SetFunctionParameterExpression expression) {
2050
     public Void visitSetFunctionParameter(SetFunctionParameterExpression expression) {
1944
         expression.value.accept(this);
2051
         expression.value.accept(this);
1945
-		JavaParameterInfo parameter = expression.parameter.getTag(JavaParameterInfo.class);
2052
+        JavaParameterInfo parameter = expression.parameter.getTag(JavaParameterInfo.class);
1946
         javaWriter.store(expression.type.accept(JavaTypeVisitor.INSTANCE), parameter.index);
2053
         javaWriter.store(expression.type.accept(JavaTypeVisitor.INSTANCE), parameter.index);
1947
         return null;
2054
         return null;
1948
     }
2055
     }
2070
     public Void visitStaticSetter(StaticSetterExpression expression) {
2177
     public Void visitStaticSetter(StaticSetterExpression expression) {
2071
         return null;
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
     @Override
2186
     @Override
2080
     public Void visitThis(ThisExpression expression) {
2187
     public Void visitThis(ThisExpression expression) {
2094
 		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
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
     @Override
2219
     @Override
2113
     public Void visitWrapOptional(WrapOptionalExpression expression) {
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
         expression.value.accept(this);
2223
         expression.value.accept(this);
2117
         return null;
2224
         return null;
2118
     }
2225
     }

+ 17
- 12
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaStatementVisitor.java View File

13
 
13
 
14
 public class JavaStatementVisitor implements StatementVisitor<Boolean> {
14
 public class JavaStatementVisitor implements StatementVisitor<Boolean> {
15
     private final JavaWriter javaWriter;
15
     private final JavaWriter javaWriter;
16
-    public final JavaExpressionVisitor expressionVisitor;
16
+    public JavaExpressionVisitor expressionVisitor;
17
 
17
 
18
     /**
18
     /**
19
      * @param javaWriter the method writer that compiles the statement
19
      * @param javaWriter the method writer that compiles the statement
23
         this.expressionVisitor = new JavaExpressionVisitor(javaWriter);
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
     @Override
31
     @Override
27
     public Boolean visitBlock(BlockStatement statement) {
32
     public Boolean visitBlock(BlockStatement statement) {
28
         Boolean returns = false;
33
         Boolean returns = false;
156
 
161
 
157
         javaWriter.label(start);
162
         javaWriter.label(start);
158
         statement.value.accept(expressionVisitor);
163
         statement.value.accept(expressionVisitor);
159
-        if(statement.value.type == BasicTypeID.STRING)
164
+        if (statement.value.type == BasicTypeID.STRING)
160
             javaWriter.invokeVirtual(new JavaMethodInfo(new JavaClassInfo("java/lang/Object"), "hashCode", "()I", 0));
165
             javaWriter.invokeVirtual(new JavaMethodInfo(new JavaClassInfo("java/lang/Object"), "hashCode", "()I", 0));
161
         boolean out = false;
166
         boolean out = false;
162
 
167
 
163
         final boolean hasNoDefault = hasNoDefault(statement);
168
         final boolean hasNoDefault = hasNoDefault(statement);
164
 
169
 
165
         final List<SwitchCase> cases = statement.cases;
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
         final Label defaultLabel = new Label();
172
         final Label defaultLabel = new Label();
168
-		
173
+
169
         int i = 0;
174
         int i = 0;
170
         for (final SwitchCase switchCase : cases) {
175
         for (final SwitchCase switchCase : cases) {
171
             if (switchCase.value != null) {
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
         javaWriter.lookupSwitch(defaultLabel, sortedSwitchLabels);
184
         javaWriter.lookupSwitch(defaultLabel, sortedSwitchLabels);
180
 
185
 
190
             }
195
             }
191
         }
196
         }
192
 
197
 
193
-        if(hasNoDefault)
198
+        if (hasNoDefault)
194
             javaWriter.label(defaultLabel);
199
             javaWriter.label(defaultLabel);
195
 
200
 
196
         javaWriter.label(end);
201
         javaWriter.label(end);
204
         for (SwitchCase switchCase : switchStatement.cases)
209
         for (SwitchCase switchCase : switchStatement.cases)
205
             if (switchCase.value == null) return false;
210
             if (switchCase.value == null) return false;
206
         return true;
211
         return true;
207
-	}
212
+    }
208
 
213
 
209
     @Override
214
     @Override
210
     public Boolean visitThrow(ThrowStatement statement) {
215
     public Boolean visitThrow(ThrowStatement statement) {

+ 56
- 57
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaWriter.java View File

1
 package org.openzen.zenscript.javabytecode.compiler;
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
 import java.lang.reflect.Field;
3
 import java.lang.reflect.Field;
8
 import java.util.ArrayList;
4
 import java.util.ArrayList;
9
 import java.util.HashMap;
5
 import java.util.HashMap;
10
 import java.util.List;
6
 import java.util.List;
11
 import java.util.Map;
7
 import java.util.Map;
12
-
8
+import org.objectweb.asm.*;
13
 import static org.objectweb.asm.Opcodes.*;
9
 import static org.objectweb.asm.Opcodes.*;
10
+import org.objectweb.asm.commons.LocalVariablesSorter;
14
 import org.openzen.zencode.shared.CodePosition;
11
 import org.openzen.zencode.shared.CodePosition;
15
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
12
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
16
 import org.openzen.zenscript.javabytecode.JavaClassInfo;
13
 import org.openzen.zenscript.javabytecode.JavaClassInfo;
17
 import org.openzen.zenscript.javabytecode.JavaFieldInfo;
14
 import org.openzen.zenscript.javabytecode.JavaFieldInfo;
15
+import org.openzen.zenscript.javabytecode.JavaLocalVariableInfo;
18
 import org.openzen.zenscript.javabytecode.JavaMethodInfo;
16
 import org.openzen.zenscript.javabytecode.JavaMethodInfo;
19
 import org.openzen.zenscript.javabytecode.JavaParameterInfo;
17
 import org.openzen.zenscript.javabytecode.JavaParameterInfo;
20
 
18
 
21
 public class JavaWriter {
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
     private final LocalVariablesSorter visitor;
30
     private final LocalVariablesSorter visitor;
33
     private final List<JavaLocalVariableInfo> localVariableInfos = new ArrayList<>();
31
     private final List<JavaLocalVariableInfo> localVariableInfos = new ArrayList<>();
32
+    public final ClassVisitor clazzVisitor;
34
     private boolean debug = true;
33
     private boolean debug = true;
35
     private boolean nameVariables = true;
34
     private boolean nameVariables = true;
36
     private int labelIndex = 1;
35
     private int labelIndex = 1;
37
     private Map<Label, String> labelNames = new HashMap<>();
36
     private Map<Label, String> labelNames = new HashMap<>();
38
 
37
 
39
     public JavaWriter(
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
         final MethodVisitor methodVisitor = visitor.visitMethod(method.modifiers, method.name, method.descriptor, signature, exceptions);
50
         final MethodVisitor methodVisitor = visitor.visitMethod(method.modifiers, method.name, method.descriptor, signature, exceptions);
52
 
51
 
53
         for (String annotation : annotations) {
52
         for (String annotation : annotations) {
178
 
177
 
179
         visitor.visitInsn(DUP);
178
         visitor.visitInsn(DUP);
180
     }
179
     }
181
-	
182
-	public void dup(Type type) {
180
+
181
+    public void dup(Type type) {
183
         if (debug)
182
         if (debug)
184
             System.out.println("dup");
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
     public void dup(boolean large) {
188
     public void dup(boolean large) {
190
         if (debug)
189
         if (debug)
241
 
240
 
242
         visitor.visitVarInsn(type.getOpcode(ILOAD), local);
241
         visitor.visitVarInsn(type.getOpcode(ILOAD), local);
243
     }
242
     }
244
-	
245
-	public void load(JavaParameterInfo parameter) {
243
+
244
+    public void load(JavaParameterInfo parameter) {
246
         if (debug)
245
         if (debug)
247
             System.out.println("load " + parameter.index);
246
             System.out.println("load " + parameter.index);
248
 
247
 
249
         visitor.visitVarInsn(parameter.type.getOpcode(ILOAD), parameter.index);
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
         if (debug)
252
         if (debug)
254
             System.out.println("load " + localVariable.local);
253
             System.out.println("load " + localVariable.local);
255
 
254
 
256
         visitor.visitVarInsn(localVariable.type.getOpcode(ILOAD), localVariable.local);
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
         if (debug)
259
         if (debug)
261
             System.out.println("store " + parameter.index);
260
             System.out.println("store " + parameter.index);
262
 
261
 
263
         visitor.visitVarInsn(parameter.type.getOpcode(ISTORE), parameter.index);
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
         if (debug)
266
         if (debug)
268
             System.out.println("store " + localVariable.local);
267
             System.out.println("store " + localVariable.local);
269
 
268
 
270
         visitor.visitVarInsn(localVariable.type.getOpcode(ISTORE), localVariable.local);
269
         visitor.visitVarInsn(localVariable.type.getOpcode(ISTORE), localVariable.local);
271
-	}
270
+    }
272
 
271
 
273
     public void storeInt(int local) {
272
     public void storeInt(int local) {
274
         if (debug)
273
         if (debug)
666
     public void iinc(int local) {
665
     public void iinc(int local) {
667
         iinc(local, 1);
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
     public void iinc(int local, int increment) {
673
     public void iinc(int local, int increment) {
675
         if (debug)
674
         if (debug)
830
     public void invokeSpecial(Class owner, String name, String descriptor) {
829
     public void invokeSpecial(Class owner, String name, String descriptor) {
831
         invokeSpecial(Type.getInternalName(owner), name, descriptor);
830
         invokeSpecial(Type.getInternalName(owner), name, descriptor);
832
     }
831
     }
833
-	
834
-	public void invokeVirtual(JavaMethodInfo method) {
832
+
833
+    public void invokeVirtual(JavaMethodInfo method) {
835
         if (debug)
834
         if (debug)
836
             System.out.println("invokeVirtual " + method.javaClass.internalClassName + '.' + method.name + method.descriptor);
835
             System.out.println("invokeVirtual " + method.javaClass.internalClassName + '.' + method.name + method.descriptor);
837
 
836
 
838
         visitor.visitMethodInsn(INVOKEVIRTUAL, method.javaClass.internalClassName, method.name, method.descriptor, false);
837
         visitor.visitMethodInsn(INVOKEVIRTUAL, method.javaClass.internalClassName, method.name, method.descriptor, false);
839
-	}
838
+    }
840
 
839
 
841
     public void invokeInterface(JavaMethodInfo method) {
840
     public void invokeInterface(JavaMethodInfo method) {
842
         if (debug)
841
         if (debug)
1182
     }
1181
     }
1183
 
1182
 
1184
     public void lookupSwitch(Label defaultLabel, JavaSwitchLabel[] switchLabels) {
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
         visitor.visitLookupSwitchInsn(defaultLabel, keys, labels);
1191
         visitor.visitLookupSwitchInsn(defaultLabel, keys, labels);
1193
     }
1192
     }
1194
 
1193
 

+ 3
- 1
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/definitions/JavaDefinitionVisitor.java View File

9
 import org.openzen.zenscript.codemodel.type.ITypeID;
9
 import org.openzen.zenscript.codemodel.type.ITypeID;
10
 import org.openzen.zenscript.javabytecode.JavaClassInfo;
10
 import org.openzen.zenscript.javabytecode.JavaClassInfo;
11
 import org.openzen.zenscript.javabytecode.JavaMethodInfo;
11
 import org.openzen.zenscript.javabytecode.JavaMethodInfo;
12
+import org.openzen.zenscript.javabytecode.JavaModule;
12
 import org.openzen.zenscript.javabytecode.compiler.*;
13
 import org.openzen.zenscript.javabytecode.compiler.*;
13
 
14
 
14
 
15
 
172
 
173
 
173
     @Override
174
     @Override
174
     public byte[] visitAlias(AliasDefinition definition) {
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
 	@Override
180
 	@Override

+ 9
- 2
Parser/src/main/java/org/openzen/zenscript/parser/definitions/ParsedFunction.java View File

7
 package org.openzen.zenscript.parser.definitions;
7
 package org.openzen.zenscript.parser.definitions;
8
 
8
 
9
 import org.openzen.zencode.shared.CodePosition;
9
 import org.openzen.zencode.shared.CodePosition;
10
+import org.openzen.zencode.shared.CompileException;
11
+import org.openzen.zencode.shared.CompileExceptionCode;
10
 import static org.openzen.zenscript.lexer.ZSTokenType.*;
12
 import static org.openzen.zenscript.lexer.ZSTokenType.*;
11
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
13
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
12
 import org.openzen.zenscript.codemodel.definition.FunctionDefinition;
14
 import org.openzen.zenscript.codemodel.definition.FunctionDefinition;
15
 import org.openzen.zenscript.codemodel.scope.BaseScope;
17
 import org.openzen.zenscript.codemodel.scope.BaseScope;
16
 import org.openzen.zenscript.codemodel.scope.FunctionScope;
18
 import org.openzen.zenscript.codemodel.scope.FunctionScope;
17
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
19
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
20
+import org.openzen.zenscript.codemodel.type.ITypeID;
18
 import org.openzen.zenscript.parser.ParsedAnnotation;
21
 import org.openzen.zenscript.parser.ParsedAnnotation;
19
 import org.openzen.zenscript.parser.ParsedDefinition;
22
 import org.openzen.zenscript.parser.ParsedDefinition;
20
 import org.openzen.zenscript.parser.PrecompilationState;
23
 import org.openzen.zenscript.parser.PrecompilationState;
72
 		FunctionScope innerScope = new FunctionScope(scope, compiled.header);
75
 		FunctionScope innerScope = new FunctionScope(scope, compiled.header);
73
 		compiled.setCode(body.compile(innerScope, compiled.header));
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 View File

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

+ 26
- 0
ScriptingExample/scripts/match.zs View File

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
+//});

Loading…
Cancel
Save