Merge pull request #144 from birth-software/more-self-hosted-work
More self-hosted work
This commit is contained in:
commit
ebcb452b9d
File diff suppressed because it is too large
Load Diff
@ -1328,6 +1328,7 @@ pub const LLVM = struct {
|
|||||||
const array_type = LLVM.Type.Array.get(element_type, array.count + @intFromBool(extra_element)) orelse return Type.Error.array;
|
const array_type = LLVM.Type.Array.get(element_type, array.count + @intFromBool(extra_element)) orelse return Type.Error.array;
|
||||||
break :blk array_type.toType();
|
break :blk array_type.toType();
|
||||||
},
|
},
|
||||||
|
.any => (llvm.pointer_type orelse unreachable).toType(),
|
||||||
else => |t| @panic(@tagName(t)),
|
else => |t| @panic(@tagName(t)),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -154,7 +154,6 @@ pub extern fn NativityLLVMRunOptimizationPipeline(module: *LLVM.Module, target_m
|
|||||||
pub extern fn NativityLLVMModuleAddPassesToEmitFile(module: *LLVM.Module, target_machine: *LLVM.Target.Machine, object_file_path_ptr: [*]const u8, object_file_path_len: usize, codegen_file_type: LLVM.CodeGenFileType, disable_verify: bool) bool;
|
pub extern fn NativityLLVMModuleAddPassesToEmitFile(module: *LLVM.Module, target_machine: *LLVM.Target.Machine, object_file_path_ptr: [*]const u8, object_file_path_len: usize, codegen_file_type: LLVM.CodeGenFileType, disable_verify: bool) bool;
|
||||||
pub extern fn NativityLLVMTypeAssertEqual(a: *LLVM.Type, b: *LLVM.Type) void;
|
pub extern fn NativityLLVMTypeAssertEqual(a: *LLVM.Type, b: *LLVM.Type) void;
|
||||||
|
|
||||||
|
|
||||||
pub extern fn LLVMInitializeAArch64TargetInfo() void;
|
pub extern fn LLVMInitializeAArch64TargetInfo() void;
|
||||||
pub extern fn LLVMInitializeAMDGPUTargetInfo() void;
|
pub extern fn LLVMInitializeAMDGPUTargetInfo() void;
|
||||||
pub extern fn LLVMInitializeARMTargetInfo() void;
|
pub extern fn LLVMInitializeARMTargetInfo() void;
|
||||||
|
@ -98,6 +98,7 @@ pub const Node = struct {
|
|||||||
slice_type,
|
slice_type,
|
||||||
array_type,
|
array_type,
|
||||||
argument_declaration,
|
argument_declaration,
|
||||||
|
comptime_argument_declaration,
|
||||||
intrinsic,
|
intrinsic,
|
||||||
ssize_type,
|
ssize_type,
|
||||||
usize_type,
|
usize_type,
|
||||||
@ -202,6 +203,7 @@ pub const Node = struct {
|
|||||||
for_expressions,
|
for_expressions,
|
||||||
slice_metadata,
|
slice_metadata,
|
||||||
orelse_expression,
|
orelse_expression,
|
||||||
|
type,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -479,6 +481,13 @@ const Analyzer = struct {
|
|||||||
|
|
||||||
while (analyzer.peekToken() != end_token) {
|
while (analyzer.peekToken() != end_token) {
|
||||||
const identifier_token = analyzer.token_i;
|
const identifier_token = analyzer.token_i;
|
||||||
|
const id: Node.Id = switch (analyzer.peekToken()) {
|
||||||
|
.operator_dollar => b: {
|
||||||
|
analyzer.consumeToken();
|
||||||
|
break :b .comptime_argument_declaration;
|
||||||
|
},
|
||||||
|
else => .argument_declaration,
|
||||||
|
};
|
||||||
switch (analyzer.peekToken()) {
|
switch (analyzer.peekToken()) {
|
||||||
.identifier, .discard => analyzer.consumeToken(),
|
.identifier, .discard => analyzer.consumeToken(),
|
||||||
else => |t| @panic(@tagName(t)),
|
else => |t| @panic(@tagName(t)),
|
||||||
@ -491,7 +500,7 @@ const Analyzer = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try list.append(analyzer.my_allocator, try analyzer.addNode(.{
|
try list.append(analyzer.my_allocator, try analyzer.addNode(.{
|
||||||
.id = .argument_declaration,
|
.id = id,
|
||||||
.token = identifier_token,
|
.token = identifier_token,
|
||||||
.left = type_expression,
|
.left = type_expression,
|
||||||
.right = Node.Index.null,
|
.right = Node.Index.null,
|
||||||
@ -805,17 +814,12 @@ const Analyzer = struct {
|
|||||||
break :b else_expression;
|
break :b else_expression;
|
||||||
} else .null;
|
} else .null;
|
||||||
|
|
||||||
const for_node = try analyzer.addNode(.{
|
const for_node = try analyzer.addNode(.{ .id = .for_loop, .token = token, .left = for_condition_node, .right = try analyzer.addNode(.{
|
||||||
.id = .for_loop,
|
.id = .for_expressions,
|
||||||
.token = token,
|
.token = .null,
|
||||||
.left = for_condition_node,
|
.left = true_expression,
|
||||||
.right = try analyzer.addNode(.{
|
.right = else_expression,
|
||||||
.id = .for_expressions,
|
}) });
|
||||||
.token = .null,
|
|
||||||
.left = true_expression,
|
|
||||||
.right = else_expression,
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
return for_node;
|
return for_node;
|
||||||
}
|
}
|
||||||
@ -1142,6 +1146,7 @@ const Analyzer = struct {
|
|||||||
.fixed_keyword_else,
|
.fixed_keyword_else,
|
||||||
.identifier,
|
.identifier,
|
||||||
.discard,
|
.discard,
|
||||||
|
.fixed_keyword_test,
|
||||||
=> break,
|
=> break,
|
||||||
.operator_compare_equal => .compare_equal,
|
.operator_compare_equal => .compare_equal,
|
||||||
.operator_compare_not_equal => .compare_not_equal,
|
.operator_compare_not_equal => .compare_not_equal,
|
||||||
@ -1517,7 +1522,8 @@ const Analyzer = struct {
|
|||||||
if (analyzer.peekToken() == .operator_asterisk and analyzer.peekTokenAhead(1) == .operator_bang) {
|
if (analyzer.peekToken() == .operator_asterisk and analyzer.peekTokenAhead(1) == .operator_bang) {
|
||||||
const asterisk = try analyzer.expectToken(.operator_asterisk);
|
const asterisk = try analyzer.expectToken(.operator_asterisk);
|
||||||
analyzer.consumeToken();
|
analyzer.consumeToken();
|
||||||
const type_node = try analyzer.suffixExpression();
|
// if (analyzer.peekToken() == .operator_left_bracket) @breakpoint();
|
||||||
|
const type_node = try analyzer.typeExpression();
|
||||||
|
|
||||||
const all_errors_node = try analyzer.addNode(.{
|
const all_errors_node = try analyzer.addNode(.{
|
||||||
.id = .all_errors,
|
.id = .all_errors,
|
||||||
@ -1905,6 +1911,15 @@ const Analyzer = struct {
|
|||||||
const token = analyzer.peekToken();
|
const token = analyzer.peekToken();
|
||||||
|
|
||||||
return try switch (token) {
|
return try switch (token) {
|
||||||
|
.fixed_keyword_type => try analyzer.addNode(.{
|
||||||
|
.id = .type,
|
||||||
|
.token = b: {
|
||||||
|
analyzer.consumeToken();
|
||||||
|
break :b token_i;
|
||||||
|
},
|
||||||
|
.left = .null,
|
||||||
|
.right = .null,
|
||||||
|
}),
|
||||||
.fixed_keyword_any => try analyzer.addNode(.{
|
.fixed_keyword_any => try analyzer.addNode(.{
|
||||||
.id = .any,
|
.id = .any,
|
||||||
.token = b: {
|
.token = b: {
|
||||||
|
@ -424,7 +424,7 @@ fn compile_self_hosted(allocator: Allocator, args: struct {
|
|||||||
is_test: bool,
|
is_test: bool,
|
||||||
optimization: Optimization,
|
optimization: Optimization,
|
||||||
}) ![]const u8 {
|
}) ![]const u8 {
|
||||||
const name = try std.mem.concat(allocator, u8, &.{self_hosted_exe_name, "_", @tagName(args.optimization)});
|
const name = try std.mem.concat(allocator, u8, &.{ self_hosted_exe_name, "_", @tagName(args.optimization) });
|
||||||
const compile_run = try std.ChildProcess.run(.{
|
const compile_run = try std.ChildProcess.run(.{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
// TODO: delete -main_source_file?
|
// TODO: delete -main_source_file?
|
||||||
@ -450,10 +450,10 @@ fn compile_self_hosted(allocator: Allocator, args: struct {
|
|||||||
return err;
|
return err;
|
||||||
};
|
};
|
||||||
|
|
||||||
return try std.mem.concat(allocator, u8, &.{"nat/", name});
|
return try std.mem.concat(allocator, u8, &.{ "nat/", name });
|
||||||
}
|
}
|
||||||
|
|
||||||
const Optimization = enum{
|
const Optimization = enum {
|
||||||
none,
|
none,
|
||||||
debug_prefer_fast,
|
debug_prefer_fast,
|
||||||
debug_prefer_size,
|
debug_prefer_size,
|
||||||
@ -469,7 +469,7 @@ fn run_test_suite(allocator: Allocator, args: struct {
|
|||||||
compiler_path: []const u8,
|
compiler_path: []const u8,
|
||||||
}) bool {
|
}) bool {
|
||||||
const self_hosted = args.self_hosted;
|
const self_hosted = args.self_hosted;
|
||||||
std.debug.print("TESTING {s} COMPILER: {s}...\n=================\n", .{if (self_hosted) "SELF-HOSTED" else "BOOTSTRAP", args.compiler_path});
|
std.debug.print("TESTING {s} COMPILER: {s}...\n=================\n", .{ if (self_hosted) "SELF-HOSTED" else "BOOTSTRAP", args.compiler_path });
|
||||||
var errors = false;
|
var errors = false;
|
||||||
|
|
||||||
runStandalone(allocator, .{
|
runStandalone(allocator, .{
|
||||||
|
@ -512,6 +512,22 @@ const memfd_create = fn(name: [&:0]const u8, flags: u32) MemFdCreateError!FileDe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const basename = fn (path: []const u8) ?[]const u8 {
|
||||||
|
var i: usize = path.length;
|
||||||
|
|
||||||
|
while (i > 0) {
|
||||||
|
i -= 1;
|
||||||
|
|
||||||
|
if (path[i] == '/') {
|
||||||
|
i = i + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const p = path[i..];
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
const IoChannelBehavior = enum{
|
const IoChannelBehavior = enum{
|
||||||
pipe,
|
pipe,
|
||||||
close,
|
close,
|
||||||
|
@ -113,8 +113,10 @@ const Arena = struct{
|
|||||||
};
|
};
|
||||||
|
|
||||||
const commit_granularity = 2 * 1024 * 1024;
|
const commit_granularity = 2 * 1024 * 1024;
|
||||||
|
const reserve = os.reserve;
|
||||||
|
const commit = os.commit;
|
||||||
|
|
||||||
const allocate = fn (requested_size: u64) *!&Arena {
|
const init = fn (requested_size: u64) *!&Arena {
|
||||||
var size = requested_size;
|
var size = requested_size;
|
||||||
const size_roundup_granularity = megabytes(64);
|
const size_roundup_granularity = megabytes(64);
|
||||||
size += size_roundup_granularity - 1;
|
size += size_roundup_granularity - 1;
|
||||||
@ -122,8 +124,8 @@ const Arena = struct{
|
|||||||
const initial_commit_size = commit_granularity;
|
const initial_commit_size = commit_granularity;
|
||||||
assert(initial_commit_size >= #size(Arena));
|
assert(initial_commit_size >= #size(Arena));
|
||||||
|
|
||||||
const reserved_memory = try os.reserve(size);
|
const reserved_memory = try reserve(size);
|
||||||
try os.commit(reserved_memory, initial_commit_size);
|
try commit(reserved_memory, initial_commit_size);
|
||||||
|
|
||||||
const arena: &Arena = #cast(reserved_memory);
|
const arena: &Arena = #cast(reserved_memory);
|
||||||
arena.@ = .{
|
arena.@ = .{
|
||||||
@ -135,6 +137,40 @@ const Arena = struct{
|
|||||||
|
|
||||||
return arena;
|
return arena;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const allocate = fn (arena: &Arena, size: u64) *!&any {
|
||||||
|
|
||||||
|
if (arena.position + size <= arena.size) {
|
||||||
|
const base: &any = #cast(arena);
|
||||||
|
var post_alignment_position = arena.position + arena.alignment - 1;
|
||||||
|
post_alignment_position -= post_alignment_position % arena.alignment;
|
||||||
|
const alignment = post_alignment_position - arena.position;
|
||||||
|
const result = base + arena.position + alignment;
|
||||||
|
arena.position += size + alignment;
|
||||||
|
|
||||||
|
if (arena.commit_position < arena.position - arena.commit_position) {
|
||||||
|
var size_to_commit = arena.position - arena.commit_position;
|
||||||
|
size_to_commit += commit_granularity - 1;
|
||||||
|
size_to_commit -= size_to_commit % commit_granularity;
|
||||||
|
try commit(base + arena.commit_position, size_to_commit);
|
||||||
|
arena.commit_position += size_to_commit;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const new = fn (arena: &Arena, $T: type) *!&T {
|
||||||
|
const result: &T = #cast(arena.allocate(#size(T)));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
const new_array = fn (arena: &Arena, $T: type, count: usize) *![]T {
|
||||||
|
const result: [&]T = #cast(try arena.allocate(#size(T) * count));
|
||||||
|
return result[0..count];
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const Writer = struct{
|
const Writer = struct{
|
||||||
@ -181,8 +217,38 @@ const c_len = fn (pointer_to_string: [&:0]const u8) usize {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const c_slice = fn (pointer_to_string: [&:0]const u8) [:0]const u8 {
|
const c_slice = fn (pointer_to_string: [&:0]const u8) [:0]const u8 {
|
||||||
const len = c_len(pointer_to_string);
|
const length = c_len(pointer_to_string);
|
||||||
return pointer_to_string[0..len:0];
|
return pointer_to_string[0..length:0];
|
||||||
|
}
|
||||||
|
|
||||||
|
const concatenate_bytes = fn (arena: &Arena, byte_sequences: []const []const u8) *![]u8 {
|
||||||
|
var byte_count: usize = 0;
|
||||||
|
for (byte_sequences) |byte_sequence| {
|
||||||
|
byte_count += byte_sequence.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
var concatenation = try arena.new_array($u8, byte_count);
|
||||||
|
var offset: usize = 0;
|
||||||
|
|
||||||
|
for (byte_sequences) |bs| {
|
||||||
|
var i: usize = 0;
|
||||||
|
|
||||||
|
while (i < bs.length) {
|
||||||
|
concatenation[offset + i] = bs[i];
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return concatenation;
|
||||||
|
}
|
||||||
|
|
||||||
|
test "concatenate" {
|
||||||
|
var arena = try Arena.init(2*1024*1024);
|
||||||
|
const concatenation = try concatenate_bytes(arena, .{ "ABC", "DEF" }.&);
|
||||||
|
const are_equal = byte_equal(concatenation, "ABCDEF");
|
||||||
|
try testing.expect(are_equal);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Target = struct {
|
const Target = struct {
|
||||||
|
12
src/main.nat
12
src/main.nat
@ -34,11 +34,17 @@ const get_argument = fn (real_argument: []const u8, wanted_argument: []const u8,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: turn this into a block with result
|
||||||
|
const make_output_path = fn (main_source_file_path: []const u8) []const u8 {
|
||||||
|
assert(main_source_file_path.length > 0);
|
||||||
|
}
|
||||||
|
|
||||||
const command_exe = fn (arena: &Arena, command_arguments: []const [&:0]const u8) void {
|
const command_exe = fn (arena: &Arena, command_arguments: []const [&:0]const u8) void {
|
||||||
var i: usize = 0;
|
var i: usize = 0;
|
||||||
|
|
||||||
var maybe_output_argument: ?[]const u8 = null;
|
var maybe_output_argument: ?[]const u8 = null;
|
||||||
var maybe_main_source_file: ?[]const u8 = null;
|
var maybe_main_source_file: ?[]const u8 = null;
|
||||||
|
var maybe_main_executable_name: ?[]const u8 = null;
|
||||||
|
|
||||||
while (i < command_arguments.length) {
|
while (i < command_arguments.length) {
|
||||||
const command_argument = c_slice(command_arguments[i]);
|
const command_argument = c_slice(command_arguments[i]);
|
||||||
@ -61,10 +67,14 @@ const command_exe = fn (arena: &Arena, command_arguments: []const [&:0]const u8)
|
|||||||
print("error: no main source file specified\n");
|
print("error: no main source file specified\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const main_executable_name = maybe_main_executable_name orelse (std.os.basename(main_source_file[0..main_source_file.length - 9]) orelse unreachable); // 9 => "/main.nat".length
|
||||||
|
|
||||||
|
print("Foo\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
const main = fn() *!void {
|
const main = fn() *!void {
|
||||||
const arena = try Arena.allocate(std.megabytes(64));
|
const arena = try Arena.init(std.megabytes(64));
|
||||||
const argument_count = std.start.argument_count;
|
const argument_count = std.start.argument_count;
|
||||||
|
|
||||||
if (argument_count <= 1) {
|
if (argument_count <= 1) {
|
||||||
|
12
test/standalone/concatenate/main.nat
Normal file
12
test/standalone/concatenate/main.nat
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
const std = #import("std");
|
||||||
|
const Arena = std.Arena;
|
||||||
|
const concatenate_bytes = std.concatenate_bytes;
|
||||||
|
const byte_equal = std.byte_equal;
|
||||||
|
const expect = std.testing.expect;
|
||||||
|
|
||||||
|
const main = fn () *!void {
|
||||||
|
var arena = try Arena.init(2*1024*1024);
|
||||||
|
const concatenation = try concatenate_bytes(arena, .{ "ABC", "DEF" }.&);
|
||||||
|
const are_equal = byte_equal(concatenation, "ABCDEF");
|
||||||
|
try expect(are_equal);
|
||||||
|
}
|
@ -2,5 +2,5 @@ const std = #import("std");
|
|||||||
const Arena = std.Arena;
|
const Arena = std.Arena;
|
||||||
|
|
||||||
const main = fn() *!void {
|
const main = fn() *!void {
|
||||||
var arena = try Arena.allocate(2*1024*1024);
|
var arena = try Arena.init(2*1024*1024);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user