...
This commit is contained in:
@@ -56,7 +56,7 @@ public static class QBEGenerator
|
||||
}
|
||||
|
||||
foreach (var funcDef in _syntaxTree.Definitions.OfType<BoundLocalFuncDefinitionNode>())
|
||||
{
|
||||
{
|
||||
EmitFuncDefinition(FuncName(funcDef), funcDef.Parameters, funcDef.ReturnType, funcDef.Body, funcDef.Exported);
|
||||
_builder.AppendLine();
|
||||
}
|
||||
@@ -140,7 +140,6 @@ public static class QBEGenerator
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
},
|
||||
NubStructType => "storel",
|
||||
NubFixedArrayType => "storel",
|
||||
NubFuncType => "storel",
|
||||
NubCStringType => "storel",
|
||||
NubStringType => "storel",
|
||||
@@ -170,7 +169,6 @@ public static class QBEGenerator
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
},
|
||||
NubStructType => "loadl",
|
||||
NubFixedArrayType => "loadl",
|
||||
NubFuncType => "loadl",
|
||||
NubCStringType => "loadl",
|
||||
NubStringType => "loadl",
|
||||
@@ -200,7 +198,6 @@ public static class QBEGenerator
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
},
|
||||
NubStructType => "=l",
|
||||
NubFixedArrayType => "=l",
|
||||
NubFuncType => "=l",
|
||||
NubCStringType => "=l",
|
||||
NubStringType => "=l",
|
||||
@@ -236,10 +233,6 @@ public static class QBEGenerator
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
case NubFixedArrayType nubFixedArrayType:
|
||||
{
|
||||
return AlignmentOf(nubFixedArrayType.ElementType);
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw new ArgumentOutOfRangeException();
|
||||
@@ -295,10 +288,6 @@ public static class QBEGenerator
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
case NubFixedArrayType nubFixedArrayType:
|
||||
{
|
||||
return SizeOf(nubFixedArrayType.ElementType) * nubFixedArrayType.Capacity + 8;
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw new ArgumentOutOfRangeException();
|
||||
@@ -326,16 +315,6 @@ public static class QBEGenerator
|
||||
throw new UnreachableException($"Member '{member}' not found in struct");
|
||||
}
|
||||
|
||||
private static bool IsPointerType(NubType type)
|
||||
{
|
||||
if (type.IsVoid)
|
||||
{
|
||||
throw new InvalidOperationException($"{nameof(IsPointerType)} should not be called on void types");
|
||||
}
|
||||
|
||||
return type is NubStructType or NubFixedArrayType;
|
||||
}
|
||||
|
||||
private static void EmitFuncDefinition(string name, List<BoundFuncParameter> parameters, NubType returnType, BoundBlockNode body, bool exported)
|
||||
{
|
||||
_variables.Clear();
|
||||
@@ -369,7 +348,6 @@ public static class QBEGenerator
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
},
|
||||
NubStructType structType => StructName(_definitionTable.LookupStruct(structType.Namespace, structType.Name).GetValue()),
|
||||
NubFixedArrayType => "l",
|
||||
NubFuncType => "l",
|
||||
NubCStringType => "l",
|
||||
NubStringType => "l",
|
||||
@@ -402,7 +380,6 @@ public static class QBEGenerator
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
},
|
||||
NubStructType structType => StructName(_definitionTable.LookupStruct(structType.Namespace, structType.Name).GetValue()),
|
||||
NubFixedArrayType => "l",
|
||||
NubFuncType => "l",
|
||||
NubCStringType => "l",
|
||||
NubStringType => "l",
|
||||
@@ -485,7 +462,6 @@ public static class QBEGenerator
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
},
|
||||
NubStructType structType => StructName(_definitionTable.LookupStruct(structType.Namespace, structType.Name).GetValue()),
|
||||
NubFixedArrayType fixedArrayType => $"b {SizeOf(fixedArrayType)}",
|
||||
NubFuncType => "l",
|
||||
NubCStringType => "l",
|
||||
NubStringType => "l",
|
||||
@@ -558,16 +534,6 @@ public static class QBEGenerator
|
||||
EmitCopy(arrayType.ElementType, value, pointer);
|
||||
break;
|
||||
}
|
||||
case NubFixedArrayType fixedArrayType:
|
||||
{
|
||||
var pointer = VarName();
|
||||
_builder.AppendLine($" {pointer} =l mul {index}, {SizeOf(fixedArrayType.ElementType)}");
|
||||
_builder.AppendLine($" {pointer} =l add {pointer}, 8");
|
||||
_builder.AppendLine($" {pointer} =l add {array}, {pointer}");
|
||||
|
||||
EmitCopy(fixedArrayType.ElementType, value, pointer);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw new ArgumentOutOfRangeException();
|
||||
@@ -746,7 +712,6 @@ public static class QBEGenerator
|
||||
var elementType = arrayIndexAccess.Array.Type switch
|
||||
{
|
||||
NubArrayType arrayType => arrayType.ElementType,
|
||||
NubFixedArrayType fixedArrayType => fixedArrayType.ElementType,
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
};
|
||||
|
||||
@@ -769,23 +734,23 @@ public static class QBEGenerator
|
||||
{
|
||||
var count = VarName();
|
||||
_builder.AppendLine($" {count} =l loadl {array}");
|
||||
|
||||
|
||||
var isNegative = VarName();
|
||||
_builder.AppendLine($" {isNegative} =w csltl {index}, 0");
|
||||
|
||||
|
||||
var isOob = VarName();
|
||||
_builder.AppendLine($" {isOob} =w csgel {index}, {count}");
|
||||
|
||||
|
||||
var anyOob = VarName();
|
||||
_builder.AppendLine($" {anyOob} =w or {isNegative}, {isOob}");
|
||||
|
||||
|
||||
var oobLabel = LabelName();
|
||||
var notOobLabel = LabelName();
|
||||
_builder.AppendLine($" jnz {anyOob}, {oobLabel}, {notOobLabel}");
|
||||
|
||||
|
||||
_builder.AppendLine(oobLabel);
|
||||
_builder.AppendLine($" call $nub_panic_array_oob()");
|
||||
|
||||
|
||||
_builder.AppendLine(notOobLabel);
|
||||
}
|
||||
|
||||
@@ -793,12 +758,12 @@ public static class QBEGenerator
|
||||
{
|
||||
var capacity = EmitUnwrap(EmitExpression(arrayInitializer.Capacity));
|
||||
var elementSize = SizeOf(arrayInitializer.ElementType);
|
||||
|
||||
|
||||
var capacityInBytes = VarName();
|
||||
_builder.AppendLine($" {capacityInBytes} =l mul {capacity}, {elementSize}");
|
||||
var totalSize = VarName();
|
||||
_builder.AppendLine($" {totalSize} =l add {capacityInBytes}, 8");
|
||||
|
||||
|
||||
var arrayPointer = VarName();
|
||||
_builder.AppendLine($" {arrayPointer} =l alloc8 {totalSize}");
|
||||
_builder.AppendLine($" storel {capacity}, {arrayPointer}");
|
||||
@@ -1100,6 +1065,7 @@ public static class QBEGenerator
|
||||
{
|
||||
return new Val(literal.Literal, literal.Type, ValKind.Immediate);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case LiteralKind.Float:
|
||||
@@ -1122,6 +1088,7 @@ public static class QBEGenerator
|
||||
var bits = BitConverter.DoubleToInt64Bits(value);
|
||||
return new Val(bits.ToString(), literal.Type, ValKind.Immediate);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case LiteralKind.String:
|
||||
@@ -1139,6 +1106,7 @@ public static class QBEGenerator
|
||||
_cStringLiterals.Add(cStringLiteral);
|
||||
return new Val(cStringLiteral.Name, literal.Type, ValKind.Immediate);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case LiteralKind.Bool:
|
||||
@@ -1147,10 +1115,11 @@ public static class QBEGenerator
|
||||
{
|
||||
return new Val(bool.Parse(literal.Literal) ? "1" : "0", literal.Type, ValKind.Immediate);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
throw new NotSupportedException($"Cannot create literal of kind '{literal.Kind}' for type {literal.Type}");
|
||||
}
|
||||
|
||||
@@ -1250,7 +1219,7 @@ public static class QBEGenerator
|
||||
_builder.AppendLine($" {output} =l loadl {item}");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
throw new UnreachableException();
|
||||
}
|
||||
case NubStringType:
|
||||
@@ -1267,7 +1236,7 @@ public static class QBEGenerator
|
||||
{
|
||||
var structDefinition = _definitionTable.LookupStruct(structType.Namespace, structType.Name).GetValue();
|
||||
var offset = OffsetOf(structDefinition, memberAccess.Member);
|
||||
|
||||
|
||||
var offsetName = VarName();
|
||||
_builder.AppendLine($" {offsetName} =l add {item}, {offset}");
|
||||
_builder.AppendLine($" {output} {QBEAssign(memberAccess.Type)} {QBELoad(memberAccess.Type)} {item}");
|
||||
@@ -1278,7 +1247,7 @@ public static class QBEGenerator
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return new Val(output, memberAccess.Type, ValKind.Immediate);
|
||||
}
|
||||
|
||||
@@ -1330,7 +1299,6 @@ public static class QBEGenerator
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
},
|
||||
NubStructType structType => StructName(_definitionTable.LookupStruct(structType.Namespace, structType.Name).GetValue()),
|
||||
NubFixedArrayType => "l",
|
||||
NubFuncType => "l",
|
||||
NubCStringType => "l",
|
||||
NubStringType => "l",
|
||||
@@ -1372,25 +1340,29 @@ public static class QBEGenerator
|
||||
{
|
||||
throw new InvalidOperationException("Cannot unwrap temporary of void type");
|
||||
}
|
||||
|
||||
|
||||
switch (val.Kind)
|
||||
{
|
||||
case ValKind.Func:
|
||||
case ValKind.Immediate:
|
||||
{
|
||||
return val.Name;
|
||||
}
|
||||
case ValKind.Pointer:
|
||||
if (IsPointerType(val.Type))
|
||||
{
|
||||
if (val.Type is NubStructType)
|
||||
{
|
||||
return val.Name;
|
||||
}
|
||||
else
|
||||
{
|
||||
var result = VarName();
|
||||
_builder.AppendLine($" {result} {QBEAssign(val.Type)} {QBELoad(val.Type)} {val.Name}");
|
||||
return result;
|
||||
}
|
||||
|
||||
var result = VarName();
|
||||
_builder.AppendLine($" {result} {QBEAssign(val.Type)} {QBELoad(val.Type)} {val.Name}");
|
||||
return result;
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Common;
|
||||
using Syntax.Diagnostics;
|
||||
using Syntax.Parsing.Node;
|
||||
@@ -730,29 +729,9 @@ public static class Parser
|
||||
|
||||
if (TryExpectSymbol(Symbol.OpenBracket))
|
||||
{
|
||||
if (Peek().TryGetValue(out var token) && token is LiteralToken { Kind: LiteralKind.Integer, Value: var sizeValue })
|
||||
{
|
||||
Next();
|
||||
ExpectSymbol(Symbol.CloseBracket);
|
||||
var baseType = ParseType();
|
||||
|
||||
var size = int.Parse(sizeValue);
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
return new NubFixedArrayType(baseType, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new UnreachableException();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ExpectSymbol(Symbol.CloseBracket);
|
||||
var baseType = ParseType();
|
||||
return new NubArrayType(baseType);
|
||||
}
|
||||
ExpectSymbol(Symbol.CloseBracket);
|
||||
var baseType = ParseType();
|
||||
return new NubArrayType(baseType);
|
||||
}
|
||||
|
||||
if (!Peek().TryGetValue(out var peekToken))
|
||||
|
||||
@@ -166,24 +166,6 @@ public class NubArrayType(NubType elementType) : NubType
|
||||
}
|
||||
}
|
||||
|
||||
public class NubFixedArrayType(NubType elementType, int capacity) : NubType
|
||||
{
|
||||
public NubType ElementType { get; } = elementType;
|
||||
public int Capacity { get; } = capacity;
|
||||
|
||||
public override string ToString() => $"[{Capacity}]{ElementType}";
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
return obj is NubFixedArrayType other && ElementType.Equals(other.ElementType) && Capacity == other.Capacity;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(ElementType, Capacity);
|
||||
}
|
||||
}
|
||||
|
||||
public class NubAnyType : NubType
|
||||
{
|
||||
public override string ToString() => "any";
|
||||
|
||||
Reference in New Issue
Block a user