Better literal handling
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using NubLang.Tokenization;
|
||||
using NubLang.TypeChecking.Node;
|
||||
|
||||
namespace NubLang.Generation.QBE;
|
||||
@@ -666,6 +664,13 @@ public class QBEGenerator
|
||||
{
|
||||
return rValue switch
|
||||
{
|
||||
StringLiteralNode expr => EmitStringLiteral(expr),
|
||||
CStringLiteralNode expr => EmitCStringLiteral(expr),
|
||||
IntLiteralNode expr => expr.Value.ToString(),
|
||||
UIntLiteralNode expr => expr.Value.ToString(),
|
||||
Float32LiteralNode expr => BitConverter.SingleToInt32Bits(expr.Value).ToString(),
|
||||
Float64LiteralNode expr => BitConverter.DoubleToInt64Bits(expr.Value).ToString(),
|
||||
BoolLiteralNode expr => expr.Value ? "1" : "0",
|
||||
AddressOfNode expr => EmitAddressOf(expr.LValue),
|
||||
ArrayInitializerNode expr => EmitArrayInitializer(expr),
|
||||
BinaryExpressionNode expr => EmitBinaryExpression(expr),
|
||||
@@ -675,7 +680,6 @@ public class QBEGenerator
|
||||
FuncCallNode expr => EmitFuncCall(expr),
|
||||
FuncIdentifierNode expr => FuncName(expr.Module, expr.Name, expr.ExternSymbol),
|
||||
FuncParameterIdentifierNode expr => $"%{expr.Name}",
|
||||
LiteralNode expr => EmitLiteral(expr),
|
||||
StructFuncCallNode expr => EmitStructFuncCall(expr),
|
||||
StructInitializerNode expr => EmitStructInitializer(expr),
|
||||
UnaryExpressionNode expr => EmitUnaryExpression(expr),
|
||||
@@ -695,6 +699,20 @@ public class QBEGenerator
|
||||
return EmitLoad(lValue.Type, address);
|
||||
}
|
||||
|
||||
private string EmitStringLiteral(StringLiteralNode expr)
|
||||
{
|
||||
var stringLiteral = new StringLiteral(expr.Value, StringName());
|
||||
_stringLiterals.Add(stringLiteral);
|
||||
return stringLiteral.Name;
|
||||
}
|
||||
|
||||
private string EmitCStringLiteral(CStringLiteralNode expr)
|
||||
{
|
||||
var cStringLiteral = new CStringLiteral(expr.Value, CStringName());
|
||||
_cStringLiterals.Add(cStringLiteral);
|
||||
return cStringLiteral.Name;
|
||||
}
|
||||
|
||||
private string EmitArrayInitializer(ArrayInitializerNode arrayInitializer)
|
||||
{
|
||||
var capacity = EmitExpression(arrayInitializer.Capacity);
|
||||
@@ -922,88 +940,6 @@ public class QBEGenerator
|
||||
};
|
||||
}
|
||||
|
||||
private string EmitLiteral(LiteralNode literal)
|
||||
{
|
||||
switch (literal.Kind)
|
||||
{
|
||||
case LiteralKind.Integer:
|
||||
{
|
||||
if (literal.Type is FloatTypeNode { Width: 32 })
|
||||
{
|
||||
var value = float.Parse(literal.Value, CultureInfo.InvariantCulture);
|
||||
var bits = BitConverter.SingleToInt32Bits(value);
|
||||
return bits.ToString();
|
||||
}
|
||||
|
||||
if (literal.Type is FloatTypeNode { Width: 64 })
|
||||
{
|
||||
var value = double.Parse(literal.Value, CultureInfo.InvariantCulture);
|
||||
var bits = BitConverter.DoubleToInt64Bits(value);
|
||||
return bits.ToString();
|
||||
}
|
||||
|
||||
if (literal.Type is IntTypeNode)
|
||||
{
|
||||
return literal.Value;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case LiteralKind.Float:
|
||||
{
|
||||
if (literal.Type is IntTypeNode)
|
||||
{
|
||||
return literal.Value.Split(".").First();
|
||||
}
|
||||
|
||||
if (literal.Type is FloatTypeNode { Width: 32 })
|
||||
{
|
||||
var value = float.Parse(literal.Value, CultureInfo.InvariantCulture);
|
||||
var bits = BitConverter.SingleToInt32Bits(value);
|
||||
return bits.ToString();
|
||||
}
|
||||
|
||||
if (literal.Type is FloatTypeNode { Width: 64 })
|
||||
{
|
||||
var value = double.Parse(literal.Value, CultureInfo.InvariantCulture);
|
||||
var bits = BitConverter.DoubleToInt64Bits(value);
|
||||
return bits.ToString();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case LiteralKind.String:
|
||||
{
|
||||
if (literal.Type is StringTypeNode)
|
||||
{
|
||||
var stringLiteral = new StringLiteral(literal.Value, StringName());
|
||||
_stringLiterals.Add(stringLiteral);
|
||||
return stringLiteral.Name;
|
||||
}
|
||||
|
||||
if (literal.Type is CStringTypeNode)
|
||||
{
|
||||
var cStringLiteral = new CStringLiteral(literal.Value, CStringName());
|
||||
_cStringLiterals.Add(cStringLiteral);
|
||||
return cStringLiteral.Name;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case LiteralKind.Bool:
|
||||
{
|
||||
if (literal.Type is BoolTypeNode)
|
||||
{
|
||||
return bool.Parse(literal.Value) ? "1" : "0";
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
throw new NotSupportedException($"Cannot create literal of kind '{literal.Kind}' for type {literal.Type}");
|
||||
}
|
||||
|
||||
private string EmitStructInitializer(StructInitializerNode structInitializer)
|
||||
{
|
||||
var destination = TmpName();
|
||||
|
||||
Reference in New Issue
Block a user