...
This commit is contained in:
@@ -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(),
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|||||||
@@ -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(),
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user