Browse Source

- Added (key, value) iterator for associative arrays

- Added type bounds checking code
- Fixed definitions not being added to the respective packages
- Fixed various bugs with generics
- Added some things to stdlib and created collections library
Stan Hebben 6 years ago
parent
commit
f307a7d81e
89 changed files with 668 additions and 228 deletions
  1. 4
    3
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/FunctionHeader.java
  2. 20
    3
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/HighLevelDefinition.java
  3. 4
    4
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/definition/ZSPackage.java
  4. 1
    1
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/CallArguments.java
  5. 2
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/CallExpression.java
  6. 4
    1
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/CallStaticExpression.java
  7. 1
    2
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/EnumConstantExpression.java
  8. 5
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/Expression.java
  9. 3
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/WrapOptionalExpression.java
  10. 1
    1
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/generic/GenericParameterBound.java
  11. 7
    3
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/generic/ParameterSuperBound.java
  12. 2
    2
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/generic/ParameterTypeBound.java
  13. 3
    2
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/generic/TypeParameter.java
  14. 1
    1
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/FunctionalMember.java
  15. 1
    2
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/InnerDefinition.java
  16. 77
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/builtin/AssocIterator.java
  17. 2
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/partial/IPartialExpression.java
  18. 8
    1
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/partial/PartialGlobalExpression.java
  19. 11
    3
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/partial/PartialMemberGroupExpression.java
  20. 5
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/partial/PartialPackageExpression.java
  21. 10
    3
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/partial/PartialStaticMemberGroupExpression.java
  22. 5
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/partial/PartialTypeExpression.java
  23. 3
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/scope/TypeScope.java
  24. 5
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/ArrayTypeID.java
  25. 6
    1
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/AssocTypeID.java
  26. 5
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/BasicTypeID.java
  27. 5
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/ConstTypeID.java
  28. 27
    15
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/DefinitionTypeID.java
  29. 5
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/FunctionTypeID.java
  30. 5
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/GenericMapTypeID.java
  31. 21
    7
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/GenericName.java
  32. 8
    2
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/GenericTypeID.java
  33. 4
    5
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/GlobalTypeRegistry.java
  34. 10
    5
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/ITypeID.java
  35. 5
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/IteratorTypeID.java
  36. 5
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/OptionalTypeID.java
  37. 5
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/RangeTypeID.java
  38. 1
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/BuiltinTypeMembers.java
  39. 3
    3
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/DefinitionMemberGroup.java
  40. 2
    2
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/LocalMemberCache.java
  41. 25
    7
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/TypeMemberBuilder.java
  42. 23
    7
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/TypeMembers.java
  43. 4
    0
      Constructor/libraries/collections/module.json
  44. 9
    0
      Constructor/libraries/collections/src/HashSet.zs
  45. 43
    0
      Constructor/libraries/collections/src/LinkedList.zs
  46. 5
    0
      Constructor/libraries/collections/src/NoSuchElementException.zs
  47. 7
    0
      Constructor/libraries/collections/src/Queue.zs
  48. 8
    0
      Constructor/libraries/collections/src/Set.zs
  49. 3
    1
      Constructor/libraries/stdlib/module.json
  50. 3
    0
      Constructor/libraries/stdlib/src/Comparable.zs
  51. 0
    0
      Constructor/libraries/stdlib/src/IllegalOperationException.zs
  52. 6
    0
      Constructor/libraries/stdlib/src/StringBuildable.zs
  53. 16
    2
      Constructor/libraries/stdlib/src/StringBuilder.zs
  54. 6
    11
      Constructor/src/main/java/org/openzen/zenscript/constructor/Main.java
  55. 30
    5
      Constructor/src/main/java/org/openzen/zenscript/constructor/Project.java
  56. 5
    0
      Constructor/src/main/java/org/openzen/zenscript/constructor/module/DirectoryModuleLoader.java
  57. 2
    0
      Constructor/src/main/java/org/openzen/zenscript/constructor/module/ModuleReference.java
  58. 11
    8
      Linker/src/main/java/org/openzen/zenscript/linker/DefinitionScope.java
  59. 2
    2
      Linker/src/main/java/org/openzen/zenscript/linker/FileScope.java
  60. 1
    1
      Linker/src/main/java/org/openzen/zenscript/linker/ForeachScope.java
  61. 2
    2
      Linker/src/main/java/org/openzen/zenscript/linker/FunctionScope.java
  62. 5
    4
      Linker/src/main/java/org/openzen/zenscript/linker/GenericFunctionScope.java
  63. 1
    1
      Linker/src/main/java/org/openzen/zenscript/linker/ImplementationScope.java
  64. 1
    1
      Linker/src/main/java/org/openzen/zenscript/linker/LambdaScope.java
  65. 1
    1
      Linker/src/main/java/org/openzen/zenscript/linker/StatementScope.java
  66. 2
    3
      Linker/src/main/java/org/openzen/zenscript/linker/symbol/ISymbol.java
  67. 2
    3
      Linker/src/main/java/org/openzen/zenscript/linker/symbol/TypeSymbol.java
  68. 2
    3
      Parser/src/main/java/org/openzen/zenscript/lexer/CompiledDFA.java
  69. 9
    0
      Parser/src/main/java/org/openzen/zenscript/lexer/TokenStream.java
  70. 1
    1
      Parser/src/main/java/org/openzen/zenscript/lexer/ZSTokenStream.java
  71. 1
    1
      Parser/src/main/java/org/openzen/zenscript/lexer/ZSTokenType.java
  72. 10
    9
      Parser/src/main/java/org/openzen/zenscript/parser/definitions/ParsedGenericParameter.java
  73. 1
    0
      Parser/src/main/java/org/openzen/zenscript/parser/definitions/ParsedInterface.java
  74. 19
    15
      Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedCallArguments.java
  75. 3
    3
      Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpressionCall.java
  76. 1
    1
      Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpressionFunction.java
  77. 5
    0
      Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpressionIndex.java
  78. 6
    11
      Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpressionMember.java
  79. 8
    7
      Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpressionVariable.java
  80. 1
    1
      Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedNewExpression.java
  81. 13
    2
      Parser/src/main/java/org/openzen/zenscript/parser/member/ParsedDefinitionMember.java
  82. 3
    1
      Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementForeach.java
  83. 28
    11
      Parser/src/main/java/org/openzen/zenscript/parser/type/IParsedType.java
  84. 2
    11
      Parser/src/main/java/org/openzen/zenscript/parser/type/ParsedNamedType.java
  85. 2
    2
      Parser/src/main/java/org/openzen/zenscript/parser/type/ParsedTypeGenericMap.java
  86. 3
    2
      ScriptingExample/src/main/java/org/openzen/zenscript/scriptingexample/GlobalRegistry.java
  87. 2
    1
      Validator/src/main/java/org/openzen/zenscript/validator/visitors/DefinitionMemberValidator.java
  88. 15
    13
      Validator/src/main/java/org/openzen/zenscript/validator/visitors/ExpressionValidator.java
  89. 8
    2
      Validator/src/main/java/org/openzen/zenscript/validator/visitors/ValidationUtils.java

+ 4
- 3
CodeModel/src/main/java/org/openzen/zenscript/codemodel/FunctionHeader.java View File

@@ -15,6 +15,7 @@ import org.openzen.zenscript.codemodel.type.BasicTypeID;
15 15
 import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
16 16
 import org.openzen.zenscript.codemodel.type.ITypeID;
17 17
 import org.openzen.zenscript.codemodel.scope.TypeScope;
18
+import org.openzen.zenscript.codemodel.type.member.LocalMemberCache;
18 19
 
19 20
 /**
20 21
  *
@@ -58,7 +59,7 @@ public class FunctionHeader {
58 59
 		return new FunctionHeader(genericParameters, returnType, parameters);
59 60
 	}
60 61
 	
61
-	public ITypeID[] inferTypes(CallArguments arguments, List<ITypeID> resultHint) {
62
+	public ITypeID[] inferTypes(LocalMemberCache cache, CallArguments arguments, List<ITypeID> resultHint) {
62 63
 		if (arguments.arguments.length != this.parameters.length)
63 64
 			return null;
64 65
 		
@@ -66,7 +67,7 @@ public class FunctionHeader {
66 67
 		if (!resultHint.isEmpty()) {
67 68
 			Map<TypeParameter, ITypeID> temp = new HashMap<>();
68 69
 			for (ITypeID hint : resultHint) {
69
-				if (returnType.inferTypeParameters(hint, temp)) {
70
+				if (returnType.inferTypeParameters(cache, hint, temp)) {
70 71
 					mapping = temp;
71 72
 					break;
72 73
 				}
@@ -75,7 +76,7 @@ public class FunctionHeader {
75 76
 		
76 77
 		// TODO: lambda header inference
77 78
 		for (int i = 0; i < parameters.length; i++)
78
-			if (!parameters[i].type.inferTypeParameters(arguments.arguments[i].type, mapping))
79
+			if (!parameters[i].type.inferTypeParameters(cache, arguments.arguments[i].type, mapping))
79 80
 				return null;
80 81
 		
81 82
 		if (mapping.size() > typeParameters.length)

+ 20
- 3
CodeModel/src/main/java/org/openzen/zenscript/codemodel/HighLevelDefinition.java View File

@@ -10,6 +10,7 @@ import java.util.List;
10 10
 import org.openzen.zenscript.codemodel.definition.DefinitionVisitor;
11 11
 import org.openzen.zenscript.codemodel.definition.ZSPackage;
12 12
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
13
+import org.openzen.zenscript.codemodel.member.ConstructorMember;
13 14
 import org.openzen.zenscript.codemodel.member.EnumConstantMember;
14 15
 import org.openzen.zenscript.codemodel.member.FieldMember;
15 16
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
@@ -22,14 +23,12 @@ import org.openzen.zenscript.shared.Taggable;
22 23
  * @author Hoofdgebruiker
23 24
  */
24 25
 public abstract class HighLevelDefinition extends Taggable {
25
-	private static final TypeParameter[] NO_PARAMETERS = new TypeParameter[0];
26
-	
27 26
 	public final CodePosition position;
28 27
 	public final ZSPackage pkg;
29 28
 	public final String name;
30 29
 	public final int modifiers;
31 30
 	public final List<IDefinitionMember> members = new ArrayList<>();
32
-	public TypeParameter[] genericParameters = NO_PARAMETERS;
31
+	public TypeParameter[] genericParameters = null;
33 32
 	
34 33
 	public HighLevelDefinition outerDefinition;
35 34
 	public ITypeID superType;
@@ -40,6 +39,13 @@ public abstract class HighLevelDefinition extends Taggable {
40 39
 		this.name = name;
41 40
 		this.modifiers = modifiers;
42 41
 		this.outerDefinition = outerDefinition;
42
+		
43
+		if (pkg != null)
44
+			pkg.register(this);
45
+	}
46
+	
47
+	public int getNumberOfGenericParameters() {
48
+		return genericParameters == null ? 0 : genericParameters.length;
43 49
 	}
44 50
 	
45 51
 	public void setOuterDefinition(HighLevelDefinition outerDefinition) {
@@ -77,6 +83,17 @@ public abstract class HighLevelDefinition extends Taggable {
77 83
 		return enumMembers;
78 84
 	}
79 85
 	
86
+	public boolean hasEmptyConstructor() {
87
+		for (IDefinitionMember member : members) {
88
+			if (member instanceof ConstructorMember) {
89
+				if (((ConstructorMember) member).header.parameters.length == 0)
90
+					return true;
91
+			}
92
+		}
93
+		
94
+		return false;
95
+	}
96
+	
80 97
 	public boolean isStatic() {
81 98
 		return (modifiers & Modifiers.STATIC) > 0;
82 99
 	}

+ 4
- 4
CodeModel/src/main/java/org/openzen/zenscript/codemodel/definition/ZSPackage.java View File

@@ -38,15 +38,15 @@ public class ZSPackage {
38 38
 		if (subPackages.containsKey(name))
39 39
 			throw new RuntimeException("Such package already exists: " + name);
40 40
 		
41
-		subPackages.put(name, this);
41
+		subPackages.put(name, subPackage);
42 42
 	}
43 43
 	
44 44
 	public IPartialExpression getMember(CodePosition position, GlobalTypeRegistry registry, GenericName name) {
45
-		if (subPackages.containsKey(name.name) && name.arguments.isEmpty())
45
+		if (subPackages.containsKey(name.name) && name.hasNoArguments())
46 46
 			return new PartialPackageExpression(position, subPackages.get(name.name));
47 47
 		
48 48
 		if (types.containsKey(name.name)) {
49
-			if (types.get(name.name).genericParameters.length != name.arguments.size())
49
+			if (types.get(name.name).genericParameters.length != name.getNumberOfArguments())
50 50
 				throw new CompileException(position, CompileExceptionCode.TYPE_ARGUMENTS_INVALID_NUMBER, "Invalid number of type arguments");
51 51
 			
52 52
 			return new PartialTypeExpression(position, registry.getForDefinition(types.get(name.name), name.arguments));
@@ -77,7 +77,7 @@ public class ZSPackage {
77 77
 			return null;
78 78
 		
79 79
 		GenericName name = nameParts.get(depth);
80
-		if (subPackages.containsKey(name.name) && name.arguments.isEmpty())
80
+		if (subPackages.containsKey(name.name) && name.hasNoArguments())
81 81
 			return subPackages.get(name.name).getType(position, scope, nameParts, depth + 1);
82 82
 		
83 83
 		if (types.containsKey(name.name)) {

+ 1
- 1
CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/CallArguments.java View File

@@ -25,7 +25,7 @@ public class CallArguments {
25 25
 	
26 26
 	public CallArguments(ITypeID[] typeArguments, Expression[] arguments) {
27 27
 		if (typeArguments == null)
28
-			throw new IllegalArgumentException("Type arguments cannot be null!");
28
+			typeArguments = NO_TYPE_ARGUMENTS;
29 29
 		if (arguments == null)
30 30
 			throw new IllegalArgumentException("Arguments cannot be null!");
31 31
 		

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

@@ -20,6 +20,7 @@ public class CallExpression extends Expression {
20 20
 	public final Expression target;
21 21
 	public final FunctionalMember member;
22 22
 	public final CallArguments arguments;
23
+	public final FunctionHeader instancedHeader;
23 24
 	
24 25
 	public CallExpression(CodePosition position, Expression target, FunctionalMember member, FunctionHeader instancedHeader, CallArguments arguments) {
25 26
 		super(position, instancedHeader.returnType);
@@ -37,6 +38,7 @@ public class CallExpression extends Expression {
37 38
 		this.target = target;
38 39
 		this.member = member;
39 40
 		this.arguments = arguments;
41
+		this.instancedHeader = instancedHeader;
40 42
 	}
41 43
 	
42 44
 	public Expression getFirstArgument() {

+ 4
- 1
CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/CallStaticExpression.java View File

@@ -5,6 +5,7 @@
5 5
  */
6 6
 package org.openzen.zenscript.codemodel.expression;
7 7
 
8
+import org.openzen.zenscript.codemodel.FunctionHeader;
8 9
 import org.openzen.zenscript.codemodel.member.FunctionalMember;
9 10
 import org.openzen.zenscript.codemodel.type.ITypeID;
10 11
 import org.openzen.zenscript.shared.CodePosition;
@@ -17,13 +18,15 @@ public class CallStaticExpression extends Expression {
17 18
 	public final FunctionalMember member;
18 19
 	public final ITypeID target;
19 20
 	public final CallArguments arguments;
21
+	public final FunctionHeader instancedHeader;
20 22
 	
21
-	public CallStaticExpression(CodePosition position, ITypeID target, FunctionalMember member, CallArguments arguments) {
23
+	public CallStaticExpression(CodePosition position, ITypeID target, FunctionalMember member, CallArguments arguments, FunctionHeader instancedHeader) {
22 24
 		super(position, member.header.returnType);
23 25
 		
24 26
 		this.member = member;
25 27
 		this.target = target;
26 28
 		this.arguments = arguments;
29
+		this.instancedHeader = instancedHeader;
27 30
 	}
28 31
 
29 32
 	@Override

+ 1
- 2
CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/EnumConstantExpression.java View File

@@ -5,7 +5,6 @@
5 5
  */
6 6
 package org.openzen.zenscript.codemodel.expression;
7 7
 
8
-import java.util.Collections;
9 8
 import org.openzen.zenscript.codemodel.definition.EnumDefinition;
10 9
 import org.openzen.zenscript.codemodel.member.EnumConstantMember;
11 10
 import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
@@ -26,7 +25,7 @@ public class EnumConstantExpression extends Expression {
26 25
 	}
27 26
 	
28 27
 	public EnumConstantExpression(CodePosition position, GlobalTypeRegistry registry, EnumDefinition type, EnumConstantMember value) {
29
-		super(position, registry.getForDefinition(type, Collections.emptyList()));
28
+		super(position, registry.getForDefinition(type, null));
30 29
 		
31 30
 		this.value = value;
32 31
 	}

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

@@ -79,4 +79,9 @@ public abstract class Expression implements IPartialExpression {
79 79
 		TypeMembers members = scope.getTypeMembers(type);
80 80
 		return members.getMemberExpression(position, this, name, false);
81 81
 	}
82
+	
83
+	@Override
84
+	public ITypeID[] getGenericCallTypes() {
85
+		return null;
86
+	}
82 87
 }

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

@@ -18,6 +18,9 @@ public class WrapOptionalExpression extends Expression {
18 18
 	public WrapOptionalExpression(CodePosition position, Expression value, ITypeID optionalType) {
19 19
 		super(position, optionalType);
20 20
 		
21
+		if (value.type.isOptional())
22
+			throw new IllegalArgumentException("Value is already optional");
23
+		
21 24
 		this.value = value;
22 25
 	}
23 26
 

+ 1
- 1
CodeModel/src/main/java/org/openzen/zenscript/codemodel/generic/GenericParameterBound.java View File

@@ -20,7 +20,7 @@ public abstract class GenericParameterBound {
20 20
 	
21 21
 	public abstract void registerMembers(LocalMemberCache cache, TypeMembers type);
22 22
 	
23
-	public abstract boolean matches(ITypeID type);
23
+	public abstract boolean matches(LocalMemberCache cache, ITypeID type);
24 24
 	
25 25
 	public abstract GenericParameterBound withGenericArguments(GlobalTypeRegistry registry, Map<TypeParameter, ITypeID> arguments);
26 26
 }

+ 7
- 3
CodeModel/src/main/java/org/openzen/zenscript/codemodel/generic/ParameterSuperBound.java View File

@@ -28,13 +28,17 @@ public class ParameterSuperBound extends GenericParameterBound {
28 28
 	}
29 29
 
30 30
 	@Override
31
-	public boolean matches(ITypeID type) {
32
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
31
+	public boolean matches(LocalMemberCache cache, ITypeID type) {
32
+		return cache.get(this.type).extendsOrImplements(type);
33 33
 	}
34 34
 
35 35
 	@Override
36 36
 	public GenericParameterBound withGenericArguments(GlobalTypeRegistry registry, Map<TypeParameter, ITypeID> arguments) {
37
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
37
+		ITypeID translated = type.withGenericArguments(registry, arguments);
38
+		if (translated == type)
39
+			return this;
40
+		
41
+		return new ParameterSuperBound(translated);
38 42
 	}
39 43
 
40 44
 	@Override

+ 2
- 2
CodeModel/src/main/java/org/openzen/zenscript/codemodel/generic/ParameterTypeBound.java View File

@@ -32,8 +32,8 @@ public class ParameterTypeBound extends GenericParameterBound {
32 32
 	}
33 33
 
34 34
 	@Override
35
-	public boolean matches(ITypeID type) {
36
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
35
+	public boolean matches(LocalMemberCache cache, ITypeID type) {
36
+		return cache.get(type).extendsOrImplements(this.type);
37 37
 	}
38 38
 
39 39
 	@Override

+ 3
- 2
CodeModel/src/main/java/org/openzen/zenscript/codemodel/generic/TypeParameter.java View File

@@ -10,6 +10,7 @@ import java.util.List;
10 10
 import java.util.Map;
11 11
 import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
12 12
 import org.openzen.zenscript.codemodel.type.ITypeID;
13
+import org.openzen.zenscript.codemodel.type.member.LocalMemberCache;
13 14
 import org.openzen.zenscript.shared.CodePosition;
14 15
 
15 16
 /**
@@ -36,9 +37,9 @@ public class TypeParameter {
36 37
 		bounds.add(bound);
37 38
 	}
38 39
 	
39
-	public boolean matches(ITypeID type) {
40
+	public boolean matches(LocalMemberCache cache, ITypeID type) {
40 41
 		for (GenericParameterBound bound : bounds) {
41
-			if (!bound.matches(type))
42
+			if (!bound.matches(cache, type))
42 43
 				return false;
43 44
 		}
44 45
 		

+ 1
- 1
CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/FunctionalMember.java View File

@@ -58,7 +58,7 @@ public abstract class FunctionalMember extends DefinitionMember implements ICall
58 58
 	
59 59
 	@Override
60 60
 	public Expression callStatic(CodePosition position, ITypeID target, FunctionHeader instancedHeader, CallArguments arguments) {
61
-		return new CallStaticExpression(position, target, this, arguments);
61
+		return new CallStaticExpression(position, target, this, arguments, instancedHeader);
62 62
 	}
63 63
 	
64 64
 	@Override

+ 1
- 2
CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/InnerDefinition.java View File

@@ -6,7 +6,6 @@
6 6
 package org.openzen.zenscript.codemodel.member;
7 7
 
8 8
 import java.util.Collections;
9
-import java.util.List;
10 9
 import java.util.Map;
11 10
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
12 11
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
@@ -32,7 +31,7 @@ public class InnerDefinition {
32 31
 		this.outerTypeArguments = outerTypeArguments;
33 32
 	}
34 33
 	
35
-	public DefinitionTypeID instance(GlobalTypeRegistry registry, List<ITypeID> typeArguments) {
34
+	public DefinitionTypeID instance(GlobalTypeRegistry registry, ITypeID[] typeArguments) {
36 35
 		return registry.getForDefinition(definition, typeArguments, outerTypeArguments);
37 36
 	}
38 37
 }

+ 77
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/builtin/AssocIterator.java View File

@@ -0,0 +1,77 @@
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.member.builtin;
7
+
8
+import java.util.Map;
9
+import org.openzen.zenscript.codemodel.generic.TypeParameter;
10
+import org.openzen.zenscript.codemodel.iterator.ForeachIteratorVisitor;
11
+import org.openzen.zenscript.codemodel.member.IDefinitionMember;
12
+import org.openzen.zenscript.codemodel.member.IIteratorMember;
13
+import org.openzen.zenscript.codemodel.member.MemberVisitor;
14
+import org.openzen.zenscript.codemodel.type.AssocTypeID;
15
+import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
16
+import org.openzen.zenscript.codemodel.type.ITypeID;
17
+import org.openzen.zenscript.codemodel.type.member.TypeMemberPriority;
18
+import org.openzen.zenscript.codemodel.type.member.TypeMembers;
19
+import org.openzen.zenscript.shared.CodePosition;
20
+import org.openzen.zenscript.shared.Taggable;
21
+
22
+/**
23
+ *
24
+ * @author Hoofdgebruiker
25
+ */
26
+public class AssocIterator extends Taggable implements IIteratorMember {
27
+	private final AssocTypeID type;
28
+	private final ITypeID[] loopVariableTypes;
29
+	
30
+	public AssocIterator(AssocTypeID type) {
31
+		this.type = type;
32
+		
33
+		loopVariableTypes = new ITypeID[2];
34
+		loopVariableTypes[0] = type.keyType;
35
+		loopVariableTypes[1] = type.valueType;
36
+	}
37
+	
38
+	@Override
39
+	public CodePosition getPosition() {
40
+		return CodePosition.BUILTIN;
41
+	}
42
+
43
+	@Override
44
+	public int getLoopVariableCount() {
45
+		return loopVariableTypes.length;
46
+	}
47
+
48
+	@Override
49
+	public ITypeID[] getLoopVariableTypes() {
50
+		return loopVariableTypes;
51
+	}
52
+
53
+	@Override
54
+	public String describe() {
55
+		return "iterator for key/value pairs in an associative array";
56
+	}
57
+
58
+	@Override
59
+	public void registerTo(TypeMembers type, TypeMemberPriority priority) {
60
+		type.addIterator(this, priority);
61
+	}
62
+
63
+	@Override
64
+	public IDefinitionMember instance(GlobalTypeRegistry registry, Map<TypeParameter, ITypeID> mapping) {
65
+		return new AssocIterator(type.withGenericArguments(registry, mapping));
66
+	}
67
+
68
+	@Override
69
+	public <T> T accept(MemberVisitor<T> visitor) {
70
+		throw new UnsupportedOperationException("Not a compilable member");
71
+	}
72
+
73
+	@Override
74
+	public <T> T acceptForIterator(ForeachIteratorVisitor<T> visitor) {
75
+		return visitor.visitArrayKeyValueIterator();
76
+	}
77
+}

+ 2
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/partial/IPartialExpression.java View File

@@ -37,6 +37,8 @@ public interface IPartialExpression {
37 37
 	
38 38
 	Expression call(CodePosition position, TypeScope scope, List<ITypeID> hints, CallArguments arguments);
39 39
 	
40
+	ITypeID[] getGenericCallTypes();
41
+	
40 42
 	default Expression assign(CodePosition position, TypeScope scope, Expression value) {
41 43
 		throw new CompileException(position, CompileExceptionCode.CANNOT_ASSIGN, "This expression is not assignable");
42 44
 	}

+ 8
- 1
CodeModel/src/main/java/org/openzen/zenscript/codemodel/partial/PartialGlobalExpression.java View File

@@ -24,11 +24,13 @@ public class PartialGlobalExpression implements IPartialExpression {
24 24
 	private final CodePosition position;
25 25
 	private final String name;
26 26
 	private final IPartialExpression resolution;
27
+	private final ITypeID[] typeParameters;
27 28
 	
28
-	public PartialGlobalExpression(CodePosition position, String name, IPartialExpression resolution) {
29
+	public PartialGlobalExpression(CodePosition position, String name, IPartialExpression resolution, ITypeID[] typeParameters) {
29 30
 		this.position = position;
30 31
 		this.name = name;
31 32
 		this.resolution = resolution;
33
+		this.typeParameters = typeParameters;
32 34
 	}
33 35
 	
34 36
 	@Override
@@ -55,4 +57,9 @@ public class PartialGlobalExpression implements IPartialExpression {
55 57
 	public Expression call(CodePosition position, TypeScope scope, List<ITypeID> hints, CallArguments arguments) {
56 58
 		return new GlobalCallExpression(position, name, arguments, resolution.call(position, scope, hints, arguments));
57 59
 	}
60
+
61
+	@Override
62
+	public ITypeID[] getGenericCallTypes() {
63
+		return typeParameters;
64
+	}
58 65
 }

+ 11
- 3
CodeModel/src/main/java/org/openzen/zenscript/codemodel/partial/PartialMemberGroupExpression.java View File

@@ -27,19 +27,22 @@ public class PartialMemberGroupExpression implements IPartialExpression {
27 27
 	private final CodePosition position;
28 28
 	private final Expression target;
29 29
 	private final DefinitionMemberGroup group;
30
+	private final ITypeID[] typeArguments;
30 31
 	private final boolean allowStaticUsage;
31 32
 	
32
-	public PartialMemberGroupExpression(CodePosition position, Expression target, DefinitionMemberGroup group, boolean allowStaticMembers) {
33
+	public PartialMemberGroupExpression(CodePosition position, Expression target, DefinitionMemberGroup group, ITypeID[] typeArguments, boolean allowStaticMembers) {
33 34
 		this.position = position;
34 35
 		this.target = target;
35 36
 		this.group = group;
37
+		this.typeArguments = typeArguments;
36 38
 		this.allowStaticUsage = allowStaticMembers;
37 39
 	}
38 40
 	
39
-	public PartialMemberGroupExpression(CodePosition position, Expression target, ICallableMember member, boolean allowStaticMembers) {
41
+	public PartialMemberGroupExpression(CodePosition position, Expression target, ICallableMember member, ITypeID[] typeArguments, boolean allowStaticMembers) {
40 42
 		this.position = position;
41 43
 		this.target = target;
42 44
 		this.group = DefinitionMemberGroup.forMethod(member);
45
+		this.typeArguments = typeArguments;
43 46
 		this.allowStaticUsage = allowStaticMembers;
44 47
 	}
45 48
 
@@ -91,6 +94,11 @@ public class PartialMemberGroupExpression implements IPartialExpression {
91 94
 	
92 95
 	@Override
93 96
 	public IPartialExpression capture(CodePosition position, LambdaClosure closure) {
94
-		return new PartialMemberGroupExpression(position, target.capture(position, closure).eval(), group, allowStaticUsage);
97
+		return new PartialMemberGroupExpression(position, target.capture(position, closure).eval(), group, typeArguments, allowStaticUsage);
98
+	}
99
+
100
+	@Override
101
+	public ITypeID[] getGenericCallTypes() {
102
+		return typeArguments;
95 103
 	}
96 104
 }

+ 5
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/partial/PartialPackageExpression.java View File

@@ -55,4 +55,9 @@ public class PartialPackageExpression implements IPartialExpression {
55 55
 	public Expression call(CodePosition position, TypeScope scope, List<ITypeID> hints, CallArguments arguments) {
56 56
 		throw new CompileException(position, CompileExceptionCode.USING_PACKAGE_AS_CALL_TARGET, "Cannot call a package");
57 57
 	}
58
+
59
+	@Override
60
+	public ITypeID[] getGenericCallTypes() {
61
+		return null;
62
+	}
58 63
 }

+ 10
- 3
CodeModel/src/main/java/org/openzen/zenscript/codemodel/partial/PartialStaticMemberGroupExpression.java View File

@@ -23,20 +23,22 @@ import org.openzen.zenscript.codemodel.type.member.TypeMemberPriority;
23 23
  * @author Hoofdgebruiker
24 24
  */
25 25
 public class PartialStaticMemberGroupExpression implements IPartialExpression {
26
-	public static PartialStaticMemberGroupExpression forMethod(CodePosition position, ITypeID target, ICallableMember method) {
26
+	public static PartialStaticMemberGroupExpression forMethod(CodePosition position, ITypeID target, ICallableMember method, ITypeID[] typeArguments) {
27 27
 		DefinitionMemberGroup group = new DefinitionMemberGroup(true);
28 28
 		group.addMethod(method, TypeMemberPriority.SPECIFIED);
29
-		return new PartialStaticMemberGroupExpression(position, target, group);
29
+		return new PartialStaticMemberGroupExpression(position, target, group, typeArguments);
30 30
 	}
31 31
 	
32 32
 	private final CodePosition position;
33 33
 	private final ITypeID target;
34 34
 	private final DefinitionMemberGroup group;
35
+	private final ITypeID[] typeArguments;
35 36
 	
36
-	public PartialStaticMemberGroupExpression(CodePosition position, ITypeID target, DefinitionMemberGroup group) {
37
+	public PartialStaticMemberGroupExpression(CodePosition position, ITypeID target, DefinitionMemberGroup group, ITypeID[] typeArguments) {
37 38
 		this.position = position;
38 39
 		this.group = group;
39 40
 		this.target = target;
41
+		this.typeArguments = typeArguments;
40 42
 	}
41 43
 	
42 44
 	@Override
@@ -71,4 +73,9 @@ public class PartialStaticMemberGroupExpression implements IPartialExpression {
71 73
 	public Expression assign(CodePosition position, TypeScope scope, Expression value) {
72 74
 		return group.staticSetter(position, scope, value);
73 75
 	}
76
+
77
+	@Override
78
+	public ITypeID[] getGenericCallTypes() {
79
+		return typeArguments;
80
+	}
74 81
 }

+ 5
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/partial/PartialTypeExpression.java View File

@@ -60,4 +60,9 @@ public class PartialTypeExpression implements IPartialExpression {
60 60
 	public Expression call(CodePosition position, TypeScope scope, List<ITypeID> hints, CallArguments arguments) {
61 61
 		return scope.getTypeMembers(type).getOrCreateGroup(OperatorType.CALL).callStatic(position, type, scope, arguments);
62 62
 	}
63
+
64
+	@Override
65
+	public ITypeID[] getGenericCallTypes() {
66
+		return null;
67
+	}
63 68
 }

+ 3
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/scope/TypeScope.java View File

@@ -7,6 +7,7 @@ package org.openzen.zenscript.codemodel.scope;
7 7
 
8 8
 import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
9 9
 import org.openzen.zenscript.codemodel.type.ITypeID;
10
+import org.openzen.zenscript.codemodel.type.member.LocalMemberCache;
10 11
 import org.openzen.zenscript.codemodel.type.member.TypeMembers;
11 12
 
12 13
 /**
@@ -16,5 +17,7 @@ import org.openzen.zenscript.codemodel.type.member.TypeMembers;
16 17
 public interface TypeScope {
17 18
 	public GlobalTypeRegistry getTypeRegistry();
18 19
 	
20
+	public LocalMemberCache getMemberCache();
21
+	
19 22
 	public TypeMembers getTypeMembers(ITypeID type);
20 23
 }

+ 5
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/ArrayTypeID.java View File

@@ -54,6 +54,11 @@ public class ArrayTypeID implements ITypeID {
54 54
 		return elementType.hasInferenceBlockingTypeParameters(parameters);
55 55
 	}
56 56
 
57
+	@Override
58
+	public boolean hasDefaultValue() {
59
+		return false;
60
+	}
61
+
57 62
 	@Override
58 63
 	public int hashCode() {
59 64
 		int hash = 7;

+ 6
- 1
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/AssocTypeID.java View File

@@ -22,7 +22,7 @@ public class AssocTypeID implements ITypeID {
22 22
 	}
23 23
 	
24 24
 	@Override
25
-	public ITypeID withGenericArguments(GlobalTypeRegistry registry, Map<TypeParameter, ITypeID> arguments) {
25
+	public AssocTypeID withGenericArguments(GlobalTypeRegistry registry, Map<TypeParameter, ITypeID> arguments) {
26 26
 		return registry.getAssociative(
27 27
 				keyType.withGenericArguments(registry, arguments),
28 28
 				valueType.withGenericArguments(registry, arguments));
@@ -53,6 +53,11 @@ public class AssocTypeID implements ITypeID {
53 53
 		return keyType.hasInferenceBlockingTypeParameters(parameters) || valueType.hasInferenceBlockingTypeParameters(parameters);
54 54
 	}
55 55
 
56
+	@Override
57
+	public boolean hasDefaultValue() {
58
+		return true;
59
+	}
60
+
56 61
 	@Override
57 62
 	public int hashCode() {
58 63
 		int hash = 7;

+ 5
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/BasicTypeID.java View File

@@ -76,4 +76,9 @@ public enum BasicTypeID implements ITypeID {
76 76
 	public boolean hasInferenceBlockingTypeParameters(TypeParameter[] parameters) {
77 77
 		return false;
78 78
 	}
79
+
80
+	@Override
81
+	public boolean hasDefaultValue() {
82
+		return true;
83
+	}
79 84
 }

+ 5
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/ConstTypeID.java View File

@@ -82,4 +82,9 @@ public class ConstTypeID implements ITypeID {
82 82
 	public String toString() {
83 83
 		return "const " + baseType.toString();
84 84
 	}
85
+
86
+	@Override
87
+	public boolean hasDefaultValue() {
88
+		return baseType.hasDefaultValue();
89
+	}
85 90
 }

+ 27
- 15
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/DefinitionTypeID.java View File

@@ -5,11 +5,9 @@
5 5
  */
6 6
 package org.openzen.zenscript.codemodel.type;
7 7
 
8
-import java.util.ArrayList;
9 8
 import java.util.Arrays;
10 9
 import java.util.Collections;
11 10
 import java.util.HashMap;
12
-import java.util.List;
13 11
 import java.util.Map;
14 12
 import java.util.Objects;
15 13
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
@@ -24,11 +22,10 @@ public class DefinitionTypeID implements ITypeID {
24 22
 		if (definition.genericParameters.length > 0)
25 23
 			throw new IllegalArgumentException("Definition has type arguments!");
26 24
 		
27
-		return new DefinitionTypeID(definition, NO_TYPE_PARAMETERS);
25
+		return new DefinitionTypeID(definition, null);
28 26
 	}
29 27
 	
30 28
 	private static final OuterTypeEntry[] NO_OUTER_ENTRIES = new OuterTypeEntry[0];
31
-	private static final ITypeID[] NO_TYPE_PARAMETERS = new ITypeID[0];
32 29
 	
33 30
 	public final HighLevelDefinition definition;
34 31
 	public final ITypeID[] typeParameters;
@@ -57,13 +54,17 @@ public class DefinitionTypeID implements ITypeID {
57 54
 			Arrays.sort(outerTypeEntries, (a, b) -> a.parameter.name.compareTo(b.parameter.name));
58 55
 		}
59 56
 		
60
-		if (typeParameters.length != definition.genericParameters.length)
57
+		if ((typeParameters == null ? 0 : typeParameters.length) != definition.getNumberOfGenericParameters())
61 58
 			throw new RuntimeException("Invalid number of type parameters");
62 59
 	}
63 60
 	
61
+	public boolean hasTypeParameters() {
62
+		return typeParameters != null && typeParameters.length > 0;
63
+	}
64
+	
64 65
 	public void init(GlobalTypeRegistry registry) {
65 66
 		ITypeID superType = definition.superType;
66
-		if (superType != null && typeParameters.length > 0) {
67
+		if (superType != null && hasTypeParameters()) {
67 68
 			Map<TypeParameter, ITypeID> genericSuperArguments = new HashMap<>();
68 69
 			for (int i = 0; i < typeParameters.length; i++)
69 70
 				genericSuperArguments.put(definition.genericParameters[i], typeParameters[i]);
@@ -76,7 +77,7 @@ public class DefinitionTypeID implements ITypeID {
76 77
 	// To be used exclusively by StaticDefinitionTypeID
77 78
 	protected DefinitionTypeID(HighLevelDefinition definition) {
78 79
 		this.definition = definition;
79
-		this.typeParameters = new ITypeID[0];
80
+		this.typeParameters = null;
80 81
 		this.superType = definition.superType;
81 82
 		this.outerTypeParameters = Collections.emptyMap();
82 83
 		this.outerTypeEntries = NO_OUTER_ENTRIES;
@@ -84,13 +85,17 @@ public class DefinitionTypeID implements ITypeID {
84 85
 	
85 86
 	@Override
86 87
 	public ITypeID withGenericArguments(GlobalTypeRegistry registry, Map<TypeParameter, ITypeID> arguments) {
87
-		if (typeParameters.length == 0 && outerTypeParameters.isEmpty())
88
+		if (!hasTypeParameters() && outerTypeParameters.isEmpty())
88 89
 			return this;
89 90
 		
90
-		List<ITypeID> instancedArguments = new ArrayList<>();
91
-		for (int i = 0; i < typeParameters.length; i++) {
92
-			instancedArguments.add(arguments.containsKey(definition.genericParameters[i]) ? arguments.get(definition.genericParameters[i]) : typeParameters[i].withGenericArguments(registry, arguments));
91
+		ITypeID[] instancedArguments = null;
92
+		if (typeParameters != null) {
93
+			instancedArguments = new ITypeID[typeParameters.length];
94
+			for (int i = 0; i < typeParameters.length; i++) {
95
+				instancedArguments[i] = arguments.containsKey(definition.genericParameters[i]) ? arguments.get(definition.genericParameters[i]) : typeParameters[i].withGenericArguments(registry, arguments);
96
+			}
93 97
 		}
98
+		
94 99
 		Map<TypeParameter, ITypeID> instancedOuter;
95 100
 		if (outerTypeParameters.isEmpty()) {
96 101
 			instancedOuter = Collections.emptyMap();
@@ -129,9 +134,11 @@ public class DefinitionTypeID implements ITypeID {
129 134
 
130 135
 	@Override
131 136
 	public boolean hasInferenceBlockingTypeParameters(TypeParameter[] parameters) {
132
-		for (ITypeID typeParameter : typeParameters)
133
-			if (typeParameter.hasInferenceBlockingTypeParameters(parameters))
134
-				return true;
137
+		if (typeParameters != null) {
138
+			for (ITypeID typeParameter : typeParameters)
139
+				if (typeParameter.hasInferenceBlockingTypeParameters(parameters))
140
+					return true;
141
+		}
135 142
 		
136 143
 		return superType != null && superType.hasInferenceBlockingTypeParameters(parameters);
137 144
 	}
@@ -164,7 +171,7 @@ public class DefinitionTypeID implements ITypeID {
164 171
 	
165 172
 	@Override
166 173
 	public String toString() {
167
-		if (typeParameters.length == 0) {
174
+		if (typeParameters == null) {
168 175
 			return definition.name;
169 176
 		} else {
170 177
 			StringBuilder result = new StringBuilder();
@@ -179,6 +186,11 @@ public class DefinitionTypeID implements ITypeID {
179 186
 			return result.toString();
180 187
 		}
181 188
 	}
189
+
190
+	@Override
191
+	public boolean hasDefaultValue() {
192
+		return definition.hasEmptyConstructor();
193
+	}
182 194
 	
183 195
 	private class OuterTypeEntry {
184 196
 		private final TypeParameter parameter;

+ 5
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/FunctionTypeID.java View File

@@ -52,6 +52,11 @@ public class FunctionTypeID implements ITypeID {
52 52
 		return header.hasInferenceBlockingTypeParameters(parameters);
53 53
 	}
54 54
 
55
+	@Override
56
+	public boolean hasDefaultValue() {
57
+		return false;
58
+	}
59
+
55 60
 	@Override
56 61
 	public int hashCode() {
57 62
 		int hash = 5;

+ 5
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/GenericMapTypeID.java View File

@@ -52,6 +52,11 @@ public class GenericMapTypeID implements ITypeID {
52 52
 	public boolean hasInferenceBlockingTypeParameters(TypeParameter[] parameters) {
53 53
 		return value.hasInferenceBlockingTypeParameters(parameters);
54 54
 	}
55
+
56
+	@Override
57
+	public boolean hasDefaultValue() {
58
+		return true;
59
+	}
55 60
 	
56 61
 	@Override
57 62
 	public String toString() {

+ 21
- 7
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/GenericName.java View File

@@ -5,31 +5,45 @@
5 5
  */
6 6
 package org.openzen.zenscript.codemodel.type;
7 7
 
8
-import java.util.Collections;
9
-import java.util.List;
10
-
11 8
 /**
12 9
  *
13 10
  * @author Hoofdgebruiker
14 11
  */
15 12
 public class GenericName {
16 13
 	public final String name;
17
-	public final List<ITypeID> arguments;
14
+	public final ITypeID[] arguments;
18 15
 	
19 16
 	public GenericName(String name) {
20
-		this(name, Collections.emptyList());
17
+		this(name, null);
21 18
 	}
22 19
 	
23
-	public GenericName(String name, List<ITypeID> arguments) {
20
+	public GenericName(String name, ITypeID[] arguments) {
24 21
 		this.name = name;
25 22
 		this.arguments = arguments;
26 23
 	}
27 24
 	
25
+	public int getNumberOfArguments() {
26
+		return arguments == null ? 0 : arguments.length;
27
+	}
28
+	
29
+	public boolean hasArguments() {
30
+		return arguments != null && arguments.length > 0;
31
+	}
32
+	
33
+	public boolean hasNoArguments() {
34
+		return arguments == null || arguments.length == 0;
35
+	}
36
+	
28 37
 	@Override
29 38
 	public String toString() {
30 39
 		StringBuilder result = new StringBuilder(name);
31
-		if (!arguments.isEmpty()) {
40
+		if (arguments != null) {
32 41
 			result.append("<");
42
+			for (int i = 0; i < arguments.length; i++) {
43
+				if (i > 0)
44
+					result.append(", ");
45
+				result.append(arguments[i].toString());
46
+			}
33 47
 			result.append(">");
34 48
 		}
35 49
 		return result.toString();

+ 8
- 2
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/GenericTypeID.java View File

@@ -7,6 +7,7 @@ package org.openzen.zenscript.codemodel.type;
7 7
 
8 8
 import java.util.Map;
9 9
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
10
+import org.openzen.zenscript.codemodel.type.member.LocalMemberCache;
10 11
 
11 12
 /**
12 13
  *
@@ -19,8 +20,8 @@ public class GenericTypeID implements ITypeID {
19 20
 		this.parameter = parameter;
20 21
 	}
21 22
 	
22
-	public boolean matches(ITypeID type) {
23
-		return parameter.matches(type);
23
+	public boolean matches(LocalMemberCache cache, ITypeID type) {
24
+		return parameter.matches(cache, type);
24 25
 	}
25 26
 	
26 27
 	@Override
@@ -57,6 +58,11 @@ public class GenericTypeID implements ITypeID {
57 58
 		return false;
58 59
 	}
59 60
 
61
+	@Override
62
+	public boolean hasDefaultValue() {
63
+		return false;
64
+	}
65
+
60 66
 	@Override
61 67
 	public int hashCode() {
62 68
 		int hash = 7;

+ 4
- 5
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/GlobalTypeRegistry.java View File

@@ -7,7 +7,6 @@ package org.openzen.zenscript.codemodel.type;
7 7
 
8 8
 import java.util.Collections;
9 9
 import java.util.HashMap;
10
-import java.util.List;
11 10
 import java.util.Map;
12 11
 import org.openzen.zenscript.codemodel.FunctionHeader;
13 12
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
@@ -111,17 +110,17 @@ public class GlobalTypeRegistry {
111 110
 		}
112 111
 	}
113 112
 	
114
-	public DefinitionTypeID getForDefinition(HighLevelDefinition definition, List<ITypeID> genericArguments) {
113
+	public DefinitionTypeID getForDefinition(HighLevelDefinition definition, ITypeID[] genericArguments) {
115 114
 		return this.getForDefinition(definition, genericArguments, Collections.emptyMap());
116 115
 	}
117 116
 	
118
-	public DefinitionTypeID getForDefinition(HighLevelDefinition definition, List<ITypeID> typeParameters, Map<TypeParameter, ITypeID> outerInstance) {
117
+	public DefinitionTypeID getForDefinition(HighLevelDefinition definition, ITypeID[] typeParameters, Map<TypeParameter, ITypeID> outerInstance) {
119 118
 		DefinitionTypeID id;
120
-		if (definition.genericParameters.length > 0 && typeParameters.isEmpty() && outerInstance.isEmpty()) {
119
+		if (definition.genericParameters == null && typeParameters == null && outerInstance.isEmpty()) {
121 120
 			// make it a static one
122 121
 			id = new StaticDefinitionTypeID(definition);
123 122
 		} else {
124
-			id = new DefinitionTypeID(definition, typeParameters.toArray(new ITypeID[typeParameters.size()]), outerInstance);
123
+			id = new DefinitionTypeID(definition, typeParameters, outerInstance);
125 124
 		}
126 125
 		
127 126
 		if (definitionTypes.containsKey(id)) {

+ 10
- 5
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/ITypeID.java View File

@@ -7,6 +7,7 @@ package org.openzen.zenscript.codemodel.type;
7 7
 
8 8
 import java.util.Map;
9 9
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
10
+import org.openzen.zenscript.codemodel.type.member.LocalMemberCache;
10 11
 
11 12
 /**
12 13
  *
@@ -33,23 +34,27 @@ public interface ITypeID {
33 34
 		return this;
34 35
 	}
35 36
 	
37
+	public boolean hasDefaultValue();
38
+	
36 39
 	public ITypeID withGenericArguments(GlobalTypeRegistry registry, Map<TypeParameter, ITypeID> arguments);
37 40
 	
38 41
 	public boolean hasInferenceBlockingTypeParameters(TypeParameter[] parameters);
39 42
 	
40 43
 	// Infers type parameters for this type so it matches with targetType
41 44
 	// returns false if that isn't possible
42
-	public default boolean inferTypeParameters(ITypeID targetType, Map<TypeParameter, ITypeID> mapping) {
43
-		return accept(new MatchingTypeVisitor(targetType, mapping));
45
+	public default boolean inferTypeParameters(LocalMemberCache cache, ITypeID targetType, Map<TypeParameter, ITypeID> mapping) {
46
+		return accept(new MatchingTypeVisitor(cache, targetType, mapping));
44 47
 	}
45 48
 	
46 49
 	public static class MatchingTypeVisitor implements ITypeVisitor<Boolean> {
47 50
 		private final ITypeID type;
48 51
 		private final Map<TypeParameter, ITypeID> mapping;
52
+		private final LocalMemberCache cache;
49 53
 		
50
-		public MatchingTypeVisitor(ITypeID type, Map<TypeParameter, ITypeID> mapping) {
54
+		public MatchingTypeVisitor(LocalMemberCache cache, ITypeID type, Map<TypeParameter, ITypeID> mapping) {
51 55
 			this.type = type;
52 56
 			this.mapping = mapping;
57
+			this.cache = cache;
53 58
 		}
54 59
 
55 60
 		@Override
@@ -141,7 +146,7 @@ public interface ITypeID {
141 146
 		public Boolean visitGeneric(GenericTypeID generic) {
142 147
 			if (mapping.containsKey(generic.parameter)) {
143 148
 				return mapping.get(generic.parameter) == type;
144
-			} else if (generic.matches(type)) {
149
+			} else if (generic.matches(cache, type)) {
145 150
 				mapping.put(generic.parameter, type);
146 151
 				return true;
147 152
 			} else {
@@ -183,7 +188,7 @@ public interface ITypeID {
183 188
 			if (type == pattern)
184 189
 				return true;
185 190
 			
186
-			return pattern.accept(new MatchingTypeVisitor(type, mapping));
191
+			return pattern.accept(new MatchingTypeVisitor(cache, type, mapping));
187 192
 		}
188 193
 
189 194
 		@Override

+ 5
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/IteratorTypeID.java View File

@@ -58,6 +58,11 @@ public class IteratorTypeID implements ITypeID {
58 58
 		return false;
59 59
 	}
60 60
 
61
+	@Override
62
+	public boolean hasDefaultValue() {
63
+		return false;
64
+	}
65
+
61 66
 	@Override
62 67
 	public int hashCode() {
63 68
 		int hash = 5;

+ 5
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/OptionalTypeID.java View File

@@ -61,6 +61,11 @@ public class OptionalTypeID implements ITypeID {
61 61
 		return baseType.hasInferenceBlockingTypeParameters(parameters);
62 62
 	}
63 63
 
64
+	@Override
65
+	public boolean hasDefaultValue() {
66
+		return true;
67
+	}
68
+
64 69
 	@Override
65 70
 	public int hashCode() {
66 71
 		int hash = 7;

+ 5
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/RangeTypeID.java View File

@@ -55,6 +55,11 @@ public class RangeTypeID implements ITypeID {
55 55
 		return from.hasInferenceBlockingTypeParameters(parameters) || to.hasInferenceBlockingTypeParameters(parameters);
56 56
 	}
57 57
 
58
+	@Override
59
+	public boolean hasDefaultValue() {
60
+		return false;
61
+	}
62
+
58 63
 	@Override
59 64
 	public int hashCode() {
60 65
 		int hash = 5;

+ 1
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/BuiltinTypeMembers.java View File

@@ -224,6 +224,7 @@ public class BuiltinTypeMembers {
224 224
 	public static final OperatorMember STRING_INDEXGET = new OperatorMember(BUILTIN, T_STRING, Modifiers.EXPORT | Modifiers.EXTERN, OperatorType.INDEXGET, new FunctionHeader(CHAR, new FunctionParameter(INT)));
225 225
 	public static final OperatorMember STRING_RANGEGET = new OperatorMember(BUILTIN, T_STRING, Modifiers.EXPORT | Modifiers.EXTERN, OperatorType.INDEXGET, new FunctionHeader(STRING, new FunctionParameter(RangeTypeID.INT)));
226 226
 	public static final GetterMember STRING_LENGTH = new GetterMember(BUILTIN, T_STRING, Modifiers.EXPORT | Modifiers.EXTERN, "length", INT);
227
+	public static final GetterMember STRING_CHARACTERS = new GetterMember(BUILTIN, T_STRING, Modifiers.PUBLIC | Modifiers.EXTERN, "characters", ArrayTypeID.CHAR);
227 228
 	
228 229
 	private static OperatorMember not(ClassDefinition cls, ITypeID result) {
229 230
 		return new OperatorMember(BUILTIN, cls, 0, OperatorType.NOT, new FunctionHeader(result));

+ 3
- 3
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/DefinitionMemberGroup.java View File

@@ -218,7 +218,7 @@ public class DefinitionMemberGroup {
218 218
 			if (header.typeParameters.length > 0) {
219 219
 				for (ITypeID resultHint : typeHints) {
220 220
 					Map<TypeParameter, ITypeID> mapping = new HashMap<>();
221
-					if (header.returnType.inferTypeParameters(resultHint, mapping)) {
221
+					if (header.returnType.inferTypeParameters(scope.getMemberCache(), resultHint, mapping)) {
222 222
 						header = header.withGenericArguments(scope.getTypeRegistry(), mapping);
223 223
 						break;
224 224
 					}
@@ -236,11 +236,11 @@ public class DefinitionMemberGroup {
236 236
 	
237 237
 	public Expression call(CodePosition position, TypeScope scope, Expression target, CallArguments arguments, boolean allowStaticUsage) {
238 238
 		ICallableMember method = selectMethod(position, scope, arguments, true, allowStaticUsage);
239
+		FunctionHeader instancedHeader = method.getHeader().withGenericArguments(scope.getTypeRegistry(), arguments.typeArguments);
239 240
 		for (int i = 0; i < arguments.arguments.length; i++) {
240
-			arguments.arguments[i] = arguments.arguments[i].castImplicit(position, scope, method.getHeader().parameters[i].type);
241
+			arguments.arguments[i] = arguments.arguments[i].castImplicit(position, scope, instancedHeader.parameters[i].type);
241 242
 		}
242 243
 		
243
-		FunctionHeader instancedHeader = method.getHeader().withGenericArguments(scope.getTypeRegistry(), arguments.typeArguments);
244 244
 		return method.call(position, target, instancedHeader, arguments);
245 245
 	}
246 246
 	

+ 2
- 2
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/LocalMemberCache.java View File

@@ -54,7 +54,7 @@ public class LocalMemberCache {
54 54
 	}
55 55
 	
56 56
 	private void registerMembers(TypeMembers members) {
57
-		members.type.accept(new TypeMemberBuilder(members, this));
57
+		members.type.accept(new TypeMemberBuilder(registry, members, this));
58 58
 		
59 59
 		for (ExpansionDefinition expansion : expansions) {
60 60
 			if (expansion.target == null)
@@ -78,7 +78,7 @@ public class LocalMemberCache {
78 78
 			return Collections.emptyMap();
79 79
 		
80 80
 		Map<TypeParameter, ITypeID> mapping = new HashMap<>();
81
-		if (pattern.inferTypeParameters(type, mapping))
81
+		if (pattern.inferTypeParameters(this, type, mapping))
82 82
 			return mapping;
83 83
 		
84 84
 		return null;

+ 25
- 7
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/TypeMemberBuilder.java View File

@@ -35,6 +35,7 @@ import org.openzen.zenscript.codemodel.member.OperatorMember;
35 35
 import org.openzen.zenscript.codemodel.member.TranslatedOperatorMember;
36 36
 import org.openzen.zenscript.codemodel.member.builtin.ArrayIteratorKeyValues;
37 37
 import org.openzen.zenscript.codemodel.member.builtin.ArrayIteratorValues;
38
+import org.openzen.zenscript.codemodel.member.builtin.AssocIterator;
38 39
 import org.openzen.zenscript.codemodel.member.builtin.ComparatorMember;
39 40
 import org.openzen.zenscript.codemodel.member.builtin.ConstantGetterMember;
40 41
 import org.openzen.zenscript.codemodel.member.builtin.RangeIterator;
@@ -48,6 +49,7 @@ import org.openzen.zenscript.codemodel.type.DefinitionTypeID;
48 49
 import org.openzen.zenscript.codemodel.type.FunctionTypeID;
49 50
 import org.openzen.zenscript.codemodel.type.GenericMapTypeID;
50 51
 import org.openzen.zenscript.codemodel.type.GenericTypeID;
52
+import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
51 53
 import org.openzen.zenscript.codemodel.type.ITypeID;
52 54
 import org.openzen.zenscript.codemodel.type.ITypeVisitor;
53 55
 import org.openzen.zenscript.codemodel.type.IteratorTypeID;
@@ -61,10 +63,12 @@ import static org.openzen.zenscript.shared.CodePosition.BUILTIN;
61 63
  * @author Hoofdgebruiker
62 64
  */
63 65
 public class TypeMemberBuilder implements ITypeVisitor<Void> {
66
+	private final GlobalTypeRegistry registry;
64 67
 	private final TypeMembers members;
65 68
 	private final LocalMemberCache cache;
66 69
 
67
-	public TypeMemberBuilder(TypeMembers members, LocalMemberCache cache) {
70
+	public TypeMemberBuilder(GlobalTypeRegistry registry, TypeMembers members, LocalMemberCache cache) {
71
+		this.registry = registry;
68 72
 		this.members = members;
69 73
 		this.cache = cache;
70 74
 		
@@ -178,7 +182,7 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
178 182
 		FunctionHeader indexSetHeader = new FunctionHeader(VOID, new FunctionParameter(keyType, "key"), new FunctionParameter(valueType, "value"));
179 183
 		members.addOperator(new OperatorMember(BUILTIN, definition, 0, OperatorType.INDEXSET, indexSetHeader));
180 184
 		
181
-		FunctionHeader getOrDefaultHeader = new FunctionHeader(valueType, new FunctionParameter(keyType, "key"), new FunctionParameter(valueType, "defaultValue"));
185
+		FunctionHeader getOrDefaultHeader = new FunctionHeader(registry.getOptional(valueType), new FunctionParameter(keyType, "key"), new FunctionParameter(valueType, "defaultValue"));
182 186
 		members.addMethod(new MethodMember(BUILTIN, definition, 0, "getOrDefault", getOrDefaultHeader));
183 187
 		
184 188
 		members.addOperator(new OperatorMember(BUILTIN, definition, 0, OperatorType.CONTAINS, new FunctionHeader(BOOL, new FunctionParameter(keyType, "key"))));
@@ -186,6 +190,8 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
186 190
 		members.addField(new FieldMember(BUILTIN, definition, Modifiers.FINAL, "size", INT));
187 191
 		members.addGetter(new GetterMember(BUILTIN, definition, 0, "empty", BOOL));
188 192
 		members.addGetter(new GetterMember(BUILTIN, definition, 0, "keys", cache.getRegistry().getArray(keyType, 1)));
193
+		
194
+		members.addIterator(new AssocIterator(assoc), TypeMemberPriority.SPECIFIED);
189 195
 		return null;
190 196
 	}
191 197
 	
@@ -195,7 +201,7 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
195 201
 		
196 202
 		ClassDefinition definition = new ClassDefinition(BUILTIN, null, "", Modifiers.EXPORT);
197 203
 		members.addConstructor(new ConstructorMember(BUILTIN, definition, 0, new FunctionHeader(VOID)));
198
-		members.addMethod(new MethodMember(BUILTIN, definition, 0, "getOptional", new FunctionHeader(map.keys, valueType, new FunctionParameter[0])));
204
+		members.addMethod(new MethodMember(BUILTIN, definition, 0, "getOptional", new FunctionHeader(map.keys, registry.getOptional(valueType), new FunctionParameter[0])));
199 205
 		members.addMethod(new MethodMember(BUILTIN, definition, 0, "put", new FunctionHeader(map.keys, BasicTypeID.VOID, new FunctionParameter(valueType))));
200 206
 		members.addMethod(new MethodMember(BUILTIN, definition, 0, "contains", new FunctionHeader(map.keys, BasicTypeID.BOOL, new FunctionParameter[0])));
201 207
 		return null;
@@ -216,10 +222,12 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
216 222
 	@Override
217 223
 	public Void visitDefinition(DefinitionTypeID type) {
218 224
 		HighLevelDefinition definition = type.definition;
219
-		if (type.typeParameters.length > 0 || !type.outerTypeParameters.isEmpty()) {
225
+		if (type.hasTypeParameters() || !type.outerTypeParameters.isEmpty()) {
220 226
 			Map<TypeParameter, ITypeID> mapping = new HashMap<>();
221
-			for (int i = 0; i < type.typeParameters.length; i++)
222
-				mapping.put(definition.genericParameters[i], type.typeParameters[i]);
227
+			if (type.typeParameters != null)
228
+				for (int i = 0; i < type.typeParameters.length; i++)
229
+					mapping.put(definition.genericParameters[i], type.typeParameters[i]);
230
+			
223 231
 			for (Map.Entry<TypeParameter, ITypeID> entry : type.outerTypeParameters.entrySet())
224 232
 				mapping.put(entry.getKey(), entry.getValue());
225 233
 			
@@ -286,7 +294,16 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
286 294
 		ClassDefinition definition = new ClassDefinition(BUILTIN, null, "", Modifiers.EXPORT);
287 295
 		members.addField(new FieldMember(BUILTIN, definition, Modifiers.FINAL, "from", fromType), TypeMemberPriority.SPECIFIED);
288 296
 		members.addField(new FieldMember(BUILTIN, definition, Modifiers.FINAL, "to", toType), TypeMemberPriority.SPECIFIED);
289
-		members.addIterator(new RangeIterator(range), TypeMemberPriority.SPECIFIED);
297
+		if (range.from == range.to && (range.from == BasicTypeID.BYTE
298
+				|| range.from == BasicTypeID.SBYTE
299
+				|| range.from == BasicTypeID.SHORT
300
+				|| range.from == BasicTypeID.USHORT
301
+				|| range.from == BasicTypeID.INT
302
+				|| range.from == BasicTypeID.UINT
303
+				|| range.from == BasicTypeID.LONG
304
+				|| range.from == BasicTypeID.ULONG)) {
305
+			members.addIterator(new RangeIterator(range), TypeMemberPriority.SPECIFIED);
306
+		}
290 307
 		return null;
291 308
 	}
292 309
 
@@ -450,6 +467,7 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
450 467
 		members.addOperator(STRING_INDEXGET);
451 468
 		members.addOperator(STRING_RANGEGET);
452 469
 		members.addGetter(STRING_LENGTH);
470
+		members.addGetter(STRING_CHARACTERS);
453 471
 
454 472
 		members.addConstructor(STRING_CONSTRUCTOR_CHARACTERS);
455 473
 		members.addConstructor(STRING_CONSTRUCTOR_CHARACTER_RANGE);

+ 23
- 7
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/TypeMembers.java View File

@@ -78,12 +78,32 @@ public final class TypeMembers {
78 78
 		return cache;
79 79
 	}
80 80
 	
81
+	public boolean extendsOrImplements(ITypeID other) {
82
+		ITypeID superType = type.getSuperType();
83
+		if (superType != null) {
84
+			if (superType == other)
85
+				return true;
86
+			if (cache.get(superType).extendsOrImplements(other))
87
+				return true;
88
+		}
89
+		
90
+		for (TypeMember<ImplementationMember> implementation : implementations) {
91
+			if (implementation.member.type == other)
92
+				return true;
93
+			if (cache.get(implementation.member.type).extendsOrImplements(other))
94
+				return true;
95
+		}
96
+		
97
+		return false;
98
+	}
99
+	
81 100
 	public GlobalTypeRegistry getTypeRegistry() {
82 101
 		return cache.getRegistry();
83 102
 	}
84 103
 	
85 104
 	public void copyMembersTo(CodePosition position, TypeMembers other, TypeMemberPriority priority) {
86 105
 		other.casters.addAll(casters);
106
+		other.iterators.addAll(iterators);
87 107
 		
88 108
 		for (Map.Entry<String, EnumConstantMember> entry : enumMembers.entrySet())
89 109
 			other.addEnumMember(entry.getValue(), priority);
@@ -369,14 +389,10 @@ public final class TypeMembers {
369 389
 		if (members.containsKey(name.name)) {
370 390
 			DefinitionMemberGroup group = members.get(name.name);
371 391
 			
372
-			if (!name.arguments.isEmpty()) {
373
-				/* ... */
374
-			}
375
-			
376 392
 			if (group.isStatic)
377
-				return new PartialStaticMemberGroupExpression(position, type, group);
393
+				return new PartialStaticMemberGroupExpression(position, type, group, name.arguments);
378 394
 			else
379
-				return new PartialMemberGroupExpression(position, target, group, allowStatic);
395
+				return new PartialMemberGroupExpression(position, target, group, name.arguments, allowStatic);
380 396
 		}
381 397
 		
382 398
 		return null;
@@ -384,7 +400,7 @@ public final class TypeMembers {
384 400
 	
385 401
 	public IPartialExpression getStaticMemberExpression(CodePosition position, GenericName name) {
386 402
 		if (members.containsKey(name.name))
387
-			return new PartialStaticMemberGroupExpression(position, type, members.get(name.name));
403
+			return new PartialStaticMemberGroupExpression(position, type, members.get(name.name), name.arguments);
388 404
 		if (innerTypes.containsKey(name.name))
389 405
 			return new PartialTypeExpression(position, innerTypes.get(name.name).instance(cache.getRegistry(), name.arguments));
390 406
 		

+ 4
- 0
Constructor/libraries/collections/module.json View File

@@ -0,0 +1,4 @@
1
+{
2
+	"package": "collections",
3
+	"host": "universal"
4
+}

+ 9
- 0
Constructor/libraries/collections/src/HashSet.zs View File

@@ -0,0 +1,9 @@
1
+export class HashSet<T> {
2
+	public implements Set<T> {
3
+		add(value as T) as bool;
4
+		remove(value as T) as bool;
5
+		
6
+		in(value as T) as bool;
7
+		for(x as T);
8
+	}
9
+}

+ 43
- 0
Constructor/libraries/collections/src/LinkedList.zs View File

@@ -0,0 +1,43 @@
1
+export class LinkedList<T> {
2
+	var first as Node?;
3
+	var last as Node?;
4
+	
5
+	public get empty as bool
6
+		=> first == null;
7
+	
8
+	public add(value as T) as void {
9
+		if first == null {
10
+			first = last = new Node(value);
11
+		} else {
12
+			val node = new Node(value);
13
+			last.next = node;
14
+			node.prev = last;
15
+			last = node;
16
+		}
17
+	}
18
+	
19
+	public implements Queue<T> {
20
+		poll() as T?
21
+			=> first == null ? null : first.value;
22
+		
23
+		peek() as T {
24
+			if first == null
25
+				throw new NoSuchElementException("Cannot peek an empty queue");
26
+			
27
+			return first.value;
28
+		}
29
+		
30
+		offer(value as T) as void
31
+			=> add(value);
32
+	}
33
+	
34
+	private struct Node {
35
+		var next as Node?;
36
+		var prev as Node?;
37
+		val value as T;
38
+		
39
+		this(value as T) {
40
+			this.value = value;
41
+		}
42
+	}
43
+}

+ 5
- 0
Constructor/libraries/collections/src/NoSuchElementException.zs View File

@@ -0,0 +1,5 @@
1
+export class NoSuchElementException : Exception {
2
+	public this(message as string) {
3
+		super(message);
4
+	}
5
+}

+ 7
- 0
Constructor/libraries/collections/src/Queue.zs View File

@@ -0,0 +1,7 @@
1
+export interface Queue<T> {
2
+	get empty as bool;
3
+	
4
+	poll() as T;
5
+	peek() as T;
6
+	push(value as T) as void;
7
+}

+ 8
- 0
Constructor/libraries/collections/src/Set.zs View File

@@ -0,0 +1,8 @@
1
+export interface Set<T> {
2
+	add(value as T) as bool;
3
+	remove(value as T) as bool;
4
+	
5
+	in(value as T) as bool;
6
+	
7
+	for(x as T);
8
+}

+ 3
- 1
Constructor/libraries/stdlib/module.json View File

@@ -2,8 +2,10 @@
2 2
 	"package": "stdlib",
3 3
 	"host": "universal",
4 4
 	"globals": {
5
+		"Comparable": {"type": "Definition", "definition": "Comparable"},
5 6
 		"Exception": {"type": "Definition", "definition": "Exception"},
6 7
 		"IllegalArgumentException": {"type": "Definition", "definition": "IllegalArgumentException"},
7
-		"StringBuilder": {"type": "Definition", "definition": "StringBuilder"}
8
+		"StringBuilder": {"type": "Definition", "definition": "StringBuilder"},
9
+		"StringBuildable": {"type": "Definition", "definition": "StringBuildable"}
8 10
 	}
9 11
 }

+ 3
- 0
Constructor/libraries/stdlib/src/Comparable.zs View File

@@ -0,0 +1,3 @@
1
+export interface Comparable<T> {
2
+	compareTo(other as T) as int;
3
+}

+ 0
- 0
Constructor/libraries/stdlib/src/IllegalOperationException.zs View File


+ 6
- 0
Constructor/libraries/stdlib/src/StringBuildable.zs View File

@@ -0,0 +1,6 @@
1
+export interface StringBuildable {
2
+	toString(output as StringBuilder) as void;
3
+	
4
+	as string
5
+		=> new StringBuilder() << this;
6
+}

+ 16
- 2
Constructor/libraries/stdlib/src/StringBuilder.zs View File

@@ -3,8 +3,22 @@ export class StringBuilder {
3 3
 	public extern this(capacity as int);
4 4
 	public extern this(value as string);
5 5
 	
6
-	public extern +=(value as string);
7
-	public extern +=(value as char);
6
+	public extern <<(value as bool) as StringBuilder;
7
+	public extern <<(value as char) as StringBuilder;
8
+	public extern <<(value as byte) as StringBuilder;
9
+	public extern <<(value as sbyte) as StringBuilder;
10
+	public extern <<(value as short) as StringBuilder;
11
+	public extern <<(value as ushort) as StringBuilder;
12
+	public extern <<(value as int) as StringBuilder;
13
+	public extern <<(value as uint) as StringBuilder;
14
+	public extern <<(value as float) as StringBuilder;
15
+	public extern <<(value as double) as StringBuilder;
16
+	public extern <<(value as string) as StringBuilder;
17
+	
18
+	public <<(value as StringBuildable) as StringBuilder {
19
+		value.toString(this);
20
+		return this;
21
+	}
8 22
 	
9 23
 	public extern implicit as string;
10 24
 }

+ 6
- 11
Constructor/src/main/java/org/openzen/zenscript/constructor/Main.java View File

@@ -3,6 +3,7 @@ package org.openzen.zenscript.constructor;
3 3
 import java.io.File;
4 4
 import java.io.IOException;
5 5
 import org.openzen.zenscript.constructor.module.DirectoryModuleLoader;
6
+import org.openzen.zenscript.constructor.module.ModuleReference;
6 7
 
7 8
 public class Main {
8 9
     /**
@@ -17,23 +18,17 @@ public class Main {
17 18
 		}
18 19
 		
19 20
 		File currentDirectory = new File(arguments.directory);
20
-		File projectJson = new File(currentDirectory, "project.json");
21
-		if (!projectJson.exists()) {
22
-			System.out.println("Error: not a valid project (missing project.json)");
23
-			return;
24
-		}
25
-		
26 21
 		ModuleLoader moduleLoader = new ModuleLoader();
27 22
 		moduleLoader.register("stdlib", new DirectoryModuleLoader(moduleLoader, "stdlib", new File("libraries/stdlib"), true));
28 23
 		
29
-		Project project = new Project(projectJson);
30
-		for (String moduleName : project.modules) {
31
-			moduleLoader.register(moduleName, new DirectoryModuleLoader(moduleLoader, moduleName, new File(currentDirectory, moduleName), false));
24
+		Project project = new Project(moduleLoader, currentDirectory);
25
+		for (ModuleReference module : project.modules) {
26
+			moduleLoader.register(module.getName(), module);
32 27
 		}
33 28
 		
34 29
 		// TODO: compile targets
35
-		for (String moduleName : project.modules) {
36
-			moduleLoader.getModule(moduleName);
30
+		for (ModuleReference module : project.modules) {
31
+			moduleLoader.getModule(module.getName());
37 32
 		}
38 33
     }
39 34
 	

+ 30
- 5
Constructor/src/main/java/org/openzen/zenscript/constructor/Project.java View File

@@ -9,20 +9,45 @@ import java.io.File;
9 9
 import java.io.IOException;
10 10
 import org.json.JSONArray;
11 11
 import org.json.JSONObject;
12
+import org.openzen.zenscript.constructor.module.DirectoryModuleLoader;
13
+import org.openzen.zenscript.constructor.module.ModuleReference;
12 14
 
13 15
 /**
14 16
  *
15 17
  * @author Hoofdgebruiker
16 18
  */
17 19
 public class Project {
18
-	public final String[] modules;
20
+	public final ModuleReference[] modules;
19 21
 	
20
-	public Project(File projectFile) throws IOException {
22
+	public Project(ModuleLoader loader, File directory) throws IOException {
23
+		if (!directory.exists())
24
+			throw new ConstructorException("Project directory doesn't exist");
25
+		if (!directory.isDirectory())
26
+			throw new ConstructorException("Project directory isn't a directory");
27
+		
28
+		File projectFile = new File(directory, "project.json");
29
+		if (!projectFile.exists())
30
+			throw new ConstructorException("Missing project.json file in project directory");
31
+		
21 32
 		JSONObject json = JSONUtils.load(projectFile);
22 33
 		
23 34
 		JSONArray jsonModules = json.getJSONArray("modules");
24
-		modules = new String[jsonModules.length()];
25
-		for (int i = 0; i < jsonModules.length(); i++)
26
-			modules[i] = jsonModules.getString(i);
35
+		modules = new ModuleReference[jsonModules.length()];
36
+		for (int i = 0; i < jsonModules.length(); i++) {
37
+			Object module = jsonModules.get(i);
38
+			if (module instanceof String) {
39
+				modules[i] = new DirectoryModuleLoader(loader, module.toString(), new File(directory, module.toString()), false);
40
+			} else if (module instanceof JSONObject) {
41
+				JSONObject jsonModule = (JSONObject) module;
42
+				String name = jsonModule.getString("name");
43
+				switch (jsonModule.getString("type")) {
44
+					case "directory":
45
+						modules[i] = new DirectoryModuleLoader(loader, name, new File(directory, jsonModule.getString("directory")), false);
46
+						break;
47
+					default:
48
+						throw new ConstructorException("Invalid module type: " + jsonModule.getString("type"));
49
+				}
50
+			}
51
+		}
27 52
 	}
28 53
 }

+ 5
- 0
Constructor/src/main/java/org/openzen/zenscript/constructor/module/DirectoryModuleLoader.java View File

@@ -35,6 +35,11 @@ public class DirectoryModuleLoader implements ModuleReference {
35 35
 		this.directory = directory;
36 36
 		this.isStdlib = isStdlib;
37 37
 	}
38
+	
39
+	@Override
40
+	public String getName() {
41
+		return moduleName;
42
+	}
38 43
 
39 44
 	@Override
40 45
 	public SemanticModule load() {

+ 2
- 0
Constructor/src/main/java/org/openzen/zenscript/constructor/module/ModuleReference.java View File

@@ -10,5 +10,7 @@ package org.openzen.zenscript.constructor.module;
10 10
  * @author Hoofdgebruiker
11 11
  */
12 12
 public interface ModuleReference {
13
+	public String getName();
14
+	
13 15
 	public SemanticModule load();
14 16
 }

+ 11
- 8
Linker/src/main/java/org/openzen/zenscript/linker/DefinitionScope.java View File

@@ -5,7 +5,6 @@
5 5
  */
6 6
 package org.openzen.zenscript.linker;
7 7
 
8
-import java.util.ArrayList;
9 8
 import java.util.HashMap;
10 9
 import java.util.List;
11 10
 import java.util.Map;
@@ -43,10 +42,14 @@ public class DefinitionScope extends BaseScope {
43 42
 		this.outer = outer;
44 43
 		this.definition = definition;
45 44
 		
46
-		List<ITypeID> genericParameterList = new ArrayList<>();
47
-		for (TypeParameter parameter : definition.genericParameters) {
48
-			genericParameterList.add(outer.getTypeRegistry().getGeneric(parameter));
49
-			genericParameters.put(parameter.name, parameter);
45
+		ITypeID[] genericParameterList = null;
46
+		if (definition.genericParameters != null) {
47
+			genericParameterList = new ITypeID[definition.genericParameters.length];
48
+			for (int i = 0; i < definition.genericParameters.length; i++) {
49
+				TypeParameter parameter = definition.genericParameters[i];
50
+				genericParameterList[i] = outer.getTypeRegistry().getGeneric(parameter);
51
+				genericParameters.put(parameter.name, parameter);
52
+			}
50 53
 		}
51 54
 		
52 55
 		if (definition instanceof ExpansionDefinition) {
@@ -67,9 +70,9 @@ public class DefinitionScope extends BaseScope {
67 70
 	public IPartialExpression get(CodePosition position, GenericName name) {
68 71
 		if (members.hasInnerType(name.name))
69 72
 			return new PartialTypeExpression(position, members.getInnerType(position, name));
70
-		if (members.hasMember(name.name) && name.arguments.isEmpty())
73
+		if (members.hasMember(name.name) && !name.hasArguments())
71 74
 			return members.getMemberExpression(position, new ThisExpression(position, type), name, true);
72
-		if (genericParameters.containsKey(name.name) && name.arguments.isEmpty())
75
+		if (genericParameters.containsKey(name.name) && !name.hasArguments())
73 76
 			return new PartialTypeExpression(position, getTypeRegistry().getGeneric(genericParameters.get(name.name)));
74 77
 		
75 78
 		return outer.get(position, name);
@@ -83,7 +86,7 @@ public class DefinitionScope extends BaseScope {
83 86
 				result = getTypeMembers(result).getInnerType(position, name.get(i));
84 87
 			}
85 88
 			return result;
86
-		} else if (genericParameters.containsKey(name.get(0).name) && name.size() == 1 && name.get(0).arguments.isEmpty()) {
89
+		} else if (genericParameters.containsKey(name.get(0).name) && name.size() == 1 && !name.get(0).hasArguments()) {
87 90
 			return getTypeRegistry().getGeneric(genericParameters.get(name.get(0).name));
88 91
 		}
89 92
 		

+ 2
- 2
Linker/src/main/java/org/openzen/zenscript/linker/FileScope.java View File

@@ -77,7 +77,7 @@ public class FileScope extends BaseScope {
77 77
 		
78 78
 		if (globalSymbols.containsKey(name.name)) {
79 79
 			IPartialExpression resolution = globalSymbols.get(name.name).getExpression(position, globalRegistry, name.arguments);
80
-			return new PartialGlobalExpression(position, name.name, resolution);
80
+			return new PartialGlobalExpression(position, name.name, resolution, name.arguments);
81 81
 		}
82 82
 		
83 83
 		return rootPackage.getMember(position, globalRegistry, name);
@@ -103,7 +103,7 @@ public class FileScope extends BaseScope {
103 103
 			}
104 104
 			
105 105
 			// TODO: take care of non-static inner classes in generic classes!
106
-			if (type != null && name.get(name.size() - 1).arguments.size() != type.definition.genericParameters.length)
106
+			if (type != null && name.get(name.size() - 1).getNumberOfArguments() != type.definition.getNumberOfGenericParameters())
107 107
 				throw new CompileException(position, CompileExceptionCode.TYPE_ARGUMENTS_INVALID_NUMBER, "Invalid number of type arguments");
108 108
 			
109 109
 			if (type != null)

+ 1
- 1
Linker/src/main/java/org/openzen/zenscript/linker/ForeachScope.java View File

@@ -39,7 +39,7 @@ public class ForeachScope extends StatementScope {
39 39
 
40 40
 	@Override
41 41
 	public IPartialExpression get(CodePosition position, GenericName name) {
42
-		if (name.arguments.isEmpty()) {
42
+		if (name.hasNoArguments()) {
43 43
 			for (VarStatement loopVariable : statement.loopVariables) {
44 44
 				if (loopVariable.name.equals(name.name))
45 45
 					return new GetLocalVariableExpression(position, loopVariable);

+ 2
- 2
Linker/src/main/java/org/openzen/zenscript/linker/FunctionScope.java View File

@@ -54,7 +54,7 @@ public class FunctionScope extends StatementScope {
54 54
 		if (fromSuper != null)
55 55
 			return fromSuper;
56 56
 		
57
-		if (name.arguments.isEmpty()) {
57
+		if (name.hasNoArguments()) {
58 58
 			for (FunctionParameter parameter : header.parameters) {
59 59
 				if (parameter.name.equals(name.name)) {
60 60
 					return new GetFunctionParameterExpression(position, parameter);
@@ -72,7 +72,7 @@ public class FunctionScope extends StatementScope {
72 72
 
73 73
 	@Override
74 74
 	public ITypeID getType(CodePosition position, List<GenericName> name) {
75
-		if (name.size() == 1 && name.get(0).arguments.isEmpty()) {
75
+		if (name.size() == 1 && name.get(0).hasNoArguments()) {
76 76
 			for (TypeParameter parameter : header.typeParameters) {
77 77
 				if (parameter.name.equals(name.get(0).name))
78 78
 					return getTypeRegistry().getGeneric(parameter);

+ 5
- 4
Linker/src/main/java/org/openzen/zenscript/linker/GenericFunctionScope.java View File

@@ -31,8 +31,9 @@ public class GenericFunctionScope extends BaseScope {
31 31
 	public GenericFunctionScope(BaseScope outer, TypeParameter[] parameters) {
32 32
 		this.outer = outer;
33 33
 		
34
-		for (TypeParameter parameter : parameters)
35
-			this.parameters.put(parameter.name, parameter);
34
+		if (parameters != null)
35
+			for (TypeParameter parameter : parameters)
36
+				this.parameters.put(parameter.name, parameter);
36 37
 	}
37 38
 	
38 39
 	@Override
@@ -42,7 +43,7 @@ public class GenericFunctionScope extends BaseScope {
42 43
 
43 44
 	@Override
44 45
 	public IPartialExpression get(CodePosition position, GenericName name) {
45
-		if (parameters.containsKey(name.name) && name.arguments.isEmpty())
46
+		if (parameters.containsKey(name.name) && name.hasNoArguments())
46 47
 			return new PartialTypeExpression(position, getTypeRegistry().getGeneric(parameters.get(name.name)));
47 48
 		
48 49
 		return outer.get(position, name);
@@ -50,7 +51,7 @@ public class GenericFunctionScope extends BaseScope {
50 51
 
51 52
 	@Override
52 53
 	public ITypeID getType(CodePosition position, List<GenericName> name) {
53
-		if (name.size() == 1 && parameters.containsKey(name.get(0).name) && name.get(0).arguments.isEmpty())
54
+		if (name.size() == 1 && parameters.containsKey(name.get(0).name) && name.get(0).hasNoArguments())
54 55
 			return getTypeRegistry().getGeneric(parameters.get(name.get(0).name));
55 56
 		
56 57
 		return outer.getType(position, name);

+ 1
- 1
Linker/src/main/java/org/openzen/zenscript/linker/ImplementationScope.java View File

@@ -53,7 +53,7 @@ public class ImplementationScope extends BaseScope {
53 53
 	public IPartialExpression get(CodePosition position, GenericName name) {
54 54
 		if (members.hasInnerType(name.name))
55 55
 			return new PartialTypeExpression(position, members.getInnerType(position, name));
56
-		if (members.hasMember(name.name) && name.arguments.isEmpty())
56
+		if (members.hasMember(name.name))
57 57
 			return members.getMemberExpression(position, new ThisExpression(position, outer.getThisType()), name, true);
58 58
 		
59 59
 		return outer.get(position, name);

+ 1
- 1
Linker/src/main/java/org/openzen/zenscript/linker/LambdaScope.java View File

@@ -43,7 +43,7 @@ public class LambdaScope extends StatementScope {
43 43
 	public IPartialExpression get(CodePosition position, GenericName name) {
44 44
 		IPartialExpression outer = this.outer.get(position, name);
45 45
 		if (outer == null) {
46
-			if (name.arguments.isEmpty()) {
46
+			if (name.hasNoArguments()) {
47 47
 				for (FunctionParameter parameter : header.parameters) {
48 48
 					if (parameter.name.equals(name.name))
49 49
 						return new GetFunctionParameterExpression(position, parameter);

+ 1
- 1
Linker/src/main/java/org/openzen/zenscript/linker/StatementScope.java View File

@@ -26,7 +26,7 @@ public abstract class StatementScope extends BaseScope {
26 26
 	
27 27
 	@Override
28 28
 	public IPartialExpression get(CodePosition position, GenericName name) {
29
-		if (variables.containsKey(name.name) && name.arguments.isEmpty())
29
+		if (variables.containsKey(name.name) && name.hasNoArguments())
30 30
 			return new GetLocalVariableExpression(position, variables.get(name.name));
31 31
 		
32 32
 		return null;

+ 2
- 3
Linker/src/main/java/org/openzen/zenscript/linker/symbol/ISymbol.java View File

@@ -5,7 +5,6 @@
5 5
  */
6 6
 package org.openzen.zenscript.linker.symbol;
7 7
 
8
-import java.util.List;
9 8
 import org.openzen.zenscript.codemodel.partial.IPartialExpression;
10 9
 import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
11 10
 import org.openzen.zenscript.codemodel.type.ITypeID;
@@ -16,7 +15,7 @@ import org.openzen.zenscript.shared.CodePosition;
16 15
  * @author Hoofdgebruiker
17 16
  */
18 17
 public interface ISymbol {
19
-	public IPartialExpression getExpression(CodePosition position, GlobalTypeRegistry types, List<ITypeID> typeArguments);
18
+	public IPartialExpression getExpression(CodePosition position, GlobalTypeRegistry types, ITypeID[] typeArguments);
20 19
 	
21
-	public ITypeID getType(CodePosition position, GlobalTypeRegistry types, List<ITypeID> typeArguments);
20
+	public ITypeID getType(CodePosition position, GlobalTypeRegistry types, ITypeID[] typeArguments);
22 21
 }

+ 2
- 3
Linker/src/main/java/org/openzen/zenscript/linker/symbol/TypeSymbol.java View File

@@ -5,7 +5,6 @@
5 5
  */
6 6
 package org.openzen.zenscript.linker.symbol;
7 7
 
8
-import java.util.List;
9 8
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
10 9
 import org.openzen.zenscript.codemodel.partial.IPartialExpression;
11 10
 import org.openzen.zenscript.codemodel.partial.PartialTypeExpression;
@@ -25,12 +24,12 @@ public class TypeSymbol implements ISymbol {
25 24
 	}
26 25
 	
27 26
 	@Override
28
-	public IPartialExpression getExpression(CodePosition position, GlobalTypeRegistry types, List<ITypeID> typeArguments) {
27
+	public IPartialExpression getExpression(CodePosition position, GlobalTypeRegistry types, ITypeID[] typeArguments) {
29 28
 		return new PartialTypeExpression(position, types.getForDefinition(definition, typeArguments));
30 29
 	}
31 30
 
32 31
 	@Override
33
-	public ITypeID getType(CodePosition position, GlobalTypeRegistry types, List<ITypeID> typeArguments) {
32
+	public ITypeID getType(CodePosition position, GlobalTypeRegistry types, ITypeID[] typeArguments) {
34 33
 		return types.getForDefinition(definition, typeArguments);
35 34
 	}
36 35
 }

+ 2
- 3
Parser/src/main/java/org/openzen/zenscript/lexer/CompiledDFA.java View File

@@ -4,7 +4,6 @@ package org.openzen.zenscript.lexer;
4 4
 import gnu.trove.iterator.TIntIterator;
5 5
 import gnu.trove.map.hash.TIntIntHashMap;
6 6
 import java.util.ArrayList;
7
-import java.util.Arrays;
8 7
 import java.util.List;
9 8
 
10 9
 /**
@@ -21,8 +20,8 @@ public class CompiledDFA<T>
21 20
 {
22 21
 	public static <T extends TokenType & Comparable<T>> CompiledDFA<T> createLexerDFA(T[] tokenTypes, Class<T> tokenClass)
23 22
 	{
24
-		List<T> tokens = new ArrayList<T>();
25
-		List<String> regexps = new ArrayList<String>();
23
+		List<T> tokens = new ArrayList<>();
24
+		List<String> regexps = new ArrayList<>();
26 25
 		for (T tokenType : tokenTypes) {
27 26
 			if (tokenType.getRegexp() != null) {
28 27
 				tokens.add(tokenType);

+ 9
- 0
Parser/src/main/java/org/openzen/zenscript/lexer/TokenStream.java View File

@@ -170,6 +170,15 @@ public abstract class TokenStream<T extends Token<TT>, TT extends TokenType> imp
170 170
 	{
171 171
         tokenMemoryCurrent = marks.pop();
172 172
     }
173
+	
174
+	/**
175
+	 * Replaces the current token with another one. Used to split composite tokens.
176
+	 * 
177
+	 * @param other 
178
+	 */
179
+	public void replace(TT other) {
180
+		next = createToken(next.getPosition(), next.getWhitespaceBefore(), next.getContent(), other);
181
+	}
173 182
 
174 183
     // ===============================
175 184
     // === Iterator implementation ===

+ 1
- 1
Parser/src/main/java/org/openzen/zenscript/lexer/ZSTokenStream.java View File

@@ -58,7 +58,7 @@ public class ZSTokenStream extends TokenStream<ZSToken, ZSTokenType> {
58 58
 		KEYWORDS.put("any", K_ANY);
59 59
 		KEYWORDS.put("bool", K_BOOL);
60 60
 		KEYWORDS.put("byte", K_BYTE);
61
-		KEYWORDS.put("ubyte", K_UBYTE);
61
+		KEYWORDS.put("sbyte", K_SBYTE);
62 62
 		KEYWORDS.put("short", K_SHORT);
63 63
 		KEYWORDS.put("ushort", K_USHORT);
64 64
 		KEYWORDS.put("int", K_INT);

+ 1
- 1
Parser/src/main/java/org/openzen/zenscript/lexer/ZSTokenType.java View File

@@ -108,7 +108,7 @@ public enum ZSTokenType implements TokenType {
108 108
 	K_ANY,
109 109
 	K_BOOL,
110 110
 	K_BYTE,
111
-	K_UBYTE,
111
+	K_SBYTE,
112 112
 	K_SHORT,
113 113
 	K_USHORT,
114 114
 	K_INT,

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

@@ -35,18 +35,19 @@ public class ParsedGenericParameter {
35 35
 	}
36 36
 	
37 37
 	public static List<ParsedGenericParameter> parseAll(ZSTokenStream tokens) {
38
+		if (tokens.optional(ZSTokenType.T_LESS) == null)
39
+			return null;
40
+		
38 41
 		List<ParsedGenericParameter> genericParameters = new ArrayList<>();
39
-		if (tokens.optional(ZSTokenType.T_LESS) != null) {
40
-			do {
41
-				genericParameters.add(ParsedGenericParameter.parse(tokens));
42
-			} while (tokens.optional(ZSTokenType.T_COMMA) != null);
43
-			tokens.required(ZSTokenType.T_GREATER, "> expected");
44
-		}
42
+		do {
43
+			genericParameters.add(ParsedGenericParameter.parse(tokens));
44
+		} while (tokens.optional(ZSTokenType.T_COMMA) != null);
45
+		tokens.required(ZSTokenType.T_GREATER, "> expected");
45 46
 		return genericParameters;
46 47
 	}
47 48
 	
48 49
 	public static void compile(BaseScope scope, TypeParameter[] compiled, List<ParsedGenericParameter> parameters) {
49
-		if (compiled.length == 0)
50
+		if (compiled == null)
50 51
 			return;
51 52
 		
52 53
 		GenericFunctionScope innerScope = new GenericFunctionScope(scope, compiled);
@@ -58,8 +59,8 @@ public class ParsedGenericParameter {
58 59
 	
59 60
 	private static TypeParameter[] NO_TYPE_PARAMETERS = new TypeParameter[0];
60 61
 	public static TypeParameter[] getCompiled(List<ParsedGenericParameter> parameters) {
61
-		if (parameters.isEmpty())
62
-			return NO_TYPE_PARAMETERS;
62
+		if (parameters == null)
63
+			return null;
63 64
 		
64 65
 		TypeParameter[] result = new TypeParameter[parameters.size()];
65 66
 		for (int i = 0; i < result.length; i++)

+ 1
- 0
Parser/src/main/java/org/openzen/zenscript/parser/definitions/ParsedInterface.java View File

@@ -55,6 +55,7 @@ public class ParsedInterface extends BaseParsedDefinition {
55 55
 		this.superInterfaces = superInterfaces;
56 56
 		
57 57
 		compiled = new InterfaceDefinition(position, pkg, name, modifiers, outerDefinition);
58
+		compiled.setTypeParameters(ParsedGenericParameter.getCompiled(genericParameters));
58 59
 	}
59 60
 
60 61
 	@Override

+ 19
- 15
Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedCallArguments.java View File

@@ -53,22 +53,24 @@ public class ParsedCallArguments {
53 53
 	public CallArguments compileCall(
54 54
 			CodePosition position, 
55 55
 			ExpressionScope scope,
56
+			ITypeID[] genericParameters,
56 57
 			DefinitionMemberGroup member)
57 58
 	{
58 59
 		List<FunctionHeader> possibleHeaders = member.getMethodMembers().stream()
59 60
 				.map(method -> method.member.getHeader())
60 61
 				.collect(Collectors.toList());
61
-		return compileCall(position, scope, possibleHeaders);
62
+		return compileCall(position, scope, genericParameters, possibleHeaders);
62 63
 	}
63 64
 	
64 65
 	public CallArguments compileCall(
65 66
 			CodePosition position,
66 67
 			ExpressionScope scope,
68
+			ITypeID[] genericParameters,
67 69
 			List<FunctionHeader> candidateFunctions)
68 70
 	{
69 71
 		List<FunctionHeader> candidates = new ArrayList<>();
70 72
 		for (FunctionHeader header : candidateFunctions) {
71
-			if (isCompatibleWith(scope, header))
73
+			if (isCompatibleWith(scope, header, genericParameters))
72 74
 				candidates.add(header);
73 75
 		}
74 76
 		
@@ -110,18 +112,20 @@ public class ParsedCallArguments {
110 112
 			cArguments[i] = cArgument.eval();
111 113
 		}
112 114
 		
113
-		ITypeID[] typeParameters = CallArguments.NO_TYPE_ARGUMENTS;
114
-		for (FunctionHeader candidate : candidates) {
115
-			if (candidate.typeParameters.length > 0) {
116
-				typeParameters = new ITypeID[candidate.typeParameters.length];
117
-				for (int i = 0; i < typeParameters.length; i++) {
118
-					if (innerScope.genericInferenceMap.get(candidate.typeParameters[i]) == null)
119
-						throw new CompileException(position, CompileExceptionCode.TYPE_ARGUMENTS_NOT_INFERRABLE, "Could not infer type parameter " + candidate.typeParameters[i].name);
120
-					else
121
-						typeParameters[i] = innerScope.genericInferenceMap.get(candidate.typeParameters[i]);
122
-				}
115
+		ITypeID[] typeParameters = genericParameters;
116
+		if (typeParameters == null) {
117
+			for (FunctionHeader candidate : candidates) {
118
+				if (candidate.typeParameters.length > 0) {
119
+					typeParameters = new ITypeID[candidate.typeParameters.length];
120
+					for (int i = 0; i < typeParameters.length; i++) {
121
+						if (innerScope.genericInferenceMap.get(candidate.typeParameters[i]) == null)
122
+							throw new CompileException(position, CompileExceptionCode.TYPE_ARGUMENTS_NOT_INFERRABLE, "Could not infer type parameter " + candidate.typeParameters[i].name);
123
+						else
124
+							typeParameters[i] = innerScope.genericInferenceMap.get(candidate.typeParameters[i]);
125
+					}
123 126
 
124
-				break;
127
+					break;
128
+				}
125 129
 			}
126 130
 		}
127 131
 		
@@ -137,12 +141,12 @@ public class ParsedCallArguments {
137 141
 		return new CallArguments(new ITypeID[0], cArguments);
138 142
 	}
139 143
 	
140
-	private boolean isCompatibleWith(BaseScope scope, FunctionHeader header) {
144
+	private boolean isCompatibleWith(BaseScope scope, FunctionHeader header, ITypeID[] typeParameters) {
141 145
 		if (arguments.size() != header.parameters.length)
142 146
 			return false;
143 147
 		
144 148
 		for (int i = 0; i < arguments.size(); i++) {
145
-			if (header.parameters[i].type.hasInferenceBlockingTypeParameters(header.typeParameters))
149
+			if (typeParameters == null && header.parameters[i].type.hasInferenceBlockingTypeParameters(header.typeParameters))
146 150
 				return false;
147 151
 			
148 152
 			if (!arguments.get(i).isCompatibleWith(scope, header.parameters[i].type))

+ 3
- 3
Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpressionCall.java View File

@@ -47,7 +47,7 @@ public class ParsedExpressionCall extends ParsedExpression {
47 47
 				throw new CompileException(position, CompileExceptionCode.SUPER_CALL_NO_SUPERCLASS, "Class has no superclass");
48 48
 			
49 49
 			DefinitionMemberGroup memberGroup = scope.getTypeMembers(targetType).getOrCreateGroup(OperatorType.CONSTRUCTOR);
50
-			CallArguments callArguments = arguments.compileCall(position, scope, memberGroup);
50
+			CallArguments callArguments = arguments.compileCall(position, scope, null, memberGroup);
51 51
 			ICallableMember member = memberGroup.selectMethod(position, scope, callArguments, true, true);
52 52
 			if (!(member instanceof ConstructorMember))
53 53
 				throw new CompileException(position, CompileExceptionCode.INTERNAL_ERROR, "Constructor is not a constructor!");
@@ -58,7 +58,7 @@ public class ParsedExpressionCall extends ParsedExpression {
58 58
 			ITypeID targetType = scope.getThisType();
59 59
 			
60 60
 			DefinitionMemberGroup memberGroup = scope.getTypeMembers(targetType).getOrCreateGroup(OperatorType.CONSTRUCTOR);
61
-			CallArguments callArguments = arguments.compileCall(position, scope, memberGroup);
61
+			CallArguments callArguments = arguments.compileCall(position, scope, null, memberGroup);
62 62
 			ICallableMember member = memberGroup.selectMethod(position, scope, callArguments, true, true);
63 63
 			if (!(member instanceof ConstructorMember))
64 64
 				throw new CompileException(position, CompileExceptionCode.INTERNAL_ERROR, "Constructor is not a constructor!");
@@ -67,7 +67,7 @@ public class ParsedExpressionCall extends ParsedExpression {
67 67
 		}
68 68
 
69 69
 		List<FunctionHeader> headers = cReceiver.getPossibleFunctionHeaders(scope, scope.hints, arguments.arguments.size());
70
-		CallArguments callArguments = arguments.compileCall(position, scope, headers);
70
+		CallArguments callArguments = arguments.compileCall(position, scope, cReceiver.getGenericCallTypes(), headers);
71 71
 		return cReceiver.call(position, scope, scope.hints, callArguments);
72 72
 	}
73 73
 

+ 1
- 1
Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpressionFunction.java View File

@@ -70,7 +70,7 @@ public class ParsedExpressionFunction extends ParsedExpression {
70 70
 			// perform type parameter inference
71 71
 			ITypeID returnType = statements.getReturnType();
72 72
 			Map<TypeParameter, ITypeID> inferredTypes = new HashMap<>();
73
-			if (!genericHeader.returnType.inferTypeParameters(returnType, inferredTypes))
73
+			if (!genericHeader.returnType.inferTypeParameters(scope.getMemberCache(), returnType, inferredTypes))
74 74
 				throw new CompileException(position, CompileExceptionCode.TYPE_ARGUMENTS_NOT_INFERRABLE, "Could not infer generic type parameters");
75 75
 			
76 76
 			for (Map.Entry<TypeParameter, ITypeID> type : inferredTypes.entrySet()) {

+ 5
- 0
Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpressionIndex.java View File

@@ -107,5 +107,10 @@ public class ParsedExpressionIndex extends ParsedExpression {
107 107
 		private Expression getLength(CodePosition position) {
108 108
 			return target.getMember(position, scope, scope.hints, new GenericName("length")).eval();
109 109
 		}
110
+
111
+		@Override
112
+		public ITypeID[] getGenericCallTypes() {
113
+			return null;
114
+		}
110 115
 	}
111 116
 }

+ 6
- 11
Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpressionMember.java View File

@@ -6,8 +6,6 @@
6 6
 
7 7
 package org.openzen.zenscript.parser.expression;
8 8
 
9
-import java.util.ArrayList;
10
-import java.util.Collections;
11 9
 import java.util.List;
12 10
 import org.openzen.zenscript.codemodel.partial.IPartialExpression;
13 11
 import org.openzen.zenscript.codemodel.type.GenericName;
@@ -37,16 +35,13 @@ public class ParsedExpressionMember extends ParsedExpression {
37 35
 
38 36
 	@Override
39 37
 	public IPartialExpression compile(ExpressionScope scope) {
40
-		List<ITypeID> genericArguments = Collections.emptyList();
41
-		if (!genericParameters.isEmpty()) {
42
-			genericArguments = new ArrayList<>();
43
-			for (IParsedType type : this.genericParameters) {
44
-				genericArguments.add(type.compile(scope));
45
-			}
46
-		}
47
-		
48 38
 		IPartialExpression cValue = value.compile(scope.withoutHints());
49
-		IPartialExpression member = cValue.getMember(position, scope, scope.hints, new GenericName(this.member, genericArguments));
39
+		ITypeID[] typeParameters = IParsedType.compileList(genericParameters, scope);
40
+		IPartialExpression member = cValue.getMember(
41
+				position,
42
+				scope,
43
+				scope.hints,
44
+				new GenericName(this.member, typeParameters));
50 45
 		if (member == null)
51 46
 			throw new CompileException(position, CompileExceptionCode.NO_SUCH_MEMBER, "Member not found: " + this.member);
52 47
 		return member;

+ 8
- 7
Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpressionVariable.java View File

@@ -6,7 +6,6 @@
6 6
 
7 7
 package org.openzen.zenscript.parser.expression;
8 8
 
9
-import java.util.ArrayList;
10 9
 import java.util.Collections;
11 10
 import java.util.List;
12 11
 import org.openzen.zenscript.codemodel.expression.ConstantStringExpression;
@@ -42,13 +41,15 @@ public class ParsedExpressionVariable extends ParsedExpression {
42 41
 
43 42
 	@Override
44 43
 	public IPartialExpression compile(ExpressionScope scope) {
45
-		List<ITypeID> genericParameters = Collections.emptyList();
46
-		if (!this.genericParameters.isEmpty()) {
47
-			genericParameters = new ArrayList<>();
48
-			for (IParsedType genericType : this.genericParameters)
49
-				genericParameters.add(genericType.compile(scope));
44
+		ITypeID[] genericArguments = null;
45
+		if (genericParameters != null) {
46
+			genericArguments = new ITypeID[genericParameters.size()];
47
+			for (int i = 0; i < genericParameters.size(); i++) {
48
+				genericArguments[i] = genericParameters.get(i).compile(scope);
49
+			}
50 50
 		}
51
-		IPartialExpression result = scope.get(position, new GenericName(name, genericParameters));
51
+		
52
+		IPartialExpression result = scope.get(position, new GenericName(name, genericArguments));
52 53
 		if (result == null) {
53 54
 			for (ITypeID hint : scope.hints) {
54 55
 				EnumConstantMember member = scope.getTypeMembers(hint).getEnumMember(name);

+ 1
- 1
Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedNewExpression.java View File

@@ -50,7 +50,7 @@ public class ParsedNewExpression extends ParsedExpression{
50 50
 	public static NewExpression compile(CodePosition position, ITypeID type, ParsedCallArguments arguments, ExpressionScope scope) {
51 51
 		DefinitionMemberGroup constructors = scope.getTypeMembers(type).getOrCreateGroup(OperatorType.CONSTRUCTOR);
52 52
 		List<ITypeID>[] predictedTypes = constructors.predictCallTypes(scope, scope.hints, arguments.arguments.size());
53
-		CallArguments compiledArguments = arguments.compileCall(position, scope, constructors);
53
+		CallArguments compiledArguments = arguments.compileCall(position, scope, null, constructors);
54 54
 		ICallableMember member = constructors.selectMethod(position, scope, compiledArguments, true, true);
55 55
 		if (member == null)
56 56
 			throw new CompileException(position, CompileExceptionCode.CALL_NO_VALID_METHOD, "No matching constructor found");

+ 13
- 2
Parser/src/main/java/org/openzen/zenscript/parser/member/ParsedDefinitionMember.java View File

@@ -16,7 +16,6 @@ import org.openzen.zenscript.codemodel.HighLevelDefinition;
16 16
 import org.openzen.zenscript.codemodel.Modifiers;
17 17
 import org.openzen.zenscript.codemodel.OperatorType;
18 18
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
19
-import org.openzen.zenscript.codemodel.member.StaticInitializerMember;
20 19
 import org.openzen.zenscript.lexer.ZSToken;
21 20
 import org.openzen.zenscript.lexer.ZSTokenStream;
22 21
 import org.openzen.zenscript.lexer.ZSTokenType;
@@ -205,7 +204,13 @@ public abstract class ParsedDefinitionMember {
205 204
 			case T_XORASSIGN:
206 205
 			case T_INCREMENT:
207 206
 			case T_DECREMENT:
208
-			case T_DOT2: {
207
+			case T_DOT2:
208
+			case T_SHL:
209
+			case T_SHR:
210
+			case T_USHR:
211
+			case T_SHLASSIGN:
212
+			case T_SHRASSIGN:
213
+			case T_USHRASSIGN: {
209 214
 				ZSToken token = tokens.next();
210 215
 				ParsedFunctionHeader header = ParsedFunctionHeader.parse(tokens);
211 216
 				ParsedFunctionBody body = ParsedStatement.parseFunctionBody(tokens);
@@ -274,6 +279,12 @@ public abstract class ParsedDefinitionMember {
274 279
 			case T_INCREMENT: return OperatorType.INCREMENT;
275 280
 			case T_DECREMENT: return OperatorType.DECREMENT;
276 281
 			case T_DOT2: return OperatorType.RANGE;
282
+			case T_SHL: return OperatorType.SHL;
283
+			case T_SHR: return OperatorType.SHR;
284
+			case T_USHR: return OperatorType.USHR;
285
+			case T_SHLASSIGN: return OperatorType.SHLASSIGN;
286
+			case T_SHRASSIGN: return OperatorType.SHRASSIGN;
287
+			case T_USHRASSIGN: return OperatorType.USHRASSIGN;
277 288
 			default:
278 289
 				throw new AssertionError("Missing switch case in getOperator");
279 290
 		}

+ 3
- 1
Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementForeach.java View File

@@ -7,6 +7,7 @@ import org.openzen.zenscript.codemodel.statement.ForeachStatement;
7 7
 import org.openzen.zenscript.codemodel.statement.Statement;
8 8
 import org.openzen.zenscript.codemodel.statement.VarStatement;
9 9
 import org.openzen.zenscript.codemodel.type.ITypeID;
10
+import org.openzen.zenscript.codemodel.type.member.TypeMembers;
10 11
 import org.openzen.zenscript.linker.ExpressionScope;
11 12
 import org.openzen.zenscript.linker.ForeachScope;
12 13
 import org.openzen.zenscript.linker.StatementScope;
@@ -32,7 +33,8 @@ public class ParsedStatementForeach extends ParsedStatement {
32 33
 	public Statement compile(StatementScope scope) {
33 34
 		Expression list = this.list.compile(new ExpressionScope(scope)).eval();
34 35
 		
35
-		IIteratorMember iterator = scope.getTypeMembers(list.type).getIterator(varnames.length);
36
+		TypeMembers members = scope.getTypeMembers(list.type);
37
+		IIteratorMember iterator = members.getIterator(varnames.length);
36 38
 		if (iterator == null)
37 39
 			throw new CompileException(position, CompileExceptionCode.NO_SUCH_ITERATOR, list.type + " doesn't have an iterator with " + varnames.length + " variables");
38 40
 		

+ 28
- 11
Parser/src/main/java/org/openzen/zenscript/parser/type/IParsedType.java View File

@@ -12,9 +12,7 @@ import org.openzen.zenscript.codemodel.type.ITypeID;
12 12
 import org.openzen.zenscript.codemodel.type.member.TypeMembers;
13 13
 import org.openzen.zenscript.lexer.ZSTokenStream;
14 14
 import org.openzen.zenscript.lexer.ZSTokenType;
15
-import static org.openzen.zenscript.lexer.ZSTokenType.T_COMMA;
16
-import static org.openzen.zenscript.lexer.ZSTokenType.T_GREATER;
17
-import static org.openzen.zenscript.lexer.ZSTokenType.T_LESS;
15
+import static org.openzen.zenscript.lexer.ZSTokenType.*;
18 16
 import org.openzen.zenscript.linker.BaseScope;
19 17
 import org.openzen.zenscript.parser.ParseException;
20 18
 import org.openzen.zenscript.parser.definitions.ParsedFunctionHeader;
@@ -64,11 +62,11 @@ public interface IParsedType {
64 62
 				break;
65 63
 			case K_BYTE:
66 64
 				tokens.next();
67
-				result = ParsedTypeBasic.SBYTE;
65
+				result = ParsedTypeBasic.BYTE;
68 66
 				break;
69
-			case K_UBYTE:
67
+			case K_SBYTE:
70 68
 				tokens.next();
71
-				result = ParsedTypeBasic.BYTE;
69
+				result = ParsedTypeBasic.SBYTE;
72 70
 				break;
73 71
 			case K_SHORT:
74 72
 				tokens.next();
@@ -175,7 +173,7 @@ public interface IParsedType {
175 173
 	
176 174
 	public static List<IParsedType> parseGenericParameters(ZSTokenStream tokens) {
177 175
 		if (!tokens.isNext(T_LESS))
178
-			return Collections.emptyList();
176
+			return null;
179 177
 		
180 178
 		tokens.pushMark();
181 179
 		tokens.next();
@@ -190,13 +188,32 @@ public interface IParsedType {
190 188
 			genericParameters.add(type);
191 189
 		} while (tokens.optional(T_COMMA) != null);
192 190
 		
193
-		if (tokens.optional(T_GREATER) == null) {
191
+		if (tokens.isNext(T_SHR)) {
192
+			tokens.replace(T_GREATER);
193
+		} else if (tokens.isNext(T_USHR)) {
194
+			tokens.replace(T_SHR);
195
+		} else if (tokens.isNext(T_SHRASSIGN)) {
196
+			tokens.replace(T_GREATEREQ);
197
+		} else if (tokens.isNext(T_USHRASSIGN)) {
198
+			tokens.replace(T_SHRASSIGN);
199
+		} else if (tokens.optional(T_GREATER) == null) {
194 200
 			tokens.reset();
195 201
 			return Collections.emptyList();
196
-		} else {
197
-			tokens.popMark();
198
-			return genericParameters;
199 202
 		}
203
+		
204
+		tokens.popMark();
205
+		return genericParameters;
206
+	}
207
+	
208
+	public static ITypeID[] compileList(List<IParsedType> typeParameters, BaseScope scope) {
209
+		ITypeID[] result = null;
210
+		if (typeParameters != null) {
211
+			result = new ITypeID[typeParameters.size()];
212
+			for (int i = 0; i < typeParameters.size(); i++) {
213
+				result[i] = typeParameters.get(i).compile(scope);
214
+			}
215
+		}
216
+		return result;
200 217
 	}
201 218
 	
202 219
 	public IParsedType withOptional();

+ 2
- 11
Parser/src/main/java/org/openzen/zenscript/parser/type/ParsedNamedType.java View File

@@ -6,7 +6,6 @@
6 6
 package org.openzen.zenscript.parser.type;
7 7
 
8 8
 import java.util.ArrayList;
9
-import java.util.Collections;
10 9
 import java.util.List;
11 10
 import org.openzen.zenscript.codemodel.type.GenericName;
12 11
 import org.openzen.zenscript.codemodel.type.ITypeID;
@@ -94,21 +93,13 @@ public class ParsedNamedType implements IParsedType {
94 93
 		}
95 94
 		
96 95
 		private GenericName compile(BaseScope scope) {
97
-			if (typeArguments.isEmpty()) {
98
-				return new GenericName(name, Collections.emptyList());
99
-			} else {
100
-				List<ITypeID> genericTypes = new ArrayList<>();
101
-				for (IParsedType type : typeArguments)
102
-					genericTypes.add(type.compile(scope));
103
-				
104
-				return new GenericName(name, genericTypes);
105
-			}
96
+			return new GenericName(name, IParsedType.compileList(typeArguments, scope));
106 97
 		}
107 98
 		
108 99
 		@Override
109 100
 		public String toString() {
110 101
 			StringBuilder result = new StringBuilder(name);
111
-			if (!typeArguments.isEmpty()) {
102
+			if (typeArguments != null) {
112 103
 				result.append("<");
113 104
 				for (int i = 0; i < typeArguments.size(); i++) {
114 105
 					if (i > 0)

+ 2
- 2
Parser/src/main/java/org/openzen/zenscript/parser/type/ParsedTypeGenericMap.java View File

@@ -75,7 +75,7 @@ public class ParsedTypeGenericMap implements IParsedType {
75 75
 
76 76
 		@Override
77 77
 		public IPartialExpression get(CodePosition position, GenericName name) {
78
-			if (typeParameters.containsKey(name.name) && name.arguments.isEmpty())
78
+			if (typeParameters.containsKey(name.name) && name.hasNoArguments())
79 79
 				return new PartialTypeExpression(position, getTypeRegistry().getGeneric(typeParameters.get(name.name)));
80 80
 			
81 81
 			return outer.get(position, name);
@@ -83,7 +83,7 @@ public class ParsedTypeGenericMap implements IParsedType {
83 83
 
84 84
 		@Override
85 85
 		public ITypeID getType(CodePosition position, List<GenericName> name) {
86
-			if (typeParameters.containsKey(name.get(0).name) && name.size() == 1 && name.get(0).arguments.isEmpty())
86
+			if (typeParameters.containsKey(name.get(0).name) && name.size() == 1 && name.get(0).hasNoArguments())
87 87
 				return getTypeRegistry().getGeneric(typeParameters.get(name.get(0).name));
88 88
 			
89 89
 			return outer.getType(position, name);

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

@@ -121,17 +121,18 @@ public class GlobalRegistry {
121 121
 	private class PrintlnSymbol implements ISymbol {
122 122
 
123 123
 		@Override
124
-		public IPartialExpression getExpression(CodePosition position, GlobalTypeRegistry types, List<ITypeID> typeArguments) {
124
+		public IPartialExpression getExpression(CodePosition position, GlobalTypeRegistry types, ITypeID[] typeArguments) {
125 125
 			//return new PartialStaticMemberGroupExpression(position, PRINTLN.callerGroup);
126 126
 			return new PartialMemberGroupExpression(
127 127
 					position,
128 128
 					new GetStaticFieldExpression(position, SYSTEM_OUT),
129 129
 					PRINTSTREAM_PRINTLN,
130
+					null,
130 131
 					false);
131 132
 		}
132 133
 
133 134
 		@Override
134
-		public ITypeID getType(CodePosition position, GlobalTypeRegistry types, List<ITypeID> typeArguments) {
135
+		public ITypeID getType(CodePosition position, GlobalTypeRegistry types, ITypeID[] typeArguments) {
135 136
 			// don't be fooled! this symbol is the System.out.println bound method and thus its type is a function
136 137
 			return new FunctionTypeID(PRINTSTREAM_PRINTLN.header);
137 138
 		}

+ 2
- 1
Validator/src/main/java/org/openzen/zenscript/validator/visitors/DefinitionMemberValidator.java View File

@@ -187,7 +187,8 @@ public class DefinitionMemberValidator implements MemberVisitor<Boolean> {
187 187
 
188 188
 	@Override
189 189
 	public Boolean visitCustomIterator(CustomIteratorMember member) {
190
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
190
+		// TODO: validate iterators
191
+		return true;
191 192
 	}
192 193
 
193 194
 	@Override

+ 15
- 13
Validator/src/main/java/org/openzen/zenscript/validator/visitors/ExpressionValidator.java View File

@@ -145,13 +145,13 @@ public class ExpressionValidator implements ExpressionVisitor<Boolean> {
145 145
 	public Boolean visitCall(CallExpression expression) {
146 146
 		boolean isValid = true;
147 147
 		isValid &= expression.target.accept(this);
148
-		isValid &= checkCallArguments(expression.position, expression.member.header, expression.arguments);
148
+		isValid &= checkCallArguments(expression.position, expression.member.header, expression.instancedHeader, expression.arguments);
149 149
 		return isValid;
150 150
 	}
151 151
 
152 152
 	@Override
153 153
 	public Boolean visitCallStatic(CallStaticExpression expression) {
154
-		return checkCallArguments(expression.position, expression.member.header, expression.arguments);
154
+		return checkCallArguments(expression.position, expression.member.header, expression.instancedHeader, expression.arguments);
155 155
 	}
156 156
 
157 157
 	@Override
@@ -297,7 +297,7 @@ public class ExpressionValidator implements ExpressionVisitor<Boolean> {
297 297
 			isValid = false;
298 298
 		}
299 299
 		scope.markConstructorForwarded();
300
-		isValid &= checkCallArguments(expression.position, expression.constructor.header, expression.arguments);
300
+		isValid &= checkCallArguments(expression.position, expression.constructor.header, expression.constructor.header, expression.arguments);
301 301
 		return isValid;
302 302
 	}
303 303
 
@@ -313,7 +313,7 @@ public class ExpressionValidator implements ExpressionVisitor<Boolean> {
313 313
 			isValid = false;
314 314
 		}
315 315
 		scope.markConstructorForwarded();
316
-		isValid &= checkCallArguments(expression.position, expression.constructor.header, expression.arguments);
316
+		isValid &= checkCallArguments(expression.position, expression.constructor.header, expression.constructor.header, expression.arguments);
317 317
 		return isValid;
318 318
 	}
319 319
 
@@ -331,7 +331,8 @@ public class ExpressionValidator implements ExpressionVisitor<Boolean> {
331 331
 
332 332
 	@Override
333 333
 	public Boolean visitFunction(FunctionExpression expression) {
334
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
334
+		// TODO
335
+		return true;
335 336
 	}
336 337
 
337 338
 	@Override
@@ -444,6 +445,7 @@ public class ExpressionValidator implements ExpressionVisitor<Boolean> {
444 445
 		boolean isValid = checkCallArguments(
445 446
 				expression.position,
446 447
 				expression.constructor.header,
448
+				expression.constructor.header,
447 449
 				expression.arguments);
448 450
 		return isValid;
449 451
 	}
@@ -618,23 +620,23 @@ public class ExpressionValidator implements ExpressionVisitor<Boolean> {
618 620
 	@Override
619 621
 	public Boolean visitWrapOptional(WrapOptionalExpression expression) {
620 622
 		boolean isValid = expression.value.accept(this);
621
-		if (expression.type.isOptional()) {
623
+		if (expression.value.type.isOptional()) {
622 624
 			validator.logError(ValidationLogEntry.Code.INVALID_OPERAND_TYPE, expression.position, "expression value is already optional");
623 625
 			isValid = false;
624 626
 		}
625 627
 		return isValid;
626 628
 	}
627 629
 	
628
-	private boolean checkCallArguments(CodePosition position, FunctionHeader header, CallArguments arguments) {
630
+	private boolean checkCallArguments(CodePosition position, FunctionHeader originalHeader, FunctionHeader instancedHeader, CallArguments arguments) {
629 631
 		boolean isValid = true;
630
-		isValid &= ValidationUtils.validateTypeArguments(validator, position, header.typeParameters, arguments.typeArguments);
632
+		isValid &= ValidationUtils.validateTypeArguments(validator, position, originalHeader.typeParameters, arguments.typeArguments);
631 633
 		
632 634
 		for (int i = 0; i < arguments.arguments.length; i++) {
633 635
 			Expression argument = arguments.arguments[i];
634 636
 			isValid &= argument.accept(this);
635 637
 			
636
-			if (i >= header.parameters.length) {
637
-				FunctionParameter variadic = header.getVariadicParameter();
638
+			if (i >= instancedHeader.parameters.length) {
639
+				FunctionParameter variadic = instancedHeader.getVariadicParameter();
638 640
 				if (variadic == null) {
639 641
 					validator.logError(ValidationLogEntry.Code.INVALID_CALL_ARGUMENT, position, "too many call arguments");
640 642
 					isValid = false;
@@ -649,7 +651,7 @@ public class ExpressionValidator implements ExpressionVisitor<Boolean> {
649 651
 				}
650 652
 			}
651 653
 			
652
-			FunctionParameter parameter = header.parameters[i];
654
+			FunctionParameter parameter = instancedHeader.parameters[i];
653 655
 			if (parameter.type != argument.type) {
654 656
 				validator.logError(
655 657
 						ValidationLogEntry.Code.INVALID_CALL_ARGUMENT,
@@ -659,8 +661,8 @@ public class ExpressionValidator implements ExpressionVisitor<Boolean> {
659 661
 			}
660 662
 		}
661 663
 		
662
-		for (int i = arguments.arguments.length; i < header.parameters.length; i++) {
663
-			FunctionParameter parameter = header.parameters[i];
664
+		for (int i = arguments.arguments.length; i < instancedHeader.parameters.length; i++) {
665
+			FunctionParameter parameter = instancedHeader.parameters[i];
664 666
 			if (parameter.defaultValue == null && !parameter.variadic) {
665 667
 				validator.logError(ValidationLogEntry.Code.INVALID_CALL_ARGUMENT, position, "missing call argument for " + parameter.name);
666 668
 				isValid = false;

+ 8
- 2
Validator/src/main/java/org/openzen/zenscript/validator/visitors/ValidationUtils.java View File

@@ -148,6 +148,11 @@ public class ValidationUtils {
148 148
 			TypeParameter[] typeParameters,
149 149
 			ITypeID[] typeArguments)
150 150
 	{
151
+		if (typeParameters == null)
152
+			return typeArguments == null;
153
+		if (typeArguments == null)
154
+			return false;
155
+		
151 156
 		if (typeParameters.length != typeArguments.length) {
152 157
 			target.logError(
153 158
 					ValidationLogEntry.Code.INVALID_TYPE_ARGUMENT,
@@ -164,13 +169,14 @@ public class ValidationUtils {
164 169
 		for (int i = 0; i < typeParameters.length; i++) {
165 170
 			TypeParameter typeParameter = typeParameters[i];
166 171
 			for (GenericParameterBound bound : typeParameter.bounds) {
167
-				if (!bound.matches(typeArguments[i])) {
172
+				// TODO - obtain member cache for validation
173
+				/*if (!bound.matches(typeArguments[i])) {
168 174
 					target.logError(
169 175
 							ValidationLogEntry.Code.INVALID_TYPE_ARGUMENT,
170 176
 							position,
171 177
 							bound.accept(new TypeParameterBoundErrorVisitor(typeArguments[i], target)));
172 178
 					isValid = false;
173
-				}
179
+				}*/
174 180
 			}
175 181
 		}
176 182
 		return isValid;

Loading…
Cancel
Save