improve addressof
This commit is contained in:
@@ -5,15 +5,19 @@ struct Human {
|
||||
}
|
||||
|
||||
export func main(args: []^string): i64 {
|
||||
let x = [3]f64
|
||||
let age: u64 = 23
|
||||
|
||||
x[0] = 1
|
||||
x[1] = 2
|
||||
x[2] = 3
|
||||
let me = alloc Human {
|
||||
age = &age
|
||||
}
|
||||
|
||||
c::printf("%f\n", x[0])
|
||||
c::printf("%f\n", x[1])
|
||||
c::printf("%f\n", x[2])
|
||||
me.age^ = 24.5
|
||||
|
||||
test(me.age^)
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func test(me: u64) {
|
||||
c::printf("%d\n", me)
|
||||
}
|
||||
@@ -49,7 +49,7 @@ error = error || typeCheckResult.HasErrors;
|
||||
|
||||
if (error) return 1;
|
||||
|
||||
var generator = new Generator();
|
||||
var generator = new QBEGenerator();
|
||||
var result = generator.Generate(files);
|
||||
|
||||
Console.Out.Write(result);
|
||||
|
||||
@@ -10,7 +10,7 @@ using Nub.Lang.Frontend.Typing;
|
||||
|
||||
namespace Nub.Lang.Frontend.Generation;
|
||||
|
||||
public class Generator
|
||||
public class QBEGenerator
|
||||
{
|
||||
private const string OutOfBoundsMessage = "Index is out of bounds\\n";
|
||||
|
||||
@@ -297,7 +297,7 @@ public class Generator
|
||||
|
||||
foreach (var parameter in node.Parameters)
|
||||
{
|
||||
var parameterName = parameter.Name;
|
||||
var parameterName = "%" + parameter.Name;
|
||||
|
||||
if (parameter.Type is NubPrimitiveType primitiveType)
|
||||
{
|
||||
@@ -319,24 +319,18 @@ public class Generator
|
||||
parameterName = GenVarName();
|
||||
_builder.AppendLine($" {parameterName} =w extub %{parameter.Name}");
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_variables[parameter.Name] = parameterName;
|
||||
}
|
||||
|
||||
_builder.AppendLine();
|
||||
|
||||
GenerateBlock(node.Body);
|
||||
|
||||
if (node.Body.Statements.LastOrDefault() is not ReturnNode)
|
||||
{
|
||||
if (node.ReturnType is NubVoidType)
|
||||
{
|
||||
_builder.AppendLine();
|
||||
_builder.AppendLine(" # Implicit return");
|
||||
_builder.AppendLine(" ret");
|
||||
}
|
||||
}
|
||||
@@ -436,17 +430,10 @@ public class Generator
|
||||
var adjustedIndex = GenVarName();
|
||||
_builder.AppendLine($" {adjustedIndex} =l mul {index}, {SizeOf(arrayType.ElementType)}");
|
||||
|
||||
var offsetName = GenVarName();
|
||||
_builder.AppendLine($" {offsetName} =l add {startName}, {adjustedIndex}");
|
||||
var pointer = GenVarName();
|
||||
_builder.AppendLine($" {pointer} =l add {startName}, {adjustedIndex}");
|
||||
|
||||
if (IsLargeType(arrayType.ElementType))
|
||||
{
|
||||
_builder.AppendLine($" blit {value}, {offsetName}, {SizeOf(arrayType.ElementType)}");
|
||||
}
|
||||
else
|
||||
{
|
||||
_builder.AppendLine($" {QBEStore(arrayType.ElementType)} {value}, {offsetName}");
|
||||
}
|
||||
GenerateCopy(arrayType.ElementType, value, pointer);
|
||||
break;
|
||||
}
|
||||
case NubFixedArrayType fixedArrayType:
|
||||
@@ -457,17 +444,10 @@ public class Generator
|
||||
var adjustedIndex = GenVarName();
|
||||
_builder.AppendLine($" {adjustedIndex} =l mul {index}, {SizeOf(fixedArrayType.ElementType)}");
|
||||
|
||||
var offsetName = GenVarName();
|
||||
_builder.AppendLine($" {offsetName} =l add {startName}, {adjustedIndex}");
|
||||
var pointer = GenVarName();
|
||||
_builder.AppendLine($" {pointer} =l add {startName}, {adjustedIndex}");
|
||||
|
||||
if (IsLargeType(fixedArrayType.ElementType))
|
||||
{
|
||||
_builder.AppendLine($" blit {value}, {offsetName}, {SizeOf(fixedArrayType.ElementType)}");
|
||||
}
|
||||
else
|
||||
{
|
||||
_builder.AppendLine($" {QBEStore(fixedArrayType.ElementType)} {value}, {offsetName}");
|
||||
}
|
||||
GenerateCopy(fixedArrayType.ElementType, value, pointer);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -501,17 +481,9 @@ public class Generator
|
||||
|
||||
private void GenerateDereferenceAssignment(DereferenceAssignmentNode dereferenceAssignment)
|
||||
{
|
||||
var location = GenerateExpression(dereferenceAssignment.Dereference.Expression);
|
||||
var pointer = GenerateExpression(dereferenceAssignment.Dereference.Expression);
|
||||
var value = GenerateExpression(dereferenceAssignment.Value);
|
||||
|
||||
if (IsLargeType(dereferenceAssignment.Value.Type))
|
||||
{
|
||||
_builder.AppendLine($" blit {value}, {location}, {SizeOf(dereferenceAssignment.Value.Type)}");
|
||||
}
|
||||
else
|
||||
{
|
||||
_builder.AppendLine($" {QBEStore(dereferenceAssignment.Value.Type)} {value}, {location}");
|
||||
}
|
||||
GenerateCopy(dereferenceAssignment.Value.Type, value, pointer);
|
||||
}
|
||||
|
||||
private void GenerateIf(IfNode ifStatement)
|
||||
@@ -547,20 +519,13 @@ public class Generator
|
||||
var offset = LookupMemberOffset(structDefinition, memberAssignment.MemberAccess.Member);
|
||||
|
||||
var item = GenerateExpression(memberAssignment.MemberAccess.Expression);
|
||||
var offsetName = GenVarName();
|
||||
var pointer = GenVarName();
|
||||
|
||||
_builder.AppendLine($" {offsetName} =l add {item}, {offset}");
|
||||
_builder.AppendLine($" {pointer} =l add {item}, {offset}");
|
||||
|
||||
var value = GenerateExpression(memberAssignment.Value);
|
||||
|
||||
if (IsLargeType(memberAssignment.Value.Type))
|
||||
{
|
||||
_builder.AppendLine($" blit {value}, {offsetName}, {SizeOf(memberAssignment.Value.Type)}");
|
||||
}
|
||||
else
|
||||
{
|
||||
_builder.AppendLine($" {QBEStore(memberAssignment.Value.Type)} {value}, {offsetName}");
|
||||
}
|
||||
GenerateCopy(memberAssignment.Value.Type, value, pointer);
|
||||
}
|
||||
|
||||
private void GenerateReturn(ReturnNode @return)
|
||||
@@ -575,48 +540,32 @@ public class Generator
|
||||
_builder.AppendLine(" ret");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void GenerateVariableAssignment(VariableAssignmentNode variableAssignment)
|
||||
{
|
||||
var result = GenerateExpression(variableAssignment.Value);
|
||||
_builder.AppendLine($" storel {result}, {_variables[variableAssignment.Identifier.Identifier]}");
|
||||
var value = GenerateExpression(variableAssignment.Value);
|
||||
var pointer = _variables[variableAssignment.Identifier.Identifier];
|
||||
GenerateCopy(variableAssignment.Value.Type, value, pointer);
|
||||
}
|
||||
|
||||
private void GenerateVariableDeclaration(VariableDeclarationNode variableDeclaration)
|
||||
{
|
||||
var type = variableDeclaration.ExplicitType.Value ?? variableDeclaration.Value.Value?.Type!;
|
||||
|
||||
string pointerName;
|
||||
var type = variableDeclaration.ExplicitType.Value ?? variableDeclaration.Value.Value!.Type;
|
||||
var pointer = GenVarName();
|
||||
_builder.AppendLine($" {pointer} =l alloc8 {SizeOf(type)}");
|
||||
|
||||
if (variableDeclaration.Value.HasValue)
|
||||
{
|
||||
var result = GenerateExpression(variableDeclaration.Value.Value);
|
||||
if (IsLargeType(type))
|
||||
{
|
||||
pointerName = result;
|
||||
}
|
||||
else
|
||||
{
|
||||
pointerName = GenVarName();
|
||||
_builder.AppendLine($" {pointerName} =l alloc8 {SizeOf(type)}");
|
||||
_builder.AppendLine($" {QBEStore(type)} {result}, {pointerName}");
|
||||
}
|
||||
var value = GenerateExpression(variableDeclaration.Value.Value);
|
||||
GenerateCopy(variableDeclaration.Value.Value.Type, value, pointer);
|
||||
}
|
||||
else
|
||||
{
|
||||
pointerName = GenVarName();
|
||||
_builder.AppendLine($" {pointerName} =l alloc8 {SizeOf(type)}");
|
||||
if (IsLargeType(type))
|
||||
{
|
||||
_builder.AppendLine($" call $nub_memset(l {pointerName}, ub 0, l {SizeOf(type)})");
|
||||
}
|
||||
else
|
||||
{
|
||||
_builder.AppendLine($" {QBEStore(type)} 0, {pointerName}");
|
||||
}
|
||||
var pointerName = GenVarName();
|
||||
_variables[variableDeclaration.Name] = pointerName;
|
||||
}
|
||||
|
||||
_variables[variableDeclaration.Name] = pointerName;
|
||||
|
||||
_variables[variableDeclaration.Name] = pointer;
|
||||
}
|
||||
|
||||
private void GenerateWhile(WhileNode whileStatement)
|
||||
@@ -645,10 +594,9 @@ public class Generator
|
||||
return expression switch
|
||||
{
|
||||
AddressOfNode addressOf => GenerateAddressOf(addressOf),
|
||||
ArrayIndexAccessNode arrayIndex => GenerateArrayIndex(arrayIndex),
|
||||
ArrayIndexAccessNode arrayIndex => GenerateArrayAccessIndex(arrayIndex),
|
||||
ArrayInitializerNode arrayInitializer => GenerateArrayInitializer(arrayInitializer),
|
||||
BinaryExpressionNode binaryExpression => GenerateBinaryExpression(binaryExpression),
|
||||
// CastNode cast => GenerateCast(cast),
|
||||
DereferenceNode dereference => GenerateDereference(dereference),
|
||||
FixedArrayInitializerNode fixedArrayInitializer => GenerateFixedArrayInitializer(fixedArrayInitializer),
|
||||
FuncCallNode funcCallExpression => GenerateFuncCall(funcCallExpression),
|
||||
@@ -661,12 +609,12 @@ public class Generator
|
||||
};
|
||||
}
|
||||
|
||||
private string GenerateArrayIndex(ArrayIndexAccessNode arrayIndexAccess)
|
||||
private string GenerateArrayIndexPointer(ArrayIndexAccessNode arrayIndexAccess)
|
||||
{
|
||||
var array = GenerateExpression(arrayIndexAccess.Array);
|
||||
var index = GenerateExpression(arrayIndexAccess.Index);
|
||||
GenerateArrayBoundsCheck(array, index);
|
||||
|
||||
|
||||
switch (arrayIndexAccess.Array.Type)
|
||||
{
|
||||
case NubArrayType arrayType:
|
||||
@@ -677,17 +625,7 @@ public class Generator
|
||||
_builder.AppendLine($" {offsetPointerName} =l mul {index}, {SizeOf(arrayType.ElementType)}");
|
||||
var resultPointerName = GenVarName();
|
||||
_builder.AppendLine($" {resultPointerName} =l add {firstItemPointerName}, {offsetPointerName}");
|
||||
|
||||
if (IsLargeType(arrayType.ElementType))
|
||||
{
|
||||
return resultPointerName;
|
||||
}
|
||||
else
|
||||
{
|
||||
var outputName = GenVarName();
|
||||
_builder.AppendLine($" {outputName} {QBEAssign(arrayType.ElementType)} {QBELoad(arrayType.ElementType)} {resultPointerName}");
|
||||
return outputName;
|
||||
}
|
||||
return resultPointerName;
|
||||
}
|
||||
case NubFixedArrayType fixedArrayType:
|
||||
{
|
||||
@@ -697,17 +635,7 @@ public class Generator
|
||||
_builder.AppendLine($" {offsetPointerName} =l mul {index}, {SizeOf(fixedArrayType.ElementType)}");
|
||||
var resultPointerName = GenVarName();
|
||||
_builder.AppendLine($" {resultPointerName} =l add {firstItemPointerName}, {offsetPointerName}");
|
||||
|
||||
if (IsLargeType(fixedArrayType.ElementType))
|
||||
{
|
||||
return resultPointerName;
|
||||
}
|
||||
else
|
||||
{
|
||||
var outputName = GenVarName();
|
||||
_builder.AppendLine($" {outputName} {QBEAssign(fixedArrayType.ElementType)} {QBELoad(fixedArrayType.ElementType)} {resultPointerName}");
|
||||
return outputName;
|
||||
}
|
||||
return resultPointerName;
|
||||
}
|
||||
default:
|
||||
{
|
||||
@@ -715,6 +643,22 @@ public class Generator
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string GenerateArrayAccessIndex(ArrayIndexAccessNode arrayIndexAccess)
|
||||
{
|
||||
var pointerName = GenerateArrayIndexPointer(arrayIndexAccess);
|
||||
|
||||
if (IsLargeType(arrayIndexAccess.Type))
|
||||
{
|
||||
return pointerName;
|
||||
}
|
||||
else
|
||||
{
|
||||
var outputName = GenVarName();
|
||||
_builder.AppendLine($" {outputName} {QBEAssign(arrayIndexAccess.Type)} {QBELoad(arrayIndexAccess.Type)} {pointerName}");
|
||||
return outputName;
|
||||
}
|
||||
}
|
||||
|
||||
private void GenerateArrayBoundsCheck(string array, string index)
|
||||
{
|
||||
@@ -768,30 +712,18 @@ public class Generator
|
||||
|
||||
private string GenerateAddressOf(AddressOfNode addressOf)
|
||||
{
|
||||
var result = GenerateExpression(addressOf.Expression);
|
||||
var outputName = GenVarName();
|
||||
switch (addressOf.Expression.Type)
|
||||
switch (addressOf.Expression)
|
||||
{
|
||||
case NubPointerType:
|
||||
case NubStructType:
|
||||
case NubPrimitiveType { Kind: PrimitiveTypeKind.I64 }:
|
||||
case NubPrimitiveType { Kind: PrimitiveTypeKind.F64 }:
|
||||
case NubPrimitiveType { Kind: PrimitiveTypeKind.U64 }:
|
||||
_builder.AppendLine($" {outputName} =l alloc8 8");
|
||||
_builder.AppendLine($" storel {result}, {outputName}");
|
||||
return outputName;
|
||||
case NubPrimitiveType { Kind: PrimitiveTypeKind.I32 }:
|
||||
case NubPrimitiveType { Kind: PrimitiveTypeKind.U32 }:
|
||||
case NubPrimitiveType { Kind: PrimitiveTypeKind.I16 }:
|
||||
case NubPrimitiveType { Kind: PrimitiveTypeKind.U16 }:
|
||||
case NubPrimitiveType { Kind: PrimitiveTypeKind.I8 }:
|
||||
case NubPrimitiveType { Kind: PrimitiveTypeKind.U8 }:
|
||||
case NubPrimitiveType { Kind: PrimitiveTypeKind.F32 }:
|
||||
_builder.AppendLine($" {outputName} =l alloc8 4");
|
||||
_builder.AppendLine($" storew {result}, {outputName}");
|
||||
return outputName;
|
||||
case ArrayIndexAccessNode arrayIndexAccess:
|
||||
return GenerateArrayIndexPointer(arrayIndexAccess);
|
||||
case DereferenceNode dereference:
|
||||
return GenerateExpression(dereference.Expression);
|
||||
case IdentifierNode identifier:
|
||||
return _variables[identifier.Identifier];
|
||||
case MemberAccessNode memberAccess:
|
||||
return GenerateMemberAccessPointer(memberAccess);
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
throw new UnreachableException();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1021,462 +953,9 @@ public class Generator
|
||||
throw new NotSupportedException($"Binary operator {binaryExpression.Operator} for types {binaryExpression.Left.Type} and {binaryExpression.Right.Type} not supported");
|
||||
}
|
||||
|
||||
// private string GenerateCast(CastNode cast)
|
||||
// {
|
||||
// var input = GenerateExpression(cast.Expression);
|
||||
// var outputType = cast.TargetType;
|
||||
// var inputType = cast.Expression.Type;
|
||||
//
|
||||
// if (inputType.Equals(outputType))
|
||||
// {
|
||||
// return input;
|
||||
// }
|
||||
//
|
||||
// if (outputType is not NubPrimitiveType primitiveOutputType || inputType is not NubPrimitiveType primitiveInputType)
|
||||
// {
|
||||
// throw new NotSupportedException("Casting is only supported for primitive types");
|
||||
// }
|
||||
//
|
||||
// var outputName = GenVarName();
|
||||
//
|
||||
// switch (primitiveInputType.Kind)
|
||||
// {
|
||||
// case PrimitiveTypeKind.I64:
|
||||
// switch (primitiveOutputType.Kind)
|
||||
// {
|
||||
// case PrimitiveTypeKind.I64:
|
||||
// case PrimitiveTypeKind.U64:
|
||||
// case PrimitiveTypeKind.I32:
|
||||
// case PrimitiveTypeKind.U32:
|
||||
// case PrimitiveTypeKind.I16:
|
||||
// case PrimitiveTypeKind.U16:
|
||||
// case PrimitiveTypeKind.I8:
|
||||
// case PrimitiveTypeKind.Any:
|
||||
// case PrimitiveTypeKind.U8:
|
||||
// return input;
|
||||
// case PrimitiveTypeKind.F64:
|
||||
// _builder.AppendLine($" {outputName} =d sltof {input}");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.F32:
|
||||
// _builder.AppendLine($" {outputName} =s sltof {input}");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.String:
|
||||
// _builder.AppendLine($" {outputName} =l call $nub_i64_to_string(l {input})");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.Bool:
|
||||
// default:
|
||||
// throw new NotSupportedException($"Casting from {primitiveInputType.Kind} to {primitiveOutputType.Kind} is not supported");
|
||||
// }
|
||||
// case PrimitiveTypeKind.I32:
|
||||
// switch (primitiveOutputType.Kind)
|
||||
// {
|
||||
// case PrimitiveTypeKind.I64:
|
||||
// case PrimitiveTypeKind.U64:
|
||||
// _builder.AppendLine($" {outputName} =l extsw {input}");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.I32:
|
||||
// case PrimitiveTypeKind.U32:
|
||||
// case PrimitiveTypeKind.I16:
|
||||
// case PrimitiveTypeKind.U16:
|
||||
// case PrimitiveTypeKind.I8:
|
||||
// case PrimitiveTypeKind.U8:
|
||||
// return input;
|
||||
// case PrimitiveTypeKind.F64:
|
||||
// var extName = GenVarName();
|
||||
// _builder.AppendLine($" {extName} =l extsw {input}");
|
||||
// _builder.AppendLine($" {outputName} =d sltof {extName}");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.F32:
|
||||
// _builder.AppendLine($" {outputName} =s swtof {input}");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.String:
|
||||
// _builder.AppendLine($" {outputName} =l call $nub_i32_to_string(w {input})");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.Any:
|
||||
// var extAnyName = GenVarName();
|
||||
// _builder.AppendLine($" {extAnyName} =l extsw {input}");
|
||||
// return extAnyName;
|
||||
// case PrimitiveTypeKind.Bool:
|
||||
// default:
|
||||
// throw new NotSupportedException($"Casting from {primitiveInputType.Kind} to {primitiveOutputType.Kind} is not supported");
|
||||
// }
|
||||
// case PrimitiveTypeKind.I16:
|
||||
// switch (primitiveOutputType.Kind)
|
||||
// {
|
||||
// case PrimitiveTypeKind.I64:
|
||||
// case PrimitiveTypeKind.U64:
|
||||
// _builder.AppendLine($" {outputName} =l extsh {input}");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.I32:
|
||||
// case PrimitiveTypeKind.U32:
|
||||
// _builder.AppendLine($" {outputName} =w extsh {input}");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.I16:
|
||||
// case PrimitiveTypeKind.U16:
|
||||
// case PrimitiveTypeKind.I8:
|
||||
// case PrimitiveTypeKind.U8:
|
||||
// return input;
|
||||
// case PrimitiveTypeKind.F64:
|
||||
// {
|
||||
// var extName = GenVarName();
|
||||
// _builder.AppendLine($" {extName} =l extsh {input}");
|
||||
// _builder.AppendLine($" {outputName} =d sltof {extName}");
|
||||
// return outputName;
|
||||
// }
|
||||
// case PrimitiveTypeKind.F32:
|
||||
// {
|
||||
// var extName = GenVarName();
|
||||
// _builder.AppendLine($" {extName} =w extsh {input}");
|
||||
// _builder.AppendLine($" {outputName} =s swtof {extName}");
|
||||
// return outputName;
|
||||
// }
|
||||
// case PrimitiveTypeKind.String:
|
||||
// {
|
||||
// var extName = GenVarName();
|
||||
// _builder.AppendLine($" {extName} =w extsh {input}");
|
||||
// _builder.AppendLine($" {outputName} =l call $nub_i32_to_string(w {extName})");
|
||||
// return outputName;
|
||||
// }
|
||||
// case PrimitiveTypeKind.Any:
|
||||
// {
|
||||
// var extName = GenVarName();
|
||||
// _builder.AppendLine($" {extName} =l extsh {input}");
|
||||
// return extName;
|
||||
// }
|
||||
// case PrimitiveTypeKind.Bool:
|
||||
// default:
|
||||
// throw new NotSupportedException($"Casting from {primitiveInputType.Kind} to {primitiveOutputType.Kind} is not supported");
|
||||
// }
|
||||
// case PrimitiveTypeKind.I8:
|
||||
// switch (primitiveOutputType.Kind)
|
||||
// {
|
||||
// case PrimitiveTypeKind.I64:
|
||||
// case PrimitiveTypeKind.U64:
|
||||
// _builder.AppendLine($" {outputName} =l extsb {input}");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.I32:
|
||||
// case PrimitiveTypeKind.U32:
|
||||
// case PrimitiveTypeKind.I16:
|
||||
// case PrimitiveTypeKind.U16:
|
||||
// _builder.AppendLine($" {outputName} =w extsb {input}");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.I8:
|
||||
// case PrimitiveTypeKind.U8:
|
||||
// return input;
|
||||
// case PrimitiveTypeKind.F64:
|
||||
// {
|
||||
// var extName = GenVarName();
|
||||
// _builder.AppendLine($" {extName} =l extsb {input}");
|
||||
// _builder.AppendLine($" {outputName} =d sltof {extName}");
|
||||
// return outputName;
|
||||
// }
|
||||
// case PrimitiveTypeKind.F32:
|
||||
// {
|
||||
// var extName = GenVarName();
|
||||
// _builder.AppendLine($" {extName} =w extsb {input}");
|
||||
// _builder.AppendLine($" {outputName} =s swtof {extName}");
|
||||
// return outputName;
|
||||
// }
|
||||
// case PrimitiveTypeKind.String:
|
||||
// {
|
||||
// var extName = GenVarName();
|
||||
// _builder.AppendLine($" {extName} =w extsb {input}");
|
||||
// _builder.AppendLine($" {outputName} =l call $nub_i32_to_string(w {extName})");
|
||||
// return outputName;
|
||||
// }
|
||||
// case PrimitiveTypeKind.Any:
|
||||
// {
|
||||
// var extName = GenVarName();
|
||||
// _builder.AppendLine($" {extName} =l extsb {input}");
|
||||
// return extName;
|
||||
// }
|
||||
// case PrimitiveTypeKind.Bool:
|
||||
// default:
|
||||
// throw new NotSupportedException($"Casting from {primitiveInputType.Kind} to {primitiveOutputType.Kind} is not supported");
|
||||
// }
|
||||
// case PrimitiveTypeKind.U64:
|
||||
// switch (primitiveOutputType.Kind)
|
||||
// {
|
||||
// case PrimitiveTypeKind.I64:
|
||||
// case PrimitiveTypeKind.U64:
|
||||
// case PrimitiveTypeKind.I32:
|
||||
// case PrimitiveTypeKind.U32:
|
||||
// case PrimitiveTypeKind.I16:
|
||||
// case PrimitiveTypeKind.U16:
|
||||
// case PrimitiveTypeKind.I8:
|
||||
// case PrimitiveTypeKind.U8:
|
||||
// return input;
|
||||
// case PrimitiveTypeKind.F64:
|
||||
// _builder.AppendLine($" {outputName} =d ultof {input}");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.F32:
|
||||
// _builder.AppendLine($" {outputName} =s ultof {input}");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.String:
|
||||
// _builder.AppendLine($" {outputName} =l call $nub_u64_to_string(l {input})");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.Any:
|
||||
// return input;
|
||||
// case PrimitiveTypeKind.Bool:
|
||||
// default:
|
||||
// throw new NotSupportedException($"Casting from {primitiveInputType.Kind} to {primitiveOutputType.Kind} is not supported");
|
||||
// }
|
||||
// case PrimitiveTypeKind.U32:
|
||||
// switch (primitiveOutputType.Kind)
|
||||
// {
|
||||
// case PrimitiveTypeKind.I64:
|
||||
// case PrimitiveTypeKind.U64:
|
||||
// _builder.AppendLine($" {outputName} =l extuw {input}");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.I32:
|
||||
// case PrimitiveTypeKind.U32:
|
||||
// case PrimitiveTypeKind.I16:
|
||||
// case PrimitiveTypeKind.U16:
|
||||
// case PrimitiveTypeKind.I8:
|
||||
// case PrimitiveTypeKind.U8:
|
||||
// return input;
|
||||
// case PrimitiveTypeKind.F64:
|
||||
// var extName = GenVarName();
|
||||
// _builder.AppendLine($" {extName} =l extuw {input}");
|
||||
// _builder.AppendLine($" {outputName} =d ultof {extName}");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.F32:
|
||||
// _builder.AppendLine($" {outputName} =s uwtof {input}");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.String:
|
||||
// _builder.AppendLine($" {outputName} =l call $nub_u32_to_string(w {input})");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.Any:
|
||||
// var extAnyName = GenVarName();
|
||||
// _builder.AppendLine($" {extAnyName} =l extuw {input}");
|
||||
// return extAnyName;
|
||||
// case PrimitiveTypeKind.Bool:
|
||||
// default:
|
||||
// throw new NotSupportedException($"Casting from {primitiveInputType.Kind} to {primitiveOutputType.Kind} is not supported");
|
||||
// }
|
||||
// case PrimitiveTypeKind.U16:
|
||||
// switch (primitiveOutputType.Kind)
|
||||
// {
|
||||
// case PrimitiveTypeKind.I64:
|
||||
// case PrimitiveTypeKind.U64:
|
||||
// _builder.AppendLine($" {outputName} =l extuh {input}");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.I32:
|
||||
// case PrimitiveTypeKind.U32:
|
||||
// _builder.AppendLine($" {outputName} =w extuh {input}");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.I16:
|
||||
// case PrimitiveTypeKind.U16:
|
||||
// case PrimitiveTypeKind.I8:
|
||||
// case PrimitiveTypeKind.U8:
|
||||
// return input;
|
||||
// case PrimitiveTypeKind.F64:
|
||||
// {
|
||||
// var extName = GenVarName();
|
||||
// _builder.AppendLine($" {extName} =l extuh {input}");
|
||||
// _builder.AppendLine($" {outputName} =d ultof {extName}");
|
||||
// return outputName;
|
||||
// }
|
||||
// case PrimitiveTypeKind.F32:
|
||||
// {
|
||||
// var extName = GenVarName();
|
||||
// _builder.AppendLine($" {extName} =w extuh {input}");
|
||||
// _builder.AppendLine($" {outputName} =s uwtof {extName}");
|
||||
// return outputName;
|
||||
// }
|
||||
// case PrimitiveTypeKind.String:
|
||||
// {
|
||||
// var extName = GenVarName();
|
||||
// _builder.AppendLine($" {extName} =w extuh {input}");
|
||||
// _builder.AppendLine($" {outputName} =l call $nub_u32_to_string(w {extName})");
|
||||
// return outputName;
|
||||
// }
|
||||
// case PrimitiveTypeKind.Any:
|
||||
// {
|
||||
// var extName = GenVarName();
|
||||
// _builder.AppendLine($" {extName} =l extuh {input}");
|
||||
// return extName;
|
||||
// }
|
||||
// case PrimitiveTypeKind.Bool:
|
||||
// default:
|
||||
// throw new NotSupportedException($"Casting from {primitiveInputType.Kind} to {primitiveOutputType.Kind} is not supported");
|
||||
// }
|
||||
// case PrimitiveTypeKind.U8:
|
||||
// switch (primitiveOutputType.Kind)
|
||||
// {
|
||||
// case PrimitiveTypeKind.I64:
|
||||
// case PrimitiveTypeKind.U64:
|
||||
// _builder.AppendLine($" {outputName} =l extub {input}");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.I32:
|
||||
// case PrimitiveTypeKind.U32:
|
||||
// case PrimitiveTypeKind.I16:
|
||||
// case PrimitiveTypeKind.U16:
|
||||
// _builder.AppendLine($" {outputName} =w extub {input}");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.I8:
|
||||
// case PrimitiveTypeKind.U8:
|
||||
// return input;
|
||||
// case PrimitiveTypeKind.F64:
|
||||
// {
|
||||
// var extName = GenVarName();
|
||||
// _builder.AppendLine($" {extName} =l extub {input}");
|
||||
// _builder.AppendLine($" {outputName} =d ultof {extName}");
|
||||
// return outputName;
|
||||
// }
|
||||
// case PrimitiveTypeKind.F32:
|
||||
// {
|
||||
// var extName = GenVarName();
|
||||
// _builder.AppendLine($" {extName} =w extub {input}");
|
||||
// _builder.AppendLine($" {outputName} =s uwtof {extName}");
|
||||
// return outputName;
|
||||
// }
|
||||
// case PrimitiveTypeKind.String:
|
||||
// {
|
||||
// var extName = GenVarName();
|
||||
// _builder.AppendLine($" {extName} =w extub {input}");
|
||||
// _builder.AppendLine($" {outputName} =l call $nub_u32_to_string(w {extName})");
|
||||
// return outputName;
|
||||
// }
|
||||
// case PrimitiveTypeKind.Any:
|
||||
// {
|
||||
// var extName = GenVarName();
|
||||
// _builder.AppendLine($" {extName} =l extub {input}");
|
||||
// return extName;
|
||||
// }
|
||||
// case PrimitiveTypeKind.Bool:
|
||||
// default:
|
||||
// throw new NotSupportedException($"Casting from {primitiveInputType.Kind} to {primitiveOutputType.Kind} is not supported");
|
||||
// }
|
||||
// case PrimitiveTypeKind.F64:
|
||||
// switch (primitiveOutputType.Kind)
|
||||
// {
|
||||
// case PrimitiveTypeKind.F64:
|
||||
// case PrimitiveTypeKind.Any:
|
||||
// return input;
|
||||
// case PrimitiveTypeKind.F32:
|
||||
// _builder.AppendLine($" {outputName} =s dtos {input}");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.I64:
|
||||
// _builder.AppendLine($" {outputName} =l dtosi {input}");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.I32:
|
||||
// case PrimitiveTypeKind.I16:
|
||||
// case PrimitiveTypeKind.I8:
|
||||
// _builder.AppendLine($" {outputName} =w dtosi {input}");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.U64:
|
||||
// _builder.AppendLine($" {outputName} =l dtoui {input}");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.U32:
|
||||
// case PrimitiveTypeKind.U16:
|
||||
// case PrimitiveTypeKind.U8:
|
||||
// _builder.AppendLine($" {outputName} =w dtoui {input}");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.String:
|
||||
// _builder.AppendLine($" {outputName} =l call $nub_f64_to_string(d {input})");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.Bool:
|
||||
// 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($" {outputName} =d stod {input}");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.F32:
|
||||
// return input;
|
||||
// case PrimitiveTypeKind.I64:
|
||||
// _builder.AppendLine($" {outputName} =l stosi {input}");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.I32:
|
||||
// case PrimitiveTypeKind.I16:
|
||||
// case PrimitiveTypeKind.I8:
|
||||
// _builder.AppendLine($" {outputName} =w stosi {input}");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.U64:
|
||||
// _builder.AppendLine($" {outputName} =l stoui {input}");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.U32:
|
||||
// case PrimitiveTypeKind.U16:
|
||||
// case PrimitiveTypeKind.U8:
|
||||
// _builder.AppendLine($" {outputName} =w stoui {input}");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.String:
|
||||
// _builder.AppendLine($" {outputName} =l call $nub_f32_to_string(s {input})");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.Any:
|
||||
// throw new NotImplementedException();
|
||||
// case PrimitiveTypeKind.Bool:
|
||||
// default:
|
||||
// throw new NotSupportedException($"Casting from {primitiveInputType.Kind} to {primitiveOutputType.Kind} is not supported");
|
||||
// }
|
||||
// case PrimitiveTypeKind.Bool:
|
||||
// switch (primitiveOutputType.Kind)
|
||||
// {
|
||||
// case PrimitiveTypeKind.Bool:
|
||||
// return input;
|
||||
// case PrimitiveTypeKind.Any:
|
||||
// _builder.AppendLine($" {outputName} =l extsw {input}");
|
||||
// return outputName;
|
||||
// case PrimitiveTypeKind.String:
|
||||
// _builder.AppendLine($" {outputName} =l call $nub_bool_to_string(s {input})");
|
||||
// return outputName;
|
||||
// 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.F64:
|
||||
// case PrimitiveTypeKind.F32:
|
||||
// default:
|
||||
// throw new NotSupportedException($"Casting from {primitiveInputType.Kind} to {primitiveOutputType.Kind} is not supported");
|
||||
// }
|
||||
// case PrimitiveTypeKind.String:
|
||||
// switch (primitiveOutputType.Kind)
|
||||
// {
|
||||
// case PrimitiveTypeKind.String:
|
||||
// case PrimitiveTypeKind.Any:
|
||||
// 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.F64:
|
||||
// case PrimitiveTypeKind.F32:
|
||||
// case PrimitiveTypeKind.Bool:
|
||||
// default:
|
||||
// throw new NotSupportedException($"Casting from {primitiveInputType.Kind} to {primitiveOutputType.Kind} is not supported");
|
||||
// }
|
||||
// case PrimitiveTypeKind.Any:
|
||||
// return input;
|
||||
// default:
|
||||
// throw new NotSupportedException($"Casting from {primitiveInputType.Kind} to {primitiveOutputType.Kind} is not supported");
|
||||
// }
|
||||
// }
|
||||
|
||||
private string GenerateIdentifier(IdentifierNode identifier)
|
||||
{
|
||||
var variable = _variables[identifier.Identifier];
|
||||
if (IsLargeType(identifier.Type))
|
||||
{
|
||||
return variable;
|
||||
}
|
||||
else
|
||||
{
|
||||
var outputName = GenVarName();
|
||||
_builder.AppendLine($" {outputName} {QBEAssign(identifier.Type)} {QBELoad(identifier.Type)} {variable}");
|
||||
return outputName;
|
||||
}
|
||||
return _variables[identifier.Identifier];
|
||||
}
|
||||
|
||||
private string GenerateLiteral(LiteralNode literal)
|
||||
@@ -1534,33 +1013,17 @@ public class Generator
|
||||
|
||||
if (structInitializer.Initializers.TryGetValue(field.Name, out var fieldValue))
|
||||
{
|
||||
var var = GenerateExpression(fieldValue);
|
||||
var offsetName = GenVarName();
|
||||
_builder.AppendLine($" {offsetName} =l add {structVar}, {offset}");
|
||||
|
||||
if (IsLargeType(field.Type))
|
||||
{
|
||||
_builder.AppendLine($" blit {var}, {offsetName}, {SizeOf(field.Type)}");
|
||||
}
|
||||
else
|
||||
{
|
||||
_builder.AppendLine($" {QBEStore(field.Type)} {var}, {offsetName}");
|
||||
}
|
||||
var value = GenerateExpression(fieldValue);
|
||||
var pointer = GenVarName();
|
||||
_builder.AppendLine($" {pointer} =l add {structVar}, {offset}");
|
||||
GenerateCopy(field.Type, value, pointer);
|
||||
}
|
||||
else if (field.Value.HasValue)
|
||||
{
|
||||
var var = GenerateExpression(field.Value.Value);
|
||||
var offsetName = GenVarName();
|
||||
_builder.AppendLine($" {offsetName} =l add {structVar}, {offset}");
|
||||
|
||||
if (IsLargeType(field.Type))
|
||||
{
|
||||
_builder.AppendLine($" blit {var}, {offsetName}, {SizeOf(field.Type)}");
|
||||
}
|
||||
else
|
||||
{
|
||||
_builder.AppendLine($" {QBEStore(field.Type)} {var}, {offsetName}");
|
||||
}
|
||||
var value = GenerateExpression(field.Value.Value);
|
||||
var pointer = GenVarName();
|
||||
_builder.AppendLine($" {pointer} =l add {structVar}, {offset}");
|
||||
GenerateCopy(field.Type, value, pointer);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1618,22 +1081,19 @@ public class Generator
|
||||
throw new NotSupportedException($"Unary operator {unaryExpression.Operator} for type {unaryExpression.Operand.Type} not supported");
|
||||
}
|
||||
|
||||
private string GenerateMemberAccess(MemberAccessNode memberAccess)
|
||||
private string GenerateMemberAccessPointer(MemberAccessNode memberAccess)
|
||||
{
|
||||
var item = GenerateExpression(memberAccess.Expression);
|
||||
|
||||
switch (memberAccess.Expression.Type)
|
||||
{
|
||||
case NubArrayType:
|
||||
{
|
||||
if (memberAccess.Member == "count")
|
||||
{
|
||||
var outputName = GenVarName();
|
||||
_builder.AppendLine($" {outputName} =l loadl {item}");
|
||||
return outputName;
|
||||
return item;
|
||||
}
|
||||
|
||||
throw new ArgumentOutOfRangeException(nameof(memberAccess.Member));
|
||||
throw new UnreachableException(nameof(memberAccess.Member));
|
||||
}
|
||||
case NubStructType structType:
|
||||
{
|
||||
@@ -1642,26 +1102,31 @@ public class Generator
|
||||
|
||||
var offsetName = GenVarName();
|
||||
_builder.AppendLine($" {offsetName} =l add {item}, {offset}");
|
||||
|
||||
if (IsLargeType(memberAccess.Type))
|
||||
{
|
||||
return offsetName;
|
||||
}
|
||||
else
|
||||
{
|
||||
var outputName = GenVarName();
|
||||
_builder.AppendLine($" {outputName} {QBEAssign(memberAccess.Type)} {QBELoad(memberAccess.Type)} {offsetName}");
|
||||
|
||||
return outputName;
|
||||
}
|
||||
return offsetName;
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(memberAccess.Expression.Type));
|
||||
throw new UnreachableException(nameof(memberAccess.Expression.Type));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string GenerateMemberAccess(MemberAccessNode memberAccess)
|
||||
{
|
||||
var pointer = GenerateMemberAccessPointer(memberAccess);
|
||||
|
||||
if (IsLargeType(memberAccess.Type))
|
||||
{
|
||||
return pointer;
|
||||
}
|
||||
else
|
||||
{
|
||||
var outputName = GenVarName();
|
||||
_builder.AppendLine($" {outputName} {QBEAssign(memberAccess.Type)} {QBELoad(memberAccess.Type)} {pointer}");
|
||||
return outputName;
|
||||
}
|
||||
}
|
||||
|
||||
private string GenerateFixedArrayInitializer(FixedArrayInitializerNode fixedArrayInitializer)
|
||||
{
|
||||
var capacityInBytes = SizeOf(fixedArrayInitializer.Type);
|
||||
@@ -1737,6 +1202,18 @@ public class Generator
|
||||
}
|
||||
}
|
||||
|
||||
private void GenerateCopy(NubType type, string value, string destinationPointer)
|
||||
{
|
||||
if (IsLargeType(type))
|
||||
{
|
||||
_builder.AppendLine($" blit {value}, {destinationPointer}, {SizeOf(type)}");
|
||||
}
|
||||
else
|
||||
{
|
||||
_builder.AppendLine($" {QBEStore(type)} {value}, {destinationPointer}");
|
||||
}
|
||||
}
|
||||
|
||||
private string GenVarName()
|
||||
{
|
||||
return $"%v{++_variableIndex}";
|
||||
@@ -2,7 +2,7 @@ using Nub.Lang.Frontend.Lexing;
|
||||
|
||||
namespace Nub.Lang.Frontend.Parsing.Expressions;
|
||||
|
||||
public class AddressOfNode(IReadOnlyList<Token> tokens, ExpressionNode expression) : ExpressionNode(tokens)
|
||||
public class AddressOfNode(IReadOnlyList<Token> tokens, LValueNode expression) : ExpressionNode(tokens)
|
||||
{
|
||||
public ExpressionNode Expression { get; } = expression;
|
||||
public LValueNode Expression { get; } = expression;
|
||||
}
|
||||
@@ -2,7 +2,7 @@ using Nub.Lang.Frontend.Lexing;
|
||||
|
||||
namespace Nub.Lang.Frontend.Parsing.Expressions;
|
||||
|
||||
public class ArrayIndexAccessNode(IReadOnlyList<Token> tokens, ExpressionNode array, ExpressionNode index) : ExpressionNode(tokens)
|
||||
public class ArrayIndexAccessNode(IReadOnlyList<Token> tokens, ExpressionNode array, ExpressionNode index) : LValueNode(tokens)
|
||||
{
|
||||
public ExpressionNode Array { get; } = array;
|
||||
public ExpressionNode Index { get; } = index;
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
// using Nub.Lang.Frontend.Lexing;
|
||||
// using Nub.Lang.Frontend.Typing;
|
||||
//
|
||||
// namespace Nub.Lang.Frontend.Parsing.Expressions;
|
||||
//
|
||||
// public class CastNode(IReadOnlyList<Token> tokens, NubType targetType, ExpressionNode expression) : ExpressionNode(tokens)
|
||||
// {
|
||||
// public NubType TargetType { get; } = targetType;
|
||||
// public ExpressionNode Expression { get; } = expression;
|
||||
// }
|
||||
@@ -2,7 +2,7 @@ using Nub.Lang.Frontend.Lexing;
|
||||
|
||||
namespace Nub.Lang.Frontend.Parsing.Expressions;
|
||||
|
||||
public class DereferenceNode(IReadOnlyList<Token> tokens, ExpressionNode expression) : ExpressionNode(tokens)
|
||||
public class DereferenceNode(IReadOnlyList<Token> tokens, ExpressionNode expression) : LValueNode(tokens)
|
||||
{
|
||||
public ExpressionNode Expression { get; } = expression;
|
||||
}
|
||||
@@ -11,4 +11,6 @@ public abstract class ExpressionNode(IReadOnlyList<Token> tokens) : Node(tokens)
|
||||
get => _type ?? throw new Exception("Tried to access expression type before type was populated");
|
||||
set => _type = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class LValueNode(IReadOnlyList<Token> tokens) : ExpressionNode(tokens);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Nub.Lang.Frontend.Parsing.Expressions;
|
||||
|
||||
public class IdentifierNode(IReadOnlyList<Token> tokens, string identifier) : ExpressionNode(tokens)
|
||||
public class IdentifierNode(IReadOnlyList<Token> tokens, string identifier) : LValueNode(tokens)
|
||||
{
|
||||
public string Identifier { get; } = identifier;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Nub.Lang.Frontend.Parsing.Expressions;
|
||||
|
||||
public class MemberAccessNode(IReadOnlyList<Token> tokens, ExpressionNode expression, string member) : ExpressionNode(tokens)
|
||||
public class MemberAccessNode(IReadOnlyList<Token> tokens, ExpressionNode expression, string member) : LValueNode(tokens)
|
||||
{
|
||||
public ExpressionNode Expression { get; } = expression;
|
||||
public string Member { get; } = member;
|
||||
|
||||
@@ -495,20 +495,18 @@ public class Parser
|
||||
expr = expression;
|
||||
break;
|
||||
}
|
||||
// case Symbol.LessThan:
|
||||
// {
|
||||
// var type = ParseType();
|
||||
// ExpectSymbol(Symbol.GreaterThan);
|
||||
// ExpectSymbol(Symbol.OpenParen);
|
||||
// var expressionToCast = ParseExpression();
|
||||
// ExpectSymbol(Symbol.CloseParen);
|
||||
// expr = new CastNode(GetTokensForNode(startIndex), type, expressionToCast);
|
||||
// break;
|
||||
// }
|
||||
case Symbol.Ampersand:
|
||||
{
|
||||
var expression = ParsePrimaryExpression();
|
||||
expr = new AddressOfNode(GetTokensForNode(startIndex), expression);
|
||||
if (expression is not LValueNode lValue)
|
||||
{
|
||||
throw new ParseException(Diagnostic
|
||||
.Error("& symbol can only be used on lvalues")
|
||||
.At(expression)
|
||||
.Build());
|
||||
}
|
||||
|
||||
expr = new AddressOfNode(GetTokensForNode(startIndex), lValue);
|
||||
break;
|
||||
}
|
||||
case Symbol.Minus:
|
||||
|
||||
@@ -362,7 +362,6 @@ public class TypeChecker
|
||||
LiteralNode literal => TypeCheckLiteral(literal, expectedType),
|
||||
IdentifierNode identifier => TypeCheckIdentifier(identifier),
|
||||
BinaryExpressionNode binaryExpr => TypeCheckBinaryExpression(binaryExpr),
|
||||
// CastNode cast => TypeCheckCast(cast),
|
||||
DereferenceNode dereference => TypeCheckDereference(dereference),
|
||||
FixedArrayInitializerNode fixedArray => TypeCheckFixedInitializerArray(fixedArray),
|
||||
FuncCallNode funcCallExpr => TypeCheckFuncCall(funcCallExpr, funcCallExpr),
|
||||
@@ -394,7 +393,7 @@ public class TypeChecker
|
||||
{
|
||||
if (literal.Kind == LiteralKind.Float)
|
||||
{
|
||||
ReportWarning("Possible loss of precision when using float in integer context", literal);
|
||||
ReportWarning("Float used in integer context. Everything after the '.' will be ignored", literal);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -517,13 +516,6 @@ public class TypeChecker
|
||||
}
|
||||
}
|
||||
|
||||
// private NubType? TypeCheckCast(CastNode cast)
|
||||
// {
|
||||
// TypeCheckExpression(cast.Expression, cast.TargetType);
|
||||
// // TODO: Check if castable
|
||||
// return cast.TargetType;
|
||||
// }
|
||||
|
||||
private NubType? TypeCheckStructInitializer(StructInitializerNode structInit)
|
||||
{
|
||||
var initialized = new HashSet<string>();
|
||||
|
||||
Reference in New Issue
Block a user