Add void type
This commit is contained in:
@@ -84,68 +84,6 @@ public class Generator
|
||||
return _builder.ToString();
|
||||
}
|
||||
|
||||
private enum TypeContext
|
||||
{
|
||||
FuncDef,
|
||||
FuncCall,
|
||||
}
|
||||
|
||||
private static string QBEType(NubType type, TypeContext context)
|
||||
{
|
||||
return context switch
|
||||
{
|
||||
TypeContext.FuncDef => type switch
|
||||
{
|
||||
NubArrayType => "l",
|
||||
NubPointerType => "l",
|
||||
NubPrimitiveType primitiveType => primitiveType.Kind switch
|
||||
{
|
||||
PrimitiveTypeKind.I64 => "l",
|
||||
PrimitiveTypeKind.I32 => "w",
|
||||
PrimitiveTypeKind.I16 => "sh",
|
||||
PrimitiveTypeKind.I8 => "sb",
|
||||
PrimitiveTypeKind.U64 => "l",
|
||||
PrimitiveTypeKind.U32 => "w",
|
||||
PrimitiveTypeKind.U16 => "uh",
|
||||
PrimitiveTypeKind.U8 => "ub",
|
||||
PrimitiveTypeKind.F64 => "d",
|
||||
PrimitiveTypeKind.F32 => "s",
|
||||
PrimitiveTypeKind.Bool => "w",
|
||||
PrimitiveTypeKind.Any => throw new NotSupportedException("any type cannot be used in function definitions"),
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
},
|
||||
NubStructType structType => $":{structType.Namespace}_{structType.Name}",
|
||||
NubFixedArrayType => "l",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(type))
|
||||
},
|
||||
TypeContext.FuncCall => type switch
|
||||
{
|
||||
NubArrayType => "l",
|
||||
NubPointerType => "l",
|
||||
NubPrimitiveType pointerType => pointerType.Kind switch
|
||||
{
|
||||
PrimitiveTypeKind.I64 => "l",
|
||||
PrimitiveTypeKind.I32 => "w",
|
||||
PrimitiveTypeKind.I16 => "sh",
|
||||
PrimitiveTypeKind.I8 => "sb",
|
||||
PrimitiveTypeKind.U64 => "l",
|
||||
PrimitiveTypeKind.U32 => "w",
|
||||
PrimitiveTypeKind.U16 => "uh",
|
||||
PrimitiveTypeKind.U8 => "ub",
|
||||
PrimitiveTypeKind.F64 => "d",
|
||||
PrimitiveTypeKind.F32 => "s",
|
||||
PrimitiveTypeKind.Bool => "w",
|
||||
PrimitiveTypeKind.Any => "l",
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
},
|
||||
NubStructType structType => $":{structType.Namespace}_{structType.Name}",
|
||||
NubFixedArrayType => "l",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(type))
|
||||
},
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(context), context, null)
|
||||
};
|
||||
}
|
||||
|
||||
private static string QBEStore(NubType type)
|
||||
{
|
||||
return $"store{type switch
|
||||
@@ -165,12 +103,11 @@ public class Generator
|
||||
PrimitiveTypeKind.F64 => "d",
|
||||
PrimitiveTypeKind.F32 => "s",
|
||||
PrimitiveTypeKind.Bool => "w",
|
||||
PrimitiveTypeKind.Any => throw new NotSupportedException("any type cannot be used in store instructions"),
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
_ => throw new UnreachableException()
|
||||
},
|
||||
NubStructType => "l",
|
||||
NubFixedArrayType => "l",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(type))
|
||||
_ => throw new NotSupportedException($"'{type}' type cannot be used in store instructions")
|
||||
}}";
|
||||
}
|
||||
|
||||
@@ -193,12 +130,11 @@ public class Generator
|
||||
PrimitiveTypeKind.F64 => "d",
|
||||
PrimitiveTypeKind.F32 => "s",
|
||||
PrimitiveTypeKind.Bool => "w",
|
||||
PrimitiveTypeKind.Any => throw new NotSupportedException("any type cannot be used in load instructions"),
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
_ => throw new UnreachableException()
|
||||
},
|
||||
NubStructType => "l",
|
||||
NubFixedArrayType => "l",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(type))
|
||||
_ => throw new NotSupportedException($"'{type}' type cannot be used in load instructions")
|
||||
}}";
|
||||
}
|
||||
|
||||
@@ -221,12 +157,11 @@ public class Generator
|
||||
PrimitiveTypeKind.F64 => "d",
|
||||
PrimitiveTypeKind.F32 => "s",
|
||||
PrimitiveTypeKind.Bool => "w",
|
||||
PrimitiveTypeKind.Any => throw new NotSupportedException("any type cannot be used in variables"),
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
_ => throw new UnreachableException()
|
||||
},
|
||||
NubStructType => "l",
|
||||
NubFixedArrayType => "l",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(type))
|
||||
_ => throw new NotSupportedException($"'{type}' type cannot be used in variables")
|
||||
}}";
|
||||
}
|
||||
|
||||
@@ -240,7 +175,6 @@ public class Generator
|
||||
{
|
||||
case PrimitiveTypeKind.I64:
|
||||
case PrimitiveTypeKind.U64:
|
||||
case PrimitiveTypeKind.Any:
|
||||
return 8;
|
||||
case PrimitiveTypeKind.I32:
|
||||
case PrimitiveTypeKind.U32:
|
||||
@@ -304,18 +238,59 @@ public class Generator
|
||||
}
|
||||
|
||||
_builder.Append("function ");
|
||||
if (node.ReturnType.HasValue)
|
||||
if (node.ReturnType is not NubVoidType)
|
||||
{
|
||||
_builder.Append($"{QBEType(node.ReturnType.Value, TypeContext.FuncDef)} ");
|
||||
}
|
||||
else if (!node.ReturnType.HasValue && node.Name == "main")
|
||||
{
|
||||
_builder.Append("l ");
|
||||
_builder.Append(node.ReturnType switch
|
||||
{
|
||||
NubArrayType => "l",
|
||||
NubPointerType => "l",
|
||||
NubPrimitiveType primitiveType => primitiveType.Kind switch
|
||||
{
|
||||
PrimitiveTypeKind.I64 => "l",
|
||||
PrimitiveTypeKind.I32 => "w",
|
||||
PrimitiveTypeKind.I16 => "sh",
|
||||
PrimitiveTypeKind.I8 => "sb",
|
||||
PrimitiveTypeKind.U64 => "l",
|
||||
PrimitiveTypeKind.U32 => "w",
|
||||
PrimitiveTypeKind.U16 => "uh",
|
||||
PrimitiveTypeKind.U8 => "ub",
|
||||
PrimitiveTypeKind.F64 => "d",
|
||||
PrimitiveTypeKind.F32 => "s",
|
||||
PrimitiveTypeKind.Bool => "w",
|
||||
_ => throw new UnreachableException()
|
||||
},
|
||||
NubStructType structType => $":{structType.Namespace}_{structType.Name}",
|
||||
NubFixedArrayType => "l",
|
||||
_ => throw new NotSupportedException($"'{node.ReturnType}' type cannot be used as a function return type")
|
||||
});
|
||||
_builder.Append(' ');
|
||||
}
|
||||
|
||||
_builder.Append(_funcNames[node]);
|
||||
|
||||
var parameterStrings = node.Parameters.Select(parameter => parameter.Variadic ? "..." : $"{QBEType(parameter.Type, TypeContext.FuncDef)} %{parameter.Name}");
|
||||
var parameterStrings = node.Parameters.Select(parameter => parameter.Variadic ? "..." : $"{parameter.Type switch
|
||||
{
|
||||
NubArrayType => "l",
|
||||
NubPointerType => "l",
|
||||
NubPrimitiveType primitiveType => primitiveType.Kind switch
|
||||
{
|
||||
PrimitiveTypeKind.I64 => "l",
|
||||
PrimitiveTypeKind.I32 => "w",
|
||||
PrimitiveTypeKind.I16 => "sh",
|
||||
PrimitiveTypeKind.I8 => "sb",
|
||||
PrimitiveTypeKind.U64 => "l",
|
||||
PrimitiveTypeKind.U32 => "w",
|
||||
PrimitiveTypeKind.U16 => "uh",
|
||||
PrimitiveTypeKind.U8 => "ub",
|
||||
PrimitiveTypeKind.F64 => "d",
|
||||
PrimitiveTypeKind.F32 => "s",
|
||||
PrimitiveTypeKind.Bool => "w",
|
||||
_ => throw new UnreachableException()
|
||||
},
|
||||
NubStructType structType => $":{structType.Namespace}_{structType.Name}",
|
||||
NubFixedArrayType => "l",
|
||||
_ => throw new NotSupportedException($"'{parameter.Type}' type cannot be used as a function parameter type")
|
||||
}} %{parameter.Name}");
|
||||
|
||||
_builder.AppendLine($"({string.Join(", ", parameterStrings)}) {{");
|
||||
_builder.AppendLine("@start");
|
||||
@@ -324,25 +299,25 @@ public class Generator
|
||||
{
|
||||
var parameterName = parameter.Name;
|
||||
|
||||
switch (QBEType(parameter.Type, TypeContext.FuncDef))
|
||||
{
|
||||
case "sb":
|
||||
parameterName = GenVarName();
|
||||
_builder.AppendLine($" {parameterName} =w extsb %{parameter.Name}");
|
||||
break;
|
||||
case "ub":
|
||||
parameterName = GenVarName();
|
||||
_builder.AppendLine($" {parameterName} =w extub %{parameter.Name}");
|
||||
break;
|
||||
case "sh":
|
||||
parameterName = GenVarName();
|
||||
_builder.AppendLine($" {parameterName} =w extsh %{parameter.Name}");
|
||||
break;
|
||||
case "uh":
|
||||
parameterName = GenVarName();
|
||||
_builder.AppendLine($" {parameterName} =w extuh %{parameter.Name}");
|
||||
break;
|
||||
}
|
||||
// switch (QBEType(parameter.Type))
|
||||
// {
|
||||
// case "sb":
|
||||
// parameterName = GenVarName();
|
||||
// _builder.AppendLine($" {parameterName} =w extsb %{parameter.Name}");
|
||||
// break;
|
||||
// case "ub":
|
||||
// parameterName = GenVarName();
|
||||
// _builder.AppendLine($" {parameterName} =w extub %{parameter.Name}");
|
||||
// break;
|
||||
// case "sh":
|
||||
// parameterName = GenVarName();
|
||||
// _builder.AppendLine($" {parameterName} =w extsh %{parameter.Name}");
|
||||
// break;
|
||||
// case "uh":
|
||||
// parameterName = GenVarName();
|
||||
// _builder.AppendLine($" {parameterName} =w extuh %{parameter.Name}");
|
||||
// break;
|
||||
// }
|
||||
|
||||
if (IsLargeType(parameter.Type))
|
||||
{
|
||||
@@ -364,13 +339,7 @@ public class Generator
|
||||
|
||||
if (node.Body.Statements.LastOrDefault() is not ReturnNode)
|
||||
{
|
||||
if (!node.ReturnType.HasValue && node.Name == "main")
|
||||
{
|
||||
_builder.AppendLine();
|
||||
_builder.AppendLine(" # Implicit return for main");
|
||||
_builder.AppendLine(" ret 0");
|
||||
}
|
||||
else if (!node.ReturnType.HasValue)
|
||||
if (node.ReturnType is NubVoidType)
|
||||
{
|
||||
_builder.AppendLine();
|
||||
_builder.AppendLine(" # Implicit return");
|
||||
@@ -386,40 +355,34 @@ public class Generator
|
||||
_builder.Append($"type :{structDefinition.Namespace}_{structDefinition.Name} = {{ ");
|
||||
foreach (var structDefinitionField in structDefinition.Fields)
|
||||
{
|
||||
var fieldDefinition = GenerateFieldType(structDefinitionField.Type);
|
||||
_builder.Append(fieldDefinition + ", ");
|
||||
var fieldQbeType = structDefinitionField.Type switch
|
||||
{
|
||||
NubArrayType => "l",
|
||||
NubPointerType => "l",
|
||||
NubPrimitiveType primitiveType => primitiveType.Kind switch
|
||||
{
|
||||
PrimitiveTypeKind.I64 => "l",
|
||||
PrimitiveTypeKind.I32 => "w",
|
||||
PrimitiveTypeKind.I16 => "h",
|
||||
PrimitiveTypeKind.I8 => "b",
|
||||
PrimitiveTypeKind.U64 => "l",
|
||||
PrimitiveTypeKind.U32 => "w",
|
||||
PrimitiveTypeKind.U16 => "h",
|
||||
PrimitiveTypeKind.U8 => "b",
|
||||
PrimitiveTypeKind.F64 => "d",
|
||||
PrimitiveTypeKind.F32 => "s",
|
||||
PrimitiveTypeKind.Bool => "w",
|
||||
_ => throw new UnreachableException()
|
||||
},
|
||||
NubStructType structType => $":{structType.Namespace}_{structType.Name}",
|
||||
NubFixedArrayType fixedArrayType => $"b {SizeOf(fixedArrayType)}",
|
||||
_ => throw new NotSupportedException($"'{structDefinitionField.Type}' type cannot be used in structs")
|
||||
};
|
||||
_builder.Append(fieldQbeType + ", ");
|
||||
}
|
||||
_builder.AppendLine("}");
|
||||
}
|
||||
|
||||
private string GenerateFieldType(NubType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
NubArrayType => "l",
|
||||
NubPointerType => "l",
|
||||
NubPrimitiveType primitiveType => primitiveType.Kind switch
|
||||
{
|
||||
PrimitiveTypeKind.I64 => "l",
|
||||
PrimitiveTypeKind.I32 => "w",
|
||||
PrimitiveTypeKind.I16 => "h",
|
||||
PrimitiveTypeKind.I8 => "b",
|
||||
PrimitiveTypeKind.U64 => "l",
|
||||
PrimitiveTypeKind.U32 => "w",
|
||||
PrimitiveTypeKind.U16 => "h",
|
||||
PrimitiveTypeKind.U8 => "b",
|
||||
PrimitiveTypeKind.F64 => "d",
|
||||
PrimitiveTypeKind.F32 => "s",
|
||||
PrimitiveTypeKind.Bool => "w",
|
||||
PrimitiveTypeKind.Any => throw new NotSupportedException("any type cannot be used in structs"),
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
},
|
||||
NubStructType structType => $":{structType.Namespace}_{structType.Name}",
|
||||
NubFixedArrayType fixedArrayType => $"b {SizeOf(fixedArrayType)}",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(type))
|
||||
};
|
||||
}
|
||||
|
||||
private void GenerateStatement(StatementNode statement)
|
||||
{
|
||||
switch (statement)
|
||||
@@ -1739,13 +1702,35 @@ public class Generator
|
||||
var parameter = funcCall.Parameters[i];
|
||||
var result = GenerateExpression(parameter);
|
||||
|
||||
var qbeParameterType = QBEType(parameter.Type, TypeContext.FuncCall);
|
||||
var qbeParameterType = parameter.Type switch
|
||||
{
|
||||
NubArrayType => "l",
|
||||
NubPointerType => "l",
|
||||
NubPrimitiveType pointerType => pointerType.Kind switch
|
||||
{
|
||||
PrimitiveTypeKind.I64 => "l",
|
||||
PrimitiveTypeKind.I32 => "w",
|
||||
PrimitiveTypeKind.I16 => "sh",
|
||||
PrimitiveTypeKind.I8 => "sb",
|
||||
PrimitiveTypeKind.U64 => "l",
|
||||
PrimitiveTypeKind.U32 => "w",
|
||||
PrimitiveTypeKind.U16 => "uh",
|
||||
PrimitiveTypeKind.U8 => "ub",
|
||||
PrimitiveTypeKind.F64 => "d",
|
||||
PrimitiveTypeKind.F32 => "s",
|
||||
PrimitiveTypeKind.Bool => "w",
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
},
|
||||
NubStructType structType => $":{structType.Namespace}_{structType.Name}",
|
||||
NubFixedArrayType => "l",
|
||||
_ => throw new NotSupportedException($"'{parameter.Type}' type cannot be used in function calls")
|
||||
};
|
||||
parameterStrings.Add($"{qbeParameterType} {result}");
|
||||
}
|
||||
|
||||
var funcName = _funcNames[funcDefinition];
|
||||
|
||||
if (funcDefinition.ReturnType.HasValue)
|
||||
if (funcDefinition.ReturnType is not NubVoidType)
|
||||
{
|
||||
var outputName = GenVarName();
|
||||
_builder.AppendLine($" {outputName} {QBEAssign(funcCall.Type)} call {funcName}({string.Join(", ", parameterStrings)})");
|
||||
|
||||
Reference in New Issue
Block a user