...
This commit is contained in:
@@ -307,7 +307,11 @@ public abstract class ExpressionNode(List<Token> tokens, NubType type) : Node(to
|
||||
public NubType Type { get; } = type;
|
||||
}
|
||||
|
||||
public class StringLiteralNode(List<Token> tokens, string value) : ExpressionNode(tokens, new NubStringType())
|
||||
public abstract class LValue(List<Token> tokens, NubType type) : ExpressionNode(tokens, type);
|
||||
|
||||
public abstract class RValue(List<Token> tokens, NubType type) : ExpressionNode(tokens, type);
|
||||
|
||||
public class StringLiteralNode(List<Token> tokens, string value) : RValue(tokens, new NubStringType())
|
||||
{
|
||||
public string Value { get; } = value;
|
||||
|
||||
@@ -317,7 +321,7 @@ public class StringLiteralNode(List<Token> tokens, string value) : ExpressionNod
|
||||
}
|
||||
}
|
||||
|
||||
public class CStringLiteralNode(List<Token> tokens, string value) : ExpressionNode(tokens, new NubPointerType(new NubIntType(true, 8)))
|
||||
public class CStringLiteralNode(List<Token> tokens, string value) : RValue(tokens, new NubPointerType(new NubIntType(true, 8)))
|
||||
{
|
||||
public string Value { get; } = value;
|
||||
|
||||
@@ -327,7 +331,7 @@ public class CStringLiteralNode(List<Token> tokens, string value) : ExpressionNo
|
||||
}
|
||||
}
|
||||
|
||||
public class I8LiteralNode(List<Token> tokens, sbyte value) : ExpressionNode(tokens, new NubIntType(true, 8))
|
||||
public class I8LiteralNode(List<Token> tokens, sbyte value) : RValue(tokens, new NubIntType(true, 8))
|
||||
{
|
||||
public sbyte Value { get; } = value;
|
||||
|
||||
@@ -337,7 +341,7 @@ public class I8LiteralNode(List<Token> tokens, sbyte value) : ExpressionNode(tok
|
||||
}
|
||||
}
|
||||
|
||||
public class I16LiteralNode(List<Token> tokens, short value) : ExpressionNode(tokens, new NubIntType(true, 16))
|
||||
public class I16LiteralNode(List<Token> tokens, short value) : RValue(tokens, new NubIntType(true, 16))
|
||||
{
|
||||
public short Value { get; } = value;
|
||||
|
||||
@@ -347,7 +351,7 @@ public class I16LiteralNode(List<Token> tokens, short value) : ExpressionNode(to
|
||||
}
|
||||
}
|
||||
|
||||
public class I32LiteralNode(List<Token> tokens, int value) : ExpressionNode(tokens, new NubIntType(true, 32))
|
||||
public class I32LiteralNode(List<Token> tokens, int value) : RValue(tokens, new NubIntType(true, 32))
|
||||
{
|
||||
public int Value { get; } = value;
|
||||
|
||||
@@ -357,7 +361,7 @@ public class I32LiteralNode(List<Token> tokens, int value) : ExpressionNode(toke
|
||||
}
|
||||
}
|
||||
|
||||
public class I64LiteralNode(List<Token> tokens, long value) : ExpressionNode(tokens, new NubIntType(true, 64))
|
||||
public class I64LiteralNode(List<Token> tokens, long value) : RValue(tokens, new NubIntType(true, 64))
|
||||
{
|
||||
public long Value { get; } = value;
|
||||
|
||||
@@ -367,7 +371,7 @@ public class I64LiteralNode(List<Token> tokens, long value) : ExpressionNode(tok
|
||||
}
|
||||
}
|
||||
|
||||
public class U8LiteralNode(List<Token> tokens, byte value) : ExpressionNode(tokens, new NubIntType(false, 8))
|
||||
public class U8LiteralNode(List<Token> tokens, byte value) : RValue(tokens, new NubIntType(false, 8))
|
||||
{
|
||||
public byte Value { get; } = value;
|
||||
|
||||
@@ -377,7 +381,7 @@ public class U8LiteralNode(List<Token> tokens, byte value) : ExpressionNode(toke
|
||||
}
|
||||
}
|
||||
|
||||
public class U16LiteralNode(List<Token> tokens, ushort value) : ExpressionNode(tokens, new NubIntType(false, 16))
|
||||
public class U16LiteralNode(List<Token> tokens, ushort value) : RValue(tokens, new NubIntType(false, 16))
|
||||
{
|
||||
public ushort Value { get; } = value;
|
||||
|
||||
@@ -387,7 +391,7 @@ public class U16LiteralNode(List<Token> tokens, ushort value) : ExpressionNode(t
|
||||
}
|
||||
}
|
||||
|
||||
public class U32LiteralNode(List<Token> tokens, uint value) : ExpressionNode(tokens, new NubIntType(false, 32))
|
||||
public class U32LiteralNode(List<Token> tokens, uint value) : RValue(tokens, new NubIntType(false, 32))
|
||||
{
|
||||
public uint Value { get; } = value;
|
||||
|
||||
@@ -397,7 +401,7 @@ public class U32LiteralNode(List<Token> tokens, uint value) : ExpressionNode(tok
|
||||
}
|
||||
}
|
||||
|
||||
public class U64LiteralNode(List<Token> tokens, ulong value) : ExpressionNode(tokens, new NubIntType(false, 64))
|
||||
public class U64LiteralNode(List<Token> tokens, ulong value) : RValue(tokens, new NubIntType(false, 64))
|
||||
{
|
||||
public ulong Value { get; } = value;
|
||||
|
||||
@@ -407,7 +411,7 @@ public class U64LiteralNode(List<Token> tokens, ulong value) : ExpressionNode(to
|
||||
}
|
||||
}
|
||||
|
||||
public class Float32LiteralNode(List<Token> tokens, float value) : ExpressionNode(tokens, new NubFloatType(32))
|
||||
public class Float32LiteralNode(List<Token> tokens, float value) : RValue(tokens, new NubFloatType(32))
|
||||
{
|
||||
public float Value { get; } = value;
|
||||
|
||||
@@ -417,7 +421,7 @@ public class Float32LiteralNode(List<Token> tokens, float value) : ExpressionNod
|
||||
}
|
||||
}
|
||||
|
||||
public class Float64LiteralNode(List<Token> tokens, double value) : ExpressionNode(tokens, new NubFloatType(64))
|
||||
public class Float64LiteralNode(List<Token> tokens, double value) : RValue(tokens, new NubFloatType(64))
|
||||
{
|
||||
public double Value { get; } = value;
|
||||
|
||||
@@ -427,7 +431,7 @@ public class Float64LiteralNode(List<Token> tokens, double value) : ExpressionNo
|
||||
}
|
||||
}
|
||||
|
||||
public class BoolLiteralNode(List<Token> tokens, bool value) : ExpressionNode(tokens, new NubBoolType())
|
||||
public class BoolLiteralNode(List<Token> tokens, bool value) : RValue(tokens, new NubBoolType())
|
||||
{
|
||||
public bool Value { get; } = value;
|
||||
|
||||
@@ -437,7 +441,7 @@ public class BoolLiteralNode(List<Token> tokens, bool value) : ExpressionNode(to
|
||||
}
|
||||
}
|
||||
|
||||
public class BinaryExpressionNode(List<Token> tokens, NubType type, ExpressionNode left, BinaryOperator @operator, ExpressionNode right) : ExpressionNode(tokens, type)
|
||||
public class BinaryExpressionNode(List<Token> tokens, NubType type, ExpressionNode left, BinaryOperator @operator, ExpressionNode right) : RValue(tokens, type)
|
||||
{
|
||||
public ExpressionNode Left { get; } = left;
|
||||
public BinaryOperator Operator { get; } = @operator;
|
||||
@@ -450,7 +454,7 @@ public class BinaryExpressionNode(List<Token> tokens, NubType type, ExpressionNo
|
||||
}
|
||||
}
|
||||
|
||||
public class UnaryExpressionNode(List<Token> tokens, NubType type, UnaryOperator @operator, ExpressionNode operand) : ExpressionNode(tokens, type)
|
||||
public class UnaryExpressionNode(List<Token> tokens, NubType type, UnaryOperator @operator, ExpressionNode operand) : RValue(tokens, type)
|
||||
{
|
||||
public UnaryOperator Operator { get; } = @operator;
|
||||
public ExpressionNode Operand { get; } = operand;
|
||||
@@ -461,7 +465,7 @@ public class UnaryExpressionNode(List<Token> tokens, NubType type, UnaryOperator
|
||||
}
|
||||
}
|
||||
|
||||
public class FuncCallNode(List<Token> tokens, NubType type, ExpressionNode expression, List<ExpressionNode> parameters) : ExpressionNode(tokens, type)
|
||||
public class FuncCallNode(List<Token> tokens, NubType type, ExpressionNode expression, List<ExpressionNode> parameters) : RValue(tokens, type)
|
||||
{
|
||||
public ExpressionNode Expression { get; } = expression;
|
||||
public List<ExpressionNode> Parameters { get; } = parameters;
|
||||
@@ -476,7 +480,7 @@ public class FuncCallNode(List<Token> tokens, NubType type, ExpressionNode expre
|
||||
}
|
||||
}
|
||||
|
||||
public class VariableIdentifierNode(List<Token> tokens, NubType type, IdentifierToken nameToken) : ExpressionNode(tokens, type)
|
||||
public class VariableIdentifierNode(List<Token> tokens, NubType type, IdentifierToken nameToken) : LValue(tokens, type)
|
||||
{
|
||||
public IdentifierToken NameToken { get; } = nameToken;
|
||||
|
||||
@@ -486,7 +490,7 @@ public class VariableIdentifierNode(List<Token> tokens, NubType type, Identifier
|
||||
}
|
||||
}
|
||||
|
||||
public class FuncIdentifierNode(List<Token> tokens, NubType type, IdentifierToken moduleToken, IdentifierToken nameToken, StringLiteralToken? externSymbolToken) : ExpressionNode(tokens, type)
|
||||
public class FuncIdentifierNode(List<Token> tokens, NubType type, IdentifierToken moduleToken, IdentifierToken nameToken, StringLiteralToken? externSymbolToken) : RValue(tokens, type)
|
||||
{
|
||||
public IdentifierToken ModuleToken { get; } = moduleToken;
|
||||
public IdentifierToken NameToken { get; } = nameToken;
|
||||
@@ -498,27 +502,7 @@ public class FuncIdentifierNode(List<Token> tokens, NubType type, IdentifierToke
|
||||
}
|
||||
}
|
||||
|
||||
public class ArrayInitializerNode(List<Token> tokens, NubType type, List<ExpressionNode> values) : ExpressionNode(tokens, type)
|
||||
{
|
||||
public List<ExpressionNode> Values { get; } = values;
|
||||
|
||||
public override IEnumerable<Node> Children()
|
||||
{
|
||||
return Values;
|
||||
}
|
||||
}
|
||||
|
||||
public class ConstArrayInitializerNode(List<Token> tokens, NubType type, List<ExpressionNode> values) : ExpressionNode(tokens, type)
|
||||
{
|
||||
public List<ExpressionNode> Values { get; } = values;
|
||||
|
||||
public override IEnumerable<Node> Children()
|
||||
{
|
||||
return Values;
|
||||
}
|
||||
}
|
||||
|
||||
public class ArrayIndexAccessNode(List<Token> tokens, NubType type, ExpressionNode target, ExpressionNode index) : ExpressionNode(tokens, type)
|
||||
public class ArrayIndexAccessNode(List<Token> tokens, NubType type, ExpressionNode target, ExpressionNode index) : LValue(tokens, type)
|
||||
{
|
||||
public ExpressionNode Target { get; } = target;
|
||||
public ExpressionNode Index { get; } = index;
|
||||
@@ -530,7 +514,7 @@ public class ArrayIndexAccessNode(List<Token> tokens, NubType type, ExpressionNo
|
||||
}
|
||||
}
|
||||
|
||||
public class ConstArrayIndexAccessNode(List<Token> tokens, NubType type, ExpressionNode target, ExpressionNode index) : ExpressionNode(tokens, type)
|
||||
public class ConstArrayIndexAccessNode(List<Token> tokens, NubType type, ExpressionNode target, ExpressionNode index) : LValue(tokens, type)
|
||||
{
|
||||
public ExpressionNode Target { get; } = target;
|
||||
public ExpressionNode Index { get; } = index;
|
||||
@@ -542,7 +526,7 @@ public class ConstArrayIndexAccessNode(List<Token> tokens, NubType type, Express
|
||||
}
|
||||
}
|
||||
|
||||
public class SliceIndexAccessNode(List<Token> tokens, NubType type, ExpressionNode target, ExpressionNode index) : ExpressionNode(tokens, type)
|
||||
public class SliceIndexAccessNode(List<Token> tokens, NubType type, ExpressionNode target, ExpressionNode index) : LValue(tokens, type)
|
||||
{
|
||||
public ExpressionNode Target { get; } = target;
|
||||
public ExpressionNode Index { get; } = index;
|
||||
@@ -554,7 +538,7 @@ public class SliceIndexAccessNode(List<Token> tokens, NubType type, ExpressionNo
|
||||
}
|
||||
}
|
||||
|
||||
public class AddressOfNode(List<Token> tokens, NubType type, ExpressionNode target) : ExpressionNode(tokens, type)
|
||||
public class AddressOfNode(List<Token> tokens, NubType type, ExpressionNode target) : RValue(tokens, type)
|
||||
{
|
||||
public ExpressionNode Target { get; } = target;
|
||||
|
||||
@@ -564,7 +548,7 @@ public class AddressOfNode(List<Token> tokens, NubType type, ExpressionNode targ
|
||||
}
|
||||
}
|
||||
|
||||
public class StructFieldAccessNode(List<Token> tokens, NubType type, ExpressionNode target, IdentifierToken fieldToken) : ExpressionNode(tokens, type)
|
||||
public class StructFieldAccessNode(List<Token> tokens, NubType type, ExpressionNode target, IdentifierToken fieldToken) : LValue(tokens, type)
|
||||
{
|
||||
public ExpressionNode Target { get; } = target;
|
||||
public IdentifierToken FieldToken { get; } = fieldToken;
|
||||
@@ -575,7 +559,37 @@ public class StructFieldAccessNode(List<Token> tokens, NubType type, ExpressionN
|
||||
}
|
||||
}
|
||||
|
||||
public class StructInitializerNode(List<Token> tokens, NubType type, Dictionary<IdentifierToken, ExpressionNode> initializers) : ExpressionNode(tokens, type)
|
||||
public class DereferenceNode(List<Token> tokens, NubType type, ExpressionNode target) : LValue(tokens, type)
|
||||
{
|
||||
public ExpressionNode Target { get; } = target;
|
||||
|
||||
public override IEnumerable<Node> Children()
|
||||
{
|
||||
yield return Target;
|
||||
}
|
||||
}
|
||||
|
||||
public class SizeNode(List<Token> tokens, NubType targetType) : RValue(tokens, new NubIntType(false, 64))
|
||||
{
|
||||
public NubType TargetType { get; } = targetType;
|
||||
|
||||
public override IEnumerable<Node> Children()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
public class CastNode(List<Token> tokens, NubType type, ExpressionNode value) : RValue(tokens, type)
|
||||
{
|
||||
public ExpressionNode Value { get; } = value;
|
||||
|
||||
public override IEnumerable<Node> Children()
|
||||
{
|
||||
yield return Value;
|
||||
}
|
||||
}
|
||||
|
||||
public class StructInitializerNode(List<Token> tokens, NubType type, Dictionary<IdentifierToken, ExpressionNode> initializers) : RValue(tokens, type)
|
||||
{
|
||||
public Dictionary<IdentifierToken, ExpressionNode> Initializers { get; } = initializers;
|
||||
|
||||
@@ -588,33 +602,13 @@ public class StructInitializerNode(List<Token> tokens, NubType type, Dictionary<
|
||||
}
|
||||
}
|
||||
|
||||
public class DereferenceNode(List<Token> tokens, NubType type, ExpressionNode target) : ExpressionNode(tokens, type)
|
||||
public class ConstArrayInitializerNode(List<Token> tokens, NubType type, List<ExpressionNode> values) : RValue(tokens, type)
|
||||
{
|
||||
public ExpressionNode Target { get; } = target;
|
||||
public List<ExpressionNode> Values { get; } = values;
|
||||
|
||||
public override IEnumerable<Node> Children()
|
||||
{
|
||||
yield return Target;
|
||||
}
|
||||
}
|
||||
|
||||
public class SizeNode(List<Token> tokens, NubType TargetType) : ExpressionNode(tokens, new NubIntType(false, 64))
|
||||
{
|
||||
public NubType TargetType { get; } = TargetType;
|
||||
|
||||
public override IEnumerable<Node> Children()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
public class CastNode(List<Token> tokens, NubType type, ExpressionNode value) : ExpressionNode(tokens, type)
|
||||
{
|
||||
public ExpressionNode Value { get; } = value;
|
||||
|
||||
public override IEnumerable<Node> Children()
|
||||
{
|
||||
yield return Value;
|
||||
return Values;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ public abstract class NubType : IEquatable<NubType>
|
||||
{
|
||||
public abstract ulong GetSize();
|
||||
public abstract ulong GetAlignment();
|
||||
public abstract bool IsAggregate();
|
||||
|
||||
public override bool Equals(object? obj) => obj is NubType other && Equals(other);
|
||||
public abstract bool Equals(NubType? other);
|
||||
@@ -22,6 +23,7 @@ public class NubVoidType : NubType
|
||||
{
|
||||
public override ulong GetSize() => 8;
|
||||
public override ulong GetAlignment() => 8;
|
||||
public override bool IsAggregate() => false;
|
||||
|
||||
public override string ToString() => "void";
|
||||
public override bool Equals(NubType? other) => other is NubVoidType;
|
||||
@@ -35,6 +37,7 @@ public sealed class NubIntType(bool signed, ulong width) : NubType
|
||||
|
||||
public override ulong GetSize() => Width / 8;
|
||||
public override ulong GetAlignment() => Width / 8;
|
||||
public override bool IsAggregate() => false;
|
||||
|
||||
public override string ToString() => $"{(Signed ? "i" : "u")}{Width}";
|
||||
public override bool Equals(NubType? other) => other is NubIntType @int && @int.Width == Width && @int.Signed == Signed;
|
||||
@@ -47,6 +50,7 @@ public sealed class NubFloatType(ulong width) : NubType
|
||||
|
||||
public override ulong GetSize() => Width / 8;
|
||||
public override ulong GetAlignment() => Width / 8;
|
||||
public override bool IsAggregate() => false;
|
||||
|
||||
public override string ToString() => $"f{Width}";
|
||||
public override bool Equals(NubType? other) => other is NubFloatType @float && @float.Width == Width;
|
||||
@@ -57,6 +61,7 @@ public class NubBoolType : NubType
|
||||
{
|
||||
public override ulong GetSize() => 1;
|
||||
public override ulong GetAlignment() => 1;
|
||||
public override bool IsAggregate() => false;
|
||||
|
||||
public override string ToString() => "bool";
|
||||
public override bool Equals(NubType? other) => other is NubBoolType;
|
||||
@@ -69,6 +74,7 @@ public sealed class NubPointerType(NubType baseType) : NubType
|
||||
|
||||
public override ulong GetSize() => 8;
|
||||
public override ulong GetAlignment() => 8;
|
||||
public override bool IsAggregate() => false;
|
||||
|
||||
public override string ToString() => "^" + BaseType;
|
||||
public override bool Equals(NubType? other) => other is NubPointerType pointer && BaseType.Equals(pointer.BaseType);
|
||||
@@ -82,6 +88,7 @@ public class NubFuncType(List<NubType> parameters, NubType returnType) : NubType
|
||||
|
||||
public override ulong GetSize() => 8;
|
||||
public override ulong GetAlignment() => 8;
|
||||
public override bool IsAggregate() => false;
|
||||
|
||||
public override string ToString() => $"func({string.Join(", ", Parameters)}): {ReturnType}";
|
||||
public override bool Equals(NubType? other) => other is NubFuncType func && ReturnType.Equals(func.ReturnType) && Parameters.SequenceEqual(func.Parameters);
|
||||
@@ -107,9 +114,14 @@ public class NubStructType(string module, string name, bool packed, List<NubStru
|
||||
public bool Packed { get; } = packed;
|
||||
public List<NubStructFieldType> Fields { get; set; } = fields;
|
||||
|
||||
public Dictionary<NubStructFieldType, ulong> GetFieldOffsets()
|
||||
public int GetFieldIndex(string name)
|
||||
{
|
||||
var offsets = new Dictionary<NubStructFieldType, ulong>();
|
||||
return Fields.FindIndex(x => x.Name == name);
|
||||
}
|
||||
|
||||
public Dictionary<string, ulong> GetFieldOffsets()
|
||||
{
|
||||
var offsets = new Dictionary<string, ulong>();
|
||||
ulong offset = 0;
|
||||
|
||||
foreach (var field in Fields)
|
||||
@@ -121,7 +133,7 @@ public class NubStructType(string module, string name, bool packed, List<NubStru
|
||||
offset += padding;
|
||||
}
|
||||
|
||||
offsets[field] = offset;
|
||||
offsets[field.Name] = offset;
|
||||
offset += field.Type.GetSize();
|
||||
}
|
||||
|
||||
@@ -137,7 +149,7 @@ public class NubStructType(string module, string name, bool packed, List<NubStru
|
||||
}
|
||||
|
||||
var lastField = Fields.Last();
|
||||
var size = offsets[lastField] + lastField.Type.GetSize();
|
||||
var size = offsets[lastField.Name] + lastField.Type.GetSize();
|
||||
|
||||
if (!Packed)
|
||||
{
|
||||
@@ -157,6 +169,8 @@ public class NubStructType(string module, string name, bool packed, List<NubStru
|
||||
return Packed ? 1 : Fields.Max(f => f.Type.GetAlignment());
|
||||
}
|
||||
|
||||
public override bool IsAggregate() => true;
|
||||
|
||||
public override string ToString() => $"{Module}::{Name}";
|
||||
public override bool Equals(NubType? other) => other is NubStructType structType && Name == structType.Name && Module == structType.Module;
|
||||
public override int GetHashCode() => HashCode.Combine(typeof(NubStructType), Module, Name);
|
||||
@@ -173,9 +187,9 @@ public class NubSliceType(NubType elementType) : NubType
|
||||
{
|
||||
public NubType ElementType { get; } = elementType;
|
||||
|
||||
// note(nub31): Fat pointer
|
||||
public override ulong GetSize() => 16;
|
||||
public override ulong GetSize() => 16; // note(nub31): Fat pointer
|
||||
public override ulong GetAlignment() => 8;
|
||||
public override bool IsAggregate() => true;
|
||||
|
||||
public override string ToString() => "[]" + ElementType;
|
||||
public override bool Equals(NubType? other) => other is NubSliceType slice && ElementType.Equals(slice.ElementType);
|
||||
@@ -189,6 +203,7 @@ public class NubConstArrayType(NubType elementType, ulong size) : NubType
|
||||
|
||||
public override ulong GetSize() => ElementType.GetSize() * Size;
|
||||
public override ulong GetAlignment() => ElementType.GetAlignment();
|
||||
public override bool IsAggregate() => true;
|
||||
|
||||
public override string ToString() => $"[{Size}]{ElementType}";
|
||||
public override bool Equals(NubType? other) => other is NubConstArrayType array && ElementType.Equals(array.ElementType) && Size == array.Size;
|
||||
@@ -201,6 +216,7 @@ public class NubArrayType(NubType elementType) : NubType
|
||||
|
||||
public override ulong GetSize() => 8;
|
||||
public override ulong GetAlignment() => 8;
|
||||
public override bool IsAggregate() => false; // note(nub31): Just a pointer
|
||||
|
||||
public override string ToString() => $"[?]{ElementType}";
|
||||
public override bool Equals(NubType? other) => other is NubArrayType array && ElementType.Equals(array.ElementType);
|
||||
@@ -209,9 +225,9 @@ public class NubArrayType(NubType elementType) : NubType
|
||||
|
||||
public class NubStringType : NubType
|
||||
{
|
||||
// note(nub31): Fat pointer
|
||||
public override ulong GetSize() => 16;
|
||||
public override ulong GetSize() => 16; // note(nub31): Fat pointer
|
||||
public override ulong GetAlignment() => 8;
|
||||
public override bool IsAggregate() => true;
|
||||
|
||||
public override string ToString() => "string";
|
||||
public override bool Equals(NubType? other) => other is NubStringType;
|
||||
|
||||
@@ -520,7 +520,7 @@ public sealed class TypeChecker
|
||||
};
|
||||
}
|
||||
|
||||
private ExpressionNode CheckArrayInitializer(ArrayInitializerSyntax expression, NubType? expectedType)
|
||||
private ConstArrayInitializerNode CheckArrayInitializer(ArrayInitializerSyntax expression, NubType? expectedType)
|
||||
{
|
||||
var elementType = expectedType switch
|
||||
{
|
||||
@@ -563,12 +563,7 @@ public sealed class TypeChecker
|
||||
values.Add(value);
|
||||
}
|
||||
|
||||
return expectedType switch
|
||||
{
|
||||
NubArrayType => new ArrayInitializerNode(expression.Tokens, new NubArrayType(elementType), values),
|
||||
NubConstArrayType constArrayType => new ConstArrayInitializerNode(expression.Tokens, constArrayType, values),
|
||||
_ => new ConstArrayInitializerNode(expression.Tokens, new NubConstArrayType(elementType, (ulong)expression.Values.Count), values)
|
||||
};
|
||||
return new ConstArrayInitializerNode(expression.Tokens, new NubConstArrayType(elementType, (ulong)expression.Values.Count), values);
|
||||
}
|
||||
|
||||
private BinaryExpressionNode CheckBinaryExpression(BinaryExpressionSyntax expression, NubType? expectedType)
|
||||
@@ -602,7 +597,7 @@ public sealed class TypeChecker
|
||||
case BinaryOperatorSyntax.NotEqual:
|
||||
{
|
||||
var left = CheckExpression(expression.Left);
|
||||
if (left.Type is not NubIntType and not NubFloatType and not NubBoolType)
|
||||
if (left.Type is not NubIntType and not NubFloatType and not NubBoolType and not NubPointerType)
|
||||
{
|
||||
throw new CompileException(Diagnostic
|
||||
.Error("Equal and not equal operators must must be used with int, float or bool types")
|
||||
@@ -718,6 +713,27 @@ public sealed class TypeChecker
|
||||
}
|
||||
case BinaryOperatorSyntax.LeftShift:
|
||||
case BinaryOperatorSyntax.RightShift:
|
||||
{
|
||||
var left = CheckExpression(expression.Left, expectedType);
|
||||
if (left.Type is not NubIntType)
|
||||
{
|
||||
throw new CompileException(Diagnostic
|
||||
.Error("Bitwise operators must be used with int types")
|
||||
.At(expression.Left)
|
||||
.Build());
|
||||
}
|
||||
|
||||
var right = CheckExpression(expression.Right, left.Type);
|
||||
if (right.Type is not NubIntType)
|
||||
{
|
||||
throw new CompileException(Diagnostic
|
||||
.Error("Bitwise operators must be used with int types")
|
||||
.At(expression.Right)
|
||||
.Build());
|
||||
}
|
||||
|
||||
return new BinaryExpressionNode(expression.Tokens, left.Type, left, op, right);
|
||||
}
|
||||
case BinaryOperatorSyntax.BitwiseAnd:
|
||||
case BinaryOperatorSyntax.BitwiseXor:
|
||||
case BinaryOperatorSyntax.BitwiseOr:
|
||||
|
||||
Reference in New Issue
Block a user