Primitive to int/float/bool
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
func main(args: []cstring): i64
|
||||
{
|
||||
puts("test" =)
|
||||
puts("test")
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -189,11 +189,11 @@ public partial class QBEGenerator
|
||||
|
||||
string sign;
|
||||
|
||||
if (simpleType is NubPrimitiveType { Kind: PrimitiveTypeKind.I8 or PrimitiveTypeKind.I16 or PrimitiveTypeKind.I32 or PrimitiveTypeKind.I64 })
|
||||
if (simpleType is NubIntType { Signed: true })
|
||||
{
|
||||
sign = "s";
|
||||
}
|
||||
else if (simpleType is NubPrimitiveType { Kind: PrimitiveTypeKind.U8 or PrimitiveTypeKind.U16 or PrimitiveTypeKind.U32 or PrimitiveTypeKind.U64 })
|
||||
else if (simpleType is NubIntType { Signed: false })
|
||||
{
|
||||
sign = "u";
|
||||
}
|
||||
@@ -245,21 +245,21 @@ public partial class QBEGenerator
|
||||
{
|
||||
case LiteralKind.Integer:
|
||||
{
|
||||
if (literal.Type is NubPrimitiveType { Kind: PrimitiveTypeKind.F32 })
|
||||
if (literal.Type is NubFloatType { Width: 32 })
|
||||
{
|
||||
var value = float.Parse(literal.Value, CultureInfo.InvariantCulture);
|
||||
var bits = BitConverter.SingleToInt32Bits(value);
|
||||
return new Val(bits.ToString(), literal.Type, ValKind.Direct);
|
||||
}
|
||||
|
||||
if (literal.Type is NubPrimitiveType { Kind: PrimitiveTypeKind.F64 })
|
||||
if (literal.Type is NubFloatType { Width: 64 })
|
||||
{
|
||||
var value = double.Parse(literal.Value, CultureInfo.InvariantCulture);
|
||||
var bits = BitConverter.DoubleToInt64Bits(value);
|
||||
return new Val(bits.ToString(), literal.Type, ValKind.Direct);
|
||||
}
|
||||
|
||||
if (literal.Type is NubPrimitiveType { Kind: PrimitiveTypeKind.I8 or PrimitiveTypeKind.U8 or PrimitiveTypeKind.I16 or PrimitiveTypeKind.U16 or PrimitiveTypeKind.I32 or PrimitiveTypeKind.U32 or PrimitiveTypeKind.I64 or PrimitiveTypeKind.U64 })
|
||||
if (literal.Type is NubIntType)
|
||||
{
|
||||
return new Val(literal.Value, literal.Type, ValKind.Direct);
|
||||
}
|
||||
@@ -268,19 +268,19 @@ public partial class QBEGenerator
|
||||
}
|
||||
case LiteralKind.Float:
|
||||
{
|
||||
if (literal.Type is NubPrimitiveType { Kind: PrimitiveTypeKind.I8 or PrimitiveTypeKind.U8 or PrimitiveTypeKind.I16 or PrimitiveTypeKind.U16 or PrimitiveTypeKind.I32 or PrimitiveTypeKind.U32 or PrimitiveTypeKind.I64 or PrimitiveTypeKind.U64 })
|
||||
if (literal.Type is NubIntType)
|
||||
{
|
||||
return new Val(literal.Value.Split(".").First(), literal.Type, ValKind.Direct);
|
||||
}
|
||||
|
||||
if (literal.Type is NubPrimitiveType { Kind: PrimitiveTypeKind.F32 })
|
||||
if (literal.Type is NubFloatType { Width: 32 })
|
||||
{
|
||||
var value = float.Parse(literal.Value, CultureInfo.InvariantCulture);
|
||||
var bits = BitConverter.SingleToInt32Bits(value);
|
||||
return new Val(bits.ToString(), literal.Type, ValKind.Direct);
|
||||
}
|
||||
|
||||
if (literal.Type is NubPrimitiveType { Kind: PrimitiveTypeKind.F64 })
|
||||
if (literal.Type is NubFloatType { Width: 64 })
|
||||
{
|
||||
var value = double.Parse(literal.Value, CultureInfo.InvariantCulture);
|
||||
var bits = BitConverter.DoubleToInt64Bits(value);
|
||||
@@ -309,7 +309,7 @@ public partial class QBEGenerator
|
||||
}
|
||||
case LiteralKind.Bool:
|
||||
{
|
||||
if (literal.Type is NubPrimitiveType { Kind: PrimitiveTypeKind.Bool })
|
||||
if (literal.Type is NubBoolType)
|
||||
{
|
||||
return new Val(bool.Parse(literal.Value) ? "1" : "0", literal.Type, ValKind.Direct);
|
||||
}
|
||||
@@ -360,16 +360,16 @@ public partial class QBEGenerator
|
||||
{
|
||||
switch (unaryExpression.Operand.Type)
|
||||
{
|
||||
case NubPrimitiveType { Kind: PrimitiveTypeKind.I64 }:
|
||||
case NubIntType { Signed: true, Width: 64 }:
|
||||
_writer.Indented($"{outputName} =l neg {operand}");
|
||||
return new Val(outputName, unaryExpression.Type, ValKind.Direct);
|
||||
case NubPrimitiveType { Kind: PrimitiveTypeKind.I32 or PrimitiveTypeKind.I16 or PrimitiveTypeKind.I8 }:
|
||||
case NubIntType { Signed: true, Width: 8 or 16 or 32 }:
|
||||
_writer.Indented($"{outputName} =w neg {operand}");
|
||||
return new Val(outputName, unaryExpression.Type, ValKind.Direct);
|
||||
case NubPrimitiveType { Kind: PrimitiveTypeKind.F64 }:
|
||||
case NubFloatType { Width: 64 }:
|
||||
_writer.Indented($"{outputName} =d neg {operand}");
|
||||
return new Val(outputName, unaryExpression.Type, ValKind.Direct);
|
||||
case NubPrimitiveType { Kind: PrimitiveTypeKind.F32 }:
|
||||
case NubFloatType { Width: 32 }:
|
||||
_writer.Indented($"{outputName} =s neg {operand}");
|
||||
return new Val(outputName, unaryExpression.Type, ValKind.Direct);
|
||||
}
|
||||
@@ -380,7 +380,7 @@ public partial class QBEGenerator
|
||||
{
|
||||
switch (unaryExpression.Operand.Type)
|
||||
{
|
||||
case NubPrimitiveType { Kind: PrimitiveTypeKind.Bool }:
|
||||
case NubBoolType:
|
||||
_writer.Indented($"{outputName} =w xor {operand}, 1");
|
||||
return new Val(outputName, unaryExpression.Type, ValKind.Direct);
|
||||
}
|
||||
|
||||
@@ -580,22 +580,54 @@ public sealed class Parser
|
||||
var startIndex = _tokenIndex;
|
||||
if (TryExpectIdentifier(out var name))
|
||||
{
|
||||
if (name.Value[0] == 'u' && int.TryParse(name.Value[1..], out var size))
|
||||
{
|
||||
if (size is not 8 and not 16 and not 32 and not 64)
|
||||
{
|
||||
throw new ParseException(Diagnostic
|
||||
.Error("Arbitrary uint size is not supported")
|
||||
.WithHelp("Use u8, u16, u32 or u64")
|
||||
.At(name)
|
||||
.Build());
|
||||
}
|
||||
|
||||
return new IntTypeSyntax(GetTokens(startIndex), false, size);
|
||||
}
|
||||
|
||||
if (name.Value[0] == 'i' && int.TryParse(name.Value[1..], out size))
|
||||
{
|
||||
if (size is not 8 and not 16 and not 32 and not 64)
|
||||
{
|
||||
throw new ParseException(Diagnostic
|
||||
.Error("Arbitrary int size is not supported")
|
||||
.WithHelp("Use i8, i16, i32 or i64")
|
||||
.At(name)
|
||||
.Build());
|
||||
}
|
||||
|
||||
return new IntTypeSyntax(GetTokens(startIndex), true, size);
|
||||
}
|
||||
|
||||
if (name.Value[0] == 'f' && int.TryParse(name.Value[1..], out size))
|
||||
{
|
||||
if (size is not 32 and not 64)
|
||||
{
|
||||
throw new ParseException(Diagnostic
|
||||
.Error("Arbitrary float size is not supported")
|
||||
.WithHelp("Use f32 or f64")
|
||||
.At(name)
|
||||
.Build());
|
||||
}
|
||||
|
||||
return new FloatTypeSyntax(GetTokens(startIndex), size);
|
||||
}
|
||||
|
||||
return name.Value switch
|
||||
{
|
||||
"void" => new VoidTypeSyntax(GetTokens(startIndex)),
|
||||
"string" => new StringTypeSyntax(GetTokens(startIndex)),
|
||||
"cstring" => new CStringTypeSyntax(GetTokens(startIndex)),
|
||||
"i64" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeSyntaxKind.I64),
|
||||
"i32" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeSyntaxKind.I32),
|
||||
"i16" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeSyntaxKind.I16),
|
||||
"i8" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeSyntaxKind.I8),
|
||||
"u64" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeSyntaxKind.U64),
|
||||
"u32" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeSyntaxKind.U32),
|
||||
"u16" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeSyntaxKind.U16),
|
||||
"u8" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeSyntaxKind.U8),
|
||||
"f64" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeSyntaxKind.F64),
|
||||
"f32" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeSyntaxKind.F32),
|
||||
"bool" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeSyntaxKind.Bool),
|
||||
"bool" => new BoolTypeSyntax(GetTokens(startIndex)),
|
||||
_ => new CustomTypeSyntax(GetTokens(startIndex), name.Value)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,35 +2,22 @@ using NubLang.Tokenization;
|
||||
|
||||
namespace NubLang.Parsing.Syntax;
|
||||
|
||||
public enum PrimitiveTypeSyntaxKind
|
||||
{
|
||||
I64,
|
||||
I32,
|
||||
I16,
|
||||
I8,
|
||||
U64,
|
||||
U32,
|
||||
U16,
|
||||
U8,
|
||||
F64,
|
||||
F32,
|
||||
Bool
|
||||
}
|
||||
|
||||
public abstract record TypeSyntax(IEnumerable<Token> Tokens) : SyntaxNode(Tokens)
|
||||
{
|
||||
public string MangledName()
|
||||
{
|
||||
return this switch
|
||||
{
|
||||
PrimitiveTypeSyntax primitive => primitive.SyntaxKind.ToString().ToLower(),
|
||||
VoidTypeSyntax => "void",
|
||||
CStringTypeSyntax => "cstring",
|
||||
StringTypeSyntax => "string",
|
||||
PointerTypeSyntax ptr => $"ptr_{ptr.BaseType.MangledName()}",
|
||||
ArrayTypeSyntax arr => $"arr_{arr.BaseType.MangledName()}",
|
||||
BoolTypeSyntax => "bool",
|
||||
CustomTypeSyntax custom => $"custom_{custom.Name}",
|
||||
FloatTypeSyntax @float => $"f{@float.Width}",
|
||||
FuncTypeSyntax func => $"func_{string.Join("_", func.Parameters.Select(x => x.MangledName()))}_to_{func.ReturnType.MangledName()}",
|
||||
IntTypeSyntax @int => $"{(@int.Signed ? "i" : "u")}{@int.Width}",
|
||||
_ => throw new NotSupportedException($"Unknown type syntax: {GetType().Name}")
|
||||
};
|
||||
}
|
||||
@@ -62,12 +49,17 @@ public record VoidTypeSyntax(IEnumerable<Token> Tokens) : TypeSyntax(Tokens)
|
||||
public override IEnumerable<SyntaxNode> GetChildren() => [];
|
||||
}
|
||||
|
||||
public record PrimitiveTypeSyntax(IEnumerable<Token> Tokens, PrimitiveTypeSyntaxKind SyntaxKind) : TypeSyntax(Tokens)
|
||||
public record IntTypeSyntax(IEnumerable<Token> Tokens, bool Signed, int Width) : TypeSyntax(Tokens)
|
||||
{
|
||||
public override IEnumerable<SyntaxNode> GetChildren() => [];
|
||||
}
|
||||
|
||||
public record CStringTypeSyntax(IEnumerable<Token> Tokens) : TypeSyntax(Tokens)
|
||||
public record FloatTypeSyntax(IEnumerable<Token> Tokens, int Width) : TypeSyntax(Tokens)
|
||||
{
|
||||
public override IEnumerable<SyntaxNode> GetChildren() => [];
|
||||
}
|
||||
|
||||
public record BoolTypeSyntax(IEnumerable<Token> Tokens) : TypeSyntax(Tokens)
|
||||
{
|
||||
public override IEnumerable<SyntaxNode> GetChildren() => [];
|
||||
}
|
||||
@@ -77,7 +69,7 @@ public record StringTypeSyntax(IEnumerable<Token> Tokens) : TypeSyntax(Tokens)
|
||||
public override IEnumerable<SyntaxNode> GetChildren() => [];
|
||||
}
|
||||
|
||||
public record CustomTypeSyntax(IEnumerable<Token> Tokens, string Name) : TypeSyntax(Tokens)
|
||||
public record CStringTypeSyntax(IEnumerable<Token> Tokens) : TypeSyntax(Tokens)
|
||||
{
|
||||
public override IEnumerable<SyntaxNode> GetChildren() => [];
|
||||
}
|
||||
@@ -88,4 +80,9 @@ public record ArrayTypeSyntax(IEnumerable<Token> Tokens, TypeSyntax BaseType) :
|
||||
{
|
||||
yield return BaseType;
|
||||
}
|
||||
}
|
||||
|
||||
public record CustomTypeSyntax(IEnumerable<Token> Tokens, string Name) : TypeSyntax(Tokens)
|
||||
{
|
||||
public override IEnumerable<SyntaxNode> GetChildren() => [];
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using NubLang.Parsing.Syntax;
|
||||
using NubLang.TypeChecking.Node;
|
||||
|
||||
namespace NubLang.TypeChecking;
|
||||
|
||||
|
||||
@@ -1,24 +1,10 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using NubLang.Generation;
|
||||
|
||||
namespace NubLang.TypeChecking;
|
||||
namespace NubLang.TypeChecking.Node;
|
||||
|
||||
public abstract class NubType : IEquatable<NubType>
|
||||
{
|
||||
public bool IsNumber => this is NubPrimitiveType
|
||||
{
|
||||
Kind: PrimitiveTypeKind.I8
|
||||
or PrimitiveTypeKind.I16
|
||||
or PrimitiveTypeKind.I32
|
||||
or PrimitiveTypeKind.I64
|
||||
or PrimitiveTypeKind.U8
|
||||
or PrimitiveTypeKind.U16
|
||||
or PrimitiveTypeKind.U32
|
||||
or PrimitiveTypeKind.U64
|
||||
or PrimitiveTypeKind.F32
|
||||
or PrimitiveTypeKind.F64
|
||||
};
|
||||
|
||||
public bool IsSimpleType([NotNullWhen(true)] out NubSimpleType? simpleType, [NotNullWhen(false)] out NubComplexType? complexType)
|
||||
{
|
||||
if (this is NubSimpleType st)
|
||||
@@ -35,7 +21,7 @@ public abstract class NubType : IEquatable<NubType>
|
||||
return false;
|
||||
}
|
||||
|
||||
throw new ArgumentException($"Type {this} is not a simple type nor a compex type");
|
||||
throw new ArgumentException($"Type {this} is not a simple type nor a complex type");
|
||||
}
|
||||
|
||||
public abstract int Size(TypedDefinitionTable definitionTable);
|
||||
@@ -95,6 +81,61 @@ public abstract class NubSimpleType : NubType
|
||||
|
||||
#region Simple types
|
||||
|
||||
public class NubIntType(bool signed, int width) : NubSimpleType
|
||||
{
|
||||
public bool Signed { get; } = signed;
|
||||
public int Width { get; } = width;
|
||||
|
||||
public override StorageSize StorageSize => Signed switch
|
||||
{
|
||||
true => Width switch
|
||||
{
|
||||
8 => StorageSize.I8,
|
||||
16 => StorageSize.I16,
|
||||
32 => StorageSize.I32,
|
||||
64 => StorageSize.I64,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(Width))
|
||||
},
|
||||
false => Width switch
|
||||
{
|
||||
8 => StorageSize.U8,
|
||||
16 => StorageSize.U16,
|
||||
32 => StorageSize.U32,
|
||||
64 => StorageSize.U64,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(Width))
|
||||
}
|
||||
};
|
||||
|
||||
public override string ToString() => $"{(Signed ? "i" : "u")}{Width}";
|
||||
public override bool Equals(NubType? other) => other is NubIntType @int && @int.Width == Width && @int.Signed == Signed;
|
||||
public override int GetHashCode() => HashCode.Combine(typeof(NubIntType), Signed, Width);
|
||||
}
|
||||
|
||||
public class NubFloatType(int width) : NubSimpleType
|
||||
{
|
||||
public int Width { get; } = width;
|
||||
|
||||
public override StorageSize StorageSize => Width switch
|
||||
{
|
||||
32 => StorageSize.F32,
|
||||
64 => StorageSize.F64,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(Width))
|
||||
};
|
||||
|
||||
public override string ToString() => $"f{Width}";
|
||||
public override bool Equals(NubType? other) => other is NubFloatType @int && @int.Width == Width;
|
||||
public override int GetHashCode() => HashCode.Combine(typeof(NubFloatType), Width);
|
||||
}
|
||||
|
||||
public class NubBoolType : NubSimpleType
|
||||
{
|
||||
public override StorageSize StorageSize => StorageSize.U8;
|
||||
|
||||
public override string ToString() => "bool";
|
||||
public override bool Equals(NubType? other) => other is NubBoolType;
|
||||
public override int GetHashCode() => HashCode.Combine(typeof(NubBoolType));
|
||||
}
|
||||
|
||||
public class NubFuncType(List<NubType> parameters, NubType returnType) : NubSimpleType
|
||||
{
|
||||
public IReadOnlyList<NubType> Parameters { get; } = parameters;
|
||||
@@ -139,67 +180,6 @@ public class NubVoidType : NubSimpleType
|
||||
public override int GetHashCode() => HashCode.Combine(typeof(NubVoidType));
|
||||
}
|
||||
|
||||
public class NubPrimitiveType(PrimitiveTypeKind kind) : NubSimpleType
|
||||
{
|
||||
public PrimitiveTypeKind Kind { get; } = kind;
|
||||
|
||||
public override StorageSize StorageSize => Kind switch
|
||||
{
|
||||
PrimitiveTypeKind.I8 => StorageSize.I8,
|
||||
PrimitiveTypeKind.I16 => StorageSize.I16,
|
||||
PrimitiveTypeKind.I32 => StorageSize.I32,
|
||||
PrimitiveTypeKind.I64 => StorageSize.I64,
|
||||
PrimitiveTypeKind.U8 => StorageSize.U8,
|
||||
PrimitiveTypeKind.U16 => StorageSize.U16,
|
||||
PrimitiveTypeKind.U32 => StorageSize.U32,
|
||||
PrimitiveTypeKind.U64 => StorageSize.U64,
|
||||
PrimitiveTypeKind.F64 => StorageSize.F64,
|
||||
PrimitiveTypeKind.F32 => StorageSize.F32,
|
||||
PrimitiveTypeKind.Bool => StorageSize.U8,
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
};
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Kind switch
|
||||
{
|
||||
PrimitiveTypeKind.I8 => "i8",
|
||||
PrimitiveTypeKind.I16 => "i16",
|
||||
PrimitiveTypeKind.I32 => "i32",
|
||||
PrimitiveTypeKind.I64 => "i64",
|
||||
|
||||
PrimitiveTypeKind.U8 => "u8",
|
||||
PrimitiveTypeKind.U16 => "u16",
|
||||
PrimitiveTypeKind.U32 => "u32",
|
||||
PrimitiveTypeKind.U64 => "u64",
|
||||
|
||||
PrimitiveTypeKind.F32 => "f32",
|
||||
PrimitiveTypeKind.F64 => "f64",
|
||||
|
||||
PrimitiveTypeKind.Bool => "bool",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(kind), Kind, null)
|
||||
};
|
||||
}
|
||||
|
||||
public override bool Equals(NubType? other) => other is NubPrimitiveType primitive && primitive.Kind == Kind;
|
||||
public override int GetHashCode() => HashCode.Combine(typeof(NubPrimitiveType), Kind.GetHashCode());
|
||||
}
|
||||
|
||||
public enum PrimitiveTypeKind
|
||||
{
|
||||
I64,
|
||||
I32,
|
||||
I16,
|
||||
I8,
|
||||
U64,
|
||||
U32,
|
||||
U16,
|
||||
U8,
|
||||
F64,
|
||||
F32,
|
||||
Bool
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public abstract class NubComplexType : NubType;
|
||||
@@ -139,7 +139,7 @@ public sealed class TypeChecker
|
||||
);
|
||||
}
|
||||
|
||||
return new If(CheckExpression(statement.Condition, new NubPrimitiveType(PrimitiveTypeKind.Bool)), CheckBlock(statement.Body), elseStatement);
|
||||
return new If(CheckExpression(statement.Condition, new NubBoolType()), CheckBlock(statement.Body), elseStatement);
|
||||
}
|
||||
|
||||
private Return CheckReturn(ReturnSyntax statement)
|
||||
@@ -188,7 +188,7 @@ public sealed class TypeChecker
|
||||
|
||||
private While CheckWhile(WhileSyntax statement)
|
||||
{
|
||||
return new While(CheckExpression(statement.Condition, new NubPrimitiveType(PrimitiveTypeKind.Bool)), CheckBlock(statement.Body));
|
||||
return new While(CheckExpression(statement.Condition, new NubBoolType()), CheckBlock(statement.Body));
|
||||
}
|
||||
|
||||
private Expression CheckExpression(ExpressionSyntax node, NubType? expectedType = null)
|
||||
@@ -252,12 +252,12 @@ public sealed class TypeChecker
|
||||
{
|
||||
var boundArray = CheckExpression(expression.Target);
|
||||
var elementType = ((NubArrayType)boundArray.Type).ElementType;
|
||||
return new ArrayIndexAccess(elementType, boundArray, CheckExpression(expression.Index, new NubPrimitiveType(PrimitiveTypeKind.U64)));
|
||||
return new ArrayIndexAccess(elementType, boundArray, CheckExpression(expression.Index, new NubIntType(false, 64)));
|
||||
}
|
||||
|
||||
private ArrayInitializer CheckArrayInitializer(ArrayInitializerSyntax expression)
|
||||
{
|
||||
var capacity = CheckExpression(expression.Capacity, new NubPrimitiveType(PrimitiveTypeKind.U64));
|
||||
var capacity = CheckExpression(expression.Capacity, new NubIntType(false, 64));
|
||||
var type = new NubArrayType(CheckType(expression.ElementType));
|
||||
return new ArrayInitializer(type, capacity, CheckType(expression.ElementType));
|
||||
}
|
||||
@@ -346,10 +346,10 @@ public sealed class TypeChecker
|
||||
{
|
||||
var type = expectedType ?? expression.Kind switch
|
||||
{
|
||||
LiteralKind.Integer => new NubPrimitiveType(PrimitiveTypeKind.I64),
|
||||
LiteralKind.Float => new NubPrimitiveType(PrimitiveTypeKind.F64),
|
||||
LiteralKind.Integer => new NubIntType(true, 64),
|
||||
LiteralKind.Float => new NubFloatType(64),
|
||||
LiteralKind.String => new NubStringType(),
|
||||
LiteralKind.Bool => new NubPrimitiveType(PrimitiveTypeKind.Bool),
|
||||
LiteralKind.Bool => new NubBoolType(),
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
};
|
||||
|
||||
@@ -472,9 +472,9 @@ public sealed class TypeChecker
|
||||
{
|
||||
case UnaryOperatorSyntax.Negate:
|
||||
{
|
||||
boundOperand = CheckExpression(expression.Operand, new NubPrimitiveType(PrimitiveTypeKind.I64));
|
||||
boundOperand = CheckExpression(expression.Operand, new NubIntType(true, 64));
|
||||
|
||||
if (boundOperand.Type.IsNumber)
|
||||
if (boundOperand.Type is NubIntType or NubFloatType)
|
||||
{
|
||||
type = boundOperand.Type;
|
||||
}
|
||||
@@ -483,9 +483,9 @@ public sealed class TypeChecker
|
||||
}
|
||||
case UnaryOperatorSyntax.Invert:
|
||||
{
|
||||
boundOperand = CheckExpression(expression.Operand, new NubPrimitiveType(PrimitiveTypeKind.Bool));
|
||||
boundOperand = CheckExpression(expression.Operand, new NubBoolType());
|
||||
|
||||
type = new NubPrimitiveType(PrimitiveTypeKind.Bool);
|
||||
type = new NubBoolType();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -574,25 +574,13 @@ public sealed class TypeChecker
|
||||
return node switch
|
||||
{
|
||||
ArrayTypeSyntax type => new NubArrayType(CheckType(type.BaseType)),
|
||||
BoolTypeSyntax => new NubBoolType(),
|
||||
CStringTypeSyntax => new NubCStringType(),
|
||||
CustomTypeSyntax type => new NubCustomType(type.MangledName()),
|
||||
FloatTypeSyntax @float => new NubFloatType(@float.Width),
|
||||
FuncTypeSyntax type => new NubFuncType(type.Parameters.Select(CheckType).ToList(), CheckType(type.ReturnType)),
|
||||
IntTypeSyntax @int => new NubIntType(@int.Signed, @int.Width),
|
||||
PointerTypeSyntax type => new NubPointerType(CheckType(type.BaseType)),
|
||||
PrimitiveTypeSyntax type => new NubPrimitiveType(type.SyntaxKind switch
|
||||
{
|
||||
PrimitiveTypeSyntaxKind.I64 => PrimitiveTypeKind.I64,
|
||||
PrimitiveTypeSyntaxKind.I32 => PrimitiveTypeKind.I32,
|
||||
PrimitiveTypeSyntaxKind.I16 => PrimitiveTypeKind.I16,
|
||||
PrimitiveTypeSyntaxKind.I8 => PrimitiveTypeKind.I8,
|
||||
PrimitiveTypeSyntaxKind.U64 => PrimitiveTypeKind.U64,
|
||||
PrimitiveTypeSyntaxKind.U32 => PrimitiveTypeKind.U32,
|
||||
PrimitiveTypeSyntaxKind.U16 => PrimitiveTypeKind.U16,
|
||||
PrimitiveTypeSyntaxKind.U8 => PrimitiveTypeKind.U8,
|
||||
PrimitiveTypeSyntaxKind.F64 => PrimitiveTypeKind.F64,
|
||||
PrimitiveTypeSyntaxKind.F32 => PrimitiveTypeKind.F32,
|
||||
PrimitiveTypeSyntaxKind.Bool => PrimitiveTypeKind.Bool,
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
}),
|
||||
StringTypeSyntax => new NubStringType(),
|
||||
VoidTypeSyntax => new NubVoidType(),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(node))
|
||||
|
||||
Reference in New Issue
Block a user