From 766ca9a6b968dc1ba91b1db73cb1df9af471fe9c Mon Sep 17 00:00:00 2001 From: nub31 Date: Fri, 24 Oct 2025 15:27:14 +0200 Subject: [PATCH] remove cstring --- compiler/NubLang/Ast/Node.cs | 240 +++++++++++++++++------ compiler/NubLang/Ast/NubType.cs | 20 +- compiler/NubLang/Ast/TypeChecker.cs | 30 +-- compiler/NubLang/Generation/CType.cs | 15 +- compiler/NubLang/Generation/Generator.cs | 35 ++-- compiler/NubLang/Syntax/Parser.cs | 10 - compiler/NubLang/Syntax/Syntax.cs | 4 - 7 files changed, 211 insertions(+), 143 deletions(-) diff --git a/compiler/NubLang/Ast/Node.cs b/compiler/NubLang/Ast/Node.cs index 020e8c7..aca79fd 100644 --- a/compiler/NubLang/Ast/Node.cs +++ b/compiler/NubLang/Ast/Node.cs @@ -2,8 +2,10 @@ using NubLang.Syntax; namespace NubLang.Ast; -public abstract record Node(List Tokens) +public abstract class Node(List tokens) { + public List Tokens { get; } = tokens; + public abstract IEnumerable Children(); public IEnumerable Descendants() @@ -29,26 +31,42 @@ public abstract record Node(List Tokens) #region Definitions -public abstract record DefinitionNode(List Tokens, string Module, string Name) : Node(Tokens); - -public record FuncParameterNode(List Tokens, string Name, NubType Type) : Node(Tokens) +public abstract class DefinitionNode(List tokens, string module, string name) : Node(tokens) { + public string Module { get; } = module; + public string Name { get; } = name; +} + +public class FuncParameterNode(List tokens, string name, NubType type) : Node(tokens) +{ + public string Name { get; } = name; + public NubType Type { get; } = type; + public override IEnumerable Children() { return []; } } -public record FuncPrototypeNode(List Tokens, string Module, string Name, string? ExternSymbol, List Parameters, NubType ReturnType) : Node(Tokens) +public class FuncPrototypeNode(List tokens, string module, string name, string? externSymbol, List parameters, NubType returnType) : Node(tokens) { + public string Module { get; } = module; + public string Name { get; } = name; + public string? ExternSymbol { get; } = externSymbol; + public List Parameters { get; } = parameters; + public NubType ReturnType { get; } = returnType; + public override IEnumerable Children() { return Parameters; } } -public record FuncNode(List Tokens, FuncPrototypeNode Prototype, BlockNode? Body) : DefinitionNode(Tokens, Prototype.Module, Prototype.Name) +public class FuncNode(List tokens, FuncPrototypeNode prototype, BlockNode? body) : DefinitionNode(tokens, prototype.Module, prototype.Name) { + public FuncPrototypeNode Prototype { get; } = prototype; + public BlockNode? Body { get; } = body; + public override IEnumerable Children() { yield return Prototype; @@ -63,36 +81,45 @@ public record FuncNode(List Tokens, FuncPrototypeNode Prototype, BlockNod #region Statements -public abstract record StatementNode(List Tokens) : Node(Tokens); +public abstract class StatementNode(List tokens) : Node(tokens); -public abstract record TerminalStatementNode(List Tokens) : StatementNode(Tokens); +public abstract class TerminalStatementNode(List tokens) : StatementNode(tokens); -public record BlockNode(List Tokens, List Statements) : StatementNode(Tokens) +public class BlockNode(List tokens, List statements) : StatementNode(tokens) { + public List Statements { get; } = statements; + public override IEnumerable Children() { return Statements; } } -public record StatementFuncCallNode(List Tokens, FuncCallNode FuncCall) : StatementNode(Tokens) +public class StatementFuncCallNode(List tokens, FuncCallNode funcCall) : StatementNode(tokens) { + public FuncCallNode FuncCall { get; } = funcCall; + public override IEnumerable Children() { yield return FuncCall; } } -public record ReturnNode(List Tokens, ExpressionNode? Value) : TerminalStatementNode(Tokens) +public class ReturnNode(List tokens, ExpressionNode? value) : TerminalStatementNode(tokens) { + public ExpressionNode? Value { get; } = value; + public override IEnumerable Children() { if (Value != null) yield return Value; } } -public record AssignmentNode(List Tokens, LValueExpressionNode Target, ExpressionNode Value) : StatementNode(Tokens) +public class AssignmentNode(List tokens, LValueExpressionNode target, ExpressionNode value) : StatementNode(tokens) { + public LValueExpressionNode Target { get; } = target; + public ExpressionNode Value { get; } = value; + public override IEnumerable Children() { yield return Target; @@ -100,8 +127,12 @@ public record AssignmentNode(List Tokens, LValueExpressionNode Target, Ex } } -public record IfNode(List Tokens, ExpressionNode Condition, BlockNode Body, Variant? Else) : StatementNode(Tokens) +public class IfNode(List tokens, ExpressionNode condition, BlockNode body, Variant? @else) : StatementNode(tokens) { + public ExpressionNode Condition { get; } = condition; + public BlockNode Body { get; } = body; + public Variant? Else { get; } = @else; + public override IEnumerable Children() { yield return Condition; @@ -113,15 +144,19 @@ public record IfNode(List Tokens, ExpressionNode Condition, BlockNode Bod } } -public record VariableDeclarationNode(List Tokens, string Name, ExpressionNode? Assignment, NubType Type) : StatementNode(Tokens) +public class VariableDeclarationNode(List tokens, string name, ExpressionNode? assignment, NubType type) : StatementNode(tokens) { + public string Name { get; } = name; + public ExpressionNode? Assignment { get; } = assignment; + public NubType Type { get; } = type; + public override IEnumerable Children() { if (Assignment != null) yield return Assignment; } } -public record ContinueNode(List Tokens) : TerminalStatementNode(Tokens) +public class ContinueNode(List tokens) : TerminalStatementNode(tokens) { public override IEnumerable Children() { @@ -129,7 +164,7 @@ public record ContinueNode(List Tokens) : TerminalStatementNode(Tokens) } } -public record BreakNode(List Tokens) : TerminalStatementNode(Tokens) +public class BreakNode(List tokens) : TerminalStatementNode(tokens) { public override IEnumerable Children() { @@ -137,8 +172,11 @@ public record BreakNode(List Tokens) : TerminalStatementNode(Tokens) } } -public record WhileNode(List Tokens, ExpressionNode Condition, BlockNode Body) : StatementNode(Tokens) +public class WhileNode(List tokens, ExpressionNode condition, BlockNode body) : StatementNode(tokens) { + public ExpressionNode Condition { get; } = condition; + public BlockNode Body { get; } = body; + public override IEnumerable Children() { yield return Condition; @@ -146,8 +184,13 @@ public record WhileNode(List Tokens, ExpressionNode Condition, BlockNode } } -public record ForSliceNode(List Tokens, string ElementName, string? IndexName, ExpressionNode Target, BlockNode Body) : StatementNode(Tokens) +public class ForSliceNode(List tokens, string elementName, string? indexName, ExpressionNode target, BlockNode body) : StatementNode(tokens) { + public string ElementName { get; } = elementName; + public string? IndexName { get; } = indexName; + public ExpressionNode Target { get; } = target; + public BlockNode Body { get; } = body; + public override IEnumerable Children() { yield return Target; @@ -155,8 +198,13 @@ public record ForSliceNode(List Tokens, string ElementName, string? Index } } -public record ForConstArrayNode(List Tokens, string ElementName, string? IndexName, ExpressionNode Target, BlockNode Body) : StatementNode(Tokens) +public class ForConstArrayNode(List tokens, string elementName, string? indexName, ExpressionNode target, BlockNode body) : StatementNode(tokens) { + public string ElementName { get; } = elementName; + public string? IndexName { get; } = indexName; + public ExpressionNode Target { get; } = target; + public BlockNode Body { get; } = body; + public override IEnumerable Children() { yield return Target; @@ -164,8 +212,10 @@ public record ForConstArrayNode(List Tokens, string ElementName, string? } } -public record DeferNode(List Tokens, StatementNode Statement) : StatementNode(Tokens) +public class DeferNode(List tokens, StatementNode statement) : StatementNode(tokens) { + public StatementNode Statement { get; } = statement; + public override IEnumerable Children() { yield return Statement; @@ -204,120 +254,153 @@ public enum BinaryOperator BitwiseOr } -public abstract record ExpressionNode(List Tokens, NubType Type) : Node(Tokens); - -public abstract record LValueExpressionNode(List Tokens, NubType Type) : ExpressionNode(Tokens, Type); - -public abstract record RValueExpressionNode(List Tokens, NubType Type) : ExpressionNode(Tokens, Type); - -public abstract record IntermediateExpression(List Tokens) : ExpressionNode(Tokens, new NubVoidType()); - -public record StringLiteralNode(List Tokens, string Value) : RValueExpressionNode(Tokens, new NubStringType()) +public abstract class ExpressionNode(List tokens, NubType type) : Node(tokens) { + public NubType Type { get; } = type; +} + +public abstract class LValueExpressionNode(List tokens, NubType type) : ExpressionNode(tokens, type); + +public abstract class RValueExpressionNode(List tokens, NubType type) : ExpressionNode(tokens, type); + +public abstract class IntermediateExpression(List tokens) : ExpressionNode(tokens, new NubVoidType()); + +public class StringLiteralNode(List tokens, string value) : RValueExpressionNode(tokens, new NubStringType()) +{ + public string Value { get; } = value; + public override IEnumerable Children() { return []; } } -public record CStringLiteralNode(List Tokens, string Value) : RValueExpressionNode(Tokens, new NubCStringType()) +public class CStringLiteralNode(List tokens, string value) : RValueExpressionNode(tokens, new NubPointerType(new NubIntType(true, 8))) { + public string Value { get; } = value; + public override IEnumerable Children() { return []; } } -public record I8LiteralNode(List Tokens, sbyte Value) : RValueExpressionNode(Tokens, new NubIntType(true, 8)) +public class I8LiteralNode(List tokens, sbyte value) : RValueExpressionNode(tokens, new NubIntType(true, 8)) { + public sbyte Value { get; } = value; + public override IEnumerable Children() { return []; } } -public record I16LiteralNode(List Tokens, short Value) : RValueExpressionNode(Tokens, new NubIntType(true, 16)) +public class I16LiteralNode(List tokens, short value) : RValueExpressionNode(tokens, new NubIntType(true, 16)) { + public short Value { get; } = value; + public override IEnumerable Children() { return []; } } -public record I32LiteralNode(List Tokens, int Value) : RValueExpressionNode(Tokens, new NubIntType(true, 32)) +public class I32LiteralNode(List tokens, int value) : RValueExpressionNode(tokens, new NubIntType(true, 32)) { + public int Value { get; } = value; + public override IEnumerable Children() { return []; } } -public record I64LiteralNode(List Tokens, long Value) : RValueExpressionNode(Tokens, new NubIntType(true, 64)) +public class I64LiteralNode(List tokens, long value) : RValueExpressionNode(tokens, new NubIntType(true, 64)) { + public long Value { get; } = value; + public override IEnumerable Children() { return []; } } -public record U8LiteralNode(List Tokens, byte Value) : RValueExpressionNode(Tokens, new NubIntType(false, 8)) +public class U8LiteralNode(List tokens, byte value) : RValueExpressionNode(tokens, new NubIntType(false, 8)) { + public byte Value { get; } = value; + public override IEnumerable Children() { return []; } } -public record U16LiteralNode(List Tokens, ushort Value) : RValueExpressionNode(Tokens, new NubIntType(false, 16)) +public class U16LiteralNode(List tokens, ushort value) : RValueExpressionNode(tokens, new NubIntType(false, 16)) { + public ushort Value { get; } = value; + public override IEnumerable Children() { return []; } } -public record U32LiteralNode(List Tokens, uint Value) : RValueExpressionNode(Tokens, new NubIntType(false, 32)) +public class U32LiteralNode(List tokens, uint value) : RValueExpressionNode(tokens, new NubIntType(false, 32)) { + public uint Value { get; } = value; + public override IEnumerable Children() { return []; } } -public record U64LiteralNode(List Tokens, ulong Value) : RValueExpressionNode(Tokens, new NubIntType(false, 64)) +public class U64LiteralNode(List tokens, ulong value) : RValueExpressionNode(tokens, new NubIntType(false, 64)) { + public ulong Value { get; } = value; + public override IEnumerable Children() { return []; } } -public record Float32LiteralNode(List Tokens, float Value) : RValueExpressionNode(Tokens, new NubFloatType(32)) +public class Float32LiteralNode(List tokens, float value) : RValueExpressionNode(tokens, new NubFloatType(32)) { + public float Value { get; } = value; + public override IEnumerable Children() { return []; } } -public record Float64LiteralNode(List Tokens, double Value) : RValueExpressionNode(Tokens, new NubFloatType(64)) +public class Float64LiteralNode(List tokens, double value) : RValueExpressionNode(tokens, new NubFloatType(64)) { + public double Value { get; } = value; + public override IEnumerable Children() { return []; } } -public record BoolLiteralNode(List Tokens, NubType Type, bool Value) : RValueExpressionNode(Tokens, Type) +public class BoolLiteralNode(List tokens, NubType type, bool value) : RValueExpressionNode(tokens, type) { + public bool Value { get; } = value; + public override IEnumerable Children() { return []; } } -public record BinaryExpressionNode(List Tokens, NubType Type, ExpressionNode Left, BinaryOperator Operator, ExpressionNode Right) : RValueExpressionNode(Tokens, Type) +public class BinaryExpressionNode(List tokens, NubType type, ExpressionNode left, BinaryOperator @operator, ExpressionNode right) : RValueExpressionNode(tokens, type) { + public ExpressionNode Left { get; } = left; + public BinaryOperator Operator { get; } = @operator; + public ExpressionNode Right { get; } = right; + public override IEnumerable Children() { yield return Left; @@ -325,16 +408,22 @@ public record BinaryExpressionNode(List Tokens, NubType Type, ExpressionN } } -public record UnaryExpressionNode(List Tokens, NubType Type, UnaryOperator Operator, ExpressionNode Operand) : RValueExpressionNode(Tokens, Type) +public class UnaryExpressionNode(List tokens, NubType type, UnaryOperator @operator, ExpressionNode operand) : RValueExpressionNode(tokens, type) { + public UnaryOperator Operator { get; } = @operator; + public ExpressionNode Operand { get; } = operand; + public override IEnumerable Children() { yield return Operand; } } -public record FuncCallNode(List Tokens, NubType Type, ExpressionNode Expression, List Parameters) : RValueExpressionNode(Tokens, Type) +public class FuncCallNode(List tokens, NubType type, ExpressionNode expression, List parameters) : RValueExpressionNode(tokens, type) { + public ExpressionNode Expression { get; } = expression; + public List Parameters { get; } = parameters; + public override IEnumerable Children() { yield return Expression; @@ -345,40 +434,53 @@ public record FuncCallNode(List Tokens, NubType Type, ExpressionNode Expr } } -public record VariableIdentifierNode(List Tokens, NubType Type, string Name) : LValueExpressionNode(Tokens, Type) +public class VariableIdentifierNode(List tokens, NubType type, string name) : LValueExpressionNode(tokens, type) { + public string Name { get; } = name; + public override IEnumerable Children() { return []; } } -public record FuncIdentifierNode(List Tokens, NubType Type, string Module, string Name, string? ExternSymbol) : RValueExpressionNode(Tokens, Type) +public class FuncIdentifierNode(List tokens, NubType type, string module, string name, string? externSymbol) : RValueExpressionNode(tokens, type) { + public string Module { get; } = module; + public string Name { get; } = name; + public string? ExternSymbol { get; } = externSymbol; + public override IEnumerable Children() { return []; } } -public record ArrayInitializerNode(List Tokens, NubType Type, List Values) : RValueExpressionNode(Tokens, Type) +public class ArrayInitializerNode(List tokens, NubType type, List values) : RValueExpressionNode(tokens, type) { + public List Values { get; } = values; + public override IEnumerable Children() { return Values; } } -public record ConstArrayInitializerNode(List Tokens, NubType Type, List Values) : RValueExpressionNode(Tokens, Type) +public class ConstArrayInitializerNode(List tokens, NubType type, List values) : RValueExpressionNode(tokens, type) { + public List Values { get; } = values; + public override IEnumerable Children() { return Values; } } -public record ArrayIndexAccessNode(List Tokens, NubType Type, ExpressionNode Target, ExpressionNode Index) : LValueExpressionNode(Tokens, Type) +public class ArrayIndexAccessNode(List tokens, NubType type, ExpressionNode target, ExpressionNode index) : LValueExpressionNode(tokens, type) { + public ExpressionNode Target { get; } = target; + public ExpressionNode Index { get; } = index; + public override IEnumerable Children() { yield return Target; @@ -386,8 +488,11 @@ public record ArrayIndexAccessNode(List Tokens, NubType Type, ExpressionN } } -public record ConstArrayIndexAccessNode(List Tokens, NubType Type, ExpressionNode Target, ExpressionNode Index) : LValueExpressionNode(Tokens, Type) +public class ConstArrayIndexAccessNode(List tokens, NubType type, ExpressionNode target, ExpressionNode index) : LValueExpressionNode(tokens, type) { + public ExpressionNode Target { get; } = target; + public ExpressionNode Index { get; } = index; + public override IEnumerable Children() { yield return Target; @@ -395,8 +500,11 @@ public record ConstArrayIndexAccessNode(List Tokens, NubType Type, Expres } } -public record SliceIndexAccessNode(List Tokens, NubType Type, ExpressionNode Target, ExpressionNode Index) : LValueExpressionNode(Tokens, Type) +public class SliceIndexAccessNode(List tokens, NubType type, ExpressionNode target, ExpressionNode index) : LValueExpressionNode(tokens, type) { + public ExpressionNode Target { get; } = target; + public ExpressionNode Index { get; } = index; + public override IEnumerable Children() { yield return Target; @@ -404,24 +512,31 @@ public record SliceIndexAccessNode(List Tokens, NubType Type, ExpressionN } } -public record AddressOfNode(List Tokens, NubType Type, LValueExpressionNode LValue) : RValueExpressionNode(Tokens, Type) +public class AddressOfNode(List tokens, NubType type, LValueExpressionNode lValue) : RValueExpressionNode(tokens, type) { + public LValueExpressionNode LValue { get; } = lValue; + public override IEnumerable Children() { yield return LValue; } } -public record StructFieldAccessNode(List Tokens, NubType Type, ExpressionNode Target, string Field) : LValueExpressionNode(Tokens, Type) +public class StructFieldAccessNode(List tokens, NubType type, ExpressionNode target, string field) : LValueExpressionNode(tokens, type) { + public ExpressionNode Target { get; } = target; + public string Field { get; } = field; + public override IEnumerable Children() { yield return Target; } } -public record StructInitializerNode(List Tokens, NubType Type, Dictionary Initializers) : RValueExpressionNode(Tokens, Type) +public class StructInitializerNode(List tokens, NubType type, Dictionary initializers) : RValueExpressionNode(tokens, type) { + public Dictionary Initializers { get; } = initializers; + public override IEnumerable Children() { foreach (var initializer in Initializers) @@ -431,32 +546,41 @@ public record StructInitializerNode(List Tokens, NubType Type, Dictionary } } -public record DereferenceNode(List Tokens, NubType Type, ExpressionNode Target) : LValueExpressionNode(Tokens, Type) +public class DereferenceNode(List tokens, NubType type, ExpressionNode target) : LValueExpressionNode(tokens, type) { + public ExpressionNode Target { get; } = target; + public override IEnumerable Children() { yield return Target; } } -public record SizeNode(List Tokens, NubType Type, NubType TargetType) : RValueExpressionNode(Tokens, Type) +public class SizeNode(List tokens, NubType TargetType) : RValueExpressionNode(tokens, new NubIntType(false, 64)) { + public NubType TargetType { get; } = TargetType; + public override IEnumerable Children() { return []; } } -public record CastNode(List Tokens, NubType Type, ExpressionNode Value) : RValueExpressionNode(Tokens, Type) +public class CastNode(List tokens, NubType type, ExpressionNode value) : RValueExpressionNode(tokens, type) { + public ExpressionNode Value { get; } = value; + public override IEnumerable Children() { yield return Value; } } -public record EnumReferenceIntermediateNode(List Tokens, string Module, string Name) : IntermediateExpression(Tokens) +public class EnumReferenceIntermediateNode(List tokens, string module, string name) : IntermediateExpression(tokens) { + public string Module { get; } = module; + public string Name { get; } = name; + public override IEnumerable Children() { return []; diff --git a/compiler/NubLang/Ast/NubType.cs b/compiler/NubLang/Ast/NubType.cs index e99c160..ef0981b 100644 --- a/compiler/NubLang/Ast/NubType.cs +++ b/compiler/NubLang/Ast/NubType.cs @@ -125,13 +125,6 @@ public class NubArrayType(NubType elementType) : NubType public override int GetHashCode() => HashCode.Combine(typeof(NubArrayType), ElementType); } -public class NubCStringType : NubType -{ - 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 string ToString() => "string"; @@ -143,7 +136,7 @@ public static class NameMangler { public static string Mangle(params IEnumerable types) { - var readable = string.Join("_", types.Select(EncodeType)); + var readable = string.Join(":", types.Select(EncodeType)); return ComputeShortHash(readable); } @@ -153,12 +146,13 @@ public static class NameMangler 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), - NubSliceType a => "A" + EncodeType(a.ElementType), - NubFuncType fn => "FN(" + string.Join(",", fn.Parameters.Select(EncodeType)) + ")" + EncodeType(fn.ReturnType), - NubStructType st => "ST(" + st.Module + "." + st.Name + ")", + NubArrayType a => $"A({EncodeType(a.ElementType)})", + NubConstArrayType ca => $"CA({EncodeType(ca.ElementType)})", + NubSliceType a => $"SL{EncodeType(a.ElementType)}()", + NubPointerType p => $"P({EncodeType(p.BaseType)})", + 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}") }; diff --git a/compiler/NubLang/Ast/TypeChecker.cs b/compiler/NubLang/Ast/TypeChecker.cs index 4801eb9..4224115 100644 --- a/compiler/NubLang/Ast/TypeChecker.cs +++ b/compiler/NubLang/Ast/TypeChecker.cs @@ -309,8 +309,7 @@ public sealed class TypeChecker FloatLiteralSyntax expression => CheckFloatLiteral(expression, expectedType), MemberAccessSyntax expression => CheckMemberAccess(expression, expectedType), StructInitializerSyntax expression => CheckStructInitializer(expression, expectedType), - InterpretSyntax expression => CheckExpression(expression.Target, expectedType) with { Type = ResolveType(expression.Type) }, - SizeSyntax expression => new SizeNode(node.Tokens, new NubIntType(false, 64), ResolveType(expression.Type)), + SizeSyntax expression => new SizeNode(node.Tokens, ResolveType(expression.Type)), CastSyntax expression => CheckCast(expression, expectedType), _ => throw new ArgumentOutOfRangeException(nameof(node)) }; @@ -373,7 +372,6 @@ public sealed class TypeChecker case NubPointerType when to is NubPointerType { BaseType: NubVoidType }: case NubConstArrayType constArrayType1 when to is NubArrayType arrayType && constArrayType1.ElementType == arrayType.ElementType: case NubConstArrayType constArrayType3 when to is NubSliceType sliceType2 && constArrayType3.ElementType == sliceType2.ElementType: - case NubCStringType when to is NubStringType: { return true; } @@ -391,7 +389,6 @@ public sealed class TypeChecker case NubPointerType when to is NubPointerType: case NubPointerType when to is NubIntType: case NubIntType when to is NubPointerType: - case NubCStringType when to is NubPointerType { BaseType: NubIntType { Width: 8 } }: { return true; } @@ -819,7 +816,7 @@ public sealed class TypeChecker private ExpressionNode CheckStringLiteral(StringLiteralSyntax expression, NubType? expectedType) { - if (expectedType is NubCStringType) + if (expectedType is NubPointerType { BaseType: NubIntType { Signed: true, Width: 8 } }) { return new CStringLiteralNode(expression.Tokens, expression.Value); } @@ -1031,35 +1028,12 @@ public sealed class TypeChecker }; } - private bool AlwaysReturns(StatementNode statement) - { - switch (statement) - { - case ReturnNode: - return true; - case BlockNode block: - return block.Statements.Count != 0 && AlwaysReturns(block.Statements.Last()); - case IfNode ifNode: - { - if (!AlwaysReturns(ifNode.Body)) - { - return false; - } - - return !ifNode.Else.HasValue || ifNode.Else.Value.Match(AlwaysReturns, AlwaysReturns); - } - default: - return false; - } - } - private NubType ResolveType(TypeSyntax type) { return type switch { ArrayTypeSyntax arr => new NubArrayType(ResolveType(arr.BaseType)), BoolTypeSyntax => new NubBoolType(), - CStringTypeSyntax => new NubCStringType(), IntTypeSyntax i => new NubIntType(i.Signed, i.Width), FloatTypeSyntax f => new NubFloatType(f.Width), FuncTypeSyntax func => new NubFuncType(func.Parameters.Select(ResolveType).ToList(), ResolveType(func.ReturnType)), diff --git a/compiler/NubLang/Generation/CType.cs b/compiler/NubLang/Generation/CType.cs index 07adb7a..d3d6984 100644 --- a/compiler/NubLang/Generation/CType.cs +++ b/compiler/NubLang/Generation/CType.cs @@ -12,14 +12,13 @@ public static class CType NubBoolType => "bool" + (variableName != null ? $" {variableName}" : ""), NubIntType intType => CreateIntType(intType, variableName), NubFloatType floatType => CreateFloatType(floatType, variableName), - NubCStringType => "char*" + (variableName != null ? $" {variableName}" : ""), NubPointerType ptr => CreatePointerType(ptr, variableName), - NubSliceType => "slice" + (variableName != null ? $" {variableName}" : ""), - NubStringType => "string" + (variableName != null ? $" {variableName}" : ""), + NubSliceType => "struct nub_slice" + (variableName != null ? $" {variableName}" : ""), + NubStringType => "struct nub_string" + (variableName != null ? $" {variableName}" : ""), NubConstArrayType arr => CreateConstArrayType(arr, variableName, constArraysAsPointers), NubArrayType arr => CreateArrayType(arr, variableName), NubFuncType fn => CreateFuncType(fn, variableName), - NubStructType st => $"{st.Module}_{st.Name}" + (variableName != null ? $" {variableName}" : ""), + NubStructType st => $"struct {st.Module}_{st.Name}" + (variableName != null ? $" {variableName}" : ""), _ => throw new NotSupportedException($"C type generation not supported for: {type}") }; } @@ -28,10 +27,10 @@ public static class CType { var cType = intType.Width switch { - 8 => intType.Signed ? "int8_t" : "uint8_t", - 16 => intType.Signed ? "int16_t" : "uint16_t", - 32 => intType.Signed ? "int32_t" : "uint32_t", - 64 => intType.Signed ? "int64_t" : "uint64_t", + 8 => intType.Signed ? "char" : "unsigned char", + 16 => intType.Signed ? "short" : "unsigned short", + 32 => intType.Signed ? "int" : "unsigned int", + 64 => intType.Signed ? "long long" : "unsigned long long", _ => throw new NotSupportedException($"Unsupported integer width: {intType.Width}") }; return cType + (varName != null ? $" {varName}" : ""); diff --git a/compiler/NubLang/Generation/Generator.cs b/compiler/NubLang/Generation/Generator.cs index 4b1a5c8..7c34160 100644 --- a/compiler/NubLang/Generation/Generator.cs +++ b/compiler/NubLang/Generation/Generator.cs @@ -37,26 +37,23 @@ public class Generator public string Emit() { _writer.WriteLine(""" - #include - #include - - typedef struct + struct nub_string { - size_t length; + unsigned long long length; char *data; - } string; + }; - typedef struct + struct nub_slice { - size_t length; + unsigned long long length; void *data; - } slice; + }; """); foreach (var structType in _compilationUnit.ImportedStructTypes) { - _writer.WriteLine("typedef struct"); + _writer.WriteLine($"struct {StructName(structType.Module, structType.Name)}"); _writer.WriteLine("{"); using (_writer.Indent()) { @@ -66,7 +63,7 @@ public class Generator } } - _writer.WriteLine($"}} {StructName(structType.Module, structType.Name)};"); + _writer.WriteLine("};"); _writer.WriteLine(); } @@ -198,7 +195,7 @@ public class Generator var target = EmitExpression(forSliceNode.Target); var indexName = forSliceNode.IndexName ?? NewTmp(); - _writer.WriteLine($"for (size_t {indexName} = 0; {indexName} < {target}.length; ++{indexName})"); + _writer.WriteLine($"for (unsigned long long {indexName} = 0; {indexName} < {target}.length; ++{indexName})"); _writer.WriteLine("{"); using (_writer.Indent()) { @@ -215,7 +212,7 @@ public class Generator var target = EmitExpression(forConstArrayNode.Target); var indexName = forConstArrayNode.IndexName ?? NewTmp(); - _writer.WriteLine($"for (size_t {indexName} = 0; {indexName} < {targetType.Size}; ++{indexName})"); + _writer.WriteLine($"for (unsigned long long {indexName} = 0; {indexName} < {targetType.Size}; ++{indexName})"); _writer.WriteLine("{"); using (_writer.Indent()) { @@ -470,15 +467,9 @@ public class Generator { var value = EmitExpression(castNode.Value); - if (castNode is { Type: NubSliceType, Value.Type: NubConstArrayType arrayType }) + if (castNode is { Type: NubSliceType sliceType, Value.Type: NubConstArrayType arrayType }) { - return $"(slice){{.length = {arrayType.Size}, .data = (void*){value}}}"; - } - - // todo(nub31): Stop depending on libc - if (castNode is { Type: NubCStringType, Value.Type: NubStringType }) - { - return $"(string){{.length = strlen({value}), .data = {value}}}"; + return $"({CType.Create(sliceType)}){{.length = {arrayType.Size}, .data = (void*){value}}}"; } return $"({CType.Create(castNode.Type)}){value}"; @@ -509,7 +500,7 @@ public class Generator private string EmitStringLiteral(StringLiteralNode stringLiteralNode) { var length = Encoding.UTF8.GetByteCount(stringLiteralNode.Value); - return $"(string){{.length = {length}, .data = \"{stringLiteralNode.Value}\"}}"; + return $"(nub_string){{.length = {length}, .data = \"{stringLiteralNode.Value}\"}}"; } private string EmitStructFieldAccess(StructFieldAccessNode structFieldAccessNode) diff --git a/compiler/NubLang/Syntax/Parser.cs b/compiler/NubLang/Syntax/Parser.cs index b122682..b6aacd6 100644 --- a/compiler/NubLang/Syntax/Parser.cs +++ b/compiler/NubLang/Syntax/Parser.cs @@ -510,14 +510,6 @@ public sealed class Parser ExpectSymbol(Symbol.CloseParen); return new SizeSyntax(GetTokens(startIndex), type); } - case "interpret": - { - var type = ParseType(); - ExpectSymbol(Symbol.Comma); - var expression = ParseExpression(); - ExpectSymbol(Symbol.CloseParen); - return new InterpretSyntax(GetTokens(startIndex), type, expression); - } case "cast": { var expression = ParseExpression(); @@ -736,8 +728,6 @@ public sealed class Parser return new VoidTypeSyntax(GetTokens(startIndex)); case "string": return new StringTypeSyntax(GetTokens(startIndex)); - case "cstring": - return new CStringTypeSyntax(GetTokens(startIndex)); case "bool": return new BoolTypeSyntax(GetTokens(startIndex)); default: diff --git a/compiler/NubLang/Syntax/Syntax.cs b/compiler/NubLang/Syntax/Syntax.cs index 5e1fbae..8d4472c 100644 --- a/compiler/NubLang/Syntax/Syntax.cs +++ b/compiler/NubLang/Syntax/Syntax.cs @@ -114,8 +114,6 @@ public record DereferenceSyntax(List Tokens, ExpressionSyntax Target) : E public record SizeSyntax(List Tokens, TypeSyntax Type) : ExpressionSyntax(Tokens); -public record InterpretSyntax(List Tokens, TypeSyntax Type, ExpressionSyntax Target) : ExpressionSyntax(Tokens); - public record CastSyntax(List Tokens, ExpressionSyntax Value) : ExpressionSyntax(Tokens); #endregion @@ -138,8 +136,6 @@ public record BoolTypeSyntax(List Tokens) : TypeSyntax(Tokens); public record StringTypeSyntax(List Tokens) : TypeSyntax(Tokens); -public record CStringTypeSyntax(List Tokens) : TypeSyntax(Tokens); - public record SliceTypeSyntax(List Tokens, TypeSyntax BaseType) : TypeSyntax(Tokens); public record ArrayTypeSyntax(List Tokens, TypeSyntax BaseType) : TypeSyntax(Tokens);