This commit is contained in:
nub31
2025-09-29 19:04:09 +02:00
parent afea51a9c3
commit ed09fabd44
16 changed files with 120 additions and 129 deletions

View File

@@ -0,0 +1,139 @@
namespace NubLang.Ast;
public abstract record Node;
#region Definitions
public abstract record DefinitionNode(string Module, string Name) : Node;
public record FuncParameterNode(string Name, NubType Type) : Node;
public record FuncSignatureNode(List<FuncParameterNode> Parameters, NubType ReturnType) : Node;
public record FuncNode(string Module, string Name, string? ExternSymbol, FuncSignatureNode Signature, BlockNode? Body) : DefinitionNode(Module, Name);
public record StructFieldNode(string Name, NubType Type, ExpressionNode? Value) : Node;
public record StructFuncNode(string Name, string? Hook, FuncSignatureNode Signature, BlockNode Body) : Node;
public record StructNode(string Module, string Name, List<StructFieldNode> Fields, List<StructFuncNode> Functions) : DefinitionNode(Module, Name);
public record GlobalVariableNode(string Module, string Name, ExpressionNode Value) : DefinitionNode(Module, Name);
#endregion
#region Statements
public abstract record StatementNode : Node;
public abstract record TerminalStatementNode : StatementNode;
public record BlockNode(List<StatementNode> Statements) : StatementNode;
public record StatementFuncCallNode(FuncCallNode FuncCall) : StatementNode;
public record StatementStructFuncCallNode(StructFuncCallNode StructFuncCall) : StatementNode;
public record ReturnNode(ExpressionNode? Value) : TerminalStatementNode;
public record AssignmentNode(LValueExpressionNode Target, ExpressionNode Value) : StatementNode;
public record IfNode(ExpressionNode Condition, BlockNode Body, Variant<IfNode, BlockNode>? Else) : StatementNode;
public record VariableDeclarationNode(string Name, ExpressionNode? Assignment, NubType Type) : StatementNode;
public record ContinueNode : TerminalStatementNode;
public record BreakNode : TerminalStatementNode;
public record WhileNode(ExpressionNode Condition, BlockNode Body) : StatementNode;
public record DeferNode(StatementNode Statement) : StatementNode;
#endregion
#region Expressions
public enum UnaryOperator
{
Negate,
Invert
}
public enum BinaryOperator
{
Equal,
NotEqual,
GreaterThan,
GreaterThanOrEqual,
LessThan,
LessThanOrEqual,
LogicalAnd,
LogicalOr,
Plus,
Minus,
Multiply,
Divide,
Modulo,
LeftShift,
RightShift,
BitwiseAnd,
BitwiseXor,
BitwiseOr
}
public abstract record ExpressionNode(NubType Type) : Node;
public abstract record LValueExpressionNode(NubType Type) : ExpressionNode(Type);
public abstract record RValueExpressionNode(NubType Type) : ExpressionNode(Type);
public record StringLiteralNode(NubType Type, string Value) : RValueExpressionNode(Type);
public record CStringLiteralNode(NubType Type, string Value) : RValueExpressionNode(Type);
public record IntLiteralNode(NubType Type, long Value) : RValueExpressionNode(Type);
public record UIntLiteralNode(NubType Type, ulong Value) : RValueExpressionNode(Type);
public record Float32LiteralNode(NubType Type, float Value) : RValueExpressionNode(Type);
public record Float64LiteralNode(NubType Type, double Value) : RValueExpressionNode(Type);
public record BoolLiteralNode(NubType Type, bool Value) : RValueExpressionNode(Type);
public record BinaryExpressionNode(NubType Type, ExpressionNode Left, BinaryOperator Operator, ExpressionNode Right) : RValueExpressionNode(Type);
public record UnaryExpressionNode(NubType Type, UnaryOperator Operator, ExpressionNode Operand) : RValueExpressionNode(Type);
public record FuncCallNode(NubType Type, ExpressionNode Expression, List<ExpressionNode> Parameters) : RValueExpressionNode(Type);
public record StructFuncCallNode(NubType Type, string Module, string StructName, string FuncName, ExpressionNode StructExpression, List<ExpressionNode> Parameters) : RValueExpressionNode(Type);
public record LValueIdentifierNode(NubType Type, string Name) : LValueExpressionNode(Type);
public record RValueIdentifierNode(NubType Type, string Name) : RValueExpressionNode(Type);
public record FuncIdentifierNode(NubType Type, string Module, string Name, string? ExternSymbol) : RValueExpressionNode(Type);
public record ArrayInitializerNode(NubType Type, ExpressionNode Capacity, NubType ElementType) : RValueExpressionNode(Type);
public record ArrayIndexAccessNode(NubType Type, ExpressionNode Target, ExpressionNode Index) : LValueExpressionNode(Type);
public record AddressOfNode(NubType Type, LValueExpressionNode LValue) : RValueExpressionNode(Type);
public record StructFieldAccessNode(NubType Type, ExpressionNode Target, string Field) : LValueExpressionNode(Type);
public record StructInitializerNode(NubStructType StructType, Dictionary<string, ExpressionNode> Initializers) : RValueExpressionNode(StructType);
public record DereferenceNode(NubType Type, ExpressionNode Expression) : LValueExpressionNode(Type);
public record ConvertIntNode(NubType Type, ExpressionNode Value, NubIntType ValueType, NubIntType TargetType) : RValueExpressionNode(Type);
public record ConvertFloatNode(NubType Type, ExpressionNode Value, NubFloatType ValueType, NubFloatType TargetType) : RValueExpressionNode(Type);
public record SizeBuiltinNode(NubType Type, NubType TargetType) : RValueExpressionNode(Type);
public record FloatToIntBuiltinNode(NubType Type, ExpressionNode Value, NubFloatType ValueType, NubIntType TargetType) : RValueExpressionNode(Type);
#endregion

View File

@@ -0,0 +1,194 @@
using System.Security.Cryptography;
using System.Text;
namespace NubLang.Ast;
public abstract class NubType : IEquatable<NubType>
{
public abstract bool IsValueType { get; }
public abstract bool IsScalar { get; }
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 class NubVoidType : NubType
{
public override bool IsValueType => false;
public override bool IsScalar => false;
public override string ToString() => "void";
public override bool Equals(NubType? other) => other is NubVoidType;
public override int GetHashCode() => HashCode.Combine(typeof(NubVoidType));
}
public sealed class NubIntType(bool signed, int width) : NubType
{
public override bool IsValueType => true;
public override bool IsScalar => true;
public bool Signed { get; } = signed;
public int Width { get; } = 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 sealed class NubFloatType(int width) : NubType
{
public override bool IsValueType => true;
public override bool IsScalar => true;
public int Width { get; } = width;
public override string ToString() => $"f{Width}";
public override bool Equals(NubType? other) => other is NubFloatType @float && @float.Width == Width;
public override int GetHashCode() => HashCode.Combine(typeof(NubFloatType), Width);
}
public class NubBoolType : NubType
{
public override bool IsValueType => true;
public override bool IsScalar => true;
public override string ToString() => "bool";
public override bool Equals(NubType? other) => other is NubBoolType;
public override int GetHashCode() => HashCode.Combine(typeof(NubBoolType));
}
public sealed class NubPointerType(NubType baseType) : NubType
{
public override bool IsValueType => true;
public override bool IsScalar => true;
public NubType BaseType { get; } = baseType;
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 NubFuncType(List<NubType> parameters, NubType returnType) : NubType
{
public override bool IsValueType => true;
public override bool IsScalar => true;
public List<NubType> Parameters { get; } = parameters;
public NubType ReturnType { get; } = returnType;
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 NubStructType(string module, string name, List<NubStructFieldType> fields, List<NubStructFuncType> functions) : NubType
{
public override bool IsValueType => true;
public override bool IsScalar => false;
public string Module { get; } = module;
public string Name { get; } = name;
public List<NubStructFieldType> Fields { get; set; } = fields;
public List<NubStructFuncType> Functions { get; set; } = functions;
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);
}
public class NubStructFieldType(string name, NubType type, bool hasDefaultValue)
{
public string Name { get; } = name;
public NubType Type { get; } = type;
public bool HasDefaultValue { get; } = hasDefaultValue;
}
public class NubStructFuncType(string name, string? hook, List<NubType> parameters, NubType returnType)
{
public string Name { get; } = name;
public string? Hook { get; set; } = hook;
public List<NubType> Parameters { get; } = parameters;
public NubType ReturnType { get; } = returnType;
}
public class NubArrayType(NubType elementType) : NubType
{
public override bool IsValueType => false;
public override bool IsScalar => true;
public NubType ElementType { get; } = elementType;
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);
}
public class NubCStringType : NubType
{
public override bool IsValueType => false;
public override bool IsScalar => false;
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 : NubType
{
public override bool IsValueType => false;
public override bool IsScalar => false;
public override string ToString() => "string";
public override bool Equals(NubType? other) => other is NubStringType;
public override int GetHashCode() => HashCode.Combine(typeof(NubStringType));
}
public static class NameMangler
{
public static string Mangle(params IEnumerable<NubType> types)
{
var readable = string.Join("_", types.Select(EncodeType));
return ComputeShortHash(readable);
}
private static string EncodeType(NubType node) => node switch
{
NubVoidType => "V",
NubBoolType => "B",
NubIntType i => (i.Signed ? "I" : "U") + i.Width,
NubFloatType f => "F" + f.Width,
NubCStringType => "CS",
NubStringType => "S",
NubPointerType p => "P" + EncodeType(p.BaseType),
NubArrayType a => "A" + EncodeType(a.ElementType),
NubFuncType fn => "FN(" + string.Join(",", fn.Parameters.Select(EncodeType)) + ")" + EncodeType(fn.ReturnType),
NubStructType st => "ST(" + st.Module + "." + st.Name + ")",
_ => throw new NotSupportedException($"Cannot encode type: {node}")
};
private static string ComputeShortHash(string input)
{
var bytes = Encoding.UTF8.GetBytes(input);
var hash = SHA256.HashData(bytes);
return Convert.ToHexString(hash[..8]).ToLower();
}
}

File diff suppressed because it is too large Load Diff