float literals

This commit is contained in:
nub31
2025-05-16 20:27:42 +02:00
parent e0bbb7478e
commit 2a4401bab6
3 changed files with 121 additions and 37 deletions

View File

@@ -2,18 +2,9 @@ import c;
global func main(argc: i64, argv: i64) { global func main(argc: i64, argv: i64) {
printf("args: %d, starts at %p\n", argc, argv); printf("args: %d, starts at %p\n", argc, argv);
test(12.1);
a = 128;
b = 32768;
c = 2147483648;
d = 9223372036850000000;
x = test(a, b, c, d);
printf("%d\n", x);
} }
func test(a: i8, b: i16, c: i32, d: i64): i64 { func test(a: f64) {
printf("a: %d, b: %d, c: %d, d: %d\n", a, b, c, d); printf("%f\n", a);
return 12;
} }

View File

@@ -1,4 +1,5 @@
using System.Text; using System.Globalization;
using System.Text;
using Nub.Lang.Frontend.Parsing; using Nub.Lang.Frontend.Parsing;
namespace Nub.Lang.Backend; namespace Nub.Lang.Backend;
@@ -96,7 +97,7 @@ public class Generator
case PrimitiveTypeKind.String: case PrimitiveTypeKind.String:
return "l"; return "l";
case PrimitiveTypeKind.Any: case PrimitiveTypeKind.Any:
throw new NotSupportedException("Cannot convert any to QBE type"); throw new NotSupportedException("Cannot convert 'any' type to QBE type");
case PrimitiveTypeKind.I32: case PrimitiveTypeKind.I32:
case PrimitiveTypeKind.U32: case PrimitiveTypeKind.U32:
return "w"; return "w";
@@ -139,7 +140,7 @@ public class Generator
case PrimitiveTypeKind.String: case PrimitiveTypeKind.String:
return "l"; return "l";
case PrimitiveTypeKind.Any: case PrimitiveTypeKind.Any:
throw new NotSupportedException("Cannot convert any to QBE type"); throw new NotSupportedException("Cannot convert 'any' type to QBE type");
case PrimitiveTypeKind.I32: case PrimitiveTypeKind.I32:
case PrimitiveTypeKind.U32: case PrimitiveTypeKind.U32:
return "w"; return "w";
@@ -403,7 +404,8 @@ public class Generator
private void GenerateStatementFuncCall(FuncCallStatementNode funcCall) private void GenerateStatementFuncCall(FuncCallStatementNode funcCall)
{ {
_builder.AppendLine($" {GenerateFuncCall(funcCall.FuncCall)}"); var call = GenerateFuncCall(funcCall.FuncCall);
_builder.AppendLine($" {call}");
} }
private void GenerateIf(IfNode ifStatement) private void GenerateIf(IfNode ifStatement)
@@ -778,6 +780,13 @@ public class Generator
return literal.Literal; return literal.Literal;
} }
if (literal.LiteralType.Equals(NubPrimitiveType.F64))
{
var value = double.Parse(literal.Literal, CultureInfo.InvariantCulture);
var bits = BitConverter.DoubleToInt64Bits(value);
return bits.ToString();
}
if (literal.LiteralType.Equals(NubPrimitiveType.Bool)) if (literal.LiteralType.Equals(NubPrimitiveType.Bool))
{ {
return bool.Parse(literal.Literal) ? "1" : "0"; return bool.Parse(literal.Literal) ? "1" : "0";
@@ -788,7 +797,7 @@ public class Generator
private string GenerateTypeConversion(string input, NubType inputType, NubType outputType) private string GenerateTypeConversion(string input, NubType inputType, NubType outputType)
{ {
if (inputType.Equals(outputType)) if (inputType.Equals(outputType) || outputType.Equals(NubPrimitiveType.Any))
{ {
return input; return input;
} }
@@ -798,12 +807,6 @@ public class Generator
throw new NotSupportedException("Casting is only supported for primitive types"); throw new NotSupportedException("Casting is only supported for primitive types");
} }
if (primitiveOutputType.Kind == PrimitiveTypeKind.Any) return input;
if (primitiveOutputType.Kind == PrimitiveTypeKind.Bool)
{
throw new NotSupportedException("Cannot cast any type to a bool");
}
var outputLabel = GenName("c"); var outputLabel = GenName("c");
switch (primitiveInputType.Kind) switch (primitiveInputType.Kind)
@@ -818,6 +821,7 @@ public class Generator
case PrimitiveTypeKind.I16: case PrimitiveTypeKind.I16:
case PrimitiveTypeKind.U16: case PrimitiveTypeKind.U16:
case PrimitiveTypeKind.I8: case PrimitiveTypeKind.I8:
case PrimitiveTypeKind.Any:
case PrimitiveTypeKind.U8: case PrimitiveTypeKind.U8:
return input; return input;
case PrimitiveTypeKind.F64: case PrimitiveTypeKind.F64:
@@ -827,8 +831,9 @@ public class Generator
_builder.AppendLine($" %{outputLabel} =s sltof {input}"); _builder.AppendLine($" %{outputLabel} =s sltof {input}");
return $"%{outputLabel}"; return $"%{outputLabel}";
case PrimitiveTypeKind.String: case PrimitiveTypeKind.String:
case PrimitiveTypeKind.Bool:
default: default:
throw new ArgumentOutOfRangeException(); throw new NotSupportedException($"Casting from {primitiveInputType.Kind} to {primitiveOutputType.Kind} is not supported");
} }
case PrimitiveTypeKind.I32: case PrimitiveTypeKind.I32:
switch (primitiveOutputType.Kind) switch (primitiveOutputType.Kind)
@@ -853,8 +858,10 @@ public class Generator
_builder.AppendLine($" %{outputLabel} =s swtof {input}"); _builder.AppendLine($" %{outputLabel} =s swtof {input}");
return $"%{outputLabel}"; return $"%{outputLabel}";
case PrimitiveTypeKind.String: case PrimitiveTypeKind.String:
case PrimitiveTypeKind.Bool:
case PrimitiveTypeKind.Any:
default: default:
throw new ArgumentOutOfRangeException(); throw new NotSupportedException($"Casting from {primitiveInputType.Kind} to {primitiveOutputType.Kind} is not supported");
} }
case PrimitiveTypeKind.I16: case PrimitiveTypeKind.I16:
switch (primitiveOutputType.Kind) switch (primitiveOutputType.Kind)
@@ -887,8 +894,10 @@ public class Generator
return $"%{outputLabel}"; return $"%{outputLabel}";
} }
case PrimitiveTypeKind.String: case PrimitiveTypeKind.String:
case PrimitiveTypeKind.Bool:
case PrimitiveTypeKind.Any:
default: default:
throw new ArgumentOutOfRangeException(); throw new NotSupportedException($"Casting from {primitiveInputType.Kind} to {primitiveOutputType.Kind} is not supported");
} }
case PrimitiveTypeKind.I8: case PrimitiveTypeKind.I8:
switch (primitiveOutputType.Kind) switch (primitiveOutputType.Kind)
@@ -921,8 +930,10 @@ public class Generator
return $"%{outputLabel}"; return $"%{outputLabel}";
} }
case PrimitiveTypeKind.String: case PrimitiveTypeKind.String:
case PrimitiveTypeKind.Bool:
case PrimitiveTypeKind.Any:
default: default:
throw new ArgumentOutOfRangeException(); throw new NotSupportedException($"Casting from {primitiveInputType.Kind} to {primitiveOutputType.Kind} is not supported");
} }
case PrimitiveTypeKind.U64: case PrimitiveTypeKind.U64:
switch (primitiveOutputType.Kind) switch (primitiveOutputType.Kind)
@@ -943,8 +954,10 @@ public class Generator
_builder.AppendLine($" %{outputLabel} =s ultof {input}"); _builder.AppendLine($" %{outputLabel} =s ultof {input}");
return $"%{outputLabel}"; return $"%{outputLabel}";
case PrimitiveTypeKind.String: case PrimitiveTypeKind.String:
case PrimitiveTypeKind.Bool:
case PrimitiveTypeKind.Any:
default: default:
throw new ArgumentOutOfRangeException(); throw new NotSupportedException($"Casting from {primitiveInputType.Kind} to {primitiveOutputType.Kind} is not supported");
} }
case PrimitiveTypeKind.U32: case PrimitiveTypeKind.U32:
switch (primitiveOutputType.Kind) switch (primitiveOutputType.Kind)
@@ -969,8 +982,10 @@ public class Generator
_builder.AppendLine($" %{outputLabel} =s uwtof {input}"); _builder.AppendLine($" %{outputLabel} =s uwtof {input}");
return $"%{outputLabel}"; return $"%{outputLabel}";
case PrimitiveTypeKind.String: case PrimitiveTypeKind.String:
case PrimitiveTypeKind.Bool:
case PrimitiveTypeKind.Any:
default: default:
throw new ArgumentOutOfRangeException(); throw new NotSupportedException($"Casting from {primitiveInputType.Kind} to {primitiveOutputType.Kind} is not supported");
} }
case PrimitiveTypeKind.U16: case PrimitiveTypeKind.U16:
switch (primitiveOutputType.Kind) switch (primitiveOutputType.Kind)
@@ -1003,8 +1018,10 @@ public class Generator
return $"%{outputLabel}"; return $"%{outputLabel}";
} }
case PrimitiveTypeKind.String: case PrimitiveTypeKind.String:
case PrimitiveTypeKind.Bool:
case PrimitiveTypeKind.Any:
default: default:
throw new ArgumentOutOfRangeException(); throw new NotSupportedException($"Casting from {primitiveInputType.Kind} to {primitiveOutputType.Kind} is not supported");
} }
case PrimitiveTypeKind.U8: case PrimitiveTypeKind.U8:
switch (primitiveOutputType.Kind) switch (primitiveOutputType.Kind)
@@ -1037,9 +1054,59 @@ public class Generator
return $"%{outputLabel}"; return $"%{outputLabel}";
} }
case PrimitiveTypeKind.String: case PrimitiveTypeKind.String:
case PrimitiveTypeKind.Bool:
case PrimitiveTypeKind.Any:
default: default:
throw new ArgumentOutOfRangeException(); throw new NotSupportedException($"Casting from {primitiveInputType.Kind} to {primitiveOutputType.Kind} is not supported");
} }
case PrimitiveTypeKind.F64:
switch (primitiveOutputType.Kind)
{
case PrimitiveTypeKind.F64:
return input;
case PrimitiveTypeKind.F32:
_builder.AppendLine($" %{outputLabel} =s dtos {input}");
return $"%{outputLabel}";
case PrimitiveTypeKind.I64:
case PrimitiveTypeKind.I32:
case PrimitiveTypeKind.I16:
case PrimitiveTypeKind.I8:
case PrimitiveTypeKind.U64:
case PrimitiveTypeKind.U32:
case PrimitiveTypeKind.U16:
case PrimitiveTypeKind.U8:
case PrimitiveTypeKind.Bool:
case PrimitiveTypeKind.String:
case PrimitiveTypeKind.Any:
default:
throw new NotSupportedException($"Casting from {primitiveInputType.Kind} to {primitiveOutputType.Kind} is not supported");
}
case PrimitiveTypeKind.F32:
switch (primitiveOutputType.Kind)
{
case PrimitiveTypeKind.F64:
_builder.AppendLine($" %{outputLabel} =d stord {input}");
return $"%{outputLabel}";
case PrimitiveTypeKind.F32:
return input;
case PrimitiveTypeKind.I64:
case PrimitiveTypeKind.I32:
case PrimitiveTypeKind.I16:
case PrimitiveTypeKind.I8:
case PrimitiveTypeKind.U64:
case PrimitiveTypeKind.U32:
case PrimitiveTypeKind.U16:
case PrimitiveTypeKind.U8:
case PrimitiveTypeKind.Bool:
case PrimitiveTypeKind.String:
case PrimitiveTypeKind.Any:
default:
throw new NotSupportedException($"Casting from {primitiveInputType.Kind} to {primitiveOutputType.Kind} is not supported");
}
case PrimitiveTypeKind.Bool:
case PrimitiveTypeKind.String:
case PrimitiveTypeKind.Any:
default: default:
throw new NotSupportedException($"Casting from {primitiveInputType.Kind} to {primitiveOutputType.Kind} is not supported"); throw new NotSupportedException($"Casting from {primitiveInputType.Kind} to {primitiveOutputType.Kind} is not supported");
} }
@@ -1090,7 +1157,8 @@ public class Generator
private string GenerateExpressionFuncCall(FuncCallExpressionNode funcCall) private string GenerateExpressionFuncCall(FuncCallExpressionNode funcCall)
{ {
var outputLabel = GenName(); var outputLabel = GenName();
_builder.AppendLine($" %{outputLabel} ={SQT(funcCall.Type)} {GenerateFuncCall(funcCall.FuncCall)}"); var call = GenerateFuncCall(funcCall.FuncCall);
_builder.AppendLine($" %{outputLabel} ={SQT(funcCall.Type)} {call}");
return $"%{outputLabel}"; return $"%{outputLabel}";
} }

View File

@@ -94,16 +94,41 @@ public class Lexer
if (char.IsDigit(current.Value)) if (char.IsDigit(current.Value))
{ {
var isFloat = false;
var buffer = string.Empty; var buffer = string.Empty;
while (current.HasValue && char.IsDigit(current.Value)) while (current.HasValue)
{
if (current.Value == '.')
{
if (isFloat)
{
throw new Exception("More than one period found in float literal");
}
isFloat = true;
buffer += current.Value;
Next();
current = Peek();
}
else if (char.IsDigit(current.Value))
{ {
buffer += current.Value; buffer += current.Value;
Next(); Next();
current = Peek(); current = Peek();
} }
else if (current.Value == 'f')
{
isFloat = true;
Next();
break;
}
else
{
break;
}
}
return new LiteralToken(NubPrimitiveType.I64, buffer); return new LiteralToken(isFloat ? NubPrimitiveType.F64 : NubPrimitiveType.I64, buffer);
} }
// TODO: Revisit this // TODO: Revisit this