First comptime for implementation
This commit is contained in:
parent
57a7a07b52
commit
28776701fc
@ -4125,6 +4125,7 @@ pub const V = struct {
|
|||||||
constant_int: ConstantInt,
|
constant_int: ConstantInt,
|
||||||
function_declaration: Type.Index,
|
function_declaration: Type.Index,
|
||||||
enum_value: Enum.Field.Index,
|
enum_value: Enum.Field.Index,
|
||||||
|
enum_fields: []const Enum.Field.Index,
|
||||||
error_value: Type.Error.Field.Index,
|
error_value: Type.Error.Field.Index,
|
||||||
function_definition: Function.Definition.Index,
|
function_definition: Function.Definition.Index,
|
||||||
global: *Debug.Declaration.Global,
|
global: *Debug.Declaration.Global,
|
||||||
@ -4181,7 +4182,7 @@ pub const V = struct {
|
|||||||
.comptime_int => .comptime_int,
|
.comptime_int => .comptime_int,
|
||||||
.constant_struct => |constant_struct| unit.constant_structs.get(constant_struct).type,
|
.constant_struct => |constant_struct| unit.constant_structs.get(constant_struct).type,
|
||||||
.function_declaration => |function_type| function_type,
|
.function_declaration => |function_type| function_type,
|
||||||
.polymorphic_function=> .polymorphic_function,
|
.polymorphic_function => .polymorphic_function,
|
||||||
else => |t| @panic(@tagName(t)),
|
else => |t| @panic(@tagName(t)),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -4202,6 +4203,7 @@ pub const Debug = struct {
|
|||||||
global,
|
global,
|
||||||
local,
|
local,
|
||||||
argument,
|
argument,
|
||||||
|
@"comptime",
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Global = struct {
|
pub const Global = struct {
|
||||||
@ -4906,6 +4908,41 @@ pub const Builder = struct {
|
|||||||
},
|
},
|
||||||
else => |t| @panic(@tagName(t)),
|
else => |t| @panic(@tagName(t)),
|
||||||
},
|
},
|
||||||
|
.@"comptime" => |ct| switch (ct) {
|
||||||
|
.enum_value => |enum_field_index| {
|
||||||
|
const enum_field = unit.enum_fields.get(enum_field_index);
|
||||||
|
const enum_name = unit.getIdentifier(enum_field.name);
|
||||||
|
const enum_name_z = try context.allocator.dupeZ(u8, enum_name);
|
||||||
|
const string_literal = try builder.processStringLiteralFromStringAndDebugInfo(unit, context, enum_name_z, .{
|
||||||
|
.line = 0,
|
||||||
|
.column = 0,
|
||||||
|
});
|
||||||
|
switch (type_expect) {
|
||||||
|
.type => |type_index| switch (unit.types.get(type_index).*) {
|
||||||
|
.slice => |slice| {
|
||||||
|
assert(slice.child_type == .u8);
|
||||||
|
const constant_slice = try unit.constant_slices.append(context.my_allocator, .{
|
||||||
|
.array = string_literal,
|
||||||
|
.start = 0,
|
||||||
|
.end = enum_name.len,
|
||||||
|
.type = type_index,
|
||||||
|
});
|
||||||
|
return V{
|
||||||
|
.type = type_index,
|
||||||
|
.value = .{
|
||||||
|
.@"comptime" = .{
|
||||||
|
.constant_slice = constant_slice,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
else => |t| @panic(@tagName(t)),
|
||||||
|
},
|
||||||
|
else => |t| @panic(@tagName(t)),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
else => |t| @panic(@tagName(t)),
|
||||||
|
},
|
||||||
else => |t| @panic(@tagName(t)),
|
else => |t| @panic(@tagName(t)),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -5033,7 +5070,7 @@ pub const Builder = struct {
|
|||||||
.line = 0,
|
.line = 0,
|
||||||
.column = 0,
|
.column = 0,
|
||||||
});
|
});
|
||||||
const slice = try unit.constant_slices.append(context.my_allocator,.{
|
const slice = try unit.constant_slices.append(context.my_allocator, .{
|
||||||
.array = string_literal,
|
.array = string_literal,
|
||||||
.start = 0,
|
.start = 0,
|
||||||
.end = identifier_z.len,
|
.end = identifier_z.len,
|
||||||
@ -5108,7 +5145,7 @@ pub const Builder = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_fields_array(builder: *Builder, unit: *Unit, context: *const Context, container_type_index: Type.Index, token: Token.Index) !*Debug.Declaration.Global{
|
fn get_fields_array(builder: *Builder, unit: *Unit, context: *const Context, container_type_index: Type.Index, token: Token.Index) !*Debug.Declaration.Global {
|
||||||
if (unit.fields_array.get(container_type_index)) |result| return result else {
|
if (unit.fields_array.get(container_type_index)) |result| return result else {
|
||||||
const container_type = unit.types.get(container_type_index);
|
const container_type = unit.types.get(container_type_index);
|
||||||
|
|
||||||
@ -5612,7 +5649,7 @@ pub const Builder = struct {
|
|||||||
|
|
||||||
return instantiation_global;
|
return instantiation_global;
|
||||||
},
|
},
|
||||||
else => {}
|
else => {},
|
||||||
}
|
}
|
||||||
|
|
||||||
inline for (@typeInfo(Debug.Declaration.Global.Attribute).Enum.fields) |attribute_enum_field| {
|
inline for (@typeInfo(Debug.Declaration.Global.Attribute).Enum.fields) |attribute_enum_field| {
|
||||||
@ -5924,6 +5961,9 @@ pub const Builder = struct {
|
|||||||
|
|
||||||
unreachable;
|
unreachable;
|
||||||
},
|
},
|
||||||
|
.pointer => |source_pointer| if (source_pointer.type == destination_slice.child_type) {
|
||||||
|
unreachable;
|
||||||
|
} else unreachable,
|
||||||
else => |t| @panic(@tagName(t)),
|
else => |t| @panic(@tagName(t)),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -8608,11 +8648,11 @@ pub const Builder = struct {
|
|||||||
const field_node = unit.getNode(field_node_index);
|
const field_node = unit.getNode(field_node_index);
|
||||||
const identifier = switch (unit.getTokenId(field_node.token)) {
|
const identifier = switch (unit.getTokenId(field_node.token)) {
|
||||||
.identifier => unit.getExpectedTokenBytes(field_node.token, .identifier),
|
.identifier => unit.getExpectedTokenBytes(field_node.token, .identifier),
|
||||||
.discard => try std.mem.concat(context.allocator, u8, &.{"_", &.{'0' + b: {
|
.discard => try std.mem.concat(context.allocator, u8, &.{ "_", &.{'0' + b: {
|
||||||
const ch = '0' + ignore_field_count;
|
const ch = '0' + ignore_field_count;
|
||||||
ignore_field_count += 1;
|
ignore_field_count += 1;
|
||||||
break :b ch;
|
break :b ch;
|
||||||
}}}),
|
}} }),
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
};
|
};
|
||||||
const hash = try unit.processIdentifier(context, identifier);
|
const hash = try unit.processIdentifier(context, identifier);
|
||||||
@ -9453,6 +9493,22 @@ pub const Builder = struct {
|
|||||||
else => |t| @panic(@tagName(t)),
|
else => |t| @panic(@tagName(t)),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
.fields => {
|
||||||
|
assert(argument_node_list.len == 1);
|
||||||
|
const container_type_index = try builder.resolveType(unit, context, argument_node_list[0], &.{});
|
||||||
|
const container_type = unit.types.get(container_type_index);
|
||||||
|
switch (container_type.*) {
|
||||||
|
.integer => |*integer| switch (integer.kind) {
|
||||||
|
.@"enum" => |*enum_type| {
|
||||||
|
return V.Comptime{
|
||||||
|
.enum_fields = enum_type.fields.slice(),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
else => |t| @panic(@tagName(t)),
|
||||||
|
},
|
||||||
|
else => |t| @panic(@tagName(t)),
|
||||||
|
}
|
||||||
|
},
|
||||||
else => |t| @panic(@tagName(t)),
|
else => |t| @panic(@tagName(t)),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -9719,7 +9775,6 @@ pub const Builder = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn resolveRuntimeValue(builder: *Builder, unit: *Unit, context: *const Context, type_expect: Type.Expect, node_index: Node.Index, side: Side) anyerror!V {
|
fn resolveRuntimeValue(builder: *Builder, unit: *Unit, context: *const Context, type_expect: Type.Expect, node_index: Node.Index, side: Side) anyerror!V {
|
||||||
const node = unit.getNode(node_index);
|
const node = unit.getNode(node_index);
|
||||||
|
|
||||||
@ -13220,7 +13275,6 @@ pub const Builder = struct {
|
|||||||
};
|
};
|
||||||
const argument_value = try builder.resolveRuntimeValue(unit, context, arg_type_expect, argument_node_index, .right);
|
const argument_value = try builder.resolveRuntimeValue(unit, context, arg_type_expect, argument_node_index, .right);
|
||||||
|
|
||||||
|
|
||||||
switch (argument_abi.kind) {
|
switch (argument_abi.kind) {
|
||||||
.direct => {
|
.direct => {
|
||||||
assert(argument_value.type == argument_type_index);
|
assert(argument_value.type == argument_type_index);
|
||||||
@ -13562,7 +13616,6 @@ pub const Builder = struct {
|
|||||||
},
|
},
|
||||||
else => |t| @panic(@tagName(t)),
|
else => |t| @panic(@tagName(t)),
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -13849,10 +13902,46 @@ pub const Builder = struct {
|
|||||||
assert(slices_and_range_node.len > 0);
|
assert(slices_and_range_node.len > 0);
|
||||||
assert(payloads.len > 0);
|
assert(payloads.len > 0);
|
||||||
|
|
||||||
|
const for_expressions = unit.getNode(statement_node.right);
|
||||||
|
assert(for_expressions.id == .for_expressions);
|
||||||
|
const body_node_index = for_expressions.left;
|
||||||
|
|
||||||
if (slices_and_range_node.len != payloads.len) {
|
if (slices_and_range_node.len != payloads.len) {
|
||||||
@panic("Slice/range count does not match payload count");
|
@panic("Slice/range count does not match payload count");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (slices_and_range_node.len == 1 and unit.getNode(slices_and_range_node[0]).id == .comptime_expression) {
|
||||||
|
const node = unit.getNode(slices_and_range_node[0]);
|
||||||
|
assert(slices_and_range_node.len == 1);
|
||||||
|
const comptime_value = try builder.resolveComptimeValue(unit, context, Type.Expect.none, .{}, node.left, null, .right, &.{}, null, &.{});
|
||||||
|
switch (comptime_value) {
|
||||||
|
.enum_fields => |enum_fields| {
|
||||||
|
const first_enum_field = unit.enum_fields.get(enum_fields[0]);
|
||||||
|
const payload_node = unit.getNode(payloads[0]);
|
||||||
|
const emit = false;
|
||||||
|
const comptime_payload = try builder.emitLocalVariableDeclaration(unit, context, payload_node.token, .@"const", first_enum_field.parent, V{
|
||||||
|
.type = first_enum_field.parent,
|
||||||
|
.value = .{
|
||||||
|
.@"comptime" = .{
|
||||||
|
.enum_value = enum_fields[0],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, emit, null);
|
||||||
|
_ = comptime_payload; // autofix
|
||||||
|
const identifier = unit.getExpectedTokenBytes(payload_node.token, .identifier);
|
||||||
|
const hash = try unit.processIdentifier(context, identifier);
|
||||||
|
const symbol_lookup = builder.current_scope.lookupDeclaration(hash, false) orelse unreachable;
|
||||||
|
const local_symbol: *Debug.Declaration.Local = @fieldParentPtr("declaration", symbol_lookup.declaration);
|
||||||
|
|
||||||
|
for (enum_fields) |enum_field_index| {
|
||||||
|
local_symbol.init_value.value.@"comptime".enum_value = enum_field_index; // autofix
|
||||||
|
_ = try builder.resolveRuntimeValue(unit, context, Type.Expect{ .type = .void }, body_node_index, .right);
|
||||||
|
// const enum_field = unit.enum_fields.get(enum_field_index);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
else => |t| @panic(@tagName(t)),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
const count = slices_and_range_node.len;
|
const count = slices_and_range_node.len;
|
||||||
var slices = UnpinnedArray(V){};
|
var slices = UnpinnedArray(V){};
|
||||||
|
|
||||||
@ -13945,7 +14034,7 @@ pub const Builder = struct {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
.pointer => |pointer| switch (unit.types.get(pointer.type).*){
|
.pointer => |pointer| switch (unit.types.get(pointer.type).*) {
|
||||||
.array => |array| {
|
.array => |array| {
|
||||||
const slice_type = try unit.getSliceType(context, .{
|
const slice_type = try unit.getSliceType(context, .{
|
||||||
.child_pointer_type = try unit.getPointerType(context, .{
|
.child_pointer_type = try unit.getPointerType(context, .{
|
||||||
@ -14136,9 +14225,6 @@ pub const Builder = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const for_expressions = unit.getNode(statement_node.right);
|
|
||||||
assert(for_expressions.id == .for_expressions);
|
|
||||||
const body_node_index = for_expressions.left;
|
|
||||||
_ = try builder.resolveRuntimeValue(unit, context, Type.Expect{ .type = .void }, body_node_index, .right);
|
_ = try builder.resolveRuntimeValue(unit, context, Type.Expect{ .type = .void }, body_node_index, .right);
|
||||||
|
|
||||||
const else_node_index = for_expressions.right;
|
const else_node_index = for_expressions.right;
|
||||||
@ -14207,6 +14293,7 @@ pub const Builder = struct {
|
|||||||
try builder.jump(unit, context, builder.loop_header_block);
|
try builder.jump(unit, context, builder.loop_header_block);
|
||||||
|
|
||||||
builder.current_basic_block = exit_block;
|
builder.current_basic_block = exit_block;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
.break_expression => {
|
.break_expression => {
|
||||||
try builder.jump(unit, context, builder.loop_exit_block);
|
try builder.jump(unit, context, builder.loop_exit_block);
|
||||||
@ -14727,7 +14814,7 @@ pub const Builder = struct {
|
|||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
|
|
||||||
const PhiInfo = struct{
|
const PhiInfo = struct {
|
||||||
block: BasicBlock.Index,
|
block: BasicBlock.Index,
|
||||||
instruction: Instruction.Index,
|
instruction: Instruction.Index,
|
||||||
};
|
};
|
||||||
@ -14908,7 +14995,6 @@ pub const Builder = struct {
|
|||||||
} else {
|
} else {
|
||||||
unreachable;
|
unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
else => |t| @panic(@tagName(t)),
|
else => |t| @panic(@tagName(t)),
|
||||||
}
|
}
|
||||||
@ -16030,14 +16116,14 @@ pub const Builder = struct {
|
|||||||
const line = token_debug_info.line + 1;
|
const line = token_debug_info.line + 1;
|
||||||
const column = token_debug_info.column + 1;
|
const column = token_debug_info.column + 1;
|
||||||
const file_path = file.getPath(context.allocator) catch unreachable;
|
const file_path = file.getPath(context.allocator) catch unreachable;
|
||||||
write(.panic, file_path) catch {};
|
write(.panic, file_path) catch unreachable;
|
||||||
write(.panic, ":") catch {};
|
write(.panic, ":") catch unreachable;
|
||||||
Unit.dumpInt(line, 10, false) catch {};
|
Unit.dumpInt(line, 10, false) catch unreachable;
|
||||||
write(.panic, ":") catch {};
|
write(.panic, ":") catch unreachable;
|
||||||
Unit.dumpInt(column, 10, false) catch {};
|
Unit.dumpInt(column, 10, false) catch unreachable;
|
||||||
write(.panic, ":\x1b[0m ") catch {};
|
write(.panic, ":\x1b[0m ") catch unreachable;
|
||||||
write(.panic, err.message) catch {};
|
write(.panic, err.message) catch unreachable;
|
||||||
write(.panic, "\n") catch {};
|
write(.panic, "\n") catch unreachable;
|
||||||
std.posix.abort();
|
std.posix.abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -17101,44 +17187,7 @@ pub const Unit = struct {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const FixedKeyword = enum {
|
pub const FixedKeyword = enum { @"comptime", @"const", @"var", void, noreturn, @"while", bool, true, false, @"fn", @"unreachable", @"return", ssize, usize, @"switch", @"if", @"else", @"struct", @"enum", null, @"align", @"for", undefined, @"break", @"test", @"catch", @"try", @"orelse", @"error", @"and", @"or", bitfield, Self, any, type, @"continue" };
|
||||||
@"comptime",
|
|
||||||
@"const",
|
|
||||||
@"var",
|
|
||||||
void,
|
|
||||||
noreturn,
|
|
||||||
@"while",
|
|
||||||
bool,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
@"fn",
|
|
||||||
@"unreachable",
|
|
||||||
@"return",
|
|
||||||
ssize,
|
|
||||||
usize,
|
|
||||||
@"switch",
|
|
||||||
@"if",
|
|
||||||
@"else",
|
|
||||||
@"struct",
|
|
||||||
@"enum",
|
|
||||||
null,
|
|
||||||
@"align",
|
|
||||||
@"for",
|
|
||||||
undefined,
|
|
||||||
@"break",
|
|
||||||
@"test",
|
|
||||||
@"catch",
|
|
||||||
@"try",
|
|
||||||
@"orelse",
|
|
||||||
@"error",
|
|
||||||
@"and",
|
|
||||||
@"or",
|
|
||||||
bitfield,
|
|
||||||
Self,
|
|
||||||
any,
|
|
||||||
type,
|
|
||||||
@"continue"
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const Descriptor = struct {
|
pub const Descriptor = struct {
|
||||||
main_package_path: []const u8,
|
main_package_path: []const u8,
|
||||||
|
@ -625,7 +625,6 @@ const Analyzer = struct {
|
|||||||
.operator_switch_case => break,
|
.operator_switch_case => break,
|
||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break :blk switch (array_list.length) {
|
break :blk switch (array_list.length) {
|
||||||
@ -1830,7 +1829,10 @@ const Analyzer = struct {
|
|||||||
},
|
},
|
||||||
else => |t| @panic(@tagName(t)),
|
else => |t| @panic(@tagName(t)),
|
||||||
},
|
},
|
||||||
.identifier, .discard, => b: {
|
.identifier,
|
||||||
|
.discard,
|
||||||
|
.string_literal,
|
||||||
|
=> b: {
|
||||||
analyzer.consumeToken();
|
analyzer.consumeToken();
|
||||||
|
|
||||||
switch (container_type) {
|
switch (container_type) {
|
||||||
|
@ -23,7 +23,7 @@ pub fn build(b: *std.Build) !void {
|
|||||||
const self_hosted_ci = b.option(bool, "self_hosted_ci", "This option enables the self-hosted CI behavior") orelse false;
|
const self_hosted_ci = b.option(bool, "self_hosted_ci", "This option enables the self-hosted CI behavior") orelse false;
|
||||||
const third_party_ci = b.option(bool, "third_party_ci", "This option enables the third-party CI behavior") orelse false;
|
const third_party_ci = b.option(bool, "third_party_ci", "This option enables the third-party CI behavior") orelse false;
|
||||||
const is_ci = self_hosted_ci or third_party_ci;
|
const is_ci = self_hosted_ci or third_party_ci;
|
||||||
const print_stack_trace = b.option(bool, "print_stack_trace", "This option enables printing stack traces inside the compiler") orelse is_ci or os == .macos;
|
const print_stack_trace = b.option(bool, "print_stack_trace", "This option enables printing stack traces inside the compiler") orelse is_ci;
|
||||||
const native_target = b.resolveTargetQuery(.{});
|
const native_target = b.resolveTargetQuery(.{});
|
||||||
const optimization = b.standardOptimizeOption(.{});
|
const optimization = b.standardOptimizeOption(.{});
|
||||||
const use_debug = b.option(bool, "use_debug", "This option enables the LLVM debug build in the development PC") orelse false;
|
const use_debug = b.option(bool, "use_debug", "This option enables the LLVM debug build in the development PC") orelse false;
|
||||||
|
@ -41,6 +41,77 @@ const MapFlags = switch (os) {
|
|||||||
else => #error("OS not supported"),
|
else => #error("OS not supported"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const AccessMode = enum(u2) {
|
||||||
|
read_only = 0,
|
||||||
|
write_only = 1,
|
||||||
|
read_write = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
const OpenFlags = switch (os) {
|
||||||
|
.macos => bitfield(u32) {
|
||||||
|
access_mode: AccessMode,
|
||||||
|
non_block: bool = false,
|
||||||
|
append: bool = false,
|
||||||
|
shared_lock: bool = false,
|
||||||
|
exclusive_lock: bool = false,
|
||||||
|
async: bool = false,
|
||||||
|
sync: bool = false,
|
||||||
|
no_follow: bool = false,
|
||||||
|
creat: bool = false,
|
||||||
|
truncate: bool = false,
|
||||||
|
exclusive: bool = false,
|
||||||
|
_: u3 = 0,
|
||||||
|
evt_only: bool = false,
|
||||||
|
_: u1 = 0,
|
||||||
|
no_ctty: bool = false,
|
||||||
|
_: u2 = 0,
|
||||||
|
directory: bool = false,
|
||||||
|
symlink: bool = false,
|
||||||
|
dsync: bool = false,
|
||||||
|
_: u1 = 0,
|
||||||
|
cloexec: bool = false,
|
||||||
|
_: u4 = 0,
|
||||||
|
alert: bool = false,
|
||||||
|
_: u1 = 0,
|
||||||
|
popup: bool = false,
|
||||||
|
},
|
||||||
|
.linux => linux.OpenFlags,
|
||||||
|
else => #error("OS not supported"),
|
||||||
|
};
|
||||||
|
|
||||||
|
const TimeSpec = struct{
|
||||||
|
seconds: s64,
|
||||||
|
nanoseconds: s64,
|
||||||
|
};
|
||||||
|
|
||||||
|
const Stat = switch (os) {
|
||||||
|
.macos => struct{
|
||||||
|
dev: s32,
|
||||||
|
mode: u16,
|
||||||
|
nlink: u16,
|
||||||
|
|
||||||
|
inode: u64,
|
||||||
|
uid: u32,
|
||||||
|
gid: u32,
|
||||||
|
rdev: s32,
|
||||||
|
|
||||||
|
a_timespec: TimeSpec,
|
||||||
|
m_timespec: TimeSpec,
|
||||||
|
c_timespec: TimeSpec,
|
||||||
|
birth_timespec: TimeSpec,
|
||||||
|
size: s64,
|
||||||
|
blocks: s64,
|
||||||
|
block_size: s32,
|
||||||
|
flags: u32,
|
||||||
|
gen: u32,
|
||||||
|
lspare: s32,
|
||||||
|
qspare: [2]s64,
|
||||||
|
},
|
||||||
|
.linux => linux.Stat,
|
||||||
|
else => #error("OS not supported"),
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
const FileDescriptor = s32;
|
const FileDescriptor = s32;
|
||||||
const ProcessId = s32;
|
const ProcessId = s32;
|
||||||
const MAP_FAILED = 0xffffffffffffffff;
|
const MAP_FAILED = 0xffffffffffffffff;
|
||||||
@ -71,7 +142,9 @@ const get_map_flags = fn(flags: std.os.MapFlags) MapFlags{
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const write :: extern = fn cc(.c) (file_descriptor: FileDescriptor, bytes_ptr: [&]const u8, bytes_len: usize) ssize;
|
const open :: extern = fn cc(.c) (path: [&:0]const u8, flags: OpenFlags) s32;
|
||||||
|
const read :: extern = fn cc(.c) (file_descriptor: FileDescriptor, bytes_ptr: [&]const u8, byte_count: usize) ssize;
|
||||||
|
const write :: extern = fn cc(.c) (file_descriptor: FileDescriptor, bytes_ptr: [&]const u8, byte_count: usize) ssize;
|
||||||
const exit :: extern = fn cc(.c) (exit_code: s32) noreturn;
|
const exit :: extern = fn cc(.c) (exit_code: s32) noreturn;
|
||||||
const fork :: extern = fn cc(.c) () ProcessId;
|
const fork :: extern = fn cc(.c) () ProcessId;
|
||||||
const mmap :: extern = fn cc(.c) (address: ?[&]const u8, length: usize, protection_flags: ProtectionFlags, map_flags: MapFlags, file_descriptor: FileDescriptor, offset: u64) usize;
|
const mmap :: extern = fn cc(.c) (address: ?[&]const u8, length: usize, protection_flags: ProtectionFlags, map_flags: MapFlags, file_descriptor: FileDescriptor, offset: u64) usize;
|
||||||
@ -80,5 +153,6 @@ const execve :: extern = fn cc(.c) (path: [&:0]const u8, argv: [&:null]const ?[&
|
|||||||
const realpath :: extern = fn cc(.c) (path: [&:0]const u8, resolved_path: [&:0]u8) ?[&:0]u8;
|
const realpath :: extern = fn cc(.c) (path: [&:0]const u8, resolved_path: [&:0]u8) ?[&:0]u8;
|
||||||
const waitpid :: extern = fn cc(.c) (pid: ProcessId, status: &s32, flags: s32) s32;
|
const waitpid :: extern = fn cc(.c) (pid: ProcessId, status: &s32, flags: s32) s32;
|
||||||
const mprotect :: extern = fn cc(.c) (address: &any, size: usize, flags: ProtectionFlags) s32;
|
const mprotect :: extern = fn cc(.c) (address: &any, size: usize, flags: ProtectionFlags) s32;
|
||||||
|
const fstat :: extern = fn cc(.c) (file_descriptor: FileDescriptor, stat: &Stat) s32;
|
||||||
|
|
||||||
const _NSGetExecutablePath :: extern = fn cc(.c) (buffer: [&:0]u8, buffer_size: &u32) s32;
|
const _NSGetExecutablePath :: extern = fn cc(.c) (buffer: [&:0]u8, buffer_size: &u32) s32;
|
||||||
|
@ -46,17 +46,9 @@ const FileDescriptor = struct{
|
|||||||
const read = fn(file_descriptor: FileDescriptor, bytes: []u8) ReadError!usize {
|
const read = fn(file_descriptor: FileDescriptor, bytes: []u8) ReadError!usize {
|
||||||
if (bytes.length > 0) {
|
if (bytes.length > 0) {
|
||||||
switch (current) {
|
switch (current) {
|
||||||
.linux => {
|
.linux, .macos => {
|
||||||
const len: usize = #min(max_file_operation_byte_count, bytes.length);
|
const len: usize = #min(max_file_operation_byte_count, bytes.length);
|
||||||
const syscall_result = system.read(file_descriptor.handle, bytes);
|
const syscall_result = system.read(file_descriptor.handle, bytes.pointer, bytes.length);
|
||||||
const byte_count = unwrap_syscall(syscall_result) catch |err| switch (err) {
|
|
||||||
else => return ReadError.failed,
|
|
||||||
};
|
|
||||||
return byte_count;
|
|
||||||
},
|
|
||||||
.macos => {
|
|
||||||
const len: usize = #min(max_file_operation_byte_count, bytes.length);
|
|
||||||
const syscall_result = system.read(file_descriptor.handle, bytes);
|
|
||||||
const byte_count = unwrap_syscall(syscall_result) catch |err| switch (err) {
|
const byte_count = unwrap_syscall(syscall_result) catch |err| switch (err) {
|
||||||
else => return ReadError.failed,
|
else => return ReadError.failed,
|
||||||
};
|
};
|
||||||
@ -119,13 +111,8 @@ const FileDescriptor = struct{
|
|||||||
}
|
}
|
||||||
|
|
||||||
const get_size = fn (file_descriptor: FileDescriptor) GetAttributesError!u64 {
|
const get_size = fn (file_descriptor: FileDescriptor) GetAttributesError!u64 {
|
||||||
switch (current) {
|
|
||||||
.linux => {
|
|
||||||
const file_attributes = try file_descriptor.get_attributes();
|
const file_attributes = try file_descriptor.get_attributes();
|
||||||
return file_attributes.size;
|
return file_attributes.size;
|
||||||
},
|
|
||||||
else => #error("OS not supported"),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetAttributesError = error{
|
const GetAttributesError = error{
|
||||||
@ -134,9 +121,9 @@ const FileDescriptor = struct{
|
|||||||
|
|
||||||
const get_attributes = fn (file_descriptor: FileDescriptor) GetAttributesError!FileAttributes {
|
const get_attributes = fn (file_descriptor: FileDescriptor) GetAttributesError!FileAttributes {
|
||||||
switch (current) {
|
switch (current) {
|
||||||
.linux => {
|
.linux, .macos => {
|
||||||
var stat_buffer: linux.Stat = undefined;
|
var stat_buffer: system.Stat = undefined;
|
||||||
const raw_result = linux.fstat(file_descriptor.handle, stat_buffer.&);
|
const raw_result = system.fstat(file_descriptor.handle, stat_buffer.&);
|
||||||
const result = unwrap_syscall(raw_result) catch |err| switch (err) {
|
const result = unwrap_syscall(raw_result) catch |err| switch (err) {
|
||||||
else => return GetAttributesError.failed,
|
else => return GetAttributesError.failed,
|
||||||
};
|
};
|
||||||
@ -396,14 +383,34 @@ const AccessMode = enum(u2) {
|
|||||||
const open = fn(path: [&:0]const u8, open_flags: OpenFlags) OpenError!FileDescriptor{
|
const open = fn(path: [&:0]const u8, open_flags: OpenFlags) OpenError!FileDescriptor{
|
||||||
switch (current) {
|
switch (current) {
|
||||||
.linux => {
|
.linux => {
|
||||||
const flags = linux.OpenFlags{
|
const flags = system.OpenFlags{
|
||||||
.access_mode = switch (open_flags.access_mode) {
|
.access_mode = switch (open_flags.access_mode) {
|
||||||
.read_only => .read_only,
|
.read_only => .read_only,
|
||||||
.write_only => .write_only,
|
.write_only => .write_only,
|
||||||
.read_write => .read_write,
|
.read_write => .read_write,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const syscall_result = linux.open(path, flags, 0);
|
const syscall_result = system.open(path, flags, 0);
|
||||||
|
const result = unwrap_syscall(syscall_result) catch |err| switch (err) {
|
||||||
|
else => unreachable,
|
||||||
|
};
|
||||||
|
|
||||||
|
const r: u32 = #cast(result);
|
||||||
|
|
||||||
|
const file_descriptor = FileDescriptor{
|
||||||
|
.handle = #cast(r),
|
||||||
|
};
|
||||||
|
return file_descriptor;
|
||||||
|
},
|
||||||
|
.macos => {
|
||||||
|
const flags = system.OpenFlags{
|
||||||
|
.access_mode = switch (open_flags.access_mode) {
|
||||||
|
.read_only => .read_only,
|
||||||
|
.write_only => .write_only,
|
||||||
|
.read_write => .read_write,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const syscall_result = system.open(path, flags);
|
||||||
const result = unwrap_syscall(syscall_result) catch |err| switch (err) {
|
const result = unwrap_syscall(syscall_result) catch |err| switch (err) {
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
};
|
};
|
||||||
|
@ -919,8 +919,8 @@ const openat = fn(directory_file_descriptor: FileDescriptor, path: [&:0]const u8
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const read = fn(file_descriptor: FileDescriptor, bytes: []u8) usize {
|
const read = fn(file_descriptor: FileDescriptor, byte_pointer: [&]u8, byte_count: usize) usize {
|
||||||
const result = #syscall(#cast(Syscall.read), #cast(file_descriptor), #cast(bytes.pointer), bytes.length);
|
const result = #syscall(#cast(Syscall.read), #cast(file_descriptor), #cast(byte_pointer), byte_count);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
44
src/main.nat
44
src/main.nat
@ -19,6 +19,45 @@ const Token = struct {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const FixedKeyword = enum{
|
||||||
|
"comptime",
|
||||||
|
"const",
|
||||||
|
"var",
|
||||||
|
"void",
|
||||||
|
"noreturn",
|
||||||
|
"while",
|
||||||
|
"bool",
|
||||||
|
"true",
|
||||||
|
"false",
|
||||||
|
"fn",
|
||||||
|
"unreachable",
|
||||||
|
"return",
|
||||||
|
"ssize",
|
||||||
|
"usize",
|
||||||
|
""switch",
|
||||||
|
"if",
|
||||||
|
"else",
|
||||||
|
"struct",
|
||||||
|
"enum",
|
||||||
|
"null",
|
||||||
|
"align",
|
||||||
|
"for",
|
||||||
|
"undefined",
|
||||||
|
"break",
|
||||||
|
"test",
|
||||||
|
"catch",
|
||||||
|
"try",
|
||||||
|
"orelse",
|
||||||
|
"error",
|
||||||
|
"and",
|
||||||
|
"or",
|
||||||
|
"bitfield",
|
||||||
|
"Self",
|
||||||
|
"any",
|
||||||
|
"type",
|
||||||
|
"continue",
|
||||||
|
};
|
||||||
|
|
||||||
const lex = fn (arena: &Arena, bytes: []const u8) *!void {
|
const lex = fn (arena: &Arena, bytes: []const u8) *!void {
|
||||||
if (bytes.length >= 0xffffffff) {
|
if (bytes.length >= 0xffffffff) {
|
||||||
unreachable;
|
unreachable;
|
||||||
@ -72,10 +111,11 @@ const lex = fn (arena: &Arena, bytes: []const u8) *!void {
|
|||||||
's' => .keyword_signed_integer,
|
's' => .keyword_signed_integer,
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
};
|
};
|
||||||
} else {
|
|
||||||
//unreachable;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const string_length = index - start_index;
|
||||||
|
const string = bytes[start_index..][0..string_length];
|
||||||
},
|
},
|
||||||
else => index += 1,
|
else => index += 1,
|
||||||
}
|
}
|
||||||
|
18
test/standalone/comptime_for/main.nat
Normal file
18
test/standalone/comptime_for/main.nat
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
const std = #import("std");
|
||||||
|
const print = std.print;
|
||||||
|
|
||||||
|
const Enum = enum{
|
||||||
|
first_name,
|
||||||
|
second_name,
|
||||||
|
third_name,
|
||||||
|
};
|
||||||
|
|
||||||
|
const main = fn () *!void {
|
||||||
|
print("Enum values:\n");
|
||||||
|
|
||||||
|
for ($#fields(Enum)) |e| {
|
||||||
|
const name: []const u8 = #name(e);
|
||||||
|
print(name);
|
||||||
|
print("\n");
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user