...
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using NubLang.Ast;
|
||||
using NubLang.Modules;
|
||||
@@ -156,9 +157,7 @@ public class LlvmGenerator
|
||||
EmitWhile(writer, whileNode);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
throw new ArgumentOutOfRangeException(nameof(statementNode));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -590,73 +589,81 @@ public class LlvmGenerator
|
||||
private Tmp EmitCast(IndentedTextWriter writer, CastNode castNode)
|
||||
{
|
||||
var source = Unwrap(writer, EmitExpression(writer, castNode.Value));
|
||||
var sourceType = castNode.Value.Type;
|
||||
var targetType = castNode.Type;
|
||||
|
||||
var result = NewTmp("cast");
|
||||
|
||||
switch (sourceType, targetType)
|
||||
switch (castNode.ConversionType)
|
||||
{
|
||||
case (NubIntType sourceInt, NubIntType targetInt):
|
||||
case CastNode.Conversion.IntToInt:
|
||||
{
|
||||
if (sourceInt.Width < targetInt.Width)
|
||||
{
|
||||
var op = sourceInt.Signed ? "sext" : "zext";
|
||||
writer.WriteLine($"{result} = {op} {MapType(sourceType)} {source} to {MapType(targetType)}");
|
||||
}
|
||||
else if (sourceInt.Width > targetInt.Width)
|
||||
{
|
||||
writer.WriteLine($"{result} = trunc {MapType(sourceType)} {source} to {MapType(targetType)}");
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteLine($"{result} = bitcast {MapType(sourceType)} {source} to {MapType(targetType)}");
|
||||
}
|
||||
var sourceInt = (NubIntType)castNode.Value.Type;
|
||||
var targetInt = (NubIntType)castNode.Type;
|
||||
|
||||
break;
|
||||
}
|
||||
case (NubFloatType sourceFloat, NubFloatType targetFloat):
|
||||
{
|
||||
if (sourceFloat.Width < targetFloat.Width)
|
||||
{
|
||||
writer.WriteLine($"{result} = fpext {MapType(sourceType)} {source} to {MapType(targetType)}");
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteLine($"{result} = fptrunc {MapType(sourceType)} {source} to {MapType(targetType)}");
|
||||
}
|
||||
var op = sourceInt.Width < targetInt.Width
|
||||
? sourceInt.Signed
|
||||
? "sext"
|
||||
: "zext"
|
||||
: sourceInt.Width > targetInt.Width
|
||||
? "trunc"
|
||||
: "bitcast";
|
||||
|
||||
writer.WriteLine($"{result} = {op} {MapType(sourceInt)} {source} to {MapType(targetInt)}");
|
||||
break;
|
||||
}
|
||||
case (NubIntType intType, NubFloatType):
|
||||
case CastNode.Conversion.FloatToFloat:
|
||||
{
|
||||
var intToFloatOp = intType.Signed ? "sitofp" : "uitofp";
|
||||
writer.WriteLine($"{result} = {intToFloatOp} {MapType(sourceType)} {source} to {MapType(targetType)}");
|
||||
var sourceFloat = (NubFloatType)castNode.Value.Type;
|
||||
var targetFloat = (NubFloatType)castNode.Type;
|
||||
|
||||
var op = sourceFloat.Width < targetFloat.Width ? "fpext" : "fptrunc";
|
||||
writer.WriteLine($"{result} = {op} {MapType(sourceFloat)} {source} to {MapType(targetFloat)}");
|
||||
break;
|
||||
}
|
||||
case (NubFloatType, NubIntType targetInt):
|
||||
case CastNode.Conversion.IntToFloat:
|
||||
{
|
||||
var floatToIntOp = targetInt.Signed ? "fptosi" : "fptoui";
|
||||
writer.WriteLine($"{result} = {floatToIntOp} {MapType(sourceType)} {source} to {MapType(targetType)}");
|
||||
var sourceInt = (NubIntType)castNode.Value.Type;
|
||||
var targetFloat = (NubFloatType)castNode.Type;
|
||||
|
||||
var op = sourceInt.Signed ? "sitofp" : "uitofp";
|
||||
writer.WriteLine($"{result} = {op} {MapType(sourceInt)} {source} to {MapType(targetFloat)}");
|
||||
break;
|
||||
}
|
||||
case (NubPointerType, NubPointerType):
|
||||
case (NubPointerType, NubIntType):
|
||||
case (NubIntType, NubPointerType):
|
||||
case CastNode.Conversion.FloatToInt:
|
||||
{
|
||||
writer.WriteLine($"{result} = inttoptr {MapType(sourceType)} {source} to {MapType(targetType)}");
|
||||
var sourceFloat = (NubFloatType)castNode.Value.Type;
|
||||
var targetInt = (NubIntType)castNode.Type;
|
||||
|
||||
var op = targetInt.Signed ? "fptosi" : "fptoui";
|
||||
writer.WriteLine($"{result} = {op} {MapType(sourceFloat)} {source} to {MapType(targetInt)}");
|
||||
break;
|
||||
}
|
||||
case CastNode.Conversion.PointerToPointer:
|
||||
case CastNode.Conversion.PointerToUInt64:
|
||||
case CastNode.Conversion.UInt64ToPointer:
|
||||
{
|
||||
writer.WriteLine($"{result} = inttoptr {MapType(castNode.Value.Type)} {source} to {MapType(castNode.Type)}");
|
||||
break;
|
||||
}
|
||||
case CastNode.Conversion.ConstArrayToArray:
|
||||
{
|
||||
var sourceConstArrayType = (NubConstArrayType)castNode.Value.Type;
|
||||
var targetArrayType = (NubArrayType)castNode.Type;
|
||||
|
||||
writer.WriteLine($"{result} = getelementptr {MapType(sourceConstArrayType)}, {MapType(targetArrayType)} {source}, i32 0, i32 0");
|
||||
break;
|
||||
}
|
||||
case CastNode.Conversion.ConstArrayToSlice:
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw new NotImplementedException($"Cast from {sourceType} to {targetType} not implemented");
|
||||
throw new UnreachableException();
|
||||
}
|
||||
}
|
||||
|
||||
return new Tmp(result, castNode.Type, false);
|
||||
}
|
||||
|
||||
|
||||
private Tmp EmitConstArrayIndexAccess(IndentedTextWriter writer, ConstArrayIndexAccessNode constArrayIndexAccessNode)
|
||||
{
|
||||
var arrayPtr = Unwrap(writer, EmitExpression(writer, constArrayIndexAccessNode.Target));
|
||||
@@ -898,6 +905,7 @@ public class LlvmGenerator
|
||||
switch (unaryExpressionNode.Operator)
|
||||
{
|
||||
case UnaryOperator.Negate:
|
||||
{
|
||||
switch (unaryExpressionNode.Operand.Type)
|
||||
{
|
||||
case NubIntType intType:
|
||||
@@ -907,15 +915,20 @@ public class LlvmGenerator
|
||||
writer.WriteLine($"{result} = fneg {MapType(floatType)} {operand}");
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
throw new UnreachableException();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case UnaryOperator.Invert:
|
||||
{
|
||||
writer.WriteLine($"{result} = xor i1 {operand}, true");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
return new Tmp(result, unaryExpressionNode.Type, false);
|
||||
|
||||
Reference in New Issue
Block a user