foreach
This commit is contained in:
@@ -99,6 +99,7 @@ public class TypeChecker
|
||||
NodeStatementReturn statement => CheckStatementReturn(statement),
|
||||
NodeStatementVariableDeclaration statement => CheckStatementVariableDeclaration(statement),
|
||||
NodeStatementWhile statement => CheckStatementWhile(statement),
|
||||
NodeStatementFor statement => CheckStatementFor(statement),
|
||||
NodeStatementMatch statement => CheckStatementMatch(statement),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(node))
|
||||
};
|
||||
@@ -204,6 +205,22 @@ public class TypeChecker
|
||||
}
|
||||
}
|
||||
|
||||
private TypedNodeStatementFor CheckStatementFor(NodeStatementFor statement)
|
||||
{
|
||||
var array = CheckExpression(statement.Array, null);
|
||||
if (array.Type is not NubTypeArray arrayType)
|
||||
throw BasicError($"Cannot iterate over non-array type '{array.Type}'", statement.Array);
|
||||
|
||||
TypedNodeStatement body;
|
||||
using (EnterScope())
|
||||
{
|
||||
DeclareLocalIdentifier(statement.VariableName, arrayType.ElementType);
|
||||
body = CheckStatement(statement.Body);
|
||||
}
|
||||
|
||||
return new TypedNodeStatementFor(statement.Tokens, statement.VariableName, array, body);
|
||||
}
|
||||
|
||||
private TypedNodeStatementMatch CheckStatementMatch(NodeStatementMatch statement)
|
||||
{
|
||||
var target = CheckExpression(statement.Target, null);
|
||||
@@ -264,6 +281,7 @@ public class TypeChecker
|
||||
NodeExpressionStructLiteral expression => CheckExpressionStructLiteral(expression, expectedType),
|
||||
NodeExpressionEnumLiteral expression => CheckExpressionEnumLiteral(expression, expectedType),
|
||||
NodeExpressionStringConstructor expression => CheckExpressionStringConstructor(expression, expectedType),
|
||||
NodeExpressionArrayLiteral expression => CheckExpressionArrayLiteral(expression, expectedType),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(node))
|
||||
};
|
||||
}
|
||||
@@ -675,6 +693,31 @@ public class TypeChecker
|
||||
return new TypedNodeExpressionStringConstructor(expression.Tokens, NubTypeString.Instance, value);
|
||||
}
|
||||
|
||||
private TypedNodeExpressionArrayLiteral CheckExpressionArrayLiteral(NodeExpressionArrayLiteral expression, NubType? expectedType)
|
||||
{
|
||||
NubType? elementType = null;
|
||||
if (expectedType is NubTypeArray arrayType)
|
||||
elementType = arrayType.ElementType;
|
||||
|
||||
var values = new List<TypedNodeExpression>();
|
||||
|
||||
foreach (var value in expression.Values)
|
||||
{
|
||||
var checkedValue = CheckExpression(value, elementType);
|
||||
elementType ??= checkedValue.Type;
|
||||
|
||||
if (!checkedValue.Type.IsAssignableTo(elementType))
|
||||
throw BasicError($"Type '{checkedValue.Type}' is not assignable to type of element '{elementType}'", checkedValue);
|
||||
|
||||
values.Add(checkedValue);
|
||||
}
|
||||
|
||||
if (elementType is null)
|
||||
throw BasicError("Unable to infer type of array element", expression);
|
||||
|
||||
return new TypedNodeExpressionArrayLiteral(expression.Tokens, NubTypeArray.Get(elementType), values);
|
||||
}
|
||||
|
||||
private NubType ResolveType(NodeType node)
|
||||
{
|
||||
return node switch
|
||||
@@ -908,6 +951,13 @@ public class TypedNodeStatementWhile(List<Token> tokens, TypedNodeExpression con
|
||||
public TypedNodeStatement Body { get; } = body;
|
||||
}
|
||||
|
||||
public class TypedNodeStatementFor(List<Token> tokens, TokenIdent variableName, TypedNodeExpression array, TypedNodeStatement body) : TypedNodeStatement(tokens)
|
||||
{
|
||||
public TokenIdent VariableName { get; } = variableName;
|
||||
public TypedNodeExpression Array { get; } = array;
|
||||
public TypedNodeStatement Body { get; } = body;
|
||||
}
|
||||
|
||||
public class TypedNodeStatementMatch(List<Token> tokens, TypedNodeExpression target, List<TypedNodeStatementMatch.Case> cases) : TypedNodeStatement(tokens)
|
||||
{
|
||||
public TypedNodeExpression Target { get; } = target;
|
||||
@@ -962,6 +1012,11 @@ public class TypedNodeExpressionStringConstructor(List<Token> tokens, NubType ty
|
||||
public TypedNodeExpression Value { get; } = value;
|
||||
}
|
||||
|
||||
public class TypedNodeExpressionArrayLiteral(List<Token> tokens, NubType type, List<TypedNodeExpression> values) : TypedNodeExpression(tokens, type)
|
||||
{
|
||||
public List<TypedNodeExpression> Values { get; } = values;
|
||||
}
|
||||
|
||||
public class TypedNodeExpressionStructMemberAccess(List<Token> tokens, NubType type, TypedNodeExpression target, TokenIdent name) : TypedNodeExpression(tokens, type)
|
||||
{
|
||||
public TypedNodeExpression Target { get; } = target;
|
||||
|
||||
Reference in New Issue
Block a user