WIP: dev #1
@@ -22,6 +22,19 @@ public class Generator
|
||||
#include <stdint.h>
|
||||
#include <stdlib.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
|
||||
{
|
||||
@@ -70,8 +83,8 @@ public class Generator
|
||||
{
|
||||
size_t new_length = left->length + right->length;
|
||||
|
||||
string_ptr result = (string_ptr)malloc(sizeof(string));
|
||||
result->data = (char*)malloc(new_length + 1);
|
||||
string_ptr result = (string_ptr)nub_alloc(sizeof(string));
|
||||
result->data = (char*)nub_alloc(new_length + 1);
|
||||
|
||||
memcpy(result->data, left->data, left->length);
|
||||
memcpy(result->data + left->length, right->data, right->length);
|
||||
@@ -88,8 +101,8 @@ public class Generator
|
||||
{
|
||||
size_t len = strlen(cstr);
|
||||
|
||||
string_ptr result = (string_ptr)malloc(sizeof(string));
|
||||
result->data = (char*)malloc(len + 1);
|
||||
string_ptr result = (string_ptr)nub_alloc(sizeof(string));
|
||||
result->data = (char*)nub_alloc(len + 1);
|
||||
|
||||
memcpy(result->data, cstr, len + 1);
|
||||
|
||||
@@ -105,13 +118,9 @@ public class Generator
|
||||
{ \
|
||||
if ((xs)->count >= (xs)->capacity) \
|
||||
{ \
|
||||
if ((xs)->capacity == 0) \
|
||||
(xs)->capacity = 256; \
|
||||
else \
|
||||
(xs)->capacity *= 2; \
|
||||
(xs)->items = realloc((xs)->items, (xs)->capacity * sizeof(*(xs)->items)); \
|
||||
} \
|
||||
\
|
||||
(xs)->items[(xs)->count++] = (x); \
|
||||
} while (0)
|
||||
|
||||
@@ -405,6 +414,7 @@ public class Generator
|
||||
}
|
||||
writer.WriteLine("}");
|
||||
writer.WriteLine();
|
||||
writer.WriteLine("free(array->items);");
|
||||
writer.WriteLine("free(array);");
|
||||
}
|
||||
writer.WriteLine("}");
|
||||
@@ -416,11 +426,11 @@ public class Generator
|
||||
writer.WriteLine("{");
|
||||
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->count = 0;");
|
||||
writer.WriteLine("array->capacity = 0;");
|
||||
writer.WriteLine("array->items = NULL;");
|
||||
writer.WriteLine("array->capacity = 10;");
|
||||
writer.WriteLine($"array->items = ({TypeName(arrayType.ElementType)}*)nub_alloc(sizeof({TypeName(arrayType.ElementType)}) * array->capacity);");
|
||||
writer.WriteLine("return array;");
|
||||
}
|
||||
writer.WriteLine("}");
|
||||
@@ -856,6 +866,7 @@ public class Generator
|
||||
NubTypeUInt t => $"uint{t.Width}_t",
|
||||
NubTypePointer => Tmp(),
|
||||
NubTypeString => "string_ptr",
|
||||
NubTypeChar => "char",
|
||||
NubTypeFunc => Tmp(),
|
||||
NubTypeArray => Tmp(),
|
||||
_ => throw new NotImplementedException(),
|
||||
|
||||
@@ -210,6 +210,7 @@ public class ModuleGraph
|
||||
NodeTypeSInt type => NubTypeSInt.Get(type.Width),
|
||||
NodeTypeUInt type => NubTypeUInt.Get(type.Width),
|
||||
NodeTypeString => NubTypeString.Instance,
|
||||
NodeTypeChar => NubTypeChar.Instance,
|
||||
NodeTypeVoid => NubTypeVoid.Instance,
|
||||
NodeTypeArray type => NubTypeArray.Get(ResolveType(type.ElementType, currentModule)),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(node))
|
||||
|
||||
@@ -102,6 +102,17 @@ public class NubTypeString : NubType
|
||||
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
|
||||
{
|
||||
private static readonly Dictionary<(string Module, string Name), NubTypeStruct> Cache = new();
|
||||
@@ -324,6 +335,10 @@ public class TypeEncoder
|
||||
sb.Append('S');
|
||||
break;
|
||||
|
||||
case NubTypeChar:
|
||||
sb.Append('C');
|
||||
break;
|
||||
|
||||
case NubTypePointer p:
|
||||
sb.Append("P(");
|
||||
EncodeType(sb, p.To);
|
||||
@@ -420,6 +435,7 @@ public class TypeDecoder
|
||||
'U' => DecodeUInt(),
|
||||
'I' => DecodeSInt(),
|
||||
'S' => NubTypeString.Instance,
|
||||
'C' => NubTypeChar.Instance,
|
||||
'P' => DecodePointer(),
|
||||
'F' => DecodeFunc(),
|
||||
'T' => DecodeStruct(),
|
||||
|
||||
@@ -561,6 +561,8 @@ public class Parser
|
||||
return new NodeTypeVoid(TokensFrom(startIndex));
|
||||
case "string":
|
||||
return new NodeTypeString(TokensFrom(startIndex));
|
||||
case "char":
|
||||
return new NodeTypeChar(TokensFrom(startIndex));
|
||||
case "bool":
|
||||
return new NodeTypeBool(TokensFrom(startIndex));
|
||||
case "i8":
|
||||
@@ -1060,6 +1062,8 @@ public class NodeTypeBool(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 List<TokenIdent> Sections { get; } = sections;
|
||||
|
||||
@@ -151,13 +151,13 @@ var outFile = Generator.Emit(functions, moduleGraph, entryPoint);
|
||||
|
||||
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();
|
||||
NubLib.Pack(".build/out.nublib", ".build/out.a", Manifest.Create(moduleGraph));
|
||||
}
|
||||
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;
|
||||
|
||||
@@ -494,7 +494,7 @@ public class TypeChecker
|
||||
case "length":
|
||||
return new TypedNodeExpressionStringLength(expression.Tokens, NubTypeUInt.Get(64), target);
|
||||
case "ptr":
|
||||
return new TypedNodeExpressionStringPointer(expression.Tokens, NubTypePointer.Get(NubTypeUInt.Get(8)), target);
|
||||
return new TypedNodeExpressionStringPointer(expression.Tokens, NubTypePointer.Get(NubTypeChar.Instance), target);
|
||||
default:
|
||||
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)
|
||||
{
|
||||
var stringPoitnerType = NubTypePointer.Get(NubTypeUInt.Get(8));
|
||||
var stringPoitnerType = NubTypePointer.Get(NubTypeChar.Instance);
|
||||
|
||||
var value = CheckExpression(expression.Value, stringPoitnerType);
|
||||
if (!value.Type.IsAssignableTo(stringPoitnerType))
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
module sys
|
||||
|
||||
export extern func read(fd: u32, buf: ^u8, count: u64): i64
|
||||
export extern func write(fd: u32, buf: ^u8, count: u64): i64
|
||||
export extern func open(fileName: ^u8, flags: i32, mode: u16): i64
|
||||
export extern func read(fd: u32, buf: ^char, count: u64): i64
|
||||
export extern func write(fd: u32, buf: ^char, count: u64): i64
|
||||
export extern func open(fileName: ^char, flags: i32, mode: u16): i64
|
||||
|
||||
Reference in New Issue
Block a user