...
This commit is contained in:
@@ -4,7 +4,7 @@ namespace NubLang.Generation;
|
||||
|
||||
public static class CType
|
||||
{
|
||||
public static string Create(NubType type, string? variableName = null)
|
||||
public static string Create(NubType type, string? variableName = null, bool constArraysAsPointers = true)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
@@ -16,7 +16,7 @@ public static class CType
|
||||
NubPointerType ptr => CreatePointerType(ptr, variableName),
|
||||
NubSliceType => "slice" + (variableName != null ? $" {variableName}" : ""),
|
||||
NubStringType => "string" + (variableName != null ? $" {variableName}" : ""),
|
||||
NubConstArrayType arr => CreateConstArrayType(arr, variableName),
|
||||
NubConstArrayType arr => CreateConstArrayType(arr, variableName, constArraysAsPointers),
|
||||
NubArrayType arr => CreateArrayType(arr, variableName),
|
||||
NubFuncType fn => CreateFuncType(fn, variableName),
|
||||
NubStructType st => $"{st.Module}_{st.Name}" + (variableName != null ? $" {variableName}" : ""),
|
||||
@@ -54,9 +54,16 @@ public static class CType
|
||||
return baseType + "*" + (varName != null ? $" {varName}" : "");
|
||||
}
|
||||
|
||||
private static string CreateConstArrayType(NubConstArrayType arr, string? varName)
|
||||
private static string CreateConstArrayType(NubConstArrayType arr, string? varName, bool inStructDef)
|
||||
{
|
||||
var elementType = Create(arr.ElementType);
|
||||
|
||||
// Treat const arrays as pointers unless in a struct definition
|
||||
if (!inStructDef)
|
||||
{
|
||||
return elementType + "*" + (varName != null ? $" {varName}" : "");
|
||||
}
|
||||
|
||||
if (varName != null)
|
||||
{
|
||||
return $"{elementType} {varName}[{arr.Size}]";
|
||||
|
||||
@@ -43,7 +43,7 @@ public class Generator
|
||||
typedef struct
|
||||
{
|
||||
size_t length;
|
||||
uint8_t *data;
|
||||
char *data;
|
||||
} string;
|
||||
|
||||
typedef struct
|
||||
@@ -62,7 +62,7 @@ public class Generator
|
||||
{
|
||||
foreach (var field in structType.Fields)
|
||||
{
|
||||
_writer.WriteLine($"{CType.Create(field.Type, field.Name)};");
|
||||
_writer.WriteLine($"{CType.Create(field.Type, field.Name, constArraysAsPointers: false)};");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,7 +202,7 @@ public class Generator
|
||||
_writer.WriteLine("{");
|
||||
using (_writer.Indent())
|
||||
{
|
||||
_writer.WriteLine($"{CType.Create(targetType.ElementType, forSliceNode.ElementName)} = {target}.data[{indexName}];");
|
||||
_writer.WriteLine($"{CType.Create(targetType.ElementType, forSliceNode.ElementName)} = (({CType.Create(targetType.ElementType)}*){target}.data)[{indexName}];");
|
||||
EmitBlock(forSliceNode.Body);
|
||||
}
|
||||
|
||||
@@ -337,10 +337,12 @@ public class Generator
|
||||
ArrayInitializerNode arrayInitializerNode => EmitArrayInitializer(arrayInitializerNode),
|
||||
BinaryExpressionNode binaryExpressionNode => EmitBinaryExpression(binaryExpressionNode),
|
||||
BoolLiteralNode boolLiteralNode => boolLiteralNode.Value ? "true" : "false",
|
||||
ConstArrayIndexAccessNode constArrayIndexAccessNode => EmitConstArrayIndexAccess(constArrayIndexAccessNode),
|
||||
ConstArrayInitializerNode constArrayInitializerNode => EmitConstArrayInitializer(constArrayInitializerNode),
|
||||
ConstArrayToSliceNode constArrayToSliceNode => EmitConstArrayToSlice(constArrayToSliceNode),
|
||||
ConvertCStringToStringNode convertCStringToStringNode => EmitConvertCStringToString(convertCStringToStringNode),
|
||||
ConvertFloatNode convertFloatNode => EmitConvertFloat(convertFloatNode),
|
||||
ConvertIntNode convertIntNode => EmitConvertInt(convertIntNode),
|
||||
ConvertStringToCStringNode convertStringToCStringNode => EmitConvertStringToCString(convertStringToCStringNode),
|
||||
CStringLiteralNode cStringLiteralNode => $"\"{cStringLiteralNode.Value}\"",
|
||||
DereferenceNode dereferenceNode => EmitDereference(dereferenceNode),
|
||||
Float32LiteralNode float32LiteralNode => EmitFloat32Literal(float32LiteralNode),
|
||||
@@ -372,16 +374,22 @@ public class Generator
|
||||
|
||||
private string EmitArrayIndexAccess(ArrayIndexAccessNode arrayIndexAccessNode)
|
||||
{
|
||||
var array = EmitExpression(arrayIndexAccessNode.Target);
|
||||
var target = EmitExpression(arrayIndexAccessNode.Target);
|
||||
var index = EmitExpression(arrayIndexAccessNode.Index);
|
||||
return $"{array}[{index}]";
|
||||
return $"{target}[{index}]";
|
||||
}
|
||||
|
||||
private string EmitArrayInitializer(ArrayInitializerNode arrayInitializerNode)
|
||||
{
|
||||
var capacity = EmitExpression(arrayInitializerNode.Capacity);
|
||||
var values = new List<string>();
|
||||
foreach (var value in arrayInitializerNode.Values)
|
||||
{
|
||||
values.Add(EmitExpression(value));
|
||||
}
|
||||
|
||||
var arrayType = (NubArrayType)arrayInitializerNode.Type;
|
||||
var tmp = NewTmp();
|
||||
_writer.WriteLine($"{CType.Create(arrayInitializerNode.ElementType)} {tmp}[{capacity}];");
|
||||
_writer.WriteLine($"{CType.Create(arrayType.ElementType)} {tmp}[] = {{{string.Join(", ", values)}}};");
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@@ -416,6 +424,35 @@ public class Generator
|
||||
return $"{left} {op} {right}";
|
||||
}
|
||||
|
||||
private string EmitConstArrayIndexAccess(ConstArrayIndexAccessNode constArrayIndexAccessNode)
|
||||
{
|
||||
var target = EmitExpression(constArrayIndexAccessNode.Target);
|
||||
var index = EmitExpression(constArrayIndexAccessNode.Index);
|
||||
// todo(nub31): We can emit bounds checking here
|
||||
return $"{target}[{index}]";
|
||||
}
|
||||
|
||||
private string EmitConstArrayInitializer(ConstArrayInitializerNode arrayInitializerNode)
|
||||
{
|
||||
var values = new List<string>();
|
||||
foreach (var value in arrayInitializerNode.Values)
|
||||
{
|
||||
values.Add(EmitExpression(value));
|
||||
}
|
||||
|
||||
var arrayType = (NubConstArrayType)arrayInitializerNode.Type;
|
||||
var tmp = NewTmp();
|
||||
_writer.WriteLine($"{CType.Create(arrayType.ElementType)} {tmp}[{arrayType.Size}] = {{{string.Join(", ", values)}}};");
|
||||
return tmp;
|
||||
}
|
||||
|
||||
private string EmitConstArrayToSlice(ConstArrayToSliceNode constArrayToSliceNode)
|
||||
{
|
||||
var arrayType = (NubConstArrayType)constArrayToSliceNode.Array.Type;
|
||||
var array = EmitExpression(constArrayToSliceNode.Array);
|
||||
return $"(slice){{.length = {arrayType.Size}, .data = (void*){array}}}";
|
||||
}
|
||||
|
||||
private string EmitConvertCStringToString(ConvertCStringToStringNode convertCStringToStringNode)
|
||||
{
|
||||
var value = EmitExpression(convertCStringToStringNode.Value);
|
||||
@@ -449,12 +486,6 @@ public class Generator
|
||||
return $"({targetType}){value}";
|
||||
}
|
||||
|
||||
private string EmitConvertStringToCString(ConvertStringToCStringNode convertStringToCStringNode)
|
||||
{
|
||||
var value = EmitExpression(convertStringToCStringNode.Value);
|
||||
return $"(char*){value}.data";
|
||||
}
|
||||
|
||||
private string EmitDereference(DereferenceNode dereferenceNode)
|
||||
{
|
||||
var pointer = EmitExpression(dereferenceNode.Target);
|
||||
@@ -512,10 +543,11 @@ public class Generator
|
||||
|
||||
private string EmitSliceArrayIndexAccess(SliceIndexAccessNode sliceIndexAccessNode)
|
||||
{
|
||||
var value = EmitExpression(sliceIndexAccessNode.Target);
|
||||
var targetType = (NubSliceType)sliceIndexAccessNode.Target.Type;
|
||||
var target = EmitExpression(sliceIndexAccessNode.Target);
|
||||
var index = EmitExpression(sliceIndexAccessNode.Index);
|
||||
// todo(nub31): We can emit bounds checking here
|
||||
return $"(({CType.Create(sliceIndexAccessNode.Target.Type)}){value}.data)[{index}]";
|
||||
return $"(({CType.Create(targetType.ElementType)}*){target}.data)[{index}]";
|
||||
}
|
||||
|
||||
private string EmitStringLiteral(StringLiteralNode stringLiteralNode)
|
||||
|
||||
Reference in New Issue
Block a user