204 lines
5.4 KiB
Plaintext
204 lines
5.4 KiB
Plaintext
const std = #import("std");
|
|
const Arena = std.Arena;
|
|
const c_slice = std.c_slice;
|
|
const byte_equal = std.byte_equal;
|
|
const print = std.print;
|
|
const print_usize = std.print_usize;
|
|
const exit = std.os.exit;
|
|
|
|
const lex = fn (arena: &Arena, bytes: []const u8) *!void {
|
|
if (bytes.length >= 0xffffffff) {
|
|
unreachable;
|
|
}
|
|
|
|
const length: u32 = #cast(bytes.length);
|
|
|
|
const max_initial_keyword_len: u32 = 8;
|
|
|
|
//var index: u32 = 0;
|
|
//while (index + 64 < length) {
|
|
// var i = index;
|
|
// const top = index + max_initial_keyword_len + 1;
|
|
// var space: u32 = 0;
|
|
|
|
// while (i < top) {
|
|
// const is_space = bytes[i] == ' ';
|
|
// const is_space_int: u32 = #cast(is_space);
|
|
// const space_mask = 0 -% is_space_int;
|
|
// space |= (1 << i) & space_mask;
|
|
// i += 1;
|
|
// }
|
|
|
|
// if (space == 0) {
|
|
// unreachable;
|
|
// }
|
|
|
|
// const word_byte_count = #trailing_zeroes(space);
|
|
// const word = bytes[index..][0..word_byte_count];
|
|
|
|
// if (byte_equal(word, #name(FileStartToken."comptime"))) {
|
|
// } else if (byte_equal(word, #name(FileStartToken."test"))) {
|
|
// } else if (byte_equal(word, #name(FileStartToken."const"))) {
|
|
// } else if (byte_equal(word, #name(FileStartToken."var"))) {
|
|
// } else {
|
|
// print("Wrong file declaration start\n");
|
|
// }
|
|
|
|
// break;
|
|
//}
|
|
}
|
|
|
|
const FileStartToken = enum{
|
|
"comptime",
|
|
"test",
|
|
"const",
|
|
"var",
|
|
};
|
|
|
|
const ArgumentProcessingError = error{
|
|
no_arguments,
|
|
};
|
|
|
|
const Token = struct {
|
|
const Id = enum(u8) {
|
|
invalid,
|
|
keyword_unsigned_integer,
|
|
keyword_signed_integer,
|
|
identifier,
|
|
};
|
|
};
|
|
|
|
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 get_argument = fn (real_argument: []const u8, wanted_argument: []const u8, command_arguments: []const [&:0]const u8, i_ptr: &usize) ?[]const u8 {
|
|
const i = i_ptr.@;
|
|
|
|
const are_equal = byte_equal(real_argument, wanted_argument);
|
|
if (are_equal) {
|
|
if (i < command_arguments.length) {
|
|
const new_i = i + 1;
|
|
const argument = c_slice(command_arguments[new_i]);
|
|
i_ptr.@ = new_i;
|
|
return argument;
|
|
} else {
|
|
print("error: unterminated argument: '");
|
|
print(real_argument);
|
|
print("'\n");
|
|
exit(1);
|
|
}
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
const command_exe = fn (arena: &Arena, command_arguments: []const [&:0]const u8) *!void {
|
|
var i: usize = 0;
|
|
|
|
var maybe_output_argument: ?[]const u8 = null;
|
|
var maybe_main_source_file: ?[]const u8 = null;
|
|
var maybe_main_executable_name: ?[]const u8 = null;
|
|
|
|
while (i < command_arguments.length) {
|
|
const command_argument = c_slice(command_arguments[i]);
|
|
|
|
if (get_argument(command_argument, "-o", command_arguments, i.&)) |out_arg| {
|
|
maybe_output_argument = out_arg;
|
|
} else if (get_argument(command_argument, "-main_source_file", command_arguments, i.&)) |src_arg| {
|
|
maybe_main_source_file = src_arg;
|
|
} else {
|
|
print("error: unhandled argument: '");
|
|
print(command_argument);
|
|
print("'\n");
|
|
exit(1);
|
|
}
|
|
|
|
i += 1;
|
|
}
|
|
|
|
const main_source_file = maybe_main_source_file orelse {
|
|
print("error: no main source file specified\n");
|
|
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
|
|
|
|
const file_descriptor = try std.os.open(#cast(main_source_file.pointer), .{});
|
|
const file_size = try file_descriptor.get_size();
|
|
const file_buffer = try arena.new_array($u8, file_size);
|
|
file_descriptor.read_all(file_buffer);
|
|
|
|
lex(arena, file_buffer);
|
|
}
|
|
|
|
const main = fn() *!void {
|
|
const arena = try Arena.init(std.megabytes(64));
|
|
const argument_count = std.start.argument_count;
|
|
|
|
if (argument_count <= 1) {
|
|
return ArgumentProcessingError.no_arguments;
|
|
}
|
|
|
|
const argument_values = std.start.argument_values;
|
|
const arguments = argument_values[0..argument_count];
|
|
|
|
const command = c_slice(arguments[1]);
|
|
const command_arguments = arguments[2..];
|
|
|
|
if (byte_equal(command, "build")) {
|
|
print("TODO: build");
|
|
} else if (byte_equal(command, "clang") or byte_equal(command, "-cc1") or byte_equal(command, "-cc1as")) {
|
|
unreachable;
|
|
} else if (byte_equal(command, "cc")) {
|
|
unreachable;
|
|
} else if (byte_equal(command, "c++")) {
|
|
unreachable;
|
|
} else if (byte_equal(command, "exe")) {
|
|
command_exe(arena, command_arguments);
|
|
} else if (byte_equal(command, "lib")) {
|
|
unreachable;
|
|
} else if (byte_equal(command, "obj")) {
|
|
unreachable;
|
|
} else if (byte_equal(command, "test")) {
|
|
print("TODO: test");
|
|
} else {
|
|
unreachable;
|
|
}
|
|
}
|