This commit is contained in:
nub31
2026-03-16 18:10:03 +01:00
parent bdeb2c4d73
commit bc65c3f4fd
7 changed files with 55 additions and 23 deletions

View File

@@ -22,6 +22,19 @@ public class Generator
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdio.h>
static inline void *nub_alloc(size_t size)
{
void *mem = malloc(size);
if (mem == NULL)
{
puts("Out of memory");
exit(1);
}
return mem;
}
typedef struct typedef struct
{ {
@@ -70,8 +83,8 @@ public class Generator
{ {
size_t new_length = left->length + right->length; size_t new_length = left->length + right->length;
string_ptr result = (string_ptr)malloc(sizeof(string)); string_ptr result = (string_ptr)nub_alloc(sizeof(string));
result->data = (char*)malloc(new_length + 1); result->data = (char*)nub_alloc(new_length + 1);
memcpy(result->data, left->data, left->length); memcpy(result->data, left->data, left->length);
memcpy(result->data + left->length, right->data, right->length); memcpy(result->data + left->length, right->data, right->length);
@@ -88,8 +101,8 @@ public class Generator
{ {
size_t len = strlen(cstr); size_t len = strlen(cstr);
string_ptr result = (string_ptr)malloc(sizeof(string)); string_ptr result = (string_ptr)nub_alloc(sizeof(string));
result->data = (char*)malloc(len + 1); result->data = (char*)nub_alloc(len + 1);
memcpy(result->data, cstr, len + 1); memcpy(result->data, cstr, len + 1);
@@ -105,13 +118,9 @@ public class Generator
{ \ { \
if ((xs)->count >= (xs)->capacity) \ if ((xs)->count >= (xs)->capacity) \
{ \ { \
if ((xs)->capacity == 0) \
(xs)->capacity = 256; \
else \
(xs)->capacity *= 2; \ (xs)->capacity *= 2; \
(xs)->items = realloc((xs)->items, (xs)->capacity * sizeof(*(xs)->items)); \ (xs)->items = realloc((xs)->items, (xs)->capacity * sizeof(*(xs)->items)); \
} \ } \
\
(xs)->items[(xs)->count++] = (x); \ (xs)->items[(xs)->count++] = (x); \
} while (0) } while (0)
@@ -405,6 +414,7 @@ public class Generator
} }
writer.WriteLine("}"); writer.WriteLine("}");
writer.WriteLine(); writer.WriteLine();
writer.WriteLine("free(array->items);");
writer.WriteLine("free(array);"); writer.WriteLine("free(array);");
} }
writer.WriteLine("}"); writer.WriteLine("}");
@@ -416,11 +426,11 @@ public class Generator
writer.WriteLine("{"); writer.WriteLine("{");
using (writer.Indent()) using (writer.Indent())
{ {
writer.WriteLine($"{name} array = ({name})malloc(sizeof({backingName}));"); writer.WriteLine($"{name} array = ({name})nub_alloc(sizeof({backingName}));");
writer.WriteLine("array->ref = 1;"); writer.WriteLine("array->ref = 1;");
writer.WriteLine("array->count = 0;"); writer.WriteLine("array->count = 0;");
writer.WriteLine("array->capacity = 0;"); writer.WriteLine("array->capacity = 10;");
writer.WriteLine("array->items = NULL;"); writer.WriteLine($"array->items = ({TypeName(arrayType.ElementType)}*)nub_alloc(sizeof({TypeName(arrayType.ElementType)}) * array->capacity);");
writer.WriteLine("return array;"); writer.WriteLine("return array;");
} }
writer.WriteLine("}"); writer.WriteLine("}");
@@ -856,6 +866,7 @@ public class Generator
NubTypeUInt t => $"uint{t.Width}_t", NubTypeUInt t => $"uint{t.Width}_t",
NubTypePointer => Tmp(), NubTypePointer => Tmp(),
NubTypeString => "string_ptr", NubTypeString => "string_ptr",
NubTypeChar => "char",
NubTypeFunc => Tmp(), NubTypeFunc => Tmp(),
NubTypeArray => Tmp(), NubTypeArray => Tmp(),
_ => throw new NotImplementedException(), _ => throw new NotImplementedException(),

View File

@@ -210,6 +210,7 @@ public class ModuleGraph
NodeTypeSInt type => NubTypeSInt.Get(type.Width), NodeTypeSInt type => NubTypeSInt.Get(type.Width),
NodeTypeUInt type => NubTypeUInt.Get(type.Width), NodeTypeUInt type => NubTypeUInt.Get(type.Width),
NodeTypeString => NubTypeString.Instance, NodeTypeString => NubTypeString.Instance,
NodeTypeChar => NubTypeChar.Instance,
NodeTypeVoid => NubTypeVoid.Instance, NodeTypeVoid => NubTypeVoid.Instance,
NodeTypeArray type => NubTypeArray.Get(ResolveType(type.ElementType, currentModule)), NodeTypeArray type => NubTypeArray.Get(ResolveType(type.ElementType, currentModule)),
_ => throw new ArgumentOutOfRangeException(nameof(node)) _ => throw new ArgumentOutOfRangeException(nameof(node))

View File

@@ -102,6 +102,17 @@ public class NubTypeString : NubType
public override string ToString() => "string"; public override string ToString() => "string";
} }
public class NubTypeChar : NubType
{
public static readonly NubTypeChar Instance = new();
private NubTypeChar()
{
}
public override string ToString() => "char";
}
public class NubTypeStruct : NubType public class NubTypeStruct : NubType
{ {
private static readonly Dictionary<(string Module, string Name), NubTypeStruct> Cache = new(); private static readonly Dictionary<(string Module, string Name), NubTypeStruct> Cache = new();
@@ -324,6 +335,10 @@ public class TypeEncoder
sb.Append('S'); sb.Append('S');
break; break;
case NubTypeChar:
sb.Append('C');
break;
case NubTypePointer p: case NubTypePointer p:
sb.Append("P("); sb.Append("P(");
EncodeType(sb, p.To); EncodeType(sb, p.To);
@@ -420,6 +435,7 @@ public class TypeDecoder
'U' => DecodeUInt(), 'U' => DecodeUInt(),
'I' => DecodeSInt(), 'I' => DecodeSInt(),
'S' => NubTypeString.Instance, 'S' => NubTypeString.Instance,
'C' => NubTypeChar.Instance,
'P' => DecodePointer(), 'P' => DecodePointer(),
'F' => DecodeFunc(), 'F' => DecodeFunc(),
'T' => DecodeStruct(), 'T' => DecodeStruct(),

View File

@@ -561,6 +561,8 @@ public class Parser
return new NodeTypeVoid(TokensFrom(startIndex)); return new NodeTypeVoid(TokensFrom(startIndex));
case "string": case "string":
return new NodeTypeString(TokensFrom(startIndex)); return new NodeTypeString(TokensFrom(startIndex));
case "char":
return new NodeTypeChar(TokensFrom(startIndex));
case "bool": case "bool":
return new NodeTypeBool(TokensFrom(startIndex)); return new NodeTypeBool(TokensFrom(startIndex));
case "i8": case "i8":
@@ -1060,6 +1062,8 @@ public class NodeTypeBool(List<Token> tokens) : NodeType(tokens);
public class NodeTypeString(List<Token> tokens) : NodeType(tokens); public class NodeTypeString(List<Token> tokens) : NodeType(tokens);
public class NodeTypeChar(List<Token> tokens) : NodeType(tokens);
public class NodeTypeNamed(List<Token> tokens, List<TokenIdent> sections) : NodeType(tokens) public class NodeTypeNamed(List<Token> tokens, List<TokenIdent> sections) : NodeType(tokens)
{ {
public List<TokenIdent> Sections { get; } = sections; public List<TokenIdent> Sections { get; } = sections;

View File

@@ -151,13 +151,13 @@ var outFile = Generator.Emit(functions, moduleGraph, entryPoint);
if (compileLib) if (compileLib)
{ {
Process.Start("gcc", ["-Og", "-g", "-fno-builtin", "-c", "-o", ".build/out.o", outFile, .. archivePaths]).WaitForExit(); Process.Start("gcc", ["-Og", "-g", "-Wall", "-Werror", "-c", "-o", ".build/out.o", outFile, .. archivePaths]).WaitForExit();
Process.Start("ar", ["rcs", ".build/out.a", ".build/out.o"]).WaitForExit(); Process.Start("ar", ["rcs", ".build/out.a", ".build/out.o"]).WaitForExit();
NubLib.Pack(".build/out.nublib", ".build/out.a", Manifest.Create(moduleGraph)); NubLib.Pack(".build/out.nublib", ".build/out.a", Manifest.Create(moduleGraph));
} }
else else
{ {
Process.Start("gcc", ["-Og", "-g", "-fno-builtin", "-o", ".build/out", outFile, .. archivePaths]).WaitForExit(); Process.Start("gcc", ["-Og", "-g", "-Wall", "-Werror", "-o", ".build/out", outFile, .. archivePaths]).WaitForExit();
} }
return 0; return 0;

View File

@@ -494,7 +494,7 @@ public class TypeChecker
case "length": case "length":
return new TypedNodeExpressionStringLength(expression.Tokens, NubTypeUInt.Get(64), target); return new TypedNodeExpressionStringLength(expression.Tokens, NubTypeUInt.Get(64), target);
case "ptr": case "ptr":
return new TypedNodeExpressionStringPointer(expression.Tokens, NubTypePointer.Get(NubTypeUInt.Get(8)), target); return new TypedNodeExpressionStringPointer(expression.Tokens, NubTypePointer.Get(NubTypeChar.Instance), target);
default: default:
throw BasicError($"'{expression.Name.Ident}' is not a member of type {stringType}", expression.Name); throw BasicError($"'{expression.Name.Ident}' is not a member of type {stringType}", expression.Name);
} }
@@ -684,7 +684,7 @@ public class TypeChecker
private TypedNodeExpressionStringConstructor CheckExpressionStringConstructor(NodeExpressionStringConstructor expression, NubType? expectedType) private TypedNodeExpressionStringConstructor CheckExpressionStringConstructor(NodeExpressionStringConstructor expression, NubType? expectedType)
{ {
var stringPoitnerType = NubTypePointer.Get(NubTypeUInt.Get(8)); var stringPoitnerType = NubTypePointer.Get(NubTypeChar.Instance);
var value = CheckExpression(expression.Value, stringPoitnerType); var value = CheckExpression(expression.Value, stringPoitnerType);
if (!value.Type.IsAssignableTo(stringPoitnerType)) if (!value.Type.IsAssignableTo(stringPoitnerType))

View File

@@ -1,5 +1,5 @@
module sys module sys
export extern func read(fd: u32, buf: ^u8, count: u64): i64 export extern func read(fd: u32, buf: ^char, count: u64): i64
export extern func write(fd: u32, buf: ^u8, count: u64): i64 export extern func write(fd: u32, buf: ^char, count: u64): i64
export extern func open(fileName: ^u8, flags: i32, mode: u16): i64 export extern func open(fileName: ^char, flags: i32, mode: u16): i64