float literals
This commit is contained in:
@@ -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;
|
|
||||||
}
|
}
|
||||||
@@ -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}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user