Merge pull request #93 from birth-software/fix-macos-build
fix macos build
This commit is contained in:
commit
3a78cfe11d
@ -36,6 +36,13 @@ fn reportUnterminatedArgumentError(string: []const u8) noreturn {
|
|||||||
std.debug.panic("Unterminated argument: {s}", .{string});
|
std.debug.panic("Unterminated argument: {s}", .{string});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Error = struct{
|
||||||
|
message: []const u8,
|
||||||
|
node: Node.Index,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub fn createContext(allocator: Allocator) !*const Context{
|
pub fn createContext(allocator: Allocator) !*const Context{
|
||||||
const context: *Context = try allocator.create(Context);
|
const context: *Context = try allocator.create(Context);
|
||||||
|
|
||||||
@ -69,25 +76,38 @@ pub fn compileBuildExecutable(context: *const Context, arguments: [][:0]u8) !voi
|
|||||||
.link_libc = @import("builtin").os.tag == .macos,
|
.link_libc = @import("builtin").os.tag == .macos,
|
||||||
.generate_debug_information = true,
|
.generate_debug_information = true,
|
||||||
.name = "build",
|
.name = "build",
|
||||||
|
.is_test = false,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
try unit.compile(context);
|
try unit.compile(context);
|
||||||
|
const argv: []const []const u8 = &.{ "nat/build", "-compiler_path", context.executable_absolute_path };
|
||||||
const result = try std.ChildProcess.run(.{
|
const result = try std.ChildProcess.run(.{
|
||||||
.allocator = context.allocator,
|
.allocator = context.allocator,
|
||||||
.argv = &.{ "nat/build", "-compiler_path", context.executable_absolute_path },
|
.argv = argv,
|
||||||
});
|
});
|
||||||
switch (result.term) {
|
|
||||||
.Exited => |exit_code| {
|
const success = switch (result.term) {
|
||||||
if (exit_code != 0) @panic("Bad exit code");
|
.Exited => |exit_code| exit_code == 0,
|
||||||
},
|
else => false,
|
||||||
.Signal => @panic("Signaled"),
|
};
|
||||||
.Stopped => @panic("Stopped"),
|
if (!success) {
|
||||||
.Unknown => @panic("Unknown"),
|
std.debug.print("The following command terminated with failure ({s}): {s}\n", .{@tagName(result.term), argv});
|
||||||
|
if (result.stdout.len > 0) {
|
||||||
|
std.debug.print("STDOUT:\n{s}\n", .{result.stdout});
|
||||||
|
}
|
||||||
|
if (result.stderr.len > 0) {
|
||||||
|
std.debug.print("STDOUT:\n{s}\n", .{result.stderr});
|
||||||
|
}
|
||||||
|
std.os.abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn buildExecutable(context: *const Context, arguments: [][:0]u8) !void {
|
const ExecutableOptions = struct{
|
||||||
|
is_test: bool,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn buildExecutable(context: *const Context, arguments: [][:0]u8, options: ExecutableOptions) !void {
|
||||||
var maybe_executable_path: ?[]const u8 = null;
|
var maybe_executable_path: ?[]const u8 = null;
|
||||||
var maybe_main_package_path: ?[]const u8 = null;
|
var maybe_main_package_path: ?[]const u8 = null;
|
||||||
var target_triplet: []const u8 = switch (@import("builtin").os.tag) {
|
var target_triplet: []const u8 = switch (@import("builtin").os.tag) {
|
||||||
@ -242,6 +262,7 @@ pub fn buildExecutable(context: *const Context, arguments: [][:0]u8) !void {
|
|||||||
},
|
},
|
||||||
.generate_debug_information = generate_debug_information,
|
.generate_debug_information = generate_debug_information,
|
||||||
.name = executable_name,
|
.name = executable_name,
|
||||||
|
.is_test = options.is_test,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -577,6 +598,7 @@ pub const Type = union(enum) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const Instruction = union(enum) {
|
pub const Instruction = union(enum) {
|
||||||
|
add_overflow: AddOverflow,
|
||||||
argument_declaration: *Debug.Declaration.Argument,
|
argument_declaration: *Debug.Declaration.Argument,
|
||||||
branch: Branch,
|
branch: Branch,
|
||||||
block: Debug.Block.Index,
|
block: Debug.Block.Index,
|
||||||
@ -758,6 +780,12 @@ pub const Instruction = union(enum) {
|
|||||||
source: V,
|
source: V,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const AddOverflow = struct{
|
||||||
|
left: V,
|
||||||
|
right: V,
|
||||||
|
type: Type.Index,
|
||||||
|
};
|
||||||
|
|
||||||
pub const List = BlockList(@This(), enum {});
|
pub const List = BlockList(@This(), enum {});
|
||||||
pub usingnamespace @This().List.Index;
|
pub usingnamespace @This().List.Index;
|
||||||
};
|
};
|
||||||
@ -1065,6 +1093,10 @@ pub const Debug = struct {
|
|||||||
lexed,
|
lexed,
|
||||||
parsed,
|
parsed,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub fn getPath(file: *File, allocator: Allocator) ![]const u8 {
|
||||||
|
return try std.mem.concat(allocator, u8, &.{ file.package.directory.path, "/", file.relative_path});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1074,6 +1106,7 @@ pub const Mutability = enum(u1) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const IntrinsicId = enum {
|
pub const IntrinsicId = enum {
|
||||||
|
add_overflow,
|
||||||
assert,
|
assert,
|
||||||
@"asm", //this is processed separately as it need special parsing
|
@"asm", //this is processed separately as it need special parsing
|
||||||
cast,
|
cast,
|
||||||
@ -1085,6 +1118,7 @@ pub const IntrinsicId = enum {
|
|||||||
size,
|
size,
|
||||||
sign_extend,
|
sign_extend,
|
||||||
syscall,
|
syscall,
|
||||||
|
trap,
|
||||||
zero_extend,
|
zero_extend,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1561,11 +1595,86 @@ pub const Builder = struct {
|
|||||||
switch (argument_node.id) {
|
switch (argument_node.id) {
|
||||||
.string_literal => {
|
.string_literal => {
|
||||||
const error_message = try unit.fixupStringLiteral(context, argument_node.token);
|
const error_message = try unit.fixupStringLiteral(context, argument_node.token);
|
||||||
std.debug.panic("Compile error: {s}", .{error_message});
|
builder.reportCompileError(unit, context, .{
|
||||||
|
.message = error_message,
|
||||||
|
.node = node_index,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
else => |t| @panic(@tagName(t)),
|
else => |t| @panic(@tagName(t)),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
.add_overflow => {
|
||||||
|
assert(argument_node_list.len == 2);
|
||||||
|
const left = try builder.resolveRuntimeValue(unit, context, type_expect, argument_node_list[0], .right);
|
||||||
|
const right_type_expect = switch (type_expect) {
|
||||||
|
.none => Type.Expect { .type = left.type },
|
||||||
|
else => type_expect,
|
||||||
|
};
|
||||||
|
const right = try builder.resolveRuntimeValue(unit, context, right_type_expect, argument_node_list[1], .right);
|
||||||
|
|
||||||
|
const add_overflow = try unit.instructions.append(context.allocator, .{
|
||||||
|
.add_overflow = .{
|
||||||
|
.left = left,
|
||||||
|
.right = right,
|
||||||
|
.type = left.type,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
try builder.appendInstruction(unit, context, add_overflow);
|
||||||
|
|
||||||
|
const result_type = try unit.getOptionalType(context, left.type);
|
||||||
|
|
||||||
|
const extract_value = try unit.instructions.append(context.allocator, .{
|
||||||
|
.extract_value = .{
|
||||||
|
.expression = .{
|
||||||
|
.value = .{
|
||||||
|
.runtime = add_overflow,
|
||||||
|
},
|
||||||
|
.type = result_type,
|
||||||
|
},
|
||||||
|
.index = 1,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
try builder.appendInstruction(unit, context, extract_value);
|
||||||
|
|
||||||
|
const carry = try builder.newBasicBlock(unit, context);
|
||||||
|
const normal = try builder.newBasicBlock(unit, context);
|
||||||
|
|
||||||
|
try builder.branch(unit, context, extract_value, carry, normal);
|
||||||
|
builder.current_basic_block = carry;
|
||||||
|
|
||||||
|
try builder.buildRet(unit, context, .{
|
||||||
|
.value = .{
|
||||||
|
.@"comptime" = .{
|
||||||
|
.constant_int = .{
|
||||||
|
.value = 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.type = left.type,
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.current_basic_block = normal;
|
||||||
|
|
||||||
|
const result_extract_value = try unit.instructions.append(context.allocator, .{
|
||||||
|
.extract_value = .{
|
||||||
|
.expression = .{
|
||||||
|
.value = .{
|
||||||
|
.runtime = add_overflow,
|
||||||
|
},
|
||||||
|
.type = result_type,
|
||||||
|
},
|
||||||
|
.index = 0,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
try builder.appendInstruction(unit, context, result_extract_value);
|
||||||
|
|
||||||
|
return V{
|
||||||
|
.value = .{
|
||||||
|
.runtime = result_extract_value,
|
||||||
|
},
|
||||||
|
.type = left.type,
|
||||||
|
};
|
||||||
|
},
|
||||||
else => |t| @panic(@tagName(t)),
|
else => |t| @panic(@tagName(t)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3364,6 +3473,7 @@ pub const Builder = struct {
|
|||||||
fields: u32 = 0,
|
fields: u32 = 0,
|
||||||
declarations: u32 = 0,
|
declarations: u32 = 0,
|
||||||
comptime_blocks: u32 = 0,
|
comptime_blocks: u32 = 0,
|
||||||
|
test_declarations: u32 = 0,
|
||||||
} = .{};
|
} = .{};
|
||||||
|
|
||||||
for (container_nodes) |member_index| {
|
for (container_nodes) |member_index| {
|
||||||
@ -3379,6 +3489,7 @@ pub const Builder = struct {
|
|||||||
.declaration => result.declarations += 1,
|
.declaration => result.declarations += 1,
|
||||||
.field => result.fields += 1,
|
.field => result.fields += 1,
|
||||||
.comptime_block => result.comptime_blocks += 1,
|
.comptime_block => result.comptime_blocks += 1,
|
||||||
|
.test_declaration => result.test_declarations += 1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3388,6 +3499,7 @@ pub const Builder = struct {
|
|||||||
var declaration_nodes = try ArrayList(Node.Index).initCapacity(context.allocator, count.declarations);
|
var declaration_nodes = try ArrayList(Node.Index).initCapacity(context.allocator, count.declarations);
|
||||||
var field_nodes = try ArrayList(Node.Index).initCapacity(context.allocator, count.fields);
|
var field_nodes = try ArrayList(Node.Index).initCapacity(context.allocator, count.fields);
|
||||||
var comptime_block_nodes = try ArrayList(Node.Index).initCapacity(context.allocator, count.comptime_blocks);
|
var comptime_block_nodes = try ArrayList(Node.Index).initCapacity(context.allocator, count.comptime_blocks);
|
||||||
|
var test_declarations = try ArrayList(Node.Index).initCapacity(context.allocator, count.test_declarations);
|
||||||
|
|
||||||
for (container_nodes) |member_index| {
|
for (container_nodes) |member_index| {
|
||||||
const member_node = unit.getNode(member_index);
|
const member_node = unit.getNode(member_index);
|
||||||
@ -3396,6 +3508,7 @@ pub const Builder = struct {
|
|||||||
.comptime_block => &comptime_block_nodes,
|
.comptime_block => &comptime_block_nodes,
|
||||||
.declaration => &declaration_nodes,
|
.declaration => &declaration_nodes,
|
||||||
.field => &field_nodes,
|
.field => &field_nodes,
|
||||||
|
.test_declaration => &test_declarations,
|
||||||
};
|
};
|
||||||
array_list.appendAssumeCapacity(member_index);
|
array_list.appendAssumeCapacity(member_index);
|
||||||
}
|
}
|
||||||
@ -3587,6 +3700,10 @@ pub const Builder = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (unit.descriptor.is_test and count.test_declarations > 0) {
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
return type_index;
|
return type_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5109,6 +5226,11 @@ pub const Builder = struct {
|
|||||||
break :blk v;
|
break :blk v;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
.integer => {
|
||||||
|
const v = try builder.resolveRuntimeValue(unit, context, Type.Expect.none, node.left, .left);
|
||||||
|
_ = v;
|
||||||
|
unreachable;
|
||||||
|
},
|
||||||
else => |t| @panic(@tagName(t)),
|
else => |t| @panic(@tagName(t)),
|
||||||
},
|
},
|
||||||
.none => {
|
.none => {
|
||||||
@ -7864,6 +7986,16 @@ pub const Builder = struct {
|
|||||||
try builder.appendInstruction(unit, context, ret);
|
try builder.appendInstruction(unit, context, ret);
|
||||||
unit.basic_blocks.get(builder.current_basic_block).terminated = true;
|
unit.basic_blocks.get(builder.current_basic_block).terminated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn reportCompileError(builder: *Builder, unit: *Unit, context: *const Context, err: Error) noreturn{
|
||||||
|
const err_node = unit.getNode(err.node);
|
||||||
|
const file = unit.files.get(builder.current_file);
|
||||||
|
const token_debug_info = builder.getTokenDebugInfo(unit, err_node.token);
|
||||||
|
std.debug.print("{s}:{}:{}: \x1b[31merror:\x1b[0m {s}\n", .{file.getPath(context.allocator) catch unreachable, token_debug_info.line + 1, token_debug_info.column + 1, err.message});
|
||||||
|
// std.debug.print("[COMPILATION {s}] ", .{if (compilation_success) "\x1b[32mOK\x1b[0m" else "\x1b[31mFAILED\x1b[0m"});
|
||||||
|
// file.relative_path
|
||||||
|
std.os.abort();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Enum = struct {
|
pub const Enum = struct {
|
||||||
@ -8607,7 +8739,6 @@ pub const FixedKeyword = enum {
|
|||||||
@"var",
|
@"var",
|
||||||
void,
|
void,
|
||||||
noreturn,
|
noreturn,
|
||||||
function,
|
|
||||||
@"while",
|
@"while",
|
||||||
bool,
|
bool,
|
||||||
true,
|
true,
|
||||||
@ -8628,6 +8759,7 @@ pub const FixedKeyword = enum {
|
|||||||
@"for",
|
@"for",
|
||||||
undefined,
|
undefined,
|
||||||
@"break",
|
@"break",
|
||||||
|
@"test",
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Descriptor = struct {
|
pub const Descriptor = struct {
|
||||||
@ -8636,6 +8768,7 @@ pub const Descriptor = struct {
|
|||||||
target: std.Target,
|
target: std.Target,
|
||||||
only_parse: bool,
|
only_parse: bool,
|
||||||
link_libc: bool,
|
link_libc: bool,
|
||||||
|
is_test: bool,
|
||||||
generate_debug_information: bool,
|
generate_debug_information: bool,
|
||||||
name: []const u8,
|
name: []const u8,
|
||||||
};
|
};
|
||||||
@ -8649,6 +8782,7 @@ fn getContainerMemberType(member_id: Node.Id) MemberType {
|
|||||||
.enum_field,
|
.enum_field,
|
||||||
.container_field,
|
.container_field,
|
||||||
=> .field,
|
=> .field,
|
||||||
|
.test_declaration => .test_declaration,
|
||||||
else => |t| @panic(@tagName(t)),
|
else => |t| @panic(@tagName(t)),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -8657,6 +8791,7 @@ const MemberType = enum {
|
|||||||
declaration,
|
declaration,
|
||||||
field,
|
field,
|
||||||
comptime_block,
|
comptime_block,
|
||||||
|
test_declaration,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Token = struct {
|
pub const Token = struct {
|
||||||
@ -8737,7 +8872,6 @@ pub const Token = struct {
|
|||||||
operator_compare_greater,
|
operator_compare_greater,
|
||||||
operator_compare_greater_equal,
|
operator_compare_greater_equal,
|
||||||
// Fixed keywords
|
// Fixed keywords
|
||||||
fixed_keyword_function,
|
|
||||||
fixed_keyword_const,
|
fixed_keyword_const,
|
||||||
fixed_keyword_var,
|
fixed_keyword_var,
|
||||||
fixed_keyword_void,
|
fixed_keyword_void,
|
||||||
@ -8763,7 +8897,7 @@ pub const Token = struct {
|
|||||||
fixed_keyword_for,
|
fixed_keyword_for,
|
||||||
fixed_keyword_undefined,
|
fixed_keyword_undefined,
|
||||||
fixed_keyword_break,
|
fixed_keyword_break,
|
||||||
unused0,
|
fixed_keyword_test,
|
||||||
unused1,
|
unused1,
|
||||||
unused2,
|
unused2,
|
||||||
unused3,
|
unused3,
|
||||||
|
@ -2605,7 +2605,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
|
|||||||
try assembly_statements.appendSlice(context.allocator, "\n\t");
|
try assembly_statements.appendSlice(context.allocator, "\n\t");
|
||||||
}
|
}
|
||||||
|
|
||||||
try constraints.appendSlice(context.allocator, ",~{dirflag},~{fpsr},~{flags}");
|
// try constraints.appendSlice(context.allocator, ",~{dirflag},~{fpsr},~{flags}");
|
||||||
},
|
},
|
||||||
else => |t| @panic(@tagName(t)),
|
else => |t| @panic(@tagName(t)),
|
||||||
}
|
}
|
||||||
@ -3090,6 +3090,15 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
|
|||||||
const intrinsic_call = try llvm.callIntrinsic("llvm.trap", parameter_types, parameter_values);
|
const intrinsic_call = try llvm.callIntrinsic("llvm.trap", parameter_types, parameter_values);
|
||||||
try llvm.llvm_instruction_map.putNoClobber(context.allocator, instruction_index, intrinsic_call);
|
try llvm.llvm_instruction_map.putNoClobber(context.allocator, instruction_index, intrinsic_call);
|
||||||
},
|
},
|
||||||
|
.add_overflow => |add_overflow| {
|
||||||
|
const intrinsic_type = try llvm.getType(unit, context, add_overflow.type);
|
||||||
|
const parameter_types = [_]*LLVM.Type{intrinsic_type};
|
||||||
|
const left = try llvm.emitRightValue(unit, context, add_overflow.left);
|
||||||
|
const right = try llvm.emitRightValue(unit, context, add_overflow.right);
|
||||||
|
const arguments = [_]*LLVM.Value{ left, right };
|
||||||
|
const intrinsic_call = try llvm.callIntrinsic("llvm.sadd.with.overflow", ¶meter_types, &arguments);
|
||||||
|
try llvm.llvm_instruction_map.putNoClobber(context.allocator, instruction_index, intrinsic_call);
|
||||||
|
},
|
||||||
else => |t| @panic(@tagName(t)),
|
else => |t| @panic(@tagName(t)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,6 +184,9 @@ pub const Node = struct {
|
|||||||
symbol_attribute_export,
|
symbol_attribute_export,
|
||||||
symbol_attributes,
|
symbol_attributes,
|
||||||
metadata,
|
metadata,
|
||||||
|
test_declaration,
|
||||||
|
all_errors,
|
||||||
|
error_union,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1372,7 +1375,6 @@ const Analyzer = struct {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
.operator_ampersand => try analyzer.pointerOrArrayTypeExpression(.single_pointer_type),
|
.operator_ampersand => try analyzer.pointerOrArrayTypeExpression(.single_pointer_type),
|
||||||
.operator_bang => unreachable, // error
|
|
||||||
.operator_left_bracket => switch (analyzer.peekTokenAhead(1)) {
|
.operator_left_bracket => switch (analyzer.peekTokenAhead(1)) {
|
||||||
.operator_ampersand => try analyzer.pointerOrArrayTypeExpression(.many_pointer_type),
|
.operator_ampersand => try analyzer.pointerOrArrayTypeExpression(.many_pointer_type),
|
||||||
.operator_asterisk => @panic("Meant to use ampersand?"),
|
.operator_asterisk => @panic("Meant to use ampersand?"),
|
||||||
@ -1382,6 +1384,30 @@ const Analyzer = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn errorUnionExpression(analyzer: *Analyzer) !Node.Index {
|
fn errorUnionExpression(analyzer: *Analyzer) !Node.Index {
|
||||||
|
if (analyzer.peekToken() == .operator_bang) {
|
||||||
|
const error_union_token = try analyzer.expectToken(.operator_bang);
|
||||||
|
if (analyzer.peekToken() == .operator_asterisk) {
|
||||||
|
analyzer.consumeToken();
|
||||||
|
// All errors
|
||||||
|
const all_errors_node = try analyzer.addNode(.{
|
||||||
|
.id = .all_errors,
|
||||||
|
.token = error_union_token,
|
||||||
|
.left = .null,
|
||||||
|
.right = .null,
|
||||||
|
});
|
||||||
|
const type_node = try analyzer.suffixExpression();
|
||||||
|
|
||||||
|
const error_union = try analyzer.addNode(.{
|
||||||
|
.id = .error_union,
|
||||||
|
.token = error_union_token,
|
||||||
|
.left = all_errors_node,
|
||||||
|
.right = type_node,
|
||||||
|
});
|
||||||
|
return error_union;
|
||||||
|
} else {
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
const suffix_expression = try analyzer.suffixExpression();
|
const suffix_expression = try analyzer.suffixExpression();
|
||||||
|
|
||||||
return switch (analyzer.peekToken()) {
|
return switch (analyzer.peekToken()) {
|
||||||
@ -1389,6 +1415,7 @@ const Analyzer = struct {
|
|||||||
else => suffix_expression,
|
else => suffix_expression,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn suffixExpression(analyzer: *Analyzer) !Node.Index {
|
fn suffixExpression(analyzer: *Analyzer) !Node.Index {
|
||||||
analyzer.suffix_depth += 1;
|
analyzer.suffix_depth += 1;
|
||||||
@ -1666,6 +1693,7 @@ const Analyzer = struct {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
.fixed_keyword_const, .fixed_keyword_var => try analyzer.symbolDeclaration(),
|
.fixed_keyword_const, .fixed_keyword_var => try analyzer.symbolDeclaration(),
|
||||||
|
.fixed_keyword_test => try analyzer.testDeclaration(),
|
||||||
else => |t| @panic(@tagName(t)),
|
else => |t| @panic(@tagName(t)),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1696,6 +1724,18 @@ const Analyzer = struct {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn testDeclaration(analyzer: *Analyzer) !Node.Index {
|
||||||
|
const test_token = try analyzer.expectToken(.fixed_keyword_test);
|
||||||
|
const name_node: Node.Index = if (analyzer.peekToken() == .string_literal) try analyzer.identifierNode() else .null;
|
||||||
|
const test_block = try analyzer.block();
|
||||||
|
return try analyzer.addNode(.{
|
||||||
|
.token = test_token,
|
||||||
|
.id = .test_declaration,
|
||||||
|
.left = test_block,
|
||||||
|
.right = name_node,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
fn primaryTypeExpression(analyzer: *Analyzer) anyerror!Node.Index {
|
fn primaryTypeExpression(analyzer: *Analyzer) anyerror!Node.Index {
|
||||||
const token_i = analyzer.token_i;
|
const token_i = analyzer.token_i;
|
||||||
const token = analyzer.peekToken();
|
const token = analyzer.peekToken();
|
||||||
|
@ -42,11 +42,18 @@ pub fn main() !void {
|
|||||||
todo();
|
todo();
|
||||||
} else if (equal(u8, command, "exe")) {
|
} else if (equal(u8, command, "exe")) {
|
||||||
const context = try Compilation.createContext(allocator);
|
const context = try Compilation.createContext(allocator);
|
||||||
try Compilation.buildExecutable(context, command_arguments);
|
try Compilation.buildExecutable(context, command_arguments, .{
|
||||||
|
.is_test = false,
|
||||||
|
});
|
||||||
} else if (equal(u8, command, "lib")) {
|
} else if (equal(u8, command, "lib")) {
|
||||||
todo();
|
todo();
|
||||||
} else if (equal(u8, command, "obj")) {
|
} else if (equal(u8, command, "obj")) {
|
||||||
todo();
|
todo();
|
||||||
|
} else if (equal(u8, command, "test")) {
|
||||||
|
const context = try Compilation.createContext(allocator);
|
||||||
|
try Compilation.buildExecutable(context, command_arguments, .{
|
||||||
|
.is_test = true,
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
todo();
|
todo();
|
||||||
}
|
}
|
||||||
|
@ -12,10 +12,23 @@ const Cpu = enum{
|
|||||||
|
|
||||||
const Abi = enum{
|
const Abi = enum{
|
||||||
none,
|
none,
|
||||||
gnu,
|
gnu, msvc,
|
||||||
msvc,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const CallingConvention = enum{
|
const CallingConvention = enum{
|
||||||
system_v,
|
system_v,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const PanicReason = enum{
|
||||||
|
integer_overflow,
|
||||||
|
null_unwrap,
|
||||||
|
};
|
||||||
|
|
||||||
|
const panic = fn (reason: PanicReason) noreturn{
|
||||||
|
#trap();
|
||||||
|
}
|
||||||
|
|
||||||
|
const TestFunction = struct{
|
||||||
|
name: []const u8,
|
||||||
|
function: &const fn () !*void,
|
||||||
|
};
|
||||||
|
@ -415,6 +415,15 @@ const waitpid = fn(pid: Process.Id, flags: u32) ?u32 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
.macos => {
|
||||||
|
var status: s32 = undefined;
|
||||||
|
if (macos.waitpid(pid, status.&, #cast(flags)) != -1) {
|
||||||
|
const status_u: u32 = #cast(status);
|
||||||
|
return status_u;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
else => #error("OS not supported"),
|
else => #error("OS not supported"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,5 +52,6 @@ const mmap :: extern = fn (address: ?[&]const u8, length: usize, protection_flag
|
|||||||
const munmap :: extern = fn (address: [&]const u8, length: usize) s32;
|
const munmap :: extern = fn (address: [&]const u8, length: usize) s32;
|
||||||
const execve :: extern = fn(path: [&:0]const u8, argv: [&:null]const ?[&:0]const u8, env: [&:null]const ?[&:null]const u8) s32;
|
const execve :: extern = fn(path: [&:0]const u8, argv: [&:null]const ?[&:0]const u8, env: [&:null]const ?[&:null]const u8) s32;
|
||||||
const realpath :: extern = fn(path: [&:0]const u8, resolved_path: [&:0]u8) [&:0]u8;
|
const realpath :: extern = fn(path: [&:0]const u8, resolved_path: [&:0]u8) [&:0]u8;
|
||||||
|
const waitpid :: extern = fn(pid: ProcessId, status: &s32, flags: s32) s32;
|
||||||
|
|
||||||
const _NSGetExecutablePath :: extern = fn (buffer: [&:0]u8, buffer_size: &u32) s32;
|
const _NSGetExecutablePath :: extern = fn (buffer: [&:0]u8, buffer_size: &u32) s32;
|
||||||
|
@ -35,6 +35,10 @@ const start :: export = fn (argc_argv_address: usize) noreturn {
|
|||||||
std.os.exit(exit_code = result);
|
std.os.exit(exit_code = result);
|
||||||
}
|
}
|
||||||
|
|
||||||
const main :: export = fn (argc: s32, argv: [&:null]?[&:null]u8, env: [&:null]?[&:null]u8) s32 {
|
const main :: export = fn (argc: s32, argv: [&]const [&:0]const u8, env: [&:null]const ?[&:null]const u8) s32 {
|
||||||
|
const argc_u: u32 = #cast(argc);
|
||||||
|
argument_count = argc_u;
|
||||||
|
argument_values = argv;
|
||||||
|
environment_values = env;
|
||||||
return #import("main").main();
|
return #import("main").main();
|
||||||
}
|
}
|
||||||
|
2
test/tests/main.nat
Normal file
2
test/tests/main.nat
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
test {
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user