wip
This commit is contained in:
		
							parent
							
								
									b8873564af
								
							
						
					
					
						commit
						1d9a43d66d
					
				| @ -516,6 +516,7 @@ pub const Type = struct { | ||||
|             .integer => |integer| integer.signed, | ||||
|             .bits => |bits| bits.backing_type.is_signed(), | ||||
|             .enumerator => |enumerator| enumerator.backing_type.is_signed(), | ||||
|             .alias => |alias| alias.type.is_signed(), | ||||
|             else => @trap(), | ||||
|         }; | ||||
|     } | ||||
| @ -602,6 +603,7 @@ pub const Type = struct { | ||||
|             .array => |array| array.element_type.get_bit_size() * array.element_count, | ||||
|             .structure => |structure| structure.bit_size, | ||||
|             .enumerator => |enumerator| enumerator.backing_type.get_bit_size(), | ||||
|             .alias => |alias| alias.type.get_bit_size(), | ||||
|             else => @trap(), | ||||
|         }; | ||||
|         return bit_size; | ||||
| @ -3880,7 +3882,7 @@ pub const Module = struct { | ||||
| 
 | ||||
|                             const backing_type = maybe_backing_type orelse blk: { | ||||
|                                 const bits_needed = 64 - @clz(highest_value); | ||||
|                                 const int_type = module.integer_type(bits_needed, false); | ||||
|                                 const int_type = module.integer_type(if (bits_needed == 0) 1 else bits_needed, false); | ||||
|                                 break :blk int_type; | ||||
|                             }; | ||||
| 
 | ||||
| @ -5472,7 +5474,10 @@ pub const Module = struct { | ||||
|     pub fn check_types(module: *Module, expected_type: *Type, source_type: *Type) void { | ||||
|         if (expected_type != source_type) { | ||||
|             const dst_p_src_i = expected_type.bb == .pointer and source_type.bb == .integer; | ||||
|             const result = dst_p_src_i; | ||||
|             const dst_alias_src_not = expected_type.bb == .alias and expected_type.bb.alias.type == source_type; | ||||
|             const src_alias_dst_not = source_type.bb == .alias and source_type.bb.alias.type == expected_type; | ||||
|             const both_alias_to_same_type = expected_type.bb == .alias and source_type.bb == .alias and expected_type.bb.alias.type == source_type.bb.alias.type; | ||||
|             const result = dst_p_src_i or dst_alias_src_not or src_alias_dst_not or both_alias_to_same_type; | ||||
|             if (!result) { | ||||
|                 module.report_error(); | ||||
|             } | ||||
| @ -6782,7 +6787,11 @@ pub const Module = struct { | ||||
|                     } | ||||
|                     const llvm_value = extended_value.llvm orelse unreachable; | ||||
|                     const destination_type = value_type.llvm.abi.?; | ||||
|                     const extension_instruction = switch (extended_value.type.?.bb.integer.signed) { | ||||
|                     const extension_type = switch (extended_value.type.?.bb) { | ||||
|                         .alias => |alias| alias.type, | ||||
|                         else => extended_value.type.?, | ||||
|                     }; | ||||
|                     const extension_instruction = switch (extension_type.bb.integer.signed) { | ||||
|                         true => module.llvm.builder.create_sign_extend(llvm_value, destination_type), | ||||
|                         false => module.llvm.builder.create_zero_extend(llvm_value, destination_type), | ||||
|                     }; | ||||
|  | ||||
							
								
								
									
										282
									
								
								src/compiler.bbb
									
									
									
									
									
								
							
							
						
						
									
										282
									
								
								src/compiler.bbb
									
									
									
									
									
								
							| @ -1,9 +1,85 @@ | ||||
| mode_t = typealias u64; | ||||
| int = typealias s32; | ||||
| usize = typealias u64; | ||||
| ssize = typealias s64; | ||||
| File = typealias s32; | ||||
| 
 | ||||
| [extern] memcmp = fn [cc(c)] (a: &u8, b: &u8, byte_count: u64) s32; | ||||
| uid_t = typealias u32; | ||||
| gid_t = typealias u32; | ||||
| off_t = typealias s64; | ||||
| ino_t = typealias u64; | ||||
| dev_t = typealias u64; | ||||
| 
 | ||||
| timespec = struct | ||||
| { | ||||
|     seconds: ssize, | ||||
|     nanoseconds: ssize, | ||||
| }; | ||||
| 
 | ||||
| Stat = struct | ||||
| { | ||||
|     dev: dev_t, | ||||
|     ino: ino_t, | ||||
|     nlink: usize, | ||||
| 
 | ||||
|     mode: u32, | ||||
|     uid: uid_t, | ||||
|     gid: gid_t, | ||||
|     _: u32, | ||||
|     rdev: dev_t, | ||||
|     size: off_t, | ||||
|     blksize: ssize, | ||||
|     blocks: s64, | ||||
| 
 | ||||
|     atim: timespec, | ||||
|     mtime: timespec, | ||||
|     ctim: timespec, | ||||
|     _: [3]ssize, | ||||
| } | ||||
| 
 | ||||
| OAccessMode = enum u2 | ||||
| { | ||||
|     read_only = 0, | ||||
|     write_only = 1, | ||||
|     read_write = 2, | ||||
| } | ||||
| 
 | ||||
| O = bits u32 | ||||
| { | ||||
|     access_mode: OAccessMode, | ||||
|     _: u4, | ||||
|     creat: u1, | ||||
|     excl: u1, | ||||
|     noctty: u1, | ||||
|     trunc: u1, | ||||
|     append: u1, | ||||
|     nonblock: u1, | ||||
|     dsync: u1, | ||||
|     async: u1, | ||||
|     direct: u1, | ||||
|     _: u1, | ||||
|     directory: u1, | ||||
|     nofollow: u1, | ||||
|     noatime: u1, | ||||
|     cloexec: u1, | ||||
|     sync: u1, | ||||
|     path: u1, | ||||
|     tmpfile: u1, | ||||
|     _: u9, | ||||
| } | ||||
| 
 | ||||
| [extern] memcmp = fn [cc(c)] (a: &u8, b: &u8, byte_count: usize) int; | ||||
| [extern] memcpy = fn [cc(c)] (destination: &u8, source: &u8, byte_count: u64) &u8; | ||||
| [extern] exit = fn [cc(c)] (exit_code: s32) noreturn; | ||||
| [extern] mkdir = fn [cc(c)] (path: &u8, mode: mode_t) s32; | ||||
| [extern] exit = fn [cc(c)] (exit_code: int) noreturn; | ||||
| 
 | ||||
| [extern] realpath = fn [cc(c)] (source_path: &u8, resolved_path: &u8) &u8; | ||||
| [extern] mkdir = fn [cc(c)] (path: &u8, mode: mode_t) int; | ||||
| 
 | ||||
| [extern] open = fn [cc(c)] (path: &u8, o: O, ...) int; | ||||
| [extern] close = fn [cc(c)] (fd: File) int; | ||||
| [extern] fstat = fn [cc(c)] (fd: File, s: &Stat) int; | ||||
| [extern] write = fn [cc(c)] (fd: File, pointer: &u8, byte_count: u64) ssize; | ||||
| [extern] read = fn [cc(c)] (fd: File, pointer: &u8, byte_count: u64) ssize; | ||||
| 
 | ||||
| assert = fn (ok: u1) void | ||||
| { | ||||
| @ -177,6 +253,109 @@ os_make_directory = fn (path: &u8) void | ||||
|     >result = mkdir(path, 0o755); | ||||
| } | ||||
| 
 | ||||
| OpenFlags = bits | ||||
| { | ||||
|     truncate: u1, | ||||
|     execute: u1, | ||||
|     write: u1, | ||||
|     read: u1, | ||||
|     create: u1, | ||||
|     directory: u1, | ||||
| } | ||||
| 
 | ||||
| OpenPermissions = bits | ||||
| { | ||||
|     read: u1, | ||||
|     write: u1, | ||||
|     execute: u1, | ||||
| } | ||||
| 
 | ||||
| os_file_open = fn (path: &u8, flags: OpenFlags, permissions: OpenPermissions) File | ||||
| { | ||||
|     >access_mode: OAccessMode = undefined; | ||||
|     if (flags.read and flags.write) | ||||
|     { | ||||
|         access_mode = .read_write; | ||||
|     } | ||||
|     else if (flags.read) | ||||
|     { | ||||
|         access_mode = .read_only; | ||||
|     } | ||||
|     else if (flags.write) | ||||
|     { | ||||
|         access_mode = .write_only; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         unreachable; | ||||
|     } | ||||
| 
 | ||||
|     >o: O = { | ||||
|         .access_mode = access_mode, | ||||
|         .trunc = flags.truncate, | ||||
|         .creat = flags.create, | ||||
|         .directory = flags.directory, | ||||
|     }; | ||||
| 
 | ||||
|     >mode: mode_t = #select(permissions.execute, 0o755, 0o644); | ||||
|     >fd = open(path, o, mode); | ||||
|     return fd; | ||||
| } | ||||
| 
 | ||||
| os_file_close = fn (fd: File) void | ||||
| { | ||||
|     >result = close(fd); | ||||
|     assert(result == 0); | ||||
| } | ||||
| 
 | ||||
| os_file_is_valid = fn (fd: File) u1 | ||||
| { | ||||
|     return fd >= 0; | ||||
| } | ||||
| 
 | ||||
| os_file_get_size = fn (fd: File) u64 | ||||
| { | ||||
|     >stat: Stat = undefined; | ||||
|     >result = fstat(fd, &stat); | ||||
|     assert(result == 0); | ||||
|     return #extend(stat.size); | ||||
| } | ||||
| 
 | ||||
| os_file_read_partially = fn (fd: File, pointer: &u8, length: u64) u64 | ||||
| { | ||||
|     >result = read(fd, pointer, length); | ||||
|     assert(result > 0); | ||||
|     return #extend(result); | ||||
| } | ||||
| 
 | ||||
| os_file_read = fn (fd: File, buffer: []u8, byte_count: u64) void | ||||
| { | ||||
|     assert(byte_count <= buffer.length); | ||||
| 
 | ||||
|     >total_read_byte_count: u64 = 0; | ||||
| 
 | ||||
|     while (total_read_byte_count < byte_count) | ||||
|     { | ||||
|         >read_byte_count = os_file_read_partially(fd, buffer.pointer + total_read_byte_count, byte_count - total_read_byte_count); | ||||
|         total_read_byte_count += read_byte_count; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| os_path_absolute_stack = fn (buffer: []u8, relative_file_path: &u8) []u8 | ||||
| { | ||||
|     >syscall_result = realpath(relative_file_path, buffer.pointer); | ||||
| 
 | ||||
|     >result: []u8 = zero; | ||||
| 
 | ||||
|     if (syscall_result) | ||||
|     { | ||||
|         result = c_string_to_slice(syscall_result); | ||||
|         assert(result.length < buffer.length); | ||||
|     } | ||||
| 
 | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
| Arena = struct | ||||
| { | ||||
|     reserved_size: u64, | ||||
| @ -264,6 +443,13 @@ arena_allocate_bytes = fn (arena: &Arena, size: u64, alignment: u64) &u8 | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
| arena_duplicate_string = fn (arena: &Arena, string: []u8) []u8 | ||||
| { | ||||
|     >result = arena_allocate_bytes(arena, string.length + 1, 1); | ||||
|     memcpy(result, string.pointer, string.length); | ||||
|     return result[..string.length]; | ||||
| } | ||||
| 
 | ||||
| arena_join_string = fn (arena: &Arena, pieces: [][]u8) []u8 | ||||
| { | ||||
|     >size: u64 = 0; | ||||
| @ -288,6 +474,32 @@ arena_join_string = fn (arena: &Arena, pieces: [][]u8) []u8 | ||||
|     return pointer[..size]; | ||||
| } | ||||
| 
 | ||||
| file_read = fn (arena: &Arena, path: []u8) []u8 | ||||
| { | ||||
|     >fd = os_file_open(path.pointer, { .read = 1 }, { .read = 1 }); | ||||
| 
 | ||||
|     >result: []u8 = zero; | ||||
| 
 | ||||
|     if (os_file_is_valid(fd)) | ||||
|     { | ||||
|         >file_size = os_file_get_size(fd); | ||||
|         >file_buffer = arena_allocate_bytes(arena, file_size, 1); | ||||
|         result = file_buffer[..file_size]; | ||||
|         os_file_read(fd, result, file_size); | ||||
|         os_file_close(fd); | ||||
|     } | ||||
| 
 | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
| path_absolute = fn (arena: &Arena, relative_file_path: &u8) []u8 | ||||
| { | ||||
|     >buffer: [4096]u8 = undefined; | ||||
|     >stack_slice = os_path_absolute_stack(buffer[..], relative_file_path); | ||||
|     >result = arena_duplicate_string(arena, stack_slice); | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
| GlobalState = struct | ||||
| { | ||||
|     arena: &Arena, | ||||
| @ -335,9 +547,42 @@ CompileFile = struct | ||||
| 
 | ||||
| base_cache_dir = "bb-cache"; | ||||
| 
 | ||||
| compile_file = fn (arena: &Arena, compile: CompileFile) void | ||||
| CPUArchitecture = enum | ||||
| { | ||||
|     >relative_file_path = compile.relative_file_path; | ||||
|     x86_64, | ||||
| } | ||||
| 
 | ||||
| OperatingSystem = enum | ||||
| { | ||||
|     linux, | ||||
| } | ||||
| 
 | ||||
| Target = struct | ||||
| { | ||||
|     cpu: CPUArchitecture, | ||||
|     os: OperatingSystem, | ||||
| } | ||||
| 
 | ||||
| CompileOptions = struct | ||||
| { | ||||
|     content: []u8, | ||||
|     path: []u8, | ||||
|     executable: []u8, | ||||
|     name: []u8, | ||||
|     objects: [][]u8, | ||||
|     target: Target, | ||||
|     build_mode: BuildMode, | ||||
|     has_debug_info: u1, | ||||
|     silent: u1, | ||||
| } | ||||
| 
 | ||||
| compile = fn (arena: &Arena, options: CompileOptions) void | ||||
| { | ||||
| } | ||||
| 
 | ||||
| compile_file = fn (arena: &Arena, compile_options: CompileFile) void | ||||
| { | ||||
|     >relative_file_path = compile_options.relative_file_path; | ||||
|     if (relative_file_path.length < 5) | ||||
|     { | ||||
|         fail(); | ||||
| @ -367,10 +612,33 @@ compile_file = fn (arena: &Arena, compile: CompileFile) void | ||||
|     >outputh_path_dir = arena_join_string(arena, [ | ||||
|         base_cache_dir, | ||||
|         #select(is_compiler, "/compiler/", "/"), | ||||
|         #enum_name(compile.build_mode), | ||||
|         #enum_name(compile_options.build_mode), | ||||
|         "_", | ||||
|         #select(compile.has_debug_info, "di", "nodi"), | ||||
|         #select(compile_options.has_debug_info, "di", "nodi"), | ||||
|     ][..]); | ||||
| 
 | ||||
|     os_make_directory(base_cache_dir.pointer); | ||||
|     if (is_compiler) | ||||
|     { | ||||
|         >compiler_dir = arena_join_string(arena, [ base_cache_dir, "/compiler" ][..]); | ||||
|         os_make_directory(compiler_dir.pointer); | ||||
|     } | ||||
|     os_make_directory(outputh_path_dir.pointer); | ||||
| 
 | ||||
|     >outputh_path_base = arena_join_string(arena, [ outputh_path_dir, "/", base_name ][..]); | ||||
| 
 | ||||
|     >output_object_path = arena_join_string(arena, [ outputh_path_base, ".o" ][..]); | ||||
|     >output_executable_path = outputh_path_base; | ||||
| 
 | ||||
|     >file_content = file_read(arena, relative_file_path); | ||||
|     >file_path = path_absolute(arena, relative_file_path.pointer); | ||||
|     >c_abi_object_path = ""; // TODO | ||||
| 
 | ||||
|     >options: CompileOptions = { | ||||
|         zero, | ||||
|     }; | ||||
| 
 | ||||
|     compile(arena, options); | ||||
| } | ||||
| 
 | ||||
| [export] main = fn [cc(c)] (argument_count: u32, argv: &&u8) s32 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user