This commit is contained in:
nub31
2025-07-02 19:02:33 +02:00
parent a29cb6d9db
commit 2b331e432a

View File

@@ -421,7 +421,7 @@ public static class QBEGenerator
} }
} }
parameterVars.Add(new Variable(parameter.Name, new Val(parameterName, parameter.Type, ValKind.Immediate))); parameterVars.Add(new Variable(parameter.Name, new Val(parameterName, parameter.Type, ValKind.Value)));
} }
EmitBlock(body, parameterVars); EmitBlock(body, parameterVars);
@@ -509,11 +509,7 @@ public static class QBEGenerator
private static void EmitAssignment(BoundAssignmentNode assignment) private static void EmitAssignment(BoundAssignmentNode assignment)
{ {
var expression = EmitExpression(assignment.Expression); var expression = EmitExpression(assignment.Expression);
if (expression.Kind != ValKind.Pointer) Debug.Assert(expression.Kind == ValKind.LValue);
{
throw new UnreachableException();
}
var value = EmitUnwrap(EmitExpression(assignment.Value)); var value = EmitUnwrap(EmitExpression(assignment.Value));
EmitCopy(assignment.Value.Type, value, expression.Name); EmitCopy(assignment.Value.Type, value, expression.Name);
} }
@@ -596,7 +592,7 @@ public static class QBEGenerator
{ {
var tmp = VarName(); var tmp = VarName();
_builder.AppendLine($" {tmp} =l alloc8 {SizeOf(variableDeclaration.Type)}"); _builder.AppendLine($" {tmp} =l alloc8 {SizeOf(variableDeclaration.Type)}");
_variables.Push(new Variable(variableDeclaration.Name, new Val(tmp, variableDeclaration.Type, ValKind.Pointer))); _variables.Push(new Variable(variableDeclaration.Name, new Val(tmp, variableDeclaration.Type, ValKind.LValue)));
} }
private static void EmitWhile(BoundWhileNode whileStatement) private static void EmitWhile(BoundWhileNode whileStatement)
@@ -658,7 +654,7 @@ public static class QBEGenerator
_builder.AppendLine($" {pointer} =l mul {index}, {SizeOf(elementType)}"); _builder.AppendLine($" {pointer} =l mul {index}, {SizeOf(elementType)}");
_builder.AppendLine($" {pointer} =l add {pointer}, 8"); _builder.AppendLine($" {pointer} =l add {pointer}, 8");
_builder.AppendLine($" {pointer} =l add {array}, {pointer}"); _builder.AppendLine($" {pointer} =l add {array}, {pointer}");
return new Val(pointer, arrayIndexAccess.Type, ValKind.Pointer); return new Val(pointer, arrayIndexAccess.Type, ValKind.LValue);
} }
private static void EmitArrayBoundsCheck(string array, string index) private static void EmitArrayBoundsCheck(string array, string index)
@@ -703,7 +699,7 @@ public static class QBEGenerator
_builder.AppendLine($" {dataPointer} =l add {arrayPointer}, 8"); _builder.AppendLine($" {dataPointer} =l add {arrayPointer}, 8");
_builder.AppendLine($" call $nub_memset(l {dataPointer}, w 0, l {capacityInBytes})"); _builder.AppendLine($" call $nub_memset(l {dataPointer}, w 0, l {capacityInBytes})");
return new Val(arrayPointer, arrayInitializer.Type, ValKind.Immediate); return new Val(arrayPointer, arrayInitializer.Type, ValKind.Value);
} }
private static Val EmitDereference(BoundDereferenceNode dereference) private static Val EmitDereference(BoundDereferenceNode dereference)
@@ -711,17 +707,13 @@ public static class QBEGenerator
var result = EmitUnwrap(EmitExpression(dereference.Expression)); var result = EmitUnwrap(EmitExpression(dereference.Expression));
var outputName = VarName(); var outputName = VarName();
_builder.AppendLine($" {outputName} {QBEAssign(dereference.Type)} {QBELoad(dereference.Type)} {result}"); _builder.AppendLine($" {outputName} {QBEAssign(dereference.Type)} {QBELoad(dereference.Type)} {result}");
return new Val(outputName, dereference.Type, ValKind.Immediate); return new Val(outputName, dereference.Type, ValKind.Value);
} }
private static Val EmitAddressOf(BoundAddressOfNode addressOf) private static Val EmitAddressOf(BoundAddressOfNode addressOf)
{ {
var value = EmitExpression(addressOf.Expression); var value = EmitExpression(addressOf.Expression);
if (value.Kind != ValKind.Pointer) Debug.Assert(value.Kind == ValKind.LValue);
{
throw new UnreachableException();
}
return value; return value;
} }
@@ -730,7 +722,7 @@ public static class QBEGenerator
var left = EmitUnwrap(EmitExpression(binaryExpression.Left)); var left = EmitUnwrap(EmitExpression(binaryExpression.Left));
var right = EmitUnwrap(EmitExpression(binaryExpression.Right)); var right = EmitUnwrap(EmitExpression(binaryExpression.Right));
var outputName = VarName(); var outputName = VarName();
var output = new Val(outputName, binaryExpression.Type, ValKind.Immediate); var output = new Val(outputName, binaryExpression.Type, ValKind.Value);
switch (binaryExpression.Operator) switch (binaryExpression.Operator)
{ {
@@ -964,19 +956,19 @@ public static class QBEGenerator
{ {
var value = float.Parse(literal.Literal, CultureInfo.InvariantCulture); var value = float.Parse(literal.Literal, CultureInfo.InvariantCulture);
var bits = BitConverter.SingleToInt32Bits(value); var bits = BitConverter.SingleToInt32Bits(value);
return new Val(bits.ToString(), literal.Type, ValKind.Immediate); return new Val(bits.ToString(), literal.Type, ValKind.Value);
} }
if (literal.Type.IsFloat64) if (literal.Type.IsFloat64)
{ {
var value = double.Parse(literal.Literal, CultureInfo.InvariantCulture); var value = double.Parse(literal.Literal, CultureInfo.InvariantCulture);
var bits = BitConverter.DoubleToInt64Bits(value); var bits = BitConverter.DoubleToInt64Bits(value);
return new Val(bits.ToString(), literal.Type, ValKind.Immediate); return new Val(bits.ToString(), literal.Type, ValKind.Value);
} }
if (literal.Type.IsInteger) if (literal.Type.IsInteger)
{ {
return new Val(literal.Literal, literal.Type, ValKind.Immediate); return new Val(literal.Literal, literal.Type, ValKind.Value);
} }
break; break;
@@ -985,21 +977,21 @@ public static class QBEGenerator
{ {
if (literal.Type.IsInteger) if (literal.Type.IsInteger)
{ {
return new Val(literal.Literal.Split(".").First(), literal.Type, ValKind.Immediate); return new Val(literal.Literal.Split(".").First(), literal.Type, ValKind.Value);
} }
if (literal.Type.IsFloat32) if (literal.Type.IsFloat32)
{ {
var value = float.Parse(literal.Literal, CultureInfo.InvariantCulture); var value = float.Parse(literal.Literal, CultureInfo.InvariantCulture);
var bits = BitConverter.SingleToInt32Bits(value); var bits = BitConverter.SingleToInt32Bits(value);
return new Val(bits.ToString(), literal.Type, ValKind.Immediate); return new Val(bits.ToString(), literal.Type, ValKind.Value);
} }
if (literal.Type.IsFloat64) if (literal.Type.IsFloat64)
{ {
var value = double.Parse(literal.Literal, CultureInfo.InvariantCulture); var value = double.Parse(literal.Literal, CultureInfo.InvariantCulture);
var bits = BitConverter.DoubleToInt64Bits(value); var bits = BitConverter.DoubleToInt64Bits(value);
return new Val(bits.ToString(), literal.Type, ValKind.Immediate); return new Val(bits.ToString(), literal.Type, ValKind.Value);
} }
break; break;
@@ -1010,14 +1002,14 @@ public static class QBEGenerator
{ {
var stringLiteral = new StringLiteral(literal.Literal, StringName()); var stringLiteral = new StringLiteral(literal.Literal, StringName());
_stringLiterals.Add(stringLiteral); _stringLiterals.Add(stringLiteral);
return new Val(stringLiteral.Name, literal.Type, ValKind.Immediate); return new Val(stringLiteral.Name, literal.Type, ValKind.Value);
} }
if (literal.Type.IsCString) if (literal.Type.IsCString)
{ {
var cStringLiteral = new CStringLiteral(literal.Literal, CStringName()); var cStringLiteral = new CStringLiteral(literal.Literal, CStringName());
_cStringLiterals.Add(cStringLiteral); _cStringLiterals.Add(cStringLiteral);
return new Val(cStringLiteral.Name, literal.Type, ValKind.Immediate); return new Val(cStringLiteral.Name, literal.Type, ValKind.Value);
} }
break; break;
@@ -1026,7 +1018,7 @@ public static class QBEGenerator
{ {
if (literal.Type.IsBool) if (literal.Type.IsBool)
{ {
return new Val(bool.Parse(literal.Literal) ? "1" : "0", literal.Type, ValKind.Immediate); return new Val(bool.Parse(literal.Literal) ? "1" : "0", literal.Type, ValKind.Value);
} }
break; break;
@@ -1068,7 +1060,7 @@ public static class QBEGenerator
} }
} }
return new Val(output, structInitializer.StructType, ValKind.Immediate); return new Val(output, structInitializer.StructType, ValKind.Value);
} }
private static Val EmitUnaryExpression(BoundUnaryExpressionNode unaryExpression) private static Val EmitUnaryExpression(BoundUnaryExpressionNode unaryExpression)
@@ -1084,16 +1076,16 @@ public static class QBEGenerator
{ {
case NubPrimitiveType { Kind: PrimitiveTypeKind.I64 }: case NubPrimitiveType { Kind: PrimitiveTypeKind.I64 }:
_builder.AppendLine($" {outputName} =l neg {operand}"); _builder.AppendLine($" {outputName} =l neg {operand}");
return new Val(outputName, unaryExpression.Type, ValKind.Immediate); return new Val(outputName, unaryExpression.Type, ValKind.Value);
case NubPrimitiveType { Kind: PrimitiveTypeKind.I32 or PrimitiveTypeKind.I16 or PrimitiveTypeKind.I8 }: case NubPrimitiveType { Kind: PrimitiveTypeKind.I32 or PrimitiveTypeKind.I16 or PrimitiveTypeKind.I8 }:
_builder.AppendLine($" {outputName} =w neg {operand}"); _builder.AppendLine($" {outputName} =w neg {operand}");
return new Val(outputName, unaryExpression.Type, ValKind.Immediate); return new Val(outputName, unaryExpression.Type, ValKind.Value);
case NubPrimitiveType { Kind: PrimitiveTypeKind.F64 }: case NubPrimitiveType { Kind: PrimitiveTypeKind.F64 }:
_builder.AppendLine($" {outputName} =d neg {operand}"); _builder.AppendLine($" {outputName} =d neg {operand}");
return new Val(outputName, unaryExpression.Type, ValKind.Immediate); return new Val(outputName, unaryExpression.Type, ValKind.Value);
case NubPrimitiveType { Kind: PrimitiveTypeKind.F32 }: case NubPrimitiveType { Kind: PrimitiveTypeKind.F32 }:
_builder.AppendLine($" {outputName} =s neg {operand}"); _builder.AppendLine($" {outputName} =s neg {operand}");
return new Val(outputName, unaryExpression.Type, ValKind.Immediate); return new Val(outputName, unaryExpression.Type, ValKind.Value);
} }
break; break;
@@ -1104,7 +1096,7 @@ public static class QBEGenerator
{ {
case NubPrimitiveType { Kind: PrimitiveTypeKind.Bool }: case NubPrimitiveType { Kind: PrimitiveTypeKind.Bool }:
_builder.AppendLine($" {outputName} =w xor {operand}, 1"); _builder.AppendLine($" {outputName} =w xor {operand}, 1");
return new Val(outputName, unaryExpression.Type, ValKind.Immediate); return new Val(outputName, unaryExpression.Type, ValKind.Value);
} }
break; break;
@@ -1130,7 +1122,7 @@ public static class QBEGenerator
if (memberAccess.Member == "count") if (memberAccess.Member == "count")
{ {
_builder.AppendLine($" {output} =l loadl {item}"); _builder.AppendLine($" {output} =l loadl {item}");
return new Val(output, memberAccess.Type, ValKind.Immediate); return new Val(output, memberAccess.Type, ValKind.Value);
} }
break; break;
@@ -1140,7 +1132,7 @@ public static class QBEGenerator
if (memberAccess.Member == "count") if (memberAccess.Member == "count")
{ {
_builder.AppendLine($" {output} =l call $nub_string_length(l {item})"); _builder.AppendLine($" {output} =l call $nub_string_length(l {item})");
return new Val(output, memberAccess.Type, ValKind.Immediate); return new Val(output, memberAccess.Type, ValKind.Value);
} }
break; break;
} }
@@ -1149,7 +1141,7 @@ public static class QBEGenerator
if (memberAccess.Member == "count") if (memberAccess.Member == "count")
{ {
_builder.AppendLine($" {output} =l call $nub_cstring_length(l {item})"); _builder.AppendLine($" {output} =l call $nub_cstring_length(l {item})");
return new Val(output, memberAccess.Type, ValKind.Immediate); return new Val(output, memberAccess.Type, ValKind.Value);
} }
break; break;
} }
@@ -1159,7 +1151,7 @@ public static class QBEGenerator
var offset = OffsetOf(structDefinition, memberAccess.Member); var offset = OffsetOf(structDefinition, memberAccess.Member);
_builder.AppendLine($" {output} =l add {item}, {offset}"); _builder.AppendLine($" {output} =l add {item}, {offset}");
return new Val(output, memberAccess.Type, ValKind.Pointer); return new Val(output, memberAccess.Type, ValKind.LValue);
} }
} }
@@ -1211,12 +1203,12 @@ public static class QBEGenerator
{ {
var outputName = VarName(); var outputName = VarName();
_builder.AppendLine($" {outputName} {QBEAssign(funcCall.Type)} call {funcPointer}({string.Join(", ", parameterStrings)})"); _builder.AppendLine($" {outputName} {QBEAssign(funcCall.Type)} call {funcPointer}({string.Join(", ", parameterStrings)})");
return new Val(outputName, funcCall.Type, ValKind.Immediate); return new Val(outputName, funcCall.Type, ValKind.Value);
} }
else else
{ {
_builder.AppendLine($" call {funcPointer}({string.Join(", ", parameterStrings)})"); _builder.AppendLine($" call {funcPointer}({string.Join(", ", parameterStrings)})");
return new Val(string.Empty, funcCall.Type, ValKind.Immediate); return new Val(string.Empty, funcCall.Type, ValKind.Value);
} }
} }
@@ -1242,11 +1234,11 @@ public static class QBEGenerator
switch (val.Kind) switch (val.Kind)
{ {
case ValKind.Func: case ValKind.Func:
case ValKind.Immediate: case ValKind.Value:
{ {
return val.Name; return val.Name;
} }
case ValKind.Pointer: case ValKind.LValue:
{ {
if (val.Type is NubStructType) if (val.Type is NubStructType)
{ {
@@ -1298,6 +1290,6 @@ internal class Val(string name, NubType type, ValKind kind)
internal enum ValKind internal enum ValKind
{ {
Func, Func,
Pointer, LValue,
Immediate Value
} }