Reordering

This commit is contained in:
nub31
2025-07-09 20:32:59 +02:00
parent 0aa0911b0f
commit a0b7b9026c
8 changed files with 96 additions and 72 deletions

View File

@@ -0,0 +1,60 @@
using NubLang.Syntax.Parsing.Node;
namespace NubLang.Syntax.Binding;
public class DefinitionTable
{
private readonly List<DefinitionSyntax> _definitions;
public DefinitionTable(IEnumerable<SyntaxTree> syntaxTrees)
{
_definitions = syntaxTrees.SelectMany(x => x.Definitions).ToList();
}
public IEnumerable<LocalFuncSyntax> LookupLocalFunc(string @namespace, string name)
{
return _definitions
.OfType<LocalFuncSyntax>()
.Where(x => x.Namespace == @namespace && x.Name == name);
}
public IEnumerable<ExternFuncSyntax> LookupExternFunc(string @namespace, string name)
{
return _definitions
.OfType<ExternFuncSyntax>()
.Where(x => x.Namespace == @namespace && x.Name == name);
}
public IEnumerable<StructSyntax> LookupStruct(string @namespace, string name)
{
return _definitions
.OfType<StructSyntax>()
.Where(x => x.Namespace == @namespace && x.Name == name);
}
public IEnumerable<StructFieldSyntax> LookupStructField(StructSyntax structNode, string field)
{
return structNode.Fields.Where(x => x.Name == field);
}
public IEnumerable<TraitFuncImplSyntax> LookupTraitFuncImpl(NubType forType, string name)
{
return _definitions
.OfType<TraitImplSyntax>()
.Where(x => x.ForType == forType)
.SelectMany(x => x.Functions)
.Where(x => x.Name == name);
}
public IEnumerable<TraitSyntax> LookupTrait(string @namespace, string name)
{
return _definitions
.OfType<TraitSyntax>()
.Where(x => x.Namespace == @namespace && x.Name == name);
}
public IEnumerable<TraitFuncSyntax> LookupTraitFunc(TraitSyntax trait, string name)
{
return trait.Functions.Where(x => x.Name == name);
}
}

View File

@@ -0,0 +1,316 @@
using System.Diagnostics.CodeAnalysis;
using NubLang.Generation;
namespace NubLang.Syntax.Binding;
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)
{
complexType = null;
simpleType = st;
return true;
}
if (this is NubComplexType ct)
{
complexType = ct;
simpleType = null;
return false;
}
throw new ArgumentException($"Type {this} is not a simple type nor a compex type");
}
public abstract int Size(BoundDefinitionTable definitionTable);
public abstract int Alignment(BoundDefinitionTable definitionTable);
public static int AlignTo(int offset, int alignment)
{
return (offset + alignment - 1) & ~(alignment - 1);
}
public override bool Equals(object? obj) => obj is NubType other && Equals(other);
public abstract bool Equals(NubType? other);
public abstract override int GetHashCode();
public abstract override string ToString();
public static bool operator ==(NubType? left, NubType? right) => Equals(left, right);
public static bool operator !=(NubType? left, NubType? right) => !Equals(left, right);
}
public enum StorageSize
{
Void,
I8,
I16,
I32,
I64,
U8,
U16,
U32,
U64,
F32,
F64
}
public abstract class NubSimpleType : NubType
{
public abstract StorageSize StorageSize { get; }
public override int Size(BoundDefinitionTable definitionTable)
{
return StorageSize switch
{
StorageSize.I64 or StorageSize.U64 or StorageSize.F64 => 8,
StorageSize.I32 or StorageSize.U32 or StorageSize.F32 => 4,
StorageSize.I16 or StorageSize.U16 => 2,
StorageSize.I8 or StorageSize.U8 => 1,
_ => throw new ArgumentOutOfRangeException(nameof(StorageSize))
};
}
public override int Alignment(BoundDefinitionTable definitionTable)
{
return Size(definitionTable);
}
}
#region Simple types
public class NubFuncType(NubType returnType, List<NubType> parameters) : NubSimpleType
{
public List<NubType> Parameters { get; } = parameters;
public NubType ReturnType { get; } = returnType;
public override StorageSize StorageSize => StorageSize.U64;
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);
public override int GetHashCode()
{
var hash = new HashCode();
hash.Add(typeof(NubFuncType));
hash.Add(ReturnType);
foreach (var param in Parameters)
{
hash.Add(param);
}
return hash.ToHashCode();
}
}
public class NubPointerType(NubType baseType) : NubSimpleType
{
public NubType BaseType { get; } = baseType;
public override StorageSize StorageSize => StorageSize.U64;
public override string ToString() => "^" + BaseType;
public override bool Equals(NubType? other) => other is NubPointerType pointer && BaseType.Equals(pointer.BaseType);
public override int GetHashCode() => HashCode.Combine(typeof(NubPointerType), BaseType);
}
public class NubVoidType : NubSimpleType
{
public override StorageSize StorageSize => StorageSize.Void;
public override string ToString() => "void";
public override bool Equals(NubType? other) => other is NubVoidType;
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;
#region Complex types
public class NubCStringType : NubComplexType
{
public override int Size(BoundDefinitionTable definitionTable) => 8;
public override int Alignment(BoundDefinitionTable definitionTable) => Size(definitionTable);
public override string ToString() => "cstring";
public override bool Equals(NubType? other) => other is NubCStringType;
public override int GetHashCode() => HashCode.Combine(typeof(NubCStringType));
}
public class NubStringType : NubComplexType
{
public override int Size(BoundDefinitionTable definitionTable) => 8;
public override int Alignment(BoundDefinitionTable definitionTable) => Size(definitionTable);
public override string ToString() => "string";
public override bool Equals(NubType? other) => other is NubStringType;
public override int GetHashCode() => HashCode.Combine(typeof(NubStringType));
}
public class NubCustomType(string @namespace, string name) : NubComplexType
{
public string Namespace { get; } = @namespace;
public string Name { get; } = name;
public CustomTypeKind Kind(BoundDefinitionTable definitionTable)
{
if (definitionTable.GetStructs().Any(x => x.Namespace == Namespace && x.Name == Name))
{
return CustomTypeKind.Struct;
}
if (definitionTable.GetTraits().Any(x => x.Namespace == Namespace && x.Name == Name))
{
return CustomTypeKind.Trait;
}
throw new ArgumentException($"Definition table does not have any type information for {this}");
}
public override int Size(BoundDefinitionTable definitionTable)
{
switch (Kind(definitionTable))
{
case CustomTypeKind.Struct:
{
var structDef = definitionTable.LookupStruct(Namespace, Name);
var size = 0;
var maxAlignment = 1;
foreach (var field in structDef.Fields)
{
var fieldAlignment = field.Type.Alignment(definitionTable);
maxAlignment = Math.Max(maxAlignment, fieldAlignment);
size = AlignTo(size, fieldAlignment);
size += field.Type.Size(definitionTable);
}
return AlignTo(size, maxAlignment);
}
case CustomTypeKind.Trait:
{
return 16;
}
default:
throw new ArgumentOutOfRangeException();
}
}
public override int Alignment(BoundDefinitionTable definitionTable)
{
switch (Kind(definitionTable))
{
case CustomTypeKind.Struct:
return definitionTable.LookupStruct(Namespace, Name).Fields.Max(f => f.Type.Alignment(definitionTable));
case CustomTypeKind.Trait:
return 8;
default:
throw new ArgumentOutOfRangeException();
}
}
public override string ToString() => $"{Namespace}::{Name}";
public override bool Equals(NubType? other) => other is NubCustomType custom && Namespace == custom.Namespace && Name == custom.Name;
public override int GetHashCode() => HashCode.Combine(typeof(NubCustomType), Namespace, Name);
}
public enum CustomTypeKind
{
Struct,
Trait
}
public class NubArrayType(NubType elementType) : NubComplexType
{
public NubType ElementType { get; } = elementType;
public override int Size(BoundDefinitionTable definitionTable) => 8;
public override int Alignment(BoundDefinitionTable definitionTable) => Size(definitionTable);
public override string ToString() => "[]" + ElementType;
public override bool Equals(NubType? other) => other is NubArrayType array && ElementType.Equals(array.ElementType);
public override int GetHashCode() => HashCode.Combine(typeof(NubArrayType), ElementType);
}
#endregion

View File

@@ -2,6 +2,21 @@ using NubLang.Syntax.Tokenization;
namespace NubLang.Syntax.Parsing.Node;
public enum PrimitiveTypeSyntaxKind
{
I64,
I32,
I16,
I8,
U64,
U32,
U16,
U8,
F64,
F32,
Bool
}
public abstract record TypeSyntax(IReadOnlyList<Token> Tokens) : SyntaxNode(Tokens);
public record FuncTypeSyntax(IReadOnlyList<Token> Tokens, IReadOnlyList<TypeSyntax> Parameters, TypeSyntax ReturnType) : TypeSyntax(Tokens);
@@ -10,7 +25,7 @@ public record PointerTypeSyntax(IReadOnlyList<Token> Tokens, TypeSyntax BaseType
public record VoidTypeSyntax(IReadOnlyList<Token> Tokens) : TypeSyntax(Tokens);
public record PrimitiveTypeSyntax(IReadOnlyList<Token> Tokens, PrimitiveTypeKind Kind) : TypeSyntax(Tokens);
public record PrimitiveTypeSyntax(IReadOnlyList<Token> Tokens, PrimitiveTypeSyntaxKind SyntaxKind) : TypeSyntax(Tokens);
public record CStringTypeSyntax(IReadOnlyList<Token> Tokens) : TypeSyntax(Tokens);

View File

@@ -1,6 +1,7 @@
using System.Diagnostics.CodeAnalysis;
using NubLang.Common;
using NubLang.Diagnostics;
using NubLang.Syntax.Binding;
using NubLang.Syntax.Parsing.Node;
using NubLang.Syntax.Tokenization;
@@ -660,17 +661,17 @@ public sealed class Parser
"void" => new VoidTypeSyntax(GetTokens(startIndex)),
"string" => new StringTypeSyntax(GetTokens(startIndex)),
"cstring" => new CStringTypeSyntax(GetTokens(startIndex)),
"i64" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeKind.I64),
"i32" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeKind.I32),
"i16" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeKind.I16),
"i8" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeKind.I8),
"u64" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeKind.U64),
"u32" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeKind.U32),
"u16" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeKind.U16),
"u8" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeKind.U8),
"f64" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeKind.F64),
"f32" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeKind.F32),
"bool" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeKind.Bool),
"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),
_ => ParseCustomType()
};