ソースを参照

- Experimental: variant types

- Experimental: match operator
- Adding error handling with return values and monadics
Stan Hebben 6年前
コミット
50c817b67e
48個のファイルの変更1036行の追加116行の削除
  1. 49
    0
      CodeFormatter/src/main/java/org/openzen/zenscript/formatter/DefinitionFormatter.java
  2. 11
    0
      CodeFormatter/src/main/java/org/openzen/zenscript/formatter/ExpressionFormatter.java
  3. 9
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/FunctionHeader.java
  4. 2
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/FunctionParameter.java
  5. 2
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/definition/DefinitionVisitor.java
  6. 2
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/definition/FunctionDefinition.java
  7. 50
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/definition/VariantDefinition.java
  8. 2
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/ExpressionVisitor.java
  9. 41
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/MatchExpression.java
  10. 43
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/VariantValueExpression.java
  11. 23
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/switchvalue/CharSwitchValue.java
  12. 25
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/switchvalue/EnumConstantSwitchValue.java
  13. 23
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/switchvalue/IntSwitchValue.java
  14. 23
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/switchvalue/StringSwitchValue.java
  15. 14
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/switchvalue/SwitchValue.java
  16. 22
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/switchvalue/SwitchValueVisitor.java
  17. 27
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/switchvalue/VariantOptionSwitchValue.java
  18. 6
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/partial/PartialTypeExpression.java
  19. 12
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/DefinitionTypeID.java
  20. 8
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/ITypeID.java
  21. 21
    5
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/TypeMemberBuilder.java
  22. 12
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/TypeMembers.java
  23. 2
    1
      Constructor/libraries/stdlib/module.json
  24. 4
    0
      Constructor/libraries/stdlib/src/Panic.zs
  25. 34
    0
      Constructor/libraries/stdlib/src/Result.zs
  26. 5
    0
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaExpressionVisitor.java
  27. 6
    0
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaPreDecrementVisitor.java
  28. 6
    0
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaPreIncrementVisitor.java
  29. 5
    3
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/definitions/JavaDefinitionVisitor.java
  30. 13
    6
      Linker/src/main/java/org/openzen/zenscript/linker/DefinitionScope.java
  31. 2
    0
      Parser/src/main/java/org/openzen/zenscript/lexer/ZSTokenStream.java
  32. 2
    0
      Parser/src/main/java/org/openzen/zenscript/lexer/ZSTokenType.java
  33. 4
    7
      Parser/src/main/java/org/openzen/zenscript/parser/ParsedDefinition.java
  34. 3
    0
      Parser/src/main/java/org/openzen/zenscript/parser/ParsedFile.java
  35. 0
    1
      Parser/src/main/java/org/openzen/zenscript/parser/definitions/ParsedExpansion.java
  36. 6
    4
      Parser/src/main/java/org/openzen/zenscript/parser/definitions/ParsedInterface.java
  37. 94
    0
      Parser/src/main/java/org/openzen/zenscript/parser/definitions/ParsedVariant.java
  38. 34
    0
      Parser/src/main/java/org/openzen/zenscript/parser/definitions/ParsedVariantOption.java
  39. 37
    0
      Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedCallArguments.java
  40. 120
    80
      Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpression.java
  41. 46
    2
      Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpressionCall.java
  42. 2
    2
      Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpressionFunction.java
  43. 35
    2
      Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpressionVariable.java
  44. 105
    0
      Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedMatchExpression.java
  45. 3
    1
      Shared/src/main/java/org/openzen/zenscript/shared/CompileExceptionCode.java
  46. 19
    0
      Validator/src/main/java/org/openzen/zenscript/validator/visitors/DefinitionValidator.java
  47. 7
    0
      Validator/src/main/java/org/openzen/zenscript/validator/visitors/ExpressionValidator.java
  48. 15
    2
      Validator/src/main/java/org/openzen/zenscript/validator/visitors/SuperclassValidator.java

+ 49
- 0
CodeFormatter/src/main/java/org/openzen/zenscript/formatter/DefinitionFormatter.java ファイルの表示

@@ -14,6 +14,7 @@ import org.openzen.zenscript.codemodel.definition.ExpansionDefinition;
14 14
 import org.openzen.zenscript.codemodel.definition.FunctionDefinition;
15 15
 import org.openzen.zenscript.codemodel.definition.InterfaceDefinition;
16 16
 import org.openzen.zenscript.codemodel.definition.StructDefinition;
17
+import org.openzen.zenscript.codemodel.definition.VariantDefinition;
17 18
 import org.openzen.zenscript.codemodel.expression.CallArguments;
18 19
 import org.openzen.zenscript.codemodel.member.EnumConstantMember;
19 20
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
@@ -156,6 +157,54 @@ public class DefinitionFormatter implements DefinitionVisitor<Void> {
156 157
 	public Void visitAlias(AliasDefinition definition) {
157 158
 		return null;
158 159
 	}
160
+
161
+	@Override
162
+	public Void visitVariant(VariantDefinition variant) {
163
+		FormattingUtils.formatModifiers(output, variant.modifiers);
164
+		output.append("variant ");
165
+		output.append(variant.name);
166
+		FormattingUtils.formatTypeParameters(output, variant.genericParameters, typeFormatter);
167
+		output.append(" ");
168
+		
169
+		if (settings.classBracketOnSameLine) {
170
+			output.append("{\n");
171
+		} else {
172
+			output.append("\n")
173
+					.append(indent)
174
+					.append("{\n");
175
+		}
176
+		
177
+		List<VariantDefinition.Option> options = variant.options;
178
+		boolean first = true;
179
+		for (VariantDefinition.Option option : options) {
180
+			if (first)
181
+				first = false;
182
+			else
183
+				output.append(",\n");
184
+			
185
+			output.append(indent).append(settings.indent).append(option.name);
186
+			if (option.types.length > 0) {
187
+				output.append("(");
188
+				for (int i = 0; i < option.types.length; i++) {
189
+					if (i > 0)
190
+						output.append(", ");
191
+					output.append(option.types[i].accept(typeFormatter));
192
+				}
193
+			}
194
+		}
195
+		
196
+		if (variant.members.size() > options.size()) {
197
+			output.append(";\n").append(indent).append(settings.indent).append("\n");
198
+
199
+			MemberFormatter memberFormatter = new MemberFormatter(settings, output, indent + settings.indent, typeFormatter);
200
+			for (IDefinitionMember member : variant.members) {
201
+				member.accept(memberFormatter);
202
+			}
203
+		}
204
+		
205
+		output.append("}\n");
206
+		return null;
207
+	}
159 208
 	
160 209
 	@Override
161 210
 	public String toString() {

+ 11
- 0
CodeFormatter/src/main/java/org/openzen/zenscript/formatter/ExpressionFormatter.java ファイルの表示

@@ -51,6 +51,7 @@ import org.openzen.zenscript.codemodel.expression.InterfaceCastExpression;
51 51
 import org.openzen.zenscript.codemodel.expression.IsExpression;
52 52
 import org.openzen.zenscript.codemodel.expression.MakeConstExpression;
53 53
 import org.openzen.zenscript.codemodel.expression.MapExpression;
54
+import org.openzen.zenscript.codemodel.expression.MatchExpression;
54 55
 import org.openzen.zenscript.codemodel.expression.NewExpression;
55 56
 import org.openzen.zenscript.codemodel.expression.NullExpression;
56 57
 import org.openzen.zenscript.codemodel.expression.OrOrExpression;
@@ -505,6 +506,16 @@ public class ExpressionFormatter implements ExpressionVisitor<ExpressionString>
505 506
 		result.append("}");
506 507
 		return new ExpressionString(result.toString(), OperatorPriority.PRIMARY);
507 508
 	}
509
+	
510
+	@Override
511
+	public ExpressionString visitMatch(MatchExpression expression) {
512
+		StringBuilder result = new StringBuilder();
513
+		result.append("match ");
514
+		result.append(expression.value.accept(this));
515
+		result.append(" {\n");
516
+		
517
+		throw new UnsupportedOperationException();
518
+	}
508 519
 
509 520
 	@Override
510 521
 	public ExpressionString visitNew(NewExpression expression) {

+ 9
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/FunctionHeader.java ファイルの表示

@@ -34,6 +34,15 @@ public class FunctionHeader {
34 34
 		this.parameters = NO_PARAMETERS;
35 35
 	}
36 36
 	
37
+	public FunctionHeader(ITypeID returnType, ITypeID... parameterTypes) {
38
+		this.typeParameters = null;
39
+		this.returnType = returnType;
40
+		this.parameters = new FunctionParameter[parameterTypes.length];
41
+		
42
+		for (int i = 0; i < parameterTypes.length; i++)
43
+			parameters[i] = new FunctionParameter(parameterTypes[i], null);
44
+	}
45
+	
37 46
 	public FunctionHeader(ITypeID returnType, FunctionParameter... parameters) {
38 47
 		this.typeParameters = null;
39 48
 		this.returnType = returnType;

+ 2
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/FunctionParameter.java ファイルの表示

@@ -18,6 +18,8 @@ import org.openzen.zenscript.shared.Taggable;
18 18
  * @author Hoofdgebruiker
19 19
  */
20 20
 public class FunctionParameter extends Taggable {
21
+	public static final FunctionParameter[] NONE = new FunctionParameter[0];
22
+	
21 23
 	public final ITypeID type;
22 24
 	public final String name;
23 25
 	public final Expression defaultValue;

+ 2
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/definition/DefinitionVisitor.java ファイルの表示

@@ -23,4 +23,6 @@ public interface DefinitionVisitor<T> {
23 23
 	public T visitExpansion(ExpansionDefinition definition);
24 24
 	
25 25
 	public T visitAlias(AliasDefinition definition);
26
+	
27
+	public T visitVariant(VariantDefinition variant);
26 28
 }

+ 2
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/definition/FunctionDefinition.java ファイルの表示

@@ -37,6 +37,8 @@ public class FunctionDefinition extends HighLevelDefinition {
37 37
 	
38 38
 	public void setHeader(FunctionHeader header) {
39 39
 		this.header = header;
40
+		this.genericParameters = header.typeParameters;
41
+		header = new FunctionHeader(null, header.returnType, header.parameters);
40 42
 		addMember(caller = new OperatorMember(position, this, modifiers | Modifiers.STATIC, OperatorType.CALL, header));
41 43
 		callerGroup.addMethod(caller, TypeMemberPriority.SPECIFIED);
42 44
 	}

+ 50
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/definition/VariantDefinition.java ファイルの表示

@@ -0,0 +1,50 @@
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.definition;
7
+
8
+import java.util.ArrayList;
9
+import java.util.List;
10
+import java.util.Map;
11
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
12
+import org.openzen.zenscript.codemodel.generic.TypeParameter;
13
+import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
14
+import org.openzen.zenscript.codemodel.type.ITypeID;
15
+import org.openzen.zenscript.shared.CodePosition;
16
+
17
+/**
18
+ *
19
+ * @author Hoofdgebruiker
20
+ */
21
+public class VariantDefinition extends HighLevelDefinition {
22
+	public final List<Option> options = new ArrayList<>();
23
+	
24
+	public VariantDefinition(CodePosition position, ZSPackage pkg, String name, int modifiers, HighLevelDefinition outerDefinition) {
25
+		super(position, pkg, name, modifiers, outerDefinition);
26
+	}
27
+
28
+	@Override
29
+	public <T> T accept(DefinitionVisitor<T> visitor) {
30
+		return visitor.visitVariant(this);
31
+	}
32
+	
33
+	public static class Option {
34
+		public final String name;
35
+		public final ITypeID[] types;
36
+		
37
+		public Option(String name, ITypeID[] types) {
38
+			this.name = name;
39
+			this.types = types;
40
+		}
41
+		
42
+		public Option instance(GlobalTypeRegistry registry, Map<TypeParameter, ITypeID> mapping) {
43
+			ITypeID[] newTypes = new ITypeID[types.length];
44
+			for (int i = 0; i < types.length; i++)
45
+				newTypes[i] = types[i].withGenericArguments(registry, mapping);
46
+			
47
+			return new Option(name, newTypes);
48
+		}
49
+	}
50
+}

+ 2
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/ExpressionVisitor.java ファイルの表示

@@ -96,6 +96,8 @@ public interface ExpressionVisitor<T> {
96 96
 	
97 97
 	public T visitMap(MapExpression expression);
98 98
 	
99
+	public T visitMatch(MatchExpression expression);
100
+	
99 101
 	public T visitNew(NewExpression expression);
100 102
 	
101 103
 	public T visitNull(NullExpression expression);

+ 41
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/MatchExpression.java ファイルの表示

@@ -0,0 +1,41 @@
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.zenscript.codemodel.expression.switchvalue.SwitchValue;
9
+import org.openzen.zenscript.codemodel.type.ITypeID;
10
+import org.openzen.zenscript.shared.CodePosition;
11
+
12
+/**
13
+ *
14
+ * @author Hoofdgebruiker
15
+ */
16
+public class MatchExpression extends Expression {
17
+	public final Expression value;
18
+	public final Case[] cases;
19
+	
20
+	public MatchExpression(CodePosition position, Expression value, ITypeID type, Case[] cases) {
21
+		super(position, type);
22
+		
23
+		this.value = value;
24
+		this.cases = cases;
25
+	}
26
+
27
+	@Override
28
+	public <T> T accept(ExpressionVisitor<T> visitor) {
29
+		return visitor.visitMatch(this);
30
+	}
31
+	
32
+	public static class Case {
33
+		public final SwitchValue key;
34
+		public final FunctionExpression value;
35
+		
36
+		public Case(SwitchValue key, FunctionExpression value) {
37
+			this.key = key;
38
+			this.value = value;
39
+		}
40
+	}
41
+}

+ 43
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/VariantValueExpression.java ファイルの表示

@@ -0,0 +1,43 @@
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 java.util.List;
9
+import org.openzen.zenscript.codemodel.OperatorType;
10
+import org.openzen.zenscript.codemodel.definition.VariantDefinition;
11
+import org.openzen.zenscript.codemodel.scope.TypeScope;
12
+import org.openzen.zenscript.codemodel.type.ITypeID;
13
+import org.openzen.zenscript.shared.CodePosition;
14
+
15
+/**
16
+ *
17
+ * @author Hoofdgebruiker
18
+ */
19
+public class VariantValueExpression extends Expression {
20
+	public final VariantDefinition.Option option;
21
+	public final Expression[] arguments;
22
+	
23
+	public VariantValueExpression(CodePosition position, ITypeID variantType, VariantDefinition.Option option) {
24
+		this(position, variantType, option, null);
25
+	}
26
+	
27
+	public VariantValueExpression(CodePosition position, ITypeID variantType, VariantDefinition.Option option, Expression[] arguments) {
28
+		super(position, variantType);
29
+		
30
+		this.option = option;
31
+		this.arguments = null;
32
+	}
33
+	
34
+	@Override
35
+	public Expression call(CodePosition position, TypeScope scope, List<ITypeID> hints, CallArguments arguments) {
36
+		return new VariantValueExpression(position, type, option, arguments.arguments);
37
+	}
38
+
39
+	@Override
40
+	public <T> T accept(ExpressionVisitor<T> visitor) {
41
+		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
42
+	}
43
+}

+ 23
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/switchvalue/CharSwitchValue.java ファイルの表示

@@ -0,0 +1,23 @@
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.switchvalue;
7
+
8
+/**
9
+ *
10
+ * @author Hoofdgebruiker
11
+ */
12
+public class CharSwitchValue implements SwitchValue {
13
+	public final char value;
14
+	
15
+	public CharSwitchValue(char value) {
16
+		this.value = value;
17
+	}
18
+
19
+	@Override
20
+	public <T> T accept(SwitchValueVisitor<T> visitor) {
21
+		return visitor.acceptChar(this);
22
+	}
23
+}

+ 25
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/switchvalue/EnumConstantSwitchValue.java ファイルの表示

@@ -0,0 +1,25 @@
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.switchvalue;
7
+
8
+import org.openzen.zenscript.codemodel.member.EnumConstantMember;
9
+
10
+/**
11
+ *
12
+ * @author Hoofdgebruiker
13
+ */
14
+public class EnumConstantSwitchValue implements SwitchValue {
15
+	public final EnumConstantMember constant;
16
+	
17
+	public EnumConstantSwitchValue(EnumConstantMember constant) {
18
+		this.constant = constant;
19
+	}
20
+
21
+	@Override
22
+	public <T> T accept(SwitchValueVisitor<T> visitor) {
23
+		return visitor.acceptEnumConstant(this);
24
+	}
25
+}

+ 23
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/switchvalue/IntSwitchValue.java ファイルの表示

@@ -0,0 +1,23 @@
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.switchvalue;
7
+
8
+/**
9
+ *
10
+ * @author Hoofdgebruiker
11
+ */
12
+public class IntSwitchValue implements SwitchValue {
13
+	public final int value;
14
+	
15
+	public IntSwitchValue(int value) {
16
+		this.value = value;
17
+	}
18
+
19
+	@Override
20
+	public <T> T accept(SwitchValueVisitor<T> visitor) {
21
+		return visitor.acceptInt(this);
22
+	}
23
+}

+ 23
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/switchvalue/StringSwitchValue.java ファイルの表示

@@ -0,0 +1,23 @@
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.switchvalue;
7
+
8
+/**
9
+ *
10
+ * @author Hoofdgebruiker
11
+ */
12
+public class StringSwitchValue implements SwitchValue {
13
+	public final String value;
14
+	
15
+	public StringSwitchValue(String value) {
16
+		this.value = value;
17
+	}
18
+
19
+	@Override
20
+	public <T> T accept(SwitchValueVisitor<T> visitor) {
21
+		return visitor.acceptString(this);
22
+	}
23
+}

+ 14
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/switchvalue/SwitchValue.java ファイルの表示

@@ -0,0 +1,14 @@
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.switchvalue;
7
+
8
+/**
9
+ *
10
+ * @author Hoofdgebruiker
11
+ */
12
+public interface SwitchValue {
13
+	public <T> T accept(SwitchValueVisitor<T> visitor);
14
+}

+ 22
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/switchvalue/SwitchValueVisitor.java ファイルの表示

@@ -0,0 +1,22 @@
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.switchvalue;
7
+
8
+/**
9
+ *
10
+ * @author Hoofdgebruiker
11
+ */
12
+public interface SwitchValueVisitor <T> {
13
+	public T acceptInt(IntSwitchValue value);
14
+	
15
+	public T acceptChar(CharSwitchValue value);
16
+	
17
+	public T acceptString(StringSwitchValue value);
18
+	
19
+	public T acceptEnumConstant(EnumConstantSwitchValue value);
20
+	
21
+	public T acceptVariantOption(VariantOptionSwitchValue value);
22
+}

+ 27
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/switchvalue/VariantOptionSwitchValue.java ファイルの表示

@@ -0,0 +1,27 @@
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.switchvalue;
7
+
8
+import org.openzen.zenscript.codemodel.definition.VariantDefinition;
9
+
10
+/**
11
+ *
12
+ * @author Hoofdgebruiker
13
+ */
14
+public class VariantOptionSwitchValue implements SwitchValue {
15
+	public final VariantDefinition.Option option;
16
+	public final String[] parameters;
17
+	
18
+	public VariantOptionSwitchValue(VariantDefinition.Option option, String[] parameters) {
19
+		this.option = option;
20
+		this.parameters = parameters;
21
+	}
22
+	
23
+	@Override
24
+	public <T> T accept(SwitchValueVisitor<T> visitor) {
25
+		return visitor.acceptVariantOption(this);
26
+	}
27
+}

+ 6
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/partial/PartialTypeExpression.java ファイルの表示

@@ -13,6 +13,7 @@ import org.openzen.zenscript.codemodel.FunctionHeader;
13 13
 import org.openzen.zenscript.codemodel.OperatorType;
14 14
 import org.openzen.zenscript.codemodel.expression.CallArguments;
15 15
 import org.openzen.zenscript.codemodel.expression.Expression;
16
+import org.openzen.zenscript.codemodel.expression.LambdaClosure;
16 17
 import org.openzen.zenscript.codemodel.type.GenericName;
17 18
 import org.openzen.zenscript.codemodel.type.ITypeID;
18 19
 import org.openzen.zenscript.shared.CodePosition;
@@ -65,4 +66,9 @@ public class PartialTypeExpression implements IPartialExpression {
65 66
 	public ITypeID[] getGenericCallTypes() {
66 67
 		return null;
67 68
 	}
69
+	
70
+	@Override
71
+	public IPartialExpression capture(CodePosition position, LambdaClosure closure) {
72
+		return this;
73
+	}
68 74
 }

+ 12
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/DefinitionTypeID.java ファイルの表示

@@ -11,6 +11,8 @@ import java.util.HashMap;
11 11
 import java.util.Map;
12 12
 import java.util.Objects;
13 13
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
14
+import org.openzen.zenscript.codemodel.definition.EnumDefinition;
15
+import org.openzen.zenscript.codemodel.definition.VariantDefinition;
14 16
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
15 17
 
16 18
 /**
@@ -139,6 +141,16 @@ public class DefinitionTypeID implements ITypeID {
139 141
 		return true;
140 142
 	}
141 143
 
144
+	@Override
145
+	public boolean isEnum() {
146
+		return definition instanceof EnumDefinition;
147
+	}
148
+	
149
+	@Override
150
+	public boolean isVariant() {
151
+		return definition instanceof VariantDefinition;
152
+	}
153
+	
142 154
 	@Override
143 155
 	public boolean hasInferenceBlockingTypeParameters(TypeParameter[] parameters) {
144 156
 		if (typeParameters != null) {

+ 8
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/ITypeID.java ファイルの表示

@@ -38,6 +38,14 @@ public interface ITypeID {
38 38
 	
39 39
 	public boolean isObjectType();
40 40
 	
41
+	public default boolean isEnum() {
42
+		return false;
43
+	}
44
+	
45
+	public default boolean isVariant() {
46
+		return false;
47
+	}
48
+	
41 49
 	public ITypeID withGenericArguments(GlobalTypeRegistry registry, Map<TypeParameter, ITypeID> arguments);
42 50
 	
43 51
 	public boolean hasInferenceBlockingTypeParameters(TypeParameter[] parameters);

+ 21
- 5
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/TypeMemberBuilder.java ファイルの表示

@@ -17,6 +17,7 @@ import org.openzen.zenscript.codemodel.definition.ClassDefinition;
17 17
 import org.openzen.zenscript.codemodel.definition.EnumDefinition;
18 18
 import org.openzen.zenscript.codemodel.definition.FunctionDefinition;
19 19
 import org.openzen.zenscript.codemodel.definition.StructDefinition;
20
+import org.openzen.zenscript.codemodel.definition.VariantDefinition;
20 21
 import org.openzen.zenscript.codemodel.expression.CallTranslator;
21 22
 import org.openzen.zenscript.codemodel.expression.ConstantCharExpression;
22 23
 import org.openzen.zenscript.codemodel.expression.ConstantUIntExpression;
@@ -40,7 +41,6 @@ import org.openzen.zenscript.codemodel.member.builtin.ComparatorMember;
40 41
 import org.openzen.zenscript.codemodel.member.builtin.ConstantGetterMember;
41 42
 import org.openzen.zenscript.codemodel.member.builtin.RangeIterator;
42 43
 import org.openzen.zenscript.codemodel.member.builtin.StringCharIterator;
43
-import org.openzen.zenscript.codemodel.scope.TypeScope;
44 44
 import org.openzen.zenscript.codemodel.type.ArrayTypeID;
45 45
 import org.openzen.zenscript.codemodel.type.AssocTypeID;
46 46
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
@@ -228,9 +228,13 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
228 228
 		HighLevelDefinition definition = type.definition;
229 229
 		if (type.hasTypeParameters() || !type.outerTypeParameters.isEmpty()) {
230 230
 			Map<TypeParameter, ITypeID> mapping = new HashMap<>();
231
-			if (type.typeParameters != null)
232
-				for (int i = 0; i < type.typeParameters.length; i++)
233
-					mapping.put(definition.genericParameters[i], type.typeParameters[i]);
231
+			if (type.typeParameters != null) {
232
+				if (definition.genericParameters == null)
233
+					System.out.println("Type parameters but no generic parameters");
234
+				else
235
+					for (int i = 0; i < type.typeParameters.length; i++)
236
+						mapping.put(definition.genericParameters[i], type.typeParameters[i]);
237
+			}
234 238
 			
235 239
 			if (!type.definition.isStatic())
236 240
 				for (Map.Entry<TypeParameter, ITypeID> entry : type.outerTypeParameters.entrySet())
@@ -239,10 +243,22 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
239 243
 			for (IDefinitionMember member : definition.members) {
240 244
 				member.instance(cache.getRegistry(), mapping).registerTo(members, TypeMemberPriority.SPECIFIED);
241 245
 			}
246
+			
247
+			if (definition instanceof VariantDefinition) {
248
+				VariantDefinition variant = (VariantDefinition) definition;
249
+				for (VariantDefinition.Option option : variant.options)
250
+					members.addVariantOption(option.instance(registry, mapping));
251
+			}
242 252
 		} else {
243 253
 			for (IDefinitionMember member : definition.members) {
244 254
 				member.registerTo(members, TypeMemberPriority.SPECIFIED);
245 255
 			}
256
+			
257
+			if (definition instanceof VariantDefinition) {
258
+				VariantDefinition variant = (VariantDefinition) definition;
259
+				for (VariantDefinition.Option option : variant.options)
260
+					members.addVariantOption(option);
261
+			}
246 262
 		}
247 263
 
248 264
 		DefinitionMemberGroup constructors = members.getOrCreateGroup(OperatorType.CONSTRUCTOR);
@@ -254,7 +270,7 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
254 270
 				// add default struct constructors
255 271
 				constructors.addMethod(new ConstructorMember(BUILTIN, definition, Modifiers.PUBLIC, new FunctionHeader(VOID)), TypeMemberPriority.SPECIFIED);
256 272
 				
257
-				List<FieldMember> fields = ((StructDefinition)definition).getFields();
273
+				List<FieldMember> fields = definition.getFields();
258 274
 				if (!fields.isEmpty()) {
259 275
 					FunctionParameter[] parameters = new FunctionParameter[fields.size()];
260 276
 					for (int i = 0; i < parameters.length; i++) {

+ 12
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/TypeMembers.java ファイルの表示

@@ -11,6 +11,7 @@ import java.util.List;
11 11
 import java.util.Map;
12 12
 import org.openzen.zenscript.codemodel.CompareType;
13 13
 import org.openzen.zenscript.codemodel.OperatorType;
14
+import org.openzen.zenscript.codemodel.definition.VariantDefinition;
14 15
 import org.openzen.zenscript.codemodel.expression.CallArguments;
15 16
 import org.openzen.zenscript.codemodel.expression.CallExpression;
16 17
 import org.openzen.zenscript.codemodel.expression.CheckNullExpression;
@@ -66,6 +67,7 @@ public final class TypeMembers {
66 67
 	private final List<TypeMember<IIteratorMember>> iterators = new ArrayList<>();
67 68
 	
68 69
 	private final Map<String, EnumConstantMember> enumMembers = new HashMap<>();
70
+	private final Map<String, VariantDefinition.Option> variantOptions = new HashMap<>();
69 71
 	private final Map<String, DefinitionMemberGroup> members = new HashMap<>();
70 72
 	private final Map<String, InnerDefinition> innerTypes = new HashMap<>();
71 73
 	private final Map<OperatorType, DefinitionMemberGroup> operators = new HashMap<>();
@@ -120,6 +122,8 @@ public final class TypeMembers {
120 122
 		
121 123
 		for (Map.Entry<String, EnumConstantMember> entry : enumMembers.entrySet())
122 124
 			other.addEnumMember(entry.getValue(), priority);
125
+		for (Map.Entry<String, VariantDefinition.Option> entry : variantOptions.entrySet())
126
+			other.addVariantOption(entry.getValue());
123 127
 		for (Map.Entry<String, DefinitionMemberGroup> entry : members.entrySet())
124 128
 			other.getOrCreateGroup(entry.getKey(), entry.getValue().isStatic).merge(position, entry.getValue(), priority);
125 129
 		for (Map.Entry<String, InnerDefinition> entry : innerTypes.entrySet())
@@ -221,6 +225,10 @@ public final class TypeMembers {
221 225
 		group.addMethod(member, priority);
222 226
 	}
223 227
 	
228
+	public void addVariantOption(VariantDefinition.Option option) {
229
+		variantOptions.put(option.name, option);
230
+	}
231
+	
224 232
 	public void addIterator(IIteratorMember iterator, TypeMemberPriority priority) {
225 233
 		for (int i = 0; i < iterators.size(); i++) {
226 234
 			if (iterators.get(i).member.getLoopVariableCount() == iterator.getLoopVariableCount()) {
@@ -272,6 +280,10 @@ public final class TypeMembers {
272 280
 		return enumMembers.get(name);
273 281
 	}
274 282
 	
283
+	public VariantDefinition.Option getVariantOption(String name) {
284
+		return variantOptions.get(name);
285
+	}
286
+	
275 287
 	public Expression compare(CodePosition position, TypeScope scope, CompareType operator, Expression left, Expression right) {
276 288
 		if (operator == CompareType.SAME) {
277 289
 			if (left.type.isObjectType() && right.type.isObjectType())

+ 2
- 1
Constructor/libraries/stdlib/module.json ファイルの表示

@@ -7,6 +7,7 @@
7 7
 		"Hashable": {"type": "Definition", "definition": "Hashable"},
8 8
 		"IllegalArgumentException": {"type": "Definition", "definition": "IllegalArgumentException"},
9 9
 		"StringBuilder": {"type": "Definition", "definition": "StringBuilder"},
10
-		"StringBuildable": {"type": "Definition", "definition": "StringBuildable"}
10
+		"StringBuildable": {"type": "Definition", "definition": "StringBuildable"},
11
+		"panic": {"type": "Definition", "definition": "panic"}
11 12
 	}
12 13
 }

+ 4
- 0
Constructor/libraries/stdlib/src/Panic.zs ファイルの表示

@@ -0,0 +1,4 @@
1
+// TODO: function overloading on global functions
2
+//extern function panic() as void;
3
+
4
+extern function panic<T>(message as string) as T;

+ 34
- 0
Constructor/libraries/stdlib/src/Result.zs ファイルの表示

@@ -0,0 +1,34 @@
1
+export variant Result<T, E> {
2
+	Success(T),
3
+	Failure(E);
4
+	
5
+	public then<R>(fn as function(result as T) as R) as Result<R, E> {
6
+		return match this {
7
+			Success(result) => Success(fn(result)),
8
+			Failure(error) => Failure(error)
9
+		};
10
+	}
11
+	
12
+	public handle<X>(handler as function(error as E) as Result<T, X>) as Result<T, X> {
13
+		return match this {
14
+			Success(result) => Success(result),
15
+			Failure(error) => handler(error)
16
+		};
17
+	}
18
+	
19
+	public expect() as T {
20
+		return match this {
21
+			Success(result) => result,
22
+			Failure(error) => panic<T>("demand with error value")
23
+		};
24
+	}
25
+}
26
+
27
+export expand <T, E : Exception> Result<T, E> {
28
+	public unwrap() as T {
29
+		return match this {
30
+			Success(result) => result,
31
+			Failure(error) => { throw error; }
32
+		};
33
+	}
34
+}

+ 5
- 0
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaExpressionVisitor.java ファイルの表示

@@ -403,6 +403,11 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
403 403
         }
404 404
         return null;
405 405
     }
406
+	
407
+	@Override
408
+	public Void visitMatch(MatchExpression expression) {
409
+		throw new UnsupportedOperationException();
410
+	}
406 411
 
407 412
     @Override
408 413
     public Void visitNew(NewExpression expression) {

+ 6
- 0
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaPreDecrementVisitor.java ファイルの表示

@@ -50,6 +50,7 @@ import org.openzen.zenscript.codemodel.expression.InterfaceCastExpression;
50 50
 import org.openzen.zenscript.codemodel.expression.IsExpression;
51 51
 import org.openzen.zenscript.codemodel.expression.MakeConstExpression;
52 52
 import org.openzen.zenscript.codemodel.expression.MapExpression;
53
+import org.openzen.zenscript.codemodel.expression.MatchExpression;
53 54
 import org.openzen.zenscript.codemodel.expression.NewExpression;
54 55
 import org.openzen.zenscript.codemodel.expression.NullExpression;
55 56
 import org.openzen.zenscript.codemodel.expression.OrOrExpression;
@@ -325,6 +326,11 @@ public class JavaPreDecrementVisitor implements ExpressionVisitor<Void> {
325 326
 		throw new UnsupportedOperationException("Invalid increment target");
326 327
 	}
327 328
 
329
+	@Override
330
+	public Void visitMatch(MatchExpression expression) {
331
+		throw new UnsupportedOperationException("Invalid increment target");
332
+	}
333
+
328 334
 	@Override
329 335
 	public Void visitNew(NewExpression expression) {
330 336
 		throw new UnsupportedOperationException("Invalid increment target");

+ 6
- 0
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaPreIncrementVisitor.java ファイルの表示

@@ -50,6 +50,7 @@ import org.openzen.zenscript.codemodel.expression.InterfaceCastExpression;
50 50
 import org.openzen.zenscript.codemodel.expression.IsExpression;
51 51
 import org.openzen.zenscript.codemodel.expression.MakeConstExpression;
52 52
 import org.openzen.zenscript.codemodel.expression.MapExpression;
53
+import org.openzen.zenscript.codemodel.expression.MatchExpression;
53 54
 import org.openzen.zenscript.codemodel.expression.NewExpression;
54 55
 import org.openzen.zenscript.codemodel.expression.NullExpression;
55 56
 import org.openzen.zenscript.codemodel.expression.OrOrExpression;
@@ -331,6 +332,11 @@ public class JavaPreIncrementVisitor implements ExpressionVisitor<Void> {
331 332
 		throw new UnsupportedOperationException("Invalid increment target");
332 333
 	}
333 334
 
335
+	@Override
336
+	public Void visitMatch(MatchExpression expression) {
337
+		throw new UnsupportedOperationException("Invalid increment target");
338
+	}
339
+
334 340
 	@Override
335 341
 	public Void visitNew(NewExpression expression) {
336 342
 		throw new UnsupportedOperationException("Invalid increment target");

+ 5
- 3
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/definitions/JavaDefinitionVisitor.java ファイルの表示

@@ -1,12 +1,9 @@
1 1
 package org.openzen.zenscript.javabytecode.compiler.definitions;
2 2
 
3
-import java.util.List;
4 3
 import org.objectweb.asm.ClassWriter;
5 4
 import org.objectweb.asm.Opcodes;
6 5
 import org.objectweb.asm.Type;
7 6
 import org.openzen.zenscript.codemodel.definition.*;
8
-import org.openzen.zenscript.codemodel.expression.Expression;
9
-import org.openzen.zenscript.codemodel.member.EnumConstantMember;
10 7
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
11 8
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
12 9
 import org.openzen.zenscript.codemodel.type.ITypeID;
@@ -177,4 +174,9 @@ public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
177 174
     public byte[] visitAlias(AliasDefinition definition) {
178 175
         return null;
179 176
     }
177
+
178
+	@Override
179
+	public byte[] visitVariant(VariantDefinition variant) {
180
+		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
181
+	}
180 182
 }

+ 13
- 6
Linker/src/main/java/org/openzen/zenscript/linker/DefinitionScope.java ファイルの表示

@@ -39,6 +39,10 @@ public class DefinitionScope extends BaseScope {
39 39
 	private final Map<String, TypeParameter> genericParameters = new HashMap<>();
40 40
 	
41 41
 	public DefinitionScope(BaseScope outer, HighLevelDefinition definition) {
42
+		this(outer, definition, true);
43
+	}
44
+	
45
+	public DefinitionScope(BaseScope outer, HighLevelDefinition definition, boolean withMembers) {
42 46
 		this.outer = outer;
43 47
 		this.definition = definition;
44 48
 		
@@ -58,7 +62,8 @@ public class DefinitionScope extends BaseScope {
58 62
 		} else {
59 63
 			type = outer.getTypeRegistry().getForDefinition(definition, genericParameterList);
60 64
 		}
61
-		members = outer.getMemberCache().get(type);
65
+		
66
+		members = withMembers ? outer.getMemberCache().get(type) : null;
62 67
 	}
63 68
 	
64 69
 	@Override
@@ -68,10 +73,12 @@ public class DefinitionScope extends BaseScope {
68 73
 
69 74
 	@Override
70 75
 	public IPartialExpression get(CodePosition position, GenericName name) {
71
-		if (members.hasInnerType(name.name))
72
-			return new PartialTypeExpression(position, members.getInnerType(position, name));
73
-		if (members.hasMember(name.name) && !name.hasArguments())
74
-			return members.getMemberExpression(position, new ThisExpression(position, type), name, true);
76
+		if (members != null) {
77
+			if (members.hasInnerType(name.name))
78
+				return new PartialTypeExpression(position, members.getInnerType(position, name));
79
+			if (members.hasMember(name.name) && !name.hasArguments())
80
+				return members.getMemberExpression(position, new ThisExpression(position, type), name, true);
81
+		}
75 82
 		if (genericParameters.containsKey(name.name) && !name.hasArguments())
76 83
 			return new PartialTypeExpression(position, getTypeRegistry().getGeneric(genericParameters.get(name.name)));
77 84
 		
@@ -80,7 +87,7 @@ public class DefinitionScope extends BaseScope {
80 87
 
81 88
 	@Override
82 89
 	public ITypeID getType(CodePosition position, List<GenericName> name) {
83
-		if (members.hasInnerType(name.get(0).name)) {
90
+		if (members != null && members.hasInnerType(name.get(0).name)) {
84 91
 			ITypeID result = members.getInnerType(position, name.get(0));
85 92
 			for (int i = 1; i < name.size(); i++) {
86 93
 				result = getTypeMembers(result).getInnerType(position, name.get(i));

+ 2
- 0
Parser/src/main/java/org/openzen/zenscript/lexer/ZSTokenStream.java ファイルの表示

@@ -32,6 +32,7 @@ public class ZSTokenStream extends TokenStream<ZSToken, ZSTokenType> {
32 32
 		KEYWORDS.put("struct", K_STRUCT);
33 33
 		KEYWORDS.put("expand", K_EXPAND);
34 34
 		KEYWORDS.put("function", K_FUNCTION);
35
+		KEYWORDS.put("variant", K_VARIANT);
35 36
 		
36 37
 		KEYWORDS.put("abstract", K_ABSTRACT);
37 38
 		KEYWORDS.put("final", K_FINAL);
@@ -88,6 +89,7 @@ public class ZSTokenStream extends TokenStream<ZSToken, ZSTokenType> {
88 89
 		KEYWORDS.put("in", K_IN);
89 90
 		KEYWORDS.put("is", K_IS);
90 91
 		KEYWORDS.put("as", K_AS);
92
+		KEYWORDS.put("match", K_MATCH);
91 93
 		
92 94
 		KEYWORDS.put("this", K_THIS);
93 95
 		KEYWORDS.put("super", K_SUPER);

+ 2
- 0
Parser/src/main/java/org/openzen/zenscript/lexer/ZSTokenType.java ファイルの表示

@@ -82,6 +82,7 @@ public enum ZSTokenType implements TokenType {
82 82
 	K_ENUM,
83 83
 	K_STRUCT,
84 84
 	K_EXPAND,
85
+	K_VARIANT,
85 86
 	
86 87
 	K_ABSTRACT,
87 88
 	K_FINAL,
@@ -138,6 +139,7 @@ public enum ZSTokenType implements TokenType {
138 139
 	K_IN,
139 140
 	K_IS,
140 141
 	K_AS,
142
+	K_MATCH,
141 143
 	
142 144
 	K_SUPER,
143 145
 	K_THIS,

+ 4
- 7
Parser/src/main/java/org/openzen/zenscript/parser/ParsedDefinition.java ファイルの表示

@@ -9,13 +9,7 @@ import org.openzen.zenscript.codemodel.HighLevelDefinition;
9 9
 import org.openzen.zenscript.codemodel.definition.ZSPackage;
10 10
 import org.openzen.zenscript.shared.CodePosition;
11 11
 import org.openzen.zenscript.lexer.ZSTokenStream;
12
-import static org.openzen.zenscript.lexer.ZSTokenType.K_ALIAS;
13
-import static org.openzen.zenscript.lexer.ZSTokenType.K_CLASS;
14
-import static org.openzen.zenscript.lexer.ZSTokenType.K_ENUM;
15
-import static org.openzen.zenscript.lexer.ZSTokenType.K_EXPAND;
16
-import static org.openzen.zenscript.lexer.ZSTokenType.K_FUNCTION;
17
-import static org.openzen.zenscript.lexer.ZSTokenType.K_INTERFACE;
18
-import static org.openzen.zenscript.lexer.ZSTokenType.K_STRUCT;
12
+import static org.openzen.zenscript.lexer.ZSTokenType.*;
19 13
 import org.openzen.zenscript.linker.BaseScope;
20 14
 import org.openzen.zenscript.parser.definitions.ParsedAlias;
21 15
 import org.openzen.zenscript.parser.definitions.ParsedClass;
@@ -24,6 +18,7 @@ import org.openzen.zenscript.parser.definitions.ParsedExpansion;
24 18
 import org.openzen.zenscript.parser.definitions.ParsedFunction;
25 19
 import org.openzen.zenscript.parser.definitions.ParsedInterface;
26 20
 import org.openzen.zenscript.parser.definitions.ParsedStruct;
21
+import org.openzen.zenscript.parser.definitions.ParsedVariant;
27 22
 
28 23
 /**
29 24
  *
@@ -45,6 +40,8 @@ public abstract class ParsedDefinition {
45 40
 			return ParsedFunction.parseFunction(pkg, position, modifiers, tokens, outerDefinition);
46 41
 		} else if (tokens.optional(K_EXPAND) != null) {
47 42
 			return ParsedExpansion.parseExpansion(pkg, position, modifiers, tokens, outerDefinition);
43
+		} else if (tokens.optional(K_VARIANT) != null) {
44
+			return ParsedVariant.parseVariant(pkg, position, modifiers, tokens, outerDefinition);
48 45
 		} else {
49 46
 			//tokens.required(EOF, "An import, class, interface, enum, struct, function or alias expected.");
50 47
 			return null;

+ 3
- 0
Parser/src/main/java/org/openzen/zenscript/parser/ParsedFile.java ファイルの表示

@@ -76,6 +76,9 @@ public class ParsedFile {
76 76
 					case K_EXPORT:
77 77
 						modifiers |= Modifiers.EXPORT;
78 78
 						break;
79
+					case K_EXTERN:
80
+						modifiers |= Modifiers.EXTERN;
81
+						break;
79 82
 					case K_ABSTRACT:
80 83
 						modifiers |= Modifiers.ABSTRACT;
81 84
 						break;

+ 0
- 1
Parser/src/main/java/org/openzen/zenscript/parser/definitions/ParsedExpansion.java ファイルの表示

@@ -12,7 +12,6 @@ import org.openzen.zenscript.codemodel.definition.ZSPackage;
12 12
 import org.openzen.zenscript.lexer.ZSTokenStream;
13 13
 import org.openzen.zenscript.lexer.ZSTokenType;
14 14
 import org.openzen.zenscript.linker.BaseScope;
15
-import org.openzen.zenscript.linker.DefinitionScope;
16 15
 import org.openzen.zenscript.linker.GenericFunctionScope;
17 16
 import org.openzen.zenscript.parser.member.ParsedDefinitionMember;
18 17
 import org.openzen.zenscript.parser.type.IParsedType;

+ 6
- 4
Parser/src/main/java/org/openzen/zenscript/parser/definitions/ParsedInterface.java ファイルの表示

@@ -43,19 +43,19 @@ public class ParsedInterface extends BaseParsedDefinition {
43 43
 		return result;
44 44
 	}
45 45
 	
46
-	private final List<ParsedGenericParameter> genericParameters;
46
+	private final List<ParsedGenericParameter> typeParameters;
47 47
 	private final List<IParsedType> superInterfaces;
48 48
 	
49 49
 	private final InterfaceDefinition compiled;
50 50
 	
51
-	public ParsedInterface(ZSPackage pkg, CodePosition position, int modifiers, String name, List<ParsedGenericParameter> genericParameters, List<IParsedType> superInterfaces, HighLevelDefinition outerDefinition) {
51
+	public ParsedInterface(ZSPackage pkg, CodePosition position, int modifiers, String name, List<ParsedGenericParameter> typeParameters, List<IParsedType> superInterfaces, HighLevelDefinition outerDefinition) {
52 52
 		super(position, modifiers);
53 53
 		
54
-		this.genericParameters = genericParameters;
54
+		this.typeParameters = typeParameters;
55 55
 		this.superInterfaces = superInterfaces;
56 56
 		
57 57
 		compiled = new InterfaceDefinition(position, pkg, name, modifiers, outerDefinition);
58
-		compiled.setTypeParameters(ParsedGenericParameter.getCompiled(genericParameters));
58
+		compiled.setTypeParameters(ParsedGenericParameter.getCompiled(typeParameters));
59 59
 	}
60 60
 
61 61
 	@Override
@@ -65,6 +65,8 @@ public class ParsedInterface extends BaseParsedDefinition {
65 65
 
66 66
 	@Override
67 67
 	public void compileMembers(BaseScope scope) {
68
+		ParsedGenericParameter.compile(scope, compiled.genericParameters, typeParameters);
69
+		
68 70
 		for (IParsedType superInterface : superInterfaces)
69 71
 			compiled.addBaseInterface(superInterface.compile(scope));
70 72
 		

+ 94
- 0
Parser/src/main/java/org/openzen/zenscript/parser/definitions/ParsedVariant.java ファイルの表示

@@ -0,0 +1,94 @@
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.parser.definitions;
7
+
8
+import java.util.ArrayList;
9
+import java.util.List;
10
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
11
+import org.openzen.zenscript.codemodel.definition.VariantDefinition;
12
+import org.openzen.zenscript.codemodel.definition.ZSPackage;
13
+import org.openzen.zenscript.codemodel.scope.TypeScope;
14
+import org.openzen.zenscript.lexer.ZSTokenStream;
15
+import org.openzen.zenscript.lexer.ZSTokenType;
16
+import org.openzen.zenscript.linker.BaseScope;
17
+import org.openzen.zenscript.linker.DefinitionScope;
18
+import org.openzen.zenscript.parser.member.ParsedDefinitionMember;
19
+import org.openzen.zenscript.parser.type.IParsedType;
20
+import org.openzen.zenscript.shared.CodePosition;
21
+
22
+/**
23
+ *
24
+ * @author Hoofdgebruiker
25
+ */
26
+public class ParsedVariant extends BaseParsedDefinition {
27
+	public static ParsedVariant parseVariant(ZSPackage pkg, CodePosition position, int modifiers, ZSTokenStream tokens, HighLevelDefinition outerDefinition) {
28
+		String name = tokens.required(ZSTokenType.T_IDENTIFIER, "identifier expected").content;
29
+		List<ParsedGenericParameter> typeParameters = ParsedGenericParameter.parseAll(tokens);
30
+		tokens.required(ZSTokenType.T_AOPEN, "{ expected");
31
+		
32
+		ParsedVariant result = new ParsedVariant(pkg, position, modifiers, name, typeParameters, outerDefinition);
33
+		
34
+		while (!tokens.isNext(ZSTokenType.T_ACLOSE) && !tokens.isNext(ZSTokenType.T_SEMICOLON)) {
35
+			String optionName = tokens.required(ZSTokenType.T_IDENTIFIER, "identifier expected").content;
36
+			List<IParsedType> types = new ArrayList<>();
37
+			if (tokens.optional(ZSTokenType.T_BROPEN) != null) {
38
+				types.add(IParsedType.parse(tokens));
39
+				while (tokens.optional(ZSTokenType.T_COMMA) != null) {
40
+					types.add(IParsedType.parse(tokens));
41
+				}
42
+				tokens.required(ZSTokenType.T_BRCLOSE, ") expected");
43
+			}
44
+			result.addVariant(new ParsedVariantOption(optionName, types));
45
+			if (tokens.optional(ZSTokenType.T_COMMA) == null)
46
+				break;
47
+		}
48
+		
49
+		if (tokens.optional(ZSTokenType.T_SEMICOLON) != null) {
50
+			while (tokens.optional(ZSTokenType.T_ACLOSE) == null) {
51
+				result.addMember(ParsedDefinitionMember.parse(tokens, result.compiled));
52
+			}
53
+		} else {
54
+			tokens.required(ZSTokenType.T_ACLOSE, "} expected");
55
+		}
56
+		return result;
57
+	}
58
+	
59
+	private final List<ParsedGenericParameter> typeParameters;
60
+	private final List<ParsedVariantOption> variants = new ArrayList<>();
61
+	
62
+	private final VariantDefinition compiled;
63
+	
64
+	public ParsedVariant(ZSPackage pkg, CodePosition position, int modifiers, String name, List<ParsedGenericParameter> typeParameters, HighLevelDefinition outerDefinition) {
65
+		super(position, modifiers);
66
+		
67
+		this.typeParameters = typeParameters;
68
+		compiled = new VariantDefinition(position, pkg, name, modifiers, outerDefinition);
69
+		compiled.setTypeParameters(ParsedGenericParameter.getCompiled(typeParameters));
70
+	}
71
+	
72
+	public void addVariant(ParsedVariantOption value) {
73
+		variants.add(value);
74
+	}
75
+
76
+	@Override
77
+	public HighLevelDefinition getCompiled() {
78
+		return compiled;
79
+	}
80
+	
81
+	@Override
82
+	public void compileTypes(BaseScope scope) {
83
+		DefinitionScope innerScope = new DefinitionScope(scope, getCompiled(), false);
84
+		for (ParsedVariantOption variant : variants) {
85
+			compiled.options.add(variant.compile(innerScope));
86
+		}
87
+	}
88
+	
89
+	@Override
90
+	public void compileMembers(BaseScope scope) {
91
+		ParsedGenericParameter.compile(scope, compiled.genericParameters, typeParameters);
92
+		super.compileMembers(scope);
93
+	}
94
+}

+ 34
- 0
Parser/src/main/java/org/openzen/zenscript/parser/definitions/ParsedVariantOption.java ファイルの表示

@@ -0,0 +1,34 @@
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.parser.definitions;
7
+
8
+import java.util.List;
9
+import org.openzen.zenscript.codemodel.definition.VariantDefinition;
10
+import org.openzen.zenscript.codemodel.type.ITypeID;
11
+import org.openzen.zenscript.linker.BaseScope;
12
+import org.openzen.zenscript.parser.type.IParsedType;
13
+
14
+/**
15
+ *
16
+ * @author Hoofdgebruiker
17
+ */
18
+public class ParsedVariantOption {
19
+	public final String name;
20
+	public final List<IParsedType> types;
21
+	
22
+	public ParsedVariantOption(String name, List<IParsedType> types) {
23
+		this.name = name;
24
+		this.types = types;
25
+	}
26
+	
27
+	public VariantDefinition.Option compile(BaseScope scope) {
28
+		ITypeID[] cTypes = new ITypeID[types.size()];
29
+		for (int i = 0; i < cTypes.length; i++)
30
+			cTypes[i] = types.get(i).compile(scope);
31
+		
32
+		return new VariantDefinition.Option(name, cTypes);
33
+	}
34
+}

+ 37
- 0
Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedCallArguments.java ファイルの表示

@@ -132,6 +132,43 @@ public class ParsedCallArguments {
132 132
 		return new CallArguments(typeParameters, cArguments);
133 133
 	}
134 134
 	
135
+	
136
+	public CallArguments compileCall(
137
+			CodePosition position,
138
+			ExpressionScope scope,
139
+			ITypeID[] genericParameters,
140
+			FunctionHeader function)
141
+	{
142
+		ExpressionScope innerScope = scope.forCall(function);
143
+		
144
+		List<ITypeID>[] predictedTypes = new List[arguments.size()];
145
+		for (int i = 0; i < predictedTypes.length; i++) {
146
+			predictedTypes[i] = new ArrayList<>();
147
+			predictedTypes[i].add(function.parameters[i].type);
148
+		}
149
+		
150
+		Expression[] cArguments = new Expression[arguments.size()];
151
+		for (int i = 0; i < cArguments.length; i++) {
152
+			IPartialExpression cArgument = arguments.get(i).compile(innerScope.withHints(predictedTypes[i]));
153
+			cArguments[i] = cArgument.eval();
154
+		}
155
+		
156
+		ITypeID[] typeParameters = genericParameters;
157
+		if (typeParameters == null) {
158
+			if (function.typeParameters != null) {
159
+				typeParameters = new ITypeID[function.typeParameters.length];
160
+				for (int i = 0; i < typeParameters.length; i++) {
161
+					if (innerScope.genericInferenceMap.get(function.typeParameters[i]) == null)
162
+						throw new CompileException(position, CompileExceptionCode.TYPE_ARGUMENTS_NOT_INFERRABLE, "Could not infer type parameter " + function.typeParameters[i].name);
163
+					else
164
+						typeParameters[i] = innerScope.genericInferenceMap.get(function.typeParameters[i]);
165
+				}
166
+			}
167
+		}
168
+		
169
+		return new CallArguments(typeParameters, cArguments);
170
+	}
171
+	
135 172
 	private CallArguments compileCallNaive(CodePosition position, ExpressionScope scope) {
136 173
 		Expression[] cArguments = new Expression[arguments.size()];
137 174
 		for (int i = 0; i < cArguments.length; i++) {

+ 120
- 80
Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpression.java ファイルの表示

@@ -16,6 +16,7 @@ import org.openzen.zenscript.lexer.ZSTokenType;
16 16
 import org.openzen.zenscript.codemodel.CompareType;
17 17
 import org.openzen.zenscript.codemodel.OperatorType;
18 18
 import org.openzen.zenscript.codemodel.expression.Expression;
19
+import org.openzen.zenscript.codemodel.expression.switchvalue.SwitchValue;
19 20
 import org.openzen.zenscript.codemodel.partial.IPartialExpression;
20 21
 import org.openzen.zenscript.codemodel.type.ITypeID;
21 22
 import org.openzen.zenscript.lexer.ZSToken;
@@ -36,175 +37,189 @@ import static org.openzen.zenscript.shared.StringUtils.unescape;
36 37
  * @author Stanneke
37 38
  */
38 39
 public abstract class ParsedExpression {
40
+	public static class ParsingOptions {
41
+		public static final ParsingOptions DEFAULT = new ParsingOptions(true);
42
+		
43
+		public final boolean allowLambda;
44
+		
45
+		public ParsingOptions(boolean allowLambda) {
46
+			this.allowLambda = allowLambda;
47
+		}
48
+	}
49
+	
39 50
 	public static ParsedExpression parse(ZSTokenStream parser) {
40
-		return readAssignExpression(parser);
51
+		return readAssignExpression(parser, ParsingOptions.DEFAULT);
52
+	}
53
+	
54
+	public static ParsedExpression parse(ZSTokenStream parser, ParsingOptions options) {
55
+		return readAssignExpression(parser, options);
41 56
 	}
42 57
 
43
-	private static ParsedExpression readAssignExpression(ZSTokenStream parser) {
58
+	private static ParsedExpression readAssignExpression(ZSTokenStream parser, ParsingOptions options) {
44 59
 		CodePosition position = parser.getPosition();
45
-		ParsedExpression left = readConditionalExpression(position, parser);
60
+		ParsedExpression left = readConditionalExpression(position, parser, options);
46 61
 
47 62
 		switch (parser.peek().type) {
48 63
 			case T_ASSIGN:
49 64
 				parser.next();
50
-				return new ParsedExpressionAssign(position, left, readAssignExpression(parser));
65
+				return new ParsedExpressionAssign(position, left, readAssignExpression(parser, options));
51 66
 			case T_ADDASSIGN:
52 67
 				parser.next();
53
-				return new ParsedExpressionOpAssign(position, left, readAssignExpression(parser), OperatorType.ADDASSIGN);
68
+				return new ParsedExpressionOpAssign(position, left, readAssignExpression(parser, options), OperatorType.ADDASSIGN);
54 69
 			case T_SUBASSIGN:
55 70
 				parser.next();
56
-				return new ParsedExpressionOpAssign(position, left, readAssignExpression(parser), OperatorType.SUBASSIGN);
71
+				return new ParsedExpressionOpAssign(position, left, readAssignExpression(parser, options), OperatorType.SUBASSIGN);
57 72
 			case T_CATASSIGN:
58 73
 				parser.next();
59
-				return new ParsedExpressionOpAssign(position, left, readAssignExpression(parser), OperatorType.CATASSIGN);
74
+				return new ParsedExpressionOpAssign(position, left, readAssignExpression(parser, options), OperatorType.CATASSIGN);
60 75
 			case T_MULASSIGN:
61 76
 				parser.next();
62
-				return new ParsedExpressionOpAssign(position, left, readAssignExpression(parser), OperatorType.MULASSIGN);
77
+				return new ParsedExpressionOpAssign(position, left, readAssignExpression(parser, options), OperatorType.MULASSIGN);
63 78
 			case T_DIVASSIGN:
64 79
 				parser.next();
65
-				return new ParsedExpressionOpAssign(position, left, readAssignExpression(parser), OperatorType.DIVASSIGN);
80
+				return new ParsedExpressionOpAssign(position, left, readAssignExpression(parser, options), OperatorType.DIVASSIGN);
66 81
 			case T_MODASSIGN:
67 82
 				parser.next();
68
-				return new ParsedExpressionOpAssign(position, left, readAssignExpression(parser), OperatorType.MODASSIGN);
83
+				return new ParsedExpressionOpAssign(position, left, readAssignExpression(parser, options), OperatorType.MODASSIGN);
69 84
 			case T_ORASSIGN:
70 85
 				parser.next();
71
-				return new ParsedExpressionOpAssign(position, left, readAssignExpression(parser), OperatorType.ORASSIGN);
86
+				return new ParsedExpressionOpAssign(position, left, readAssignExpression(parser, options), OperatorType.ORASSIGN);
72 87
 			case T_ANDASSIGN:
73 88
 				parser.next();
74
-				return new ParsedExpressionOpAssign(position, left, readAssignExpression(parser), OperatorType.ANDASSIGN);
89
+				return new ParsedExpressionOpAssign(position, left, readAssignExpression(parser, options), OperatorType.ANDASSIGN);
75 90
 			case T_XORASSIGN:
76 91
 				parser.next();
77
-				return new ParsedExpressionOpAssign(position, left, readAssignExpression(parser), OperatorType.XORASSIGN);
92
+				return new ParsedExpressionOpAssign(position, left, readAssignExpression(parser, options), OperatorType.XORASSIGN);
78 93
 			case T_SHLASSIGN:
79 94
 				parser.next();
80
-				return new ParsedExpressionOpAssign(position, left, readAssignExpression(parser), OperatorType.SHLASSIGN);
95
+				return new ParsedExpressionOpAssign(position, left, readAssignExpression(parser, options), OperatorType.SHLASSIGN);
81 96
 			case T_SHRASSIGN:
82 97
 				parser.next();
83
-				return new ParsedExpressionOpAssign(position, left, readAssignExpression(parser), OperatorType.SHRASSIGN);
98
+				return new ParsedExpressionOpAssign(position, left, readAssignExpression(parser, options), OperatorType.SHRASSIGN);
84 99
 			case T_USHRASSIGN:
85 100
 				parser.next();
86
-				return new ParsedExpressionOpAssign(position, left, readAssignExpression(parser), OperatorType.USHRASSIGN);
101
+				return new ParsedExpressionOpAssign(position, left, readAssignExpression(parser, options), OperatorType.USHRASSIGN);
87 102
 		}
88 103
 
89 104
 		return left;
90 105
 	}
91 106
 
92
-	private static ParsedExpression readConditionalExpression(CodePosition position, ZSTokenStream parser) {
93
-		ParsedExpression left = readOrOrExpression(position, parser);
107
+	private static ParsedExpression readConditionalExpression(CodePosition position, ZSTokenStream parser, ParsingOptions options) {
108
+		ParsedExpression left = readOrOrExpression(position, parser, options);
94 109
 
95 110
 		if (parser.optional(T_QUEST) != null) {
96
-			ParsedExpression onIf = readOrOrExpression(parser.peek().position, parser);
111
+			ParsedExpression onIf = readOrOrExpression(parser.peek().position, parser, options);
97 112
 			parser.required(T_COLON, ": expected");
98
-			ParsedExpression onElse = readConditionalExpression(parser.peek().position, parser);
113
+			ParsedExpression onElse = readConditionalExpression(parser.peek().position, parser, options);
99 114
 			return new ParsedExpressionConditional(position, left, onIf, onElse);
100 115
 		}
101 116
 
102 117
 		return left;
103 118
 	}
104 119
 
105
-	private static ParsedExpression readOrOrExpression(CodePosition position, ZSTokenStream parser) {
106
-		ParsedExpression left = readAndAndExpression(position, parser);
120
+	private static ParsedExpression readOrOrExpression(CodePosition position, ZSTokenStream parser, ParsingOptions options) {
121
+		ParsedExpression left = readAndAndExpression(position, parser, options);
107 122
 
108 123
 		while (parser.optional(T_OROR) != null) {
109
-			ParsedExpression right = readAndAndExpression(parser.peek().position, parser);
124
+			ParsedExpression right = readAndAndExpression(parser.peek().position, parser, options);
110 125
 			left = new ParsedExpressionOrOr(position, left, right);
111 126
 		}
112 127
 		
113 128
 		while (parser.optional(T_COALESCE) != null) {
114
-			ParsedExpression right = readAndAndExpression(parser.peek().position, parser);
129
+			ParsedExpression right = readAndAndExpression(parser.peek().position, parser, options);
115 130
 			left = new ParsedExpressionCoalesce(position, left, right);
116 131
 		}
117 132
 		
118 133
 		return left;
119 134
 	}
120 135
 
121
-	private static ParsedExpression readAndAndExpression(CodePosition position, ZSTokenStream parser) {
122
-		ParsedExpression left = readOrExpression(position, parser);
136
+	private static ParsedExpression readAndAndExpression(CodePosition position, ZSTokenStream parser, ParsingOptions options) {
137
+		ParsedExpression left = readOrExpression(position, parser, options);
123 138
 
124 139
 		while (parser.optional(T_ANDAND) != null) {
125
-			ParsedExpression right = readOrExpression(parser.peek().position, parser);
140
+			ParsedExpression right = readOrExpression(parser.peek().position, parser, options);
126 141
 			left = new ParsedExpressionAndAnd(position, left, right);
127 142
 		}
128 143
 		return left;
129 144
 	}
130 145
 
131
-	private static ParsedExpression readOrExpression(CodePosition position, ZSTokenStream parser) {
132
-		ParsedExpression left = readXorExpression(position, parser);
146
+	private static ParsedExpression readOrExpression(CodePosition position, ZSTokenStream parser, ParsingOptions options) {
147
+		ParsedExpression left = readXorExpression(position, parser, options);
133 148
 
134 149
 		while (parser.optional(T_OR) != null) {
135
-			ParsedExpression right = readXorExpression(parser.peek().position, parser);
150
+			ParsedExpression right = readXorExpression(parser.peek().position, parser, options);
136 151
 			left = new ParsedExpressionBinary(position, left, right, OperatorType.OR);
137 152
 		}
138 153
 		return left;
139 154
 	}
140 155
 
141
-	private static ParsedExpression readXorExpression(CodePosition position, ZSTokenStream parser) {
142
-		ParsedExpression left = readAndExpression(position, parser);
156
+	private static ParsedExpression readXorExpression(CodePosition position, ZSTokenStream parser, ParsingOptions options) {
157
+		ParsedExpression left = readAndExpression(position, parser, options);
143 158
 
144 159
 		while (parser.optional(T_XOR) != null) {
145
-			ParsedExpression right = readAndExpression(parser.peek().position, parser);
160
+			ParsedExpression right = readAndExpression(parser.peek().position, parser, options);
146 161
 			left = new ParsedExpressionBinary(position, left, right, OperatorType.XOR);
147 162
 		}
148 163
 		return left;
149 164
 	}
150 165
 
151
-	private static ParsedExpression readAndExpression(CodePosition position, ZSTokenStream parser) {
152
-		ParsedExpression left = readCompareExpression(position, parser);
166
+	private static ParsedExpression readAndExpression(CodePosition position, ZSTokenStream parser, ParsingOptions options) {
167
+		ParsedExpression left = readCompareExpression(position, parser, options);
153 168
 
154 169
 		while (parser.optional(T_AND) != null) {
155
-			ParsedExpression right = readCompareExpression(parser.peek().position, parser);
170
+			ParsedExpression right = readCompareExpression(parser.peek().position, parser, options);
156 171
 			left = new ParsedExpressionBinary(position, left, right, OperatorType.AND);
157 172
 		}
158 173
 		return left;
159 174
 	}
160 175
 
161
-	private static ParsedExpression readCompareExpression(CodePosition position, ZSTokenStream parser) {
162
-		ParsedExpression left = readShiftExpression(position, parser);
176
+	private static ParsedExpression readCompareExpression(CodePosition position, ZSTokenStream parser, ParsingOptions options) {
177
+		ParsedExpression left = readShiftExpression(position, parser, options);
163 178
 
164 179
 		switch (parser.peek().getType()) {
165 180
 			case T_EQUAL2: {
166 181
 				parser.next();
167
-				ParsedExpression right = readShiftExpression(parser.peek().position, parser);
182
+				ParsedExpression right = readShiftExpression(parser.peek().position, parser, options);
168 183
 				return new ParsedExpressionCompare(position, left, right, CompareType.EQ);
169 184
 			}
170 185
 			case T_EQUAL3: {
171 186
 				parser.next();
172
-				ParsedExpression right = readShiftExpression(parser.peek().position, parser);
187
+				ParsedExpression right = readShiftExpression(parser.peek().position, parser, options);
173 188
 				return new ParsedExpressionCompare(position, left, right, CompareType.SAME);
174 189
 			}
175 190
 			case T_NOTEQUAL: {
176 191
 				parser.next();
177
-				ParsedExpression right = readShiftExpression(parser.peek().position, parser);
192
+				ParsedExpression right = readShiftExpression(parser.peek().position, parser, options);
178 193
 				return new ParsedExpressionCompare(position, left, right, CompareType.NE);
179 194
 			}
180 195
 			case T_NOTEQUAL2: {
181 196
 				parser.next();
182
-				ParsedExpression right = readShiftExpression(parser.peek().position, parser);
197
+				ParsedExpression right = readShiftExpression(parser.peek().position, parser, options);
183 198
 				return new ParsedExpressionCompare(position, left, right, CompareType.NOTSAME);
184 199
 			}
185 200
 			case T_LESS: {
186 201
 				parser.next();
187
-				ParsedExpression right = readShiftExpression(parser.peek().position, parser);
202
+				ParsedExpression right = readShiftExpression(parser.peek().position, parser, options);
188 203
 				return new ParsedExpressionCompare(position, left, right, CompareType.LT);
189 204
 			}
190 205
 			case T_LESSEQ: {
191 206
 				parser.next();
192
-				ParsedExpression right = readShiftExpression(parser.peek().position, parser);
207
+				ParsedExpression right = readShiftExpression(parser.peek().position, parser, options);
193 208
 				return new ParsedExpressionCompare(position, left, right, CompareType.LE);
194 209
 			}
195 210
 			case T_GREATER: {
196 211
 				parser.next();
197
-				ParsedExpression right = readShiftExpression(parser.peek().position, parser);
212
+				ParsedExpression right = readShiftExpression(parser.peek().position, parser, options);
198 213
 				return new ParsedExpressionCompare(position, left, right, CompareType.GT);
199 214
 			}
200 215
 			case T_GREATEREQ: {
201 216
 				parser.next();
202
-				ParsedExpression right = readShiftExpression(parser.peek().position, parser);
217
+				ParsedExpression right = readShiftExpression(parser.peek().position, parser, options);
203 218
 				return new ParsedExpressionCompare(position, left, right, CompareType.GE);
204 219
 			}
205 220
 			case K_IN: {
206 221
 				parser.next();
207
-				ParsedExpression right = readShiftExpression(parser.peek().position, parser);
222
+				ParsedExpression right = readShiftExpression(parser.peek().position, parser, options);
208 223
 				return new ParsedExpressionBinary(position, right, left, OperatorType.CONTAINS);
209 224
 			}
210 225
 			case K_IS: {
@@ -215,7 +230,7 @@ public abstract class ParsedExpression {
215 230
 			case T_NOT: {
216 231
 				parser.next();
217 232
 				if (parser.optional(K_IN) != null) {
218
-					ParsedExpression right = readShiftExpression(parser.peek().position, parser);
233
+					ParsedExpression right = readShiftExpression(parser.peek().position, parser, options);
219 234
 					return new ParsedExpressionUnary(position, new ParsedExpressionBinary(position, right, left, OperatorType.CONTAINS), OperatorType.NOT);
220 235
 				} else if (parser.optional(K_IS) != null) {
221 236
 					IParsedType type = IParsedType.parse(parser);
@@ -229,18 +244,18 @@ public abstract class ParsedExpression {
229 244
 		return left;
230 245
 	}
231 246
 	
232
-	private static ParsedExpression readShiftExpression(CodePosition position, ZSTokenStream parser) {
233
-		ParsedExpression left = readAddExpression(position, parser);
247
+	private static ParsedExpression readShiftExpression(CodePosition position, ZSTokenStream parser, ParsingOptions options) {
248
+		ParsedExpression left = readAddExpression(position, parser, options);
234 249
 		
235 250
 		while (true) {
236 251
 			if (parser.optional(T_SHL) != null) {
237
-				ParsedExpression right = readAddExpression(parser.peek().position, parser);
252
+				ParsedExpression right = readAddExpression(parser.peek().position, parser, options);
238 253
 				left = new ParsedExpressionBinary(position, left, right, OperatorType.SHL);
239 254
 			} else if (parser.optional(T_SHR) != null) {
240
-				ParsedExpression right = readAddExpression(parser.peek().position, parser);
255
+				ParsedExpression right = readAddExpression(parser.peek().position, parser, options);
241 256
 				left = new ParsedExpressionBinary(position, left, right, OperatorType.SHR);
242 257
 			} else if (parser.optional(T_USHR) != null) {
243
-				ParsedExpression right = readAddExpression(parser.peek().position, parser);
258
+				ParsedExpression right = readAddExpression(parser.peek().position, parser, options);
244 259
 				left = new ParsedExpressionBinary(position, left, right, OperatorType.USHR);
245 260
 			} else {
246 261
 				break;
@@ -250,18 +265,18 @@ public abstract class ParsedExpression {
250 265
 		return left;
251 266
 	}
252 267
 
253
-	private static ParsedExpression readAddExpression(CodePosition position, ZSTokenStream parser) {
254
-		ParsedExpression left = readMulExpression(position, parser);
268
+	private static ParsedExpression readAddExpression(CodePosition position, ZSTokenStream parser, ParsingOptions options) {
269
+		ParsedExpression left = readMulExpression(position, parser, options);
255 270
 		
256 271
 		while (true) {
257 272
 			if (parser.optional(T_ADD) != null) {
258
-				ParsedExpression right = readMulExpression(parser.peek().position, parser);
273
+				ParsedExpression right = readMulExpression(parser.peek().position, parser, options);
259 274
 				left = new ParsedExpressionBinary(position, left, right, OperatorType.ADD);
260 275
 			} else if (parser.optional(T_SUB) != null) {
261
-				ParsedExpression right = readMulExpression(parser.peek().position, parser);
276
+				ParsedExpression right = readMulExpression(parser.peek().position, parser, options);
262 277
 				left = new ParsedExpressionBinary(position, left, right, OperatorType.SUB);
263 278
 			} else if (parser.optional(T_CAT) != null) {
264
-				ParsedExpression right = readMulExpression(parser.peek().position, parser);
279
+				ParsedExpression right = readMulExpression(parser.peek().position, parser, options);
265 280
 				left = new ParsedExpressionBinary(position, left, right, OperatorType.CAT);
266 281
 			} else {
267 282
 				break;
@@ -270,18 +285,18 @@ public abstract class ParsedExpression {
270 285
 		return left;
271 286
 	}
272 287
 
273
-	private static ParsedExpression readMulExpression(CodePosition position, ZSTokenStream parser) {
274
-		ParsedExpression left = readUnaryExpression(position, parser);
288
+	private static ParsedExpression readMulExpression(CodePosition position, ZSTokenStream parser, ParsingOptions options) {
289
+		ParsedExpression left = readUnaryExpression(position, parser, options);
275 290
 
276 291
 		while (true) {
277 292
 			if (parser.optional(T_MUL) != null) {
278
-				ParsedExpression right = readUnaryExpression(parser.peek().position, parser);
293
+				ParsedExpression right = readUnaryExpression(parser.peek().position, parser, options);
279 294
 				left = new ParsedExpressionBinary(position, left, right, OperatorType.MUL);
280 295
 			} else if (parser.optional(T_DIV) != null) {
281
-				ParsedExpression right = readUnaryExpression(parser.peek().position, parser);
296
+				ParsedExpression right = readUnaryExpression(parser.peek().position, parser, options);
282 297
 				left = new ParsedExpressionBinary(position, left, right, OperatorType.DIV);
283 298
 			} else if (parser.optional(T_MOD) != null) {
284
-				ParsedExpression right = readUnaryExpression(parser.peek().position, parser);
299
+				ParsedExpression right = readUnaryExpression(parser.peek().position, parser, options);
285 300
 				left = new ParsedExpressionBinary(position, left, right, OperatorType.MOD);
286 301
 			} else {
287 302
 				break;
@@ -291,45 +306,45 @@ public abstract class ParsedExpression {
291 306
 		return left;
292 307
 	}
293 308
 
294
-	private static ParsedExpression readUnaryExpression(CodePosition position, ZSTokenStream parser) {
309
+	private static ParsedExpression readUnaryExpression(CodePosition position, ZSTokenStream parser, ParsingOptions options) {
295 310
 		switch (parser.peek().getType()) {
296 311
 			case T_NOT:
297 312
 				parser.next();
298 313
 				return new ParsedExpressionUnary(
299 314
 						position,
300
-						readUnaryExpression(parser.peek().position, parser),
315
+						readUnaryExpression(parser.peek().position, parser, options),
301 316
 						OperatorType.NOT);
302 317
 			case T_SUB:
303 318
 				parser.next();
304 319
 				return new ParsedExpressionUnary(
305 320
 						position,
306
-						readUnaryExpression(parser.peek().position, parser),
321
+						readUnaryExpression(parser.peek().position, parser, options),
307 322
 						OperatorType.NEG);
308 323
 			case T_CAT:
309 324
 				parser.next();
310 325
 				return new ParsedExpressionUnary(
311 326
 						position,
312
-						readUnaryExpression(parser.peek().position, parser),
327
+						readUnaryExpression(parser.peek().position, parser, options),
313 328
 						OperatorType.CAT);
314 329
 			case T_INCREMENT:
315 330
 				parser.next();
316 331
 				return new ParsedExpressionUnary(
317 332
 						position,
318
-						readUnaryExpression(parser.peek().position, parser),
333
+						readUnaryExpression(parser.peek().position, parser, options),
319 334
 						OperatorType.INCREMENT);
320 335
 			case T_DECREMENT:
321 336
 				parser.next();
322 337
 				return new ParsedExpressionUnary(
323 338
 						position,
324
-						readUnaryExpression(parser.peek().position, parser),
339
+						readUnaryExpression(parser.peek().position, parser, options),
325 340
 						OperatorType.DECREMENT);
326 341
 			default:
327
-				return readPostfixExpression(position, parser);
342
+				return readPostfixExpression(position, parser, options);
328 343
 		}
329 344
 	}
330 345
 
331
-	private static ParsedExpression readPostfixExpression(CodePosition position, ZSTokenStream parser) {
332
-		ParsedExpression base = readPrimaryExpression(position, parser);
346
+	private static ParsedExpression readPostfixExpression(CodePosition position, ZSTokenStream parser, ParsingOptions options) {
347
+		ParsedExpression base = readPrimaryExpression(position, parser, options);
333 348
 
334 349
 		while (true) {
335 350
 			if (parser.optional(T_DOT) != null) {
@@ -352,12 +367,12 @@ public abstract class ParsedExpression {
352 367
 					}
353 368
 				}
354 369
 			} else if (parser.optional(T_DOT2) != null) {
355
-				ParsedExpression to = readAssignExpression(parser);
370
+				ParsedExpression to = readAssignExpression(parser, options);
356 371
 				return new ParsedExpressionRange(position, base, to);
357 372
 			} else if (parser.optional(T_SQOPEN) != null) {
358 373
 				List<ParsedExpression> indexes = new ArrayList<>();
359 374
 				do {
360
-					indexes.add(readAssignExpression(parser));
375
+					indexes.add(readAssignExpression(parser, options));
361 376
 				} while (parser.optional(ZSTokenType.T_COMMA) != null);
362 377
 				parser.required(T_SQCLOSE, "] expected");
363 378
 				base = new ParsedExpressionIndex(position, base, indexes);
@@ -371,7 +386,7 @@ public abstract class ParsedExpression {
371 386
 				base = new ParsedExpressionPostCall(position, base, OperatorType.INCREMENT);
372 387
 			} else if (parser.optional(T_DECREMENT) != null) {
373 388
 				base = new ParsedExpressionPostCall(position, base, OperatorType.DECREMENT);
374
-			} else if (parser.optional(T_LAMBDA) != null) {
389
+			} else if (options.allowLambda && parser.optional(T_LAMBDA) != null) {
375 390
 				ParsedFunctionBody body = ParsedStatement.parseLambdaBody(parser, true);
376 391
 				base = new ParsedExpressionFunction(position, base.toLambdaHeader(), body);
377 392
 			} else {
@@ -382,7 +397,7 @@ public abstract class ParsedExpression {
382 397
 		return base;
383 398
 	}
384 399
 	
385
-	private static ParsedExpression readPrimaryExpression(CodePosition position, ZSTokenStream parser) {
400
+	private static ParsedExpression readPrimaryExpression(CodePosition position, ZSTokenStream parser, ParsingOptions options) {
386 401
 		switch (parser.peek().getType()) {
387 402
 			case T_INT:
388 403
 				return new ParsedExpressionInt(position, Long.parseLong(parser.next().content));
@@ -416,7 +431,7 @@ public abstract class ParsedExpression {
416 431
 				List<ParsedExpression> contents = new ArrayList<>();
417 432
 				if (parser.optional(T_SQCLOSE) == null) {
418 433
 					while (parser.optional(T_SQCLOSE) == null) {
419
-						contents.add(readAssignExpression(parser));
434
+						contents.add(readAssignExpression(parser, options));
420 435
 						if (parser.optional(T_COMMA) == null) {
421 436
 							parser.required(T_SQCLOSE, "] or , expected");
422 437
 							break;
@@ -431,13 +446,13 @@ public abstract class ParsedExpression {
431 446
 				List<ParsedExpression> keys = new ArrayList<>();
432 447
 				List<ParsedExpression> values = new ArrayList<>();
433 448
 				while (parser.optional(T_ACLOSE) == null) {
434
-					ParsedExpression expression = readAssignExpression(parser);
449
+					ParsedExpression expression = readAssignExpression(parser, options);
435 450
 					if (parser.optional(T_COLON) == null) {
436 451
 						keys.add(null);
437 452
 						values.add(expression);
438 453
 					} else {
439 454
 						keys.add(expression);
440
-						values.add(readAssignExpression(parser));
455
+						values.add(readAssignExpression(parser, options));
441 456
 					}
442 457
 
443 458
 					if (parser.optional(T_COMMA) == null) {
@@ -460,7 +475,7 @@ public abstract class ParsedExpression {
460 475
 				parser.next();
461 476
 				List<ParsedExpression> expressions = new ArrayList<>();
462 477
 				do {
463
-					expressions.add(readAssignExpression(parser));
478
+					expressions.add(readAssignExpression(parser, options));
464 479
 				} while (parser.optional(ZSTokenType.T_COMMA) != null);
465 480
 				parser.required(T_BRCLOSE, ") expected");
466 481
 				return new ParsedExpressionBracket(position, expressions);
@@ -474,6 +489,27 @@ public abstract class ParsedExpression {
474 489
 				
475 490
 				return new ParsedNewExpression(position, type, newArguments);
476 491
 			}
492
+			case K_MATCH: {
493
+				parser.next();
494
+				ParsedExpression source = parse(parser);
495
+				parser.required(T_AOPEN, "{ expected");
496
+				
497
+				List<ParsedMatchExpression.Case> cases = new ArrayList<>();
498
+				while (parser.optional(T_ACLOSE) == null) {
499
+					ParsedExpression key = null;
500
+					if (parser.optional(K_DEFAULT) == null)
501
+						key = parse(parser, new ParsingOptions(false));
502
+					
503
+					parser.required(T_LAMBDA, "=> expected");
504
+					ParsedFunctionBody body = ParsedStatement.parseLambdaBody(parser, true);
505
+					cases.add(new ParsedMatchExpression.Case(key, body));
506
+					
507
+					if (parser.optional(T_COMMA) == null)
508
+						break;
509
+				}
510
+				parser.required(T_ACLOSE, "} expected");
511
+				return new ParsedMatchExpression(position, source, cases);
512
+			}
477 513
 			default: {
478 514
 				IParsedType type = IParsedType.parse(parser);
479 515
 				if (type == null) {
@@ -509,6 +545,10 @@ public abstract class ParsedExpression {
509 545
 		return compile(scope).eval();
510 546
 	}
511 547
 	
548
+	public SwitchValue compileToSwitchValue(ITypeID type, ExpressionScope scope) {
549
+		throw new CompileException(position, CompileExceptionCode.INVALID_SWITCH_CASE, "Invalid switch case");
550
+	}
551
+	
512 552
 	public ParsedFunctionHeader toLambdaHeader() {
513 553
 		throw new ParseException(position, "Not a valid lambda header");
514 554
 	}

+ 46
- 2
Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpressionCall.java ファイルの表示

@@ -9,14 +9,21 @@ package org.openzen.zenscript.parser.expression;
9 9
 import java.util.List;
10 10
 import org.openzen.zenscript.codemodel.FunctionHeader;
11 11
 import org.openzen.zenscript.codemodel.OperatorType;
12
+import org.openzen.zenscript.codemodel.definition.VariantDefinition;
12 13
 import org.openzen.zenscript.codemodel.expression.CallArguments;
13 14
 import org.openzen.zenscript.codemodel.expression.ConstructorThisCallExpression;
15
+import org.openzen.zenscript.codemodel.expression.VariantValueExpression;
16
+import org.openzen.zenscript.codemodel.expression.switchvalue.SwitchValue;
17
+import org.openzen.zenscript.codemodel.expression.switchvalue.VariantOptionSwitchValue;
14 18
 import org.openzen.zenscript.codemodel.member.ConstructorMember;
15 19
 import org.openzen.zenscript.codemodel.member.ICallableMember;
16 20
 import org.openzen.zenscript.codemodel.partial.IPartialExpression;
21
+import org.openzen.zenscript.codemodel.type.BasicTypeID;
17 22
 import org.openzen.zenscript.codemodel.type.ITypeID;
18 23
 import org.openzen.zenscript.codemodel.type.member.DefinitionMemberGroup;
24
+import org.openzen.zenscript.codemodel.type.member.TypeMembers;
19 25
 import org.openzen.zenscript.linker.ExpressionScope;
26
+import org.openzen.zenscript.parser.definitions.ParsedFunctionParameter;
20 27
 import org.openzen.zenscript.shared.CodePosition;
21 28
 import org.openzen.zenscript.shared.CompileException;
22 29
 import org.openzen.zenscript.shared.CompileExceptionCode;
@@ -38,7 +45,18 @@ public class ParsedExpressionCall extends ParsedExpression {
38 45
 
39 46
 	@Override
40 47
 	public IPartialExpression compile(ExpressionScope scope) {
41
-		IPartialExpression cReceiver = receiver.compile(scope.withoutHints());
48
+		if (receiver instanceof ParsedExpressionVariable) {
49
+			ParsedExpressionVariable variable = (ParsedExpressionVariable) receiver;
50
+			for (ITypeID hint : scope.hints) {
51
+				TypeMembers members = scope.getTypeMembers(hint);
52
+				if (members.getVariantOption(variable.name) != null) {
53
+					VariantDefinition.Option variantOption = members.getVariantOption(variable.name);
54
+					FunctionHeader header = new FunctionHeader(BasicTypeID.VOID, variantOption.types);
55
+					CallArguments cArguments = arguments.compileCall(position, scope, null, header);
56
+					return new VariantValueExpression(position, hint, variantOption, cArguments.arguments);
57
+				}
58
+			}
59
+		}
42 60
 		
43 61
 		if (receiver instanceof ParsedExpressionSuper) {
44 62
 			// super call (intended as first call in constructor)
@@ -65,11 +83,37 @@ public class ParsedExpressionCall extends ParsedExpression {
65 83
 			
66 84
 			return new ConstructorThisCallExpression(position, scope.getThisType(), (ConstructorMember) member, callArguments, scope);
67 85
 		}
68
-
86
+		
87
+		IPartialExpression cReceiver = receiver.compile(scope.withoutHints());
69 88
 		List<FunctionHeader> headers = cReceiver.getPossibleFunctionHeaders(scope, scope.hints, arguments.arguments.size());
70 89
 		CallArguments callArguments = arguments.compileCall(position, scope, cReceiver.getGenericCallTypes(), headers);
71 90
 		return cReceiver.call(position, scope, scope.hints, callArguments);
72 91
 	}
92
+	
93
+	@Override
94
+	public SwitchValue compileToSwitchValue(ITypeID type, ExpressionScope scope) {
95
+		if (!(receiver instanceof ParsedExpressionVariable))
96
+			throw new CompileException(position, CompileExceptionCode.INVALID_SWITCH_CASE, "Invalid switch case");
97
+		
98
+		String name = ((ParsedExpressionVariable)receiver).name;
99
+		TypeMembers members = scope.getTypeMembers(type);
100
+		if (type.isVariant()) {
101
+			VariantDefinition.Option option = members.getVariantOption(name);
102
+			if (option == null)
103
+				throw new CompileException(position, CompileExceptionCode.NO_SUCH_MEMBER, "Variant option does not exist: " + name);
104
+			
105
+			String[] values = new String[arguments.arguments.size()];
106
+			for (int i = 0; i < values.length; i++) {
107
+				ParsedExpression argument = arguments.arguments.get(i);
108
+				ParsedFunctionParameter lambdaHeader = argument.toLambdaParameter();
109
+				values[i] = lambdaHeader.name;
110
+			}
111
+			
112
+			return new VariantOptionSwitchValue(option, values);
113
+		} else {
114
+			throw new CompileException(position, CompileExceptionCode.INVALID_SWITCH_CASE, "Invalid switch case");
115
+		}
116
+	}
73 117
 
74 118
 	@Override
75 119
 	public boolean hasStrongType() {

+ 2
- 2
Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpressionFunction.java ファイルの表示

@@ -31,8 +31,8 @@ import org.openzen.zenscript.shared.CompileExceptionCode;
31 31
  * @author Stan
32 32
  */
33 33
 public class ParsedExpressionFunction extends ParsedExpression {
34
-	private final ParsedFunctionHeader header;
35
-	private final ParsedFunctionBody body;
34
+	public final ParsedFunctionHeader header;
35
+	public final ParsedFunctionBody body;
36 36
 	
37 37
 	public ParsedExpressionFunction(CodePosition position, ParsedFunctionHeader header, ParsedFunctionBody body) {
38 38
 		super(position);

+ 35
- 2
Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpressionVariable.java ファイルの表示

@@ -8,13 +8,19 @@ package org.openzen.zenscript.parser.expression;
8 8
 
9 9
 import java.util.Collections;
10 10
 import java.util.List;
11
+import org.openzen.zenscript.codemodel.definition.VariantDefinition;
11 12
 import org.openzen.zenscript.codemodel.expression.ConstantStringExpression;
12 13
 import org.openzen.zenscript.codemodel.expression.EnumConstantExpression;
13 14
 import org.openzen.zenscript.codemodel.expression.Expression;
15
+import org.openzen.zenscript.codemodel.expression.VariantValueExpression;
16
+import org.openzen.zenscript.codemodel.expression.switchvalue.EnumConstantSwitchValue;
17
+import org.openzen.zenscript.codemodel.expression.switchvalue.SwitchValue;
18
+import org.openzen.zenscript.codemodel.expression.switchvalue.VariantOptionSwitchValue;
14 19
 import org.openzen.zenscript.codemodel.member.EnumConstantMember;
15 20
 import org.openzen.zenscript.codemodel.partial.IPartialExpression;
16 21
 import org.openzen.zenscript.codemodel.type.GenericName;
17 22
 import org.openzen.zenscript.codemodel.type.ITypeID;
23
+import org.openzen.zenscript.codemodel.type.member.TypeMembers;
18 24
 import org.openzen.zenscript.linker.ExpressionScope;
19 25
 import org.openzen.zenscript.parser.definitions.ParsedFunctionHeader;
20 26
 import org.openzen.zenscript.parser.definitions.ParsedFunctionParameter;
@@ -29,7 +35,7 @@ import org.openzen.zenscript.shared.CompileExceptionCode;
29 35
  * @author Stanneke
30 36
  */
31 37
 public class ParsedExpressionVariable extends ParsedExpression {
32
-	private final String name;
38
+	public final String name;
33 39
 	private final List<IParsedType> genericParameters;
34 40
 	
35 41
 	public ParsedExpressionVariable(CodePosition position, String name, List<IParsedType> genericParameters) {
@@ -52,9 +58,14 @@ public class ParsedExpressionVariable extends ParsedExpression {
52 58
 		IPartialExpression result = scope.get(position, new GenericName(name, genericArguments));
53 59
 		if (result == null) {
54 60
 			for (ITypeID hint : scope.hints) {
55
-				EnumConstantMember member = scope.getTypeMembers(hint).getEnumMember(name);
61
+				TypeMembers members = scope.getTypeMembers(hint);
62
+				EnumConstantMember member = members.getEnumMember(name);
56 63
 				if (member != null)
57 64
 					return new EnumConstantExpression(position, hint, member);
65
+				
66
+				VariantDefinition.Option option = members.getVariantOption(name);
67
+				if (option != null)
68
+					return new VariantValueExpression(position, hint, option);
58 69
 			}
59 70
 			
60 71
 			throw new CompileException(position, CompileExceptionCode.UNDEFINED_VARIABLE, "No such symbol: " + name);
@@ -68,6 +79,28 @@ public class ParsedExpressionVariable extends ParsedExpression {
68 79
 		return new ConstantStringExpression(position, name);
69 80
 	}
70 81
 	
82
+	@Override
83
+	public SwitchValue compileToSwitchValue(ITypeID type, ExpressionScope scope) {
84
+		TypeMembers members = scope.getTypeMembers(type);
85
+		if (type.isEnum()) {
86
+			EnumConstantMember member = members.getEnumMember(name);
87
+			if (member == null)
88
+				throw new CompileException(position, CompileExceptionCode.NO_SUCH_MEMBER, "Enum member does not exist: " + name);
89
+				
90
+			return new EnumConstantSwitchValue(member);
91
+		} else if (type.isVariant()) {
92
+			VariantDefinition.Option option = members.getVariantOption(name);
93
+			if (option == null)
94
+				throw new CompileException(position, CompileExceptionCode.NO_SUCH_MEMBER, "Variant option does not exist: " + name);
95
+			if (option.types.length > 0)
96
+				throw new CompileException(position, CompileExceptionCode.MISSING_VARIANT_CASEPARAMETERS, "Variant case is missing parameters");
97
+			
98
+			return new VariantOptionSwitchValue(option, new String[0]);
99
+		} else {
100
+			throw new CompileException(position, CompileExceptionCode.INVALID_SWITCH_CASE, "Invalid switch case");
101
+		}
102
+	}
103
+	
71 104
 	@Override
72 105
 	public ParsedFunctionHeader toLambdaHeader() {
73 106
 		return new ParsedFunctionHeader(Collections.singletonList(toLambdaParameter()), ParsedTypeBasic.ANY);

+ 105
- 0
Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedMatchExpression.java ファイルの表示

@@ -0,0 +1,105 @@
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.parser.expression;
7
+
8
+import java.util.List;
9
+import org.openzen.zenscript.codemodel.FunctionHeader;
10
+import org.openzen.zenscript.codemodel.FunctionParameter;
11
+import org.openzen.zenscript.codemodel.expression.Expression;
12
+import org.openzen.zenscript.codemodel.expression.FunctionExpression;
13
+import org.openzen.zenscript.codemodel.expression.LambdaClosure;
14
+import org.openzen.zenscript.codemodel.expression.MatchExpression;
15
+import org.openzen.zenscript.codemodel.expression.switchvalue.SwitchValue;
16
+import org.openzen.zenscript.codemodel.expression.switchvalue.VariantOptionSwitchValue;
17
+import org.openzen.zenscript.codemodel.partial.IPartialExpression;
18
+import org.openzen.zenscript.codemodel.statement.Statement;
19
+import org.openzen.zenscript.codemodel.type.BasicTypeID;
20
+import org.openzen.zenscript.codemodel.type.ITypeID;
21
+import org.openzen.zenscript.linker.ExpressionScope;
22
+import org.openzen.zenscript.linker.LambdaScope;
23
+import org.openzen.zenscript.linker.StatementScope;
24
+import org.openzen.zenscript.parser.statements.ParsedFunctionBody;
25
+import org.openzen.zenscript.shared.CodePosition;
26
+import org.openzen.zenscript.shared.CompileException;
27
+import org.openzen.zenscript.shared.CompileExceptionCode;
28
+
29
+/**
30
+ *
31
+ * @author Hoofdgebruiker
32
+ */
33
+public class ParsedMatchExpression extends ParsedExpression {
34
+	public final ParsedExpression value;
35
+	public final List<Case> cases;
36
+	
37
+	public ParsedMatchExpression(CodePosition position, ParsedExpression value, List<Case> cases) {
38
+		super(position);
39
+		
40
+		this.value = value;
41
+		this.cases = cases;
42
+	}
43
+
44
+	@Override
45
+	public IPartialExpression compile(ExpressionScope scope) {
46
+		Expression cValue = value.compileKey(scope);
47
+		MatchExpression.Case[] cCases = new MatchExpression.Case[cases.size()];
48
+		for (int i = 0; i < cases.size(); i++) {
49
+			Case matchCase = cases.get(i);
50
+			cCases[i] = matchCase.compile(cValue.type, scope);
51
+		}
52
+		
53
+		ITypeID result = cCases[0].value.header.returnType;
54
+		for (int i = 1; i < cCases.length; i++) {
55
+			result = scope.getTypeMembers(result).union(cCases[i].value.header.returnType);
56
+		}
57
+		
58
+		return new MatchExpression(position, cValue, result, cCases);
59
+	}
60
+
61
+	@Override
62
+	public boolean hasStrongType() {
63
+		return false;
64
+	}
65
+	
66
+	public static class Case {
67
+		public final ParsedExpression name;
68
+		public final ParsedFunctionBody body;
69
+		
70
+		public Case(ParsedExpression name, ParsedFunctionBody body) {
71
+			this.name = name;
72
+			this.body = body;
73
+		}
74
+		
75
+		public MatchExpression.Case compile(ITypeID valueType, ExpressionScope scope) {
76
+			ITypeID result = BasicTypeID.ANY;
77
+			if (scope.getResultTypeHints().size() == 1)
78
+				result = scope.getResultTypeHints().get(0);
79
+			
80
+			if (name == null) {
81
+				FunctionHeader header = new FunctionHeader(result, FunctionParameter.NONE);
82
+				LambdaClosure closure = new LambdaClosure();
83
+				StatementScope innerScope = new LambdaScope(scope, closure, header);
84
+				Statement contents = body.compile(innerScope, header);
85
+				return new MatchExpression.Case(null, new FunctionExpression(name.position, scope.getTypeRegistry().getFunction(header), closure, contents));
86
+			}
87
+			
88
+			SwitchValue switchValue = name.compileToSwitchValue(valueType, scope.withHint(valueType));
89
+			FunctionParameter[] parameters = FunctionParameter.NONE;
90
+			if (switchValue instanceof VariantOptionSwitchValue) {
91
+				VariantOptionSwitchValue variantSwitchValue = (VariantOptionSwitchValue)switchValue;
92
+				
93
+				parameters = new FunctionParameter[variantSwitchValue.option.types.length];
94
+				for (int i = 0; i < parameters.length; i++)
95
+					parameters[i] = new FunctionParameter(variantSwitchValue.option.types[i], variantSwitchValue.parameters[i]);
96
+			}
97
+			
98
+			FunctionHeader header = new FunctionHeader(result, parameters);
99
+			LambdaClosure closure = new LambdaClosure();
100
+			StatementScope innerScope = new LambdaScope(scope, closure, header);
101
+			Statement contents = body.compile(innerScope, header);
102
+			return new MatchExpression.Case(switchValue, new FunctionExpression(name.position, scope.getTypeRegistry().getFunction(header), closure, contents));
103
+		}
104
+	}
105
+}

+ 3
- 1
Shared/src/main/java/org/openzen/zenscript/shared/CompileExceptionCode.java ファイルの表示

@@ -58,5 +58,7 @@ public enum CompileExceptionCode {
58 58
 	INTERNAL_ERROR,
59 59
 	CANNOT_SET_FINAL_VARIABLE,
60 60
 	MISSING_PARAMETER,
61
-	STATEMENT_OUTSIDE_SWITCH_CASE
61
+	STATEMENT_OUTSIDE_SWITCH_CASE,
62
+	MISSING_VARIANT_CASEPARAMETERS,
63
+	INVALID_SWITCH_CASE
62 64
 }

+ 19
- 0
Validator/src/main/java/org/openzen/zenscript/validator/visitors/DefinitionValidator.java ファイルの表示

@@ -16,6 +16,7 @@ import org.openzen.zenscript.codemodel.definition.ExpansionDefinition;
16 16
 import org.openzen.zenscript.codemodel.definition.FunctionDefinition;
17 17
 import org.openzen.zenscript.codemodel.definition.InterfaceDefinition;
18 18
 import org.openzen.zenscript.codemodel.definition.StructDefinition;
19
+import org.openzen.zenscript.codemodel.definition.VariantDefinition;
19 20
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
20 21
 import org.openzen.zenscript.validator.Validator;
21 22
 import org.openzen.zenscript.validator.analysis.StatementScope;
@@ -169,6 +170,24 @@ public class DefinitionValidator implements DefinitionVisitor<Boolean> {
169 170
 		}
170 171
 		return isValid;
171 172
 	}
173
+
174
+	@Override
175
+	public Boolean visitVariant(VariantDefinition variant) {
176
+		boolean isValid = true;
177
+		isValid &= ValidationUtils.validateModifiers(
178
+				validator,
179
+				variant.modifiers,
180
+				PUBLIC | EXPORT | PROTECTED | PRIVATE,
181
+				variant.position,
182
+				"Invalid variant modifier");
183
+		isValid &= ValidationUtils.validateIdentifier(
184
+				validator,
185
+				variant.position,
186
+				variant.name);
187
+		
188
+		isValid &= validateMembers(variant);
189
+		return isValid;
190
+	}
172 191
 	
173 192
 	private class FunctionStatementScope implements StatementScope {
174 193
 		private final FunctionHeader header;

+ 7
- 0
Validator/src/main/java/org/openzen/zenscript/validator/visitors/ExpressionValidator.java ファイルの表示

@@ -53,6 +53,7 @@ import org.openzen.zenscript.codemodel.expression.InterfaceCastExpression;
53 53
 import org.openzen.zenscript.codemodel.expression.IsExpression;
54 54
 import org.openzen.zenscript.codemodel.expression.MakeConstExpression;
55 55
 import org.openzen.zenscript.codemodel.expression.MapExpression;
56
+import org.openzen.zenscript.codemodel.expression.MatchExpression;
56 57
 import org.openzen.zenscript.codemodel.expression.NewExpression;
57 58
 import org.openzen.zenscript.codemodel.expression.NullExpression;
58 59
 import org.openzen.zenscript.codemodel.expression.OrOrExpression;
@@ -442,6 +443,12 @@ public class ExpressionValidator implements ExpressionVisitor<Boolean> {
442 443
 		return isValid;
443 444
 	}
444 445
 
446
+	@Override
447
+	public Boolean visitMatch(MatchExpression expression) {
448
+		// TODO
449
+		return true;
450
+	}
451
+
445 452
 	@Override
446 453
 	public Boolean visitNew(NewExpression expression) {
447 454
 		boolean isValid = checkCallArguments(

+ 15
- 2
Validator/src/main/java/org/openzen/zenscript/validator/visitors/SuperclassValidator.java ファイルの表示

@@ -14,6 +14,8 @@ import org.openzen.zenscript.codemodel.definition.ExpansionDefinition;
14 14
 import org.openzen.zenscript.codemodel.definition.FunctionDefinition;
15 15
 import org.openzen.zenscript.codemodel.definition.InterfaceDefinition;
16 16
 import org.openzen.zenscript.codemodel.definition.StructDefinition;
17
+import org.openzen.zenscript.codemodel.definition.VariantDefinition;
18
+import org.openzen.zenscript.shared.CodePosition;
17 19
 import org.openzen.zenscript.validator.ValidationLogEntry;
18 20
 import org.openzen.zenscript.validator.Validator;
19 21
 
@@ -23,9 +25,11 @@ import org.openzen.zenscript.validator.Validator;
23 25
  */
24 26
 public class SuperclassValidator implements DefinitionVisitor<Boolean> {
25 27
 	private final Validator validator;
28
+	private final CodePosition position;
26 29
 	
27
-	public SuperclassValidator(Validator validator) {
30
+	public SuperclassValidator(Validator validator, CodePosition position) {
28 31
 		this.validator = validator;
32
+		this.position = position;
29 33
 	}
30 34
 
31 35
 	@Override
@@ -88,6 +92,15 @@ public class SuperclassValidator implements DefinitionVisitor<Boolean> {
88 92
 
89 93
 	@Override
90 94
 	public Boolean visitAlias(AliasDefinition definition) {
91
-		throw new AssertionError();
95
+		return definition.type.accept(new SupertypeValidator(validator, position));
96
+	}
97
+
98
+	@Override
99
+	public Boolean visitVariant(VariantDefinition variant) {
100
+		validator.logError(
101
+				ValidationLogEntry.Code.SUPERCLASS_NOT_A_CLASS,
102
+				variant.position,
103
+				"Superclass cannot be a variant");
104
+		return false;
92 105
 	}
93 106
 }

読み込み中…
キャンセル
保存