diff --git a/build.bat b/build.bat index 8619f775f..2e3e58471 100644 --- a/build.bat +++ b/build.bat @@ -31,32 +31,32 @@ set linker_flags= -incremental:no -opt:ref -subsystem:console if %release_mode% EQU 0 ( rem Debug set linker_flags=%linker_flags% -debug - set libs=%libs% ..\src\utf8proc\utf8proc_debug.lib + set libs=%libs% src\utf8proc\utf8proc_debug.lib ) else ( rem Release set linker_flags=%linker_flags% - set libs=%libs% ..\src\utf8proc\utf8proc.lib + set libs=%libs% src\utf8proc\utf8proc.lib ) set compiler_settings=%compiler_includes% %compiler_flags% %compiler_warnings% set linker_settings=%libs% %linker_flags% -set build_dir= "bin\" -if not exist %build_dir% mkdir %build_dir% -pushd %build_dir% +rem set build_dir= "\" +rem if not exist %build_dir% mkdir %build_dir% +rem pushd %build_dir% del *.pdb > NUL 2> NUL del *.ilk > NUL 2> NUL del ..\misc\*.pdb > NUL 2> NUL del ..\misc\*.ilk > NUL 2> NUL - cl %compiler_settings% "..\src\main.cpp" ^ + cl %compiler_settings% "src\main.cpp" ^ /link %linker_settings% -OUT:%exe_name% ^ - && odin run ..\code/demo.odin - rem odin run ..\code/demo.odin + && odin run code/demo.odin + rem odin run code/demo.odin :do_not_compile_exe -popd +rem popd :end_of_build diff --git a/code/fmt.odin b/code/fmt.odin deleted file mode 100644 index 0c7e3a696..000000000 --- a/code/fmt.odin +++ /dev/null @@ -1,583 +0,0 @@ -#import "os.odin" as os - -print_byte_buffer :: proc(buf: ^[]byte, b: []byte) { - if buf.count < buf.capacity { - n := min(buf.capacity-buf.count, b.count) - if n > 0 { - offset := ptr_offset(buf.data, buf.count) - memory_copy(offset, ^b[0], n) - buf.count += n - } - } -} - -print_string_to_buffer :: proc(buf: ^[]byte, s: string) { - print_byte_buffer(buf, s as []byte) -} - - -byte_reverse :: proc(b: []byte) { - n := b.count - for i := 0; i < n/2; i++ { - b[i], b[n-1-i] = b[n-1-i], b[i] - } -} - -encode_rune :: proc(r: rune) -> ([4]byte, int) { - buf: [4]byte - i := r as u32 - mask: byte : 0x3f - if i <= 1<<7-1 { - buf[0] = r as byte - return buf, 1 - } - if i <= 1<<11-1 { - buf[0] = 0xc0 | (r>>6) as byte - buf[1] = 0x80 | (r) as byte & mask - return buf, 2 - } - - // Invalid or Surrogate range - if i > 0x0010ffff || - (i >= 0xd800 && i <= 0xdfff) { - r = 0xfffd - } - - if i <= 1<<16-1 { - buf[0] = 0xe0 | (r>>12) as byte - buf[1] = 0x80 | (r>>6) as byte & mask - buf[2] = 0x80 | (r) as byte & mask - return buf, 3 - } - - buf[0] = 0xf0 | (r>>18) as byte - buf[1] = 0x80 | (r>>12) as byte & mask - buf[2] = 0x80 | (r>>6) as byte & mask - buf[3] = 0x80 | (r) as byte & mask - return buf, 4 -} - -print_rune_to_buffer :: proc(buf: ^[]byte, r: rune) { - b, n := encode_rune(r) - print_string_to_buffer(buf, b[:n] as string) -} - -print_space_to_buffer :: proc(buf: ^[]byte) { print_rune_to_buffer(buf, #rune " ") } -print_nl_to_buffer :: proc(buf: ^[]byte) { print_rune_to_buffer(buf, #rune "\n") } - -print_int_to_buffer :: proc(buf: ^[]byte, i: int) { - print_int_base_to_buffer(buf, i, 10); -} -PRINT__NUM_TO_CHAR_TABLE :: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz@$" -print_int_base_to_buffer :: proc(buffer: ^[]byte, i, base: int) { - - buf: [65]byte - len := 0 - negative := false - if i < 0 { - negative = true - i = -i - } - if i == 0 { - buf[len] = #rune "0" - len++ - } - for i > 0 { - buf[len] = PRINT__NUM_TO_CHAR_TABLE[i % base] - len++ - i /= base - } - - if negative { - buf[len] = #rune "-" - len++ - } - - byte_reverse(buf[:len]) - print_string_to_buffer(buffer, buf[:len] as string) -} - -print_uint_to_buffer :: proc(buffer: ^[]byte, i: uint) { - print_uint_base_to_buffer(buffer, i, 10, 0, #rune " ") -} -print_uint_base_to_buffer :: proc(buffer: ^[]byte, i, base: uint, min_width: int, pad_char: byte) { - buf: [65]byte - len := 0 - if i == 0 { - buf[len] = #rune "0" - len++ - } - for i > 0 { - buf[len] = PRINT__NUM_TO_CHAR_TABLE[i % base] - len++ - i /= base - } - for len < min_width { - buf[len] = pad_char - len++ - } - - byte_reverse(buf[:len]) - print_string_to_buffer(buffer, buf[:len] as string) -} - -print_bool_to_buffer :: proc(buffer: ^[]byte, b : bool) { - if b { print_string_to_buffer(buffer, "true") } - else { print_string_to_buffer(buffer, "false") } -} - -print_pointer_to_buffer :: proc(buffer: ^[]byte, p: rawptr) #inline { print_uint_base_to_buffer(buffer, p as uint, 16, 0, #rune " ") } - -print_f32_to_buffer :: proc(buffer: ^[]byte, f: f32) #inline { print__f64(buffer, f as f64, 7) } -print_f64_to_buffer :: proc(buffer: ^[]byte, f: f64) #inline { print__f64(buffer, f, 10) } - -print__f64 :: proc(buffer: ^[]byte, f: f64, decimal_places: int) { - if f == 0 { - print_rune_to_buffer(buffer, #rune "0") - return - } - if f < 0 { - print_rune_to_buffer(buffer, #rune "-") - f = -f - } - - print_u64_to_buffer :: proc(buffer: ^[]byte, i: u64) { - buf: [22]byte - len := 0 - if i == 0 { - buf[len] = #rune "0" - len++ - } - for i > 0 { - buf[len] = PRINT__NUM_TO_CHAR_TABLE[i % 10] - len++ - i /= 10 - } - byte_reverse(buf[:len]) - print_string_to_buffer(buffer, buf[:len] as string) - } - - i := f as u64 - print_u64_to_buffer(buffer, i) - f -= i as f64 - - print_rune_to_buffer(buffer, #rune ".") - - mult := 10.0 - for decimal_places := 6; decimal_places >= 0; decimal_places-- { - i = (f * mult) as u64 - print_u64_to_buffer(buffer, i as u64) - f -= i as f64 / mult - mult *= 10 - } -} - -print_type_to_buffer :: proc(buf: ^[]byte, ti: ^Type_Info) { - if ti == null { return } - - using Type_Info - match type info : ti { - case Named: - print_string_to_buffer(buf, info.name) - case Integer: - match { - case ti == type_info(int): - print_string_to_buffer(buf, "int") - case ti == type_info(uint): - print_string_to_buffer(buf, "uint") - default: - if info.signed { - print_string_to_buffer(buf, "i") - } else { - print_string_to_buffer(buf, "u") - } - print_int_to_buffer(buf, 8*info.size) - } - - case Float: - match info.size { - case 4: print_string_to_buffer(buf, "f32") - case 8: print_string_to_buffer(buf, "f64") - } - case String: print_string_to_buffer(buf, "string") - case Boolean: print_string_to_buffer(buf, "bool") - case Pointer: - print_string_to_buffer(buf, "^") - print_type_to_buffer(buf, info.elem) - case Procedure: - print_string_to_buffer(buf, "proc") - if info.params == null { - print_string_to_buffer(buf, "()") - } else { - count := (info.params as ^Tuple).fields.count - if count == 1 { print_string_to_buffer(buf, "(") } - print_type_to_buffer(buf, info.params) - if count == 1 { print_string_to_buffer(buf, ")") } - } - if info.results != null { - print_string_to_buffer(buf, " -> ") - print_type_to_buffer(buf, info.results) - } - case Tuple: - count := info.fields.count - if count != 1 { print_string_to_buffer(buf, "(") } - for i := 0; i < count; i++ { - if i > 0 { print_string_to_buffer(buf, ", ") } - - f := info.fields[i] - - if f.name.count > 0 { - print_string_to_buffer(buf, f.name) - print_string_to_buffer(buf, ": ") - } - print_type_to_buffer(buf, f.type_info) - } - if count != 1 { print_string_to_buffer(buf, ")") } - - case Array: - print_string_to_buffer(buf, "[") - print_int_to_buffer(buf, info.count) - print_string_to_buffer(buf, "]") - print_type_to_buffer(buf, info.elem) - case Slice: - print_string_to_buffer(buf, "[") - print_string_to_buffer(buf, "]") - print_type_to_buffer(buf, info.elem) - case Vector: - print_string_to_buffer(buf, "{") - print_int_to_buffer(buf, info.count) - print_string_to_buffer(buf, "}") - print_type_to_buffer(buf, info.elem) - - case Struct: - print_string_to_buffer(buf, "struct ") - if info.packed { print_string_to_buffer(buf, "#packed ") } - if info.ordered { print_string_to_buffer(buf, "#ordered ") } - print_string_to_buffer(buf, "{") - for i := 0; i < info.fields.count; i++ { - if i > 0 { - print_string_to_buffer(buf, ", ") - } - print_any_to_buffer(buf, info.fields[i].name) - print_string_to_buffer(buf, ": ") - print_type_to_buffer(buf, info.fields[i].type_info) - } - print_string_to_buffer(buf, "}") - - case Union: - print_string_to_buffer(buf, "union {") - for i := 0; i < info.fields.count; i++ { - if i > 0 { - print_string_to_buffer(buf, ", ") - } - print_any_to_buffer(buf, info.fields[i].name) - print_string_to_buffer(buf, ": ") - print_type_to_buffer(buf, info.fields[i].type_info) - } - print_string_to_buffer(buf, "}") - - case Raw_Union: - print_string_to_buffer(buf, "raw_union {") - for i := 0; i < info.fields.count; i++ { - if i > 0 { - print_string_to_buffer(buf, ", ") - } - print_any_to_buffer(buf, info.fields[i].name) - print_string_to_buffer(buf, ": ") - print_type_to_buffer(buf, info.fields[i].type_info) - } - print_string_to_buffer(buf, "}") - - case Enum: - print_string_to_buffer(buf, "enum ") - print_type_to_buffer(buf, info.base) - print_string_to_buffer(buf, "{}") - } -} - - -print_any_to_buffer :: proc(buf: ^[]byte, arg: any) { - using Type_Info - match type info : arg.type_info { - case Named: - a: any - a.type_info = info.base - a.data = arg.data - match type b : info.base { - case Struct: - print_string_to_buffer(buf, info.name) - print_string_to_buffer(buf, "{") - for i := 0; i < b.fields.count; i++ { - f := b.fields[i]; - if i > 0 { - print_string_to_buffer(buf, ", ") - } - print_any_to_buffer(buf, f.name) - print_string_to_buffer(buf, " = ") - v: any - v.type_info = f.type_info - v.data = ptr_offset(arg.data as ^byte, f.offset) - print_any_to_buffer(buf, v) - } - print_string_to_buffer(buf, "}") - - default: - print_any_to_buffer(buf, a) - } - - case Integer: - if info.signed { - i: int = 0; - if arg.data != null { - match info.size { - case 1: i = (arg.data as ^i8)^ as int - case 2: i = (arg.data as ^i16)^ as int - case 4: i = (arg.data as ^i32)^ as int - case 8: i = (arg.data as ^i64)^ as int - case 16: i = (arg.data as ^i128)^ as int - } - } - print_int_to_buffer(buf, i) - } else { - i: uint = 0; - if arg.data != null { - match info.size { - case 1: i = (arg.data as ^u8)^ as uint - case 2: i = (arg.data as ^u16)^ as uint - case 4: i = (arg.data as ^u32)^ as uint - case 8: i = (arg.data as ^u64)^ as uint - case 16: i = (arg.data as ^u128)^ as uint - } - } - print_uint_to_buffer(buf, i) - } - - case Float: - f: f64 = 0 - if arg.data != null { - match info.size { - case 4: f = (arg.data as ^f32)^ as f64 - case 8: f = (arg.data as ^f64)^ as f64 - } - } - print_f64_to_buffer(buf, f) - - case String: - s := "" - if arg.data != null { - s = (arg.data as ^string)^ - } - print_string_to_buffer(buf, s) - - case Boolean: - v := false; - if arg.data != null { - v = (arg.data as ^bool)^ - } - print_bool_to_buffer(buf, v) - - case Pointer: - v := null; - if arg.data != null { - v = (arg.data as ^rawptr)^ - } - print_pointer_to_buffer(buf, v) - - case Enum: - v: any - v.data = arg.data - v.type_info = info.base - print_any_to_buffer(buf, v) - - - case Array: - print_string_to_buffer(buf, "[") - defer print_string_to_buffer(buf, "]") - - for i := 0; i < info.count; i++ { - if i > 0 { - print_string_to_buffer(buf, ", ") - } - - elem: any - elem.data = (arg.data as int + i*info.elem_size) as rawptr - elem.type_info = info.elem - print_any_to_buffer(buf, elem) - } - - case Slice: - slice := arg.data as ^[]byte - print_string_to_buffer(buf, "[") - defer print_string_to_buffer(buf, "]") - - for i := 0; i < slice.count; i++ { - if i > 0 { - print_string_to_buffer(buf, ", ") - } - - elem: any - elem.data = ptr_offset(slice.data, i*info.elem_size) - elem.type_info = info.elem - print_any_to_buffer(buf, elem) - } - - case Vector: - print_string_to_buffer(buf, "<") - defer print_string_to_buffer(buf, ">") - - for i := 0; i < info.count; i++ { - if i > 0 { - print_string_to_buffer(buf, ", ") - } - - elem: any - elem.data = ptr_offset(arg.data as ^byte, i*info.elem_size) - elem.type_info = info.elem - print_any_to_buffer(buf, elem) - } - - - case Struct: - print_string_to_buffer(buf, "struct") - print_string_to_buffer(buf, "{") - defer print_string_to_buffer(buf, "}") - - for i := 0; i < info.fields.count; i++ { - if i > 0 { - print_string_to_buffer(buf, ", ") - } - print_any_to_buffer(buf, info.fields[i].name) - print_string_to_buffer(buf, " = ") - a: any - a.data = ptr_offset(arg.data as ^byte, info.fields[i].offset) - a.type_info = info.fields[i].type_info - print_any_to_buffer(buf, a) - } - - case Union: - print_string_to_buffer(buf, "(union)") - case Raw_Union: - print_string_to_buffer(buf, "(raw_union)") - case Procedure: - print_type_to_buffer(buf, arg.type_info) - print_string_to_buffer(buf, " @ 0x") - print_pointer_to_buffer(buf, (arg.data as ^rawptr)^) - - default: - } -} - -type_info_is_string :: proc(info: ^Type_Info) -> bool { - using Type_Info - if info == null { - return false - } - - for { - match type i : info { - case Named: - info = i.base - continue - case String: - return true - default: - return false - } - } - return false -} - - -print_to_buffer :: proc(buf: ^[]byte, fmt: string, args: ..any) { - is_digit :: proc(r: rune) -> bool #inline { - return r >= #rune "0" && r <= #rune "9" - } - - parse_int :: proc(s: string, offset: int) -> (int, int) { - result := 0 - - for ; offset < s.count; offset++ { - c := s[offset] as rune - if !is_digit(c) { - break - } - - result *= 10 - result += (c - #rune "0") as int - } - - return result, offset - } - - prev := 0 - implicit_index := 0 - - for i := 0; i < fmt.count; i++ { - r := fmt[i] as rune - index := implicit_index - - if r != #rune "%" { - continue - } - - print_string_to_buffer(buf, fmt[prev:i]) - i++ // Skip % - if i < fmt.count { - next := fmt[i] as rune - - if next == #rune "%" { - print_string_to_buffer(buf, "%") - i++ - prev = i - continue - } - - if is_digit(next) { - index, i = parse_int(fmt, i) - } - } - - if 0 <= index && index < args.count { - print_any_to_buffer(buf, args[index]) - implicit_index = index+1 - } else { - // TODO(bill): Error check index out bounds - print_string_to_buffer(buf, "") - } - - prev = i - } - - print_string_to_buffer(buf, fmt[prev:]) -} - -PRINT_BUF_SIZE :: 1<<12 - -print_to_file :: proc(f: ^os.File, fmt: string, args: ..any) { - data: [PRINT_BUF_SIZE]byte - buf := data[:0] - print_to_buffer(^buf, fmt, ..args) - os.write(f, buf) -} - -println_to_file :: proc(f: ^os.File, fmt: string, args: ..any) { - data: [PRINT_BUF_SIZE]byte - buf := data[:0] - print_to_buffer(^buf, fmt, ..args) - print_nl_to_buffer(^buf) - os.write(f, buf) -} - - -print :: proc(fmt: string, args: ..any) { - print_to_file(os.get_standard_file(os.File_Standard.OUTPUT), fmt, ..args) -} -print_err :: proc(fmt: string, args: ..any) { - print_to_file(os.get_standard_file(os.File_Standard.ERROR), fmt, ..args) -} -println :: proc(fmt: string, args: ..any) { - println_to_file(os.get_standard_file(os.File_Standard.OUTPUT), fmt, ..args) -} -println_err :: proc(fmt: string, args: ..any) { - println_to_file(os.get_standard_file(os.File_Standard.ERROR), fmt, ..args) -} diff --git a/code/opengl.odin b/code/opengl.odin deleted file mode 100644 index 59f0b6480..000000000 --- a/code/opengl.odin +++ /dev/null @@ -1,49 +0,0 @@ -#foreign_system_library "opengl32" - -ZERO :: 0x0000 -ONE :: 0x0001 -TRIANGLES :: 0x0004 -BLEND :: 0x0be2 -SRC_ALPHA :: 0x0302 -ONE_MINUS_SRC_ALPHA :: 0x0303 -TEXTURE_2D :: 0x0de1 -RGBA8 :: 0x8058 -UNSIGNED_BYTE :: 0x1401 -BGRA_EXT :: 0x80e1 -TEXTURE_MAX_LEVEL :: 0x813d -RGBA :: 0x1908 - -NEAREST :: 0x2600 -LINEAR :: 0x2601 - -DEPTH_BUFFER_BIT :: 0x00000100 -STENCIL_BUFFER_BIT :: 0x00000400 -COLOR_BUFFER_BIT :: 0x00004000 - -TEXTURE_MAX_ANISOTROPY_EXT :: 0x84fe - -TEXTURE_MAG_FILTER :: 0x2800 -TEXTURE_MIN_FILTER :: 0x2801 -TEXTURE_WRAP_S :: 0x2802 -TEXTURE_WRAP_T :: 0x2803 - -Clear :: proc(mask: u32) #foreign "glClear" -ClearColor :: proc(r, g, b, a: f32) #foreign "glClearColor" -Begin :: proc(mode: i32) #foreign "glBegin" -End :: proc() #foreign "glEnd" -Color3f :: proc(r, g, b: f32) #foreign "glColor3f" -Color4f :: proc(r, g, b, a: f32) #foreign "glColor4f" -Vertex2f :: proc(x, y: f32) #foreign "glVertex2f" -Vertex3f :: proc(x, y, z: f32) #foreign "glVertex3f" -TexCoord2f :: proc(u, v: f32) #foreign "glTexCoord2f" -LoadIdentity :: proc() #foreign "glLoadIdentity" -Ortho :: proc(left, right, bottom, top, near, far: f64) #foreign "glOrtho" -BlendFunc :: proc(sfactor, dfactor: i32) #foreign "glBlendFunc" -Enable :: proc(cap: i32) #foreign "glEnable" -Disable :: proc(cap: i32) #foreign "glDisable" -GenTextures :: proc(count: i32, result: ^u32) #foreign "glGenTextures" -TexParameteri :: proc(target, pname, param: i32) #foreign "glTexParameteri" -TexParameterf :: proc(target: i32, pname: i32, param: f32) #foreign "glTexParameterf" -BindTexture :: proc(target: i32, texture: u32) #foreign "glBindTexture" -TexImage2D :: proc(target, level, internal_format, width, height, border, format, _type: i32, pixels: rawptr) #foreign "glTexImage2D" - diff --git a/code/os.odin b/code/os.odin deleted file mode 100644 index dbfd7f723..000000000 --- a/code/os.odin +++ /dev/null @@ -1,107 +0,0 @@ -#import "runtime.odin" as _ // TODO(bill): make the compile import this automatically -#import "win32.odin" as win32 - -File :: type struct { - Handle :: type win32.HANDLE - handle: Handle -} - -open :: proc(name: string) -> (File, bool) { - using win32 - buf: [300]byte - copy(buf[:], name as []byte) - f := File{CreateFileA(^buf[0], FILE_GENERIC_READ, FILE_SHARE_READ, null, OPEN_EXISTING, 0, null)} - success := f.handle != INVALID_HANDLE_VALUE as File.Handle - - return f, success -} - -create :: proc(name: string) -> (File, bool) { - using win32 - buf: [300]byte - copy(buf[:], name as []byte) - f := File{ - handle = CreateFileA(^buf[0], FILE_GENERIC_WRITE, FILE_SHARE_READ, null, CREATE_ALWAYS, 0, null), - } - success := f.handle != INVALID_HANDLE_VALUE as File.Handle - return f, success -} - - -close :: proc(using f: ^File) { - win32.CloseHandle(handle) -} - -write :: proc(using f: ^File, buf: []byte) -> bool { - bytes_written: i32 - return win32.WriteFile(handle, buf.data, buf.count as i32, ^bytes_written, null) != 0 -} - - -File_Standard :: type enum { - INPUT, - OUTPUT, - ERROR, - COUNT, -} - -__std_files := __set_file_standards(); - -__set_file_standards :: proc() -> [File_Standard.COUNT as int]File { - return [File_Standard.COUNT as int]File{ - File{handle = win32.GetStdHandle(win32.STD_INPUT_HANDLE)}, - File{handle = win32.GetStdHandle(win32.STD_OUTPUT_HANDLE)}, - File{handle = win32.GetStdHandle(win32.STD_ERROR_HANDLE)}, - } -} - -get_standard_file :: proc(std: File_Standard) -> ^File { - return ^__std_files[std] -} - - -read_entire_file :: proc(name: string) -> (string, bool) { - buf: [300]byte - copy(buf[:], name as []byte) - - f, file_ok := open(name) - if !file_ok { - return "", false - } - defer close(^f) - - length: i64 - file_size_ok := win32.GetFileSizeEx(f.handle as win32.HANDLE, ^length) != 0 - if !file_size_ok { - return "", false - } - - data := new_slice(u8, length) - if data.data == null { - return "", false - } - - single_read_length: i32 - total_read: i64 - - for total_read < length { - remaining := length - total_read - to_read: u32 - MAX :: 1<<32-1 - if remaining <= MAX { - to_read = remaining as u32 - } else { - to_read = MAX - } - - win32.ReadFile(f.handle as win32.HANDLE, ^data[total_read], to_read, ^single_read_length, null) - if single_read_length <= 0 { - free(data.data) - return "", false - } - - total_read += single_read_length as i64 - } - - return data as string, true -} diff --git a/code/runtime.odin b/code/runtime.odin deleted file mode 100644 index b0320beec..000000000 --- a/code/runtime.odin +++ /dev/null @@ -1,353 +0,0 @@ -#shared_global_scope - -// IMPORTANT NOTE(bill): Do not change the order of any of this data -// The compiler relies upon this _exact_ order -Type_Info :: union { - Member :: struct #ordered { - name: string // can be empty if tuple - type_info: ^Type_Info - offset: int // offsets are not used in tuples - } - Record :: struct #ordered { - fields: []Member - packed: bool - ordered: bool - } - - - Named: struct #ordered { - name: string - base: ^Type_Info - } - Integer: struct #ordered { - size: int // in bytes - signed: bool - } - Float: struct #ordered { - size: int // in bytes - } - String: struct #ordered {} - Boolean: struct #ordered {} - Pointer: struct #ordered { - elem: ^Type_Info - } - Procedure: struct #ordered { - params: ^Type_Info // Type_Info.Tuple - results: ^Type_Info // Type_Info.Tuple - variadic: bool - } - Array: struct #ordered { - elem: ^Type_Info - elem_size: int - count: int - } - Slice: struct #ordered { - elem: ^Type_Info - elem_size: int - } - Vector: struct #ordered { - elem: ^Type_Info - elem_size: int - count: int - } - Tuple: Record - Struct: Record - Union: Record - Raw_Union: Record - Enum: struct #ordered { - base: ^Type_Info - } -} - - - -assume :: proc(cond: bool) #foreign "llvm.assume" - -__debug_trap :: proc() #foreign "llvm.debugtrap" -__trap :: proc() #foreign "llvm.trap" -read_cycle_counter :: proc() -> u64 #foreign "llvm.readcyclecounter" - -bit_reverse16 :: proc(b: u16) -> u16 #foreign "llvm.bitreverse.i16" -bit_reverse32 :: proc(b: u32) -> u32 #foreign "llvm.bitreverse.i32" -bit_reverse64 :: proc(b: u64) -> u64 #foreign "llvm.bitreverse.i64" - -byte_swap16 :: proc(b: u16) -> u16 #foreign "llvm.bswap.i16" -byte_swap32 :: proc(b: u32) -> u32 #foreign "llvm.bswap.i32" -byte_swap64 :: proc(b: u64) -> u64 #foreign "llvm.bswap.i64" - -fmuladd32 :: proc(a, b, c: f32) -> f32 #foreign "llvm.fmuladd.f32" -fmuladd64 :: proc(a, b, c: f64) -> f64 #foreign "llvm.fmuladd.f64" - -heap_alloc :: proc(len: int) -> rawptr { - c_malloc :: proc(len: int) -> rawptr #foreign "malloc" - return c_malloc(len) -} - -heap_free :: proc(ptr: rawptr) { - c_free :: proc(ptr: rawptr) #foreign "free" - c_free(ptr) -} - -current_thread_id :: proc() -> int { - GetCurrentThreadId :: proc() -> u32 #foreign #dll_import - return GetCurrentThreadId() as int -} - -memory_zero :: proc(data: rawptr, len: int) { - llvm_memset_64bit :: proc(dst: rawptr, val: byte, len: int, align: i32, is_volatile: bool) #foreign "llvm.memset.p0i8.i64" - llvm_memset_64bit(data, 0, len, 1, false) -} - -memory_compare :: proc(dst, src: rawptr, len: int) -> int { - // TODO(bill): make a faster `memory_compare` - a := slice_ptr(dst as ^byte, len) - b := slice_ptr(src as ^byte, len) - for i := 0; i < len; i++ { - if a[i] != b[i] { - return (a[i] - b[i]) as int - } - } - return 0 -} - -memory_copy :: proc(dst, src: rawptr, len: int) #inline { - llvm_memmove_64bit :: proc(dst, src: rawptr, len: int, align: i32, is_volatile: bool) #foreign "llvm.memmove.p0i8.p0i8.i64" - llvm_memmove_64bit(dst, src, len, 1, false) -} - -__string_eq :: proc(a, b: string) -> bool { - if a.count != b.count { - return false - } - if ^a[0] == ^b[0] { - return true - } - return memory_compare(^a[0], ^b[0], a.count) == 0 -} - -__string_cmp :: proc(a, b : string) -> int { - // Translation of http://mgronhol.github.io/fast-strcmp/ - n := min(a.count, b.count) - - fast := n/size_of(int) + 1 - offset := (fast-1)*size_of(int) - curr_block := 0 - if n <= size_of(int) { - fast = 0 - } - - la := slice_ptr(^a[0] as ^int, fast) - lb := slice_ptr(^b[0] as ^int, fast) - - for ; curr_block < fast; curr_block++ { - if (la[curr_block] ~ lb[curr_block]) != 0 { - for pos := curr_block*size_of(int); pos < n; pos++ { - if (a[pos] ~ b[pos]) != 0 { - return a[pos] as int - b[pos] as int - } - } - } - - } - - for ; offset < n; offset++ { - if (a[offset] ~ b[offset]) != 0 { - return a[offset] as int - b[offset] as int - } - } - - return 0 -} - -__string_ne :: proc(a, b : string) -> bool #inline { return !__string_eq(a, b) } -__string_lt :: proc(a, b : string) -> bool #inline { return __string_cmp(a, b) < 0 } -__string_gt :: proc(a, b : string) -> bool #inline { return __string_cmp(a, b) > 0 } -__string_le :: proc(a, b : string) -> bool #inline { return __string_cmp(a, b) <= 0 } -__string_ge :: proc(a, b : string) -> bool #inline { return __string_cmp(a, b) >= 0 } - -__print_err_str :: proc(s: string) { - -} -__print_err_int :: proc(i: int) { - -} - -__assert :: proc(msg: string) { - // TODO(bill): Write message - __print_err_str(msg) - __debug_trap() -} - -__bounds_check_error :: proc(file: string, line, column: int, - index, count: int) { - if 0 <= index && index < count { - return - } - // TODO(bill): Write message - // TODO(bill): Probably reduce the need for `print` in the runtime if possible - // fmt.println_err("%(%:%) Index % is out of bounds range [0, %)", - // file, line, column, index, count) - __debug_trap() -} - -__slice_expr_error :: proc(file: string, line, column: int, - low, high, max: int) { - if 0 <= low && low <= high && high <= max { - return - } - // TODO(bill): Write message - // fmt.println_err("%(%:%) Invalid slice indices: [%:%:%]", - // file, line, column, low, high, max) - __debug_trap() -} -__substring_expr_error :: proc(file: string, line, column: int, - low, high: int) { - if 0 <= low && low <= high { - return - } - // TODO(bill): Write message - // fmt.println_err("%(%:%) Invalid substring indices: [%:%:%]", - // file, line, column, low, high) - __debug_trap() -} - - - - - - - - - - - -Allocator :: struct { - Mode :: enum { - ALLOC, - FREE, - FREE_ALL, - RESIZE, - } - Proc :: type proc(allocator_data: rawptr, mode: Mode, - size, alignment: int, - old_memory: rawptr, old_size: int, flags: u64) -> rawptr - - - procedure: Proc; - data: rawptr -} - - -Context :: struct { - thread_id: int - - allocator: Allocator - - user_data: rawptr - user_index: int -} - -#thread_local __context: Context - - -DEFAULT_ALIGNMENT :: align_of({4}f32) - - -current_context :: proc() -> ^Context { - return ^__context -} - -__check_context :: proc() { - c := current_context() - assert(c != null) - - if c.allocator.procedure == null { - c.allocator = __default_allocator() - } - if c.thread_id == 0 { - c.thread_id = current_thread_id() - } -} - -alloc :: proc(size: int) -> rawptr #inline { return alloc_align(size, DEFAULT_ALIGNMENT) } - -alloc_align :: proc(size, alignment: int) -> rawptr #inline { - __check_context() - a := current_context().allocator - return a.procedure(a.data, Allocator.Mode.ALLOC, size, alignment, null, 0, 0) -} - -free :: proc(ptr: rawptr) #inline { - __check_context() - a := current_context().allocator - _ = a.procedure(a.data, Allocator.Mode.FREE, 0, 0, ptr, 0, 0) -} -free_all :: proc() #inline { - __check_context() - a := current_context().allocator - _ = a.procedure(a.data, Allocator.Mode.FREE_ALL, 0, 0, null, 0, 0) -} - - -resize :: proc(ptr: rawptr, old_size, new_size: int) -> rawptr #inline { return resize_align(ptr, old_size, new_size, DEFAULT_ALIGNMENT) } -resize_align :: proc(ptr: rawptr, old_size, new_size, alignment: int) -> rawptr #inline { - a := current_context().allocator - return a.procedure(a.data, Allocator.Mode.RESIZE, new_size, alignment, ptr, old_size, 0) -} - - - -default_resize_align :: proc(old_memory: rawptr, old_size, new_size, alignment: int) -> rawptr { - if old_memory == null { - return alloc_align(new_size, alignment) - } - - if new_size == 0 { - free(old_memory) - return null - } - - if new_size == old_size { - return old_memory - } - - new_memory := alloc_align(new_size, alignment) - if new_memory == null { - return null - } - - memory_copy(new_memory, old_memory, min(old_size, new_size)); - free(old_memory) - return new_memory -} - - -__default_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator.Mode, - size, alignment: int, - old_memory: rawptr, old_size: int, flags: u64) -> rawptr { - using Allocator.Mode - match mode { - case ALLOC: - return heap_alloc(size) - case RESIZE: - return default_resize_align(old_memory, old_size, size, alignment) - case FREE: - heap_free(old_memory) - return null - case FREE_ALL: - // NOTE(bill): Does nothing - } - - return null -} - -__default_allocator :: proc() -> Allocator { - return Allocator{ - procedure = __default_allocator_proc, - data = null, - } -} - - - - diff --git a/code/win32.odin b/code/win32.odin deleted file mode 100644 index a1fac63f0..000000000 --- a/code/win32.odin +++ /dev/null @@ -1,451 +0,0 @@ -#foreign_system_library "user32" -#foreign_system_library "gdi32" - -HANDLE :: type rawptr -HWND :: type HANDLE -HDC :: type HANDLE -HINSTANCE :: type HANDLE -HICON :: type HANDLE -HCURSOR :: type HANDLE -HMENU :: type HANDLE -HBRUSH :: type HANDLE -HGDIOBJ :: type HANDLE -WPARAM :: type uint -LPARAM :: type int -LRESULT :: type int -ATOM :: type i16 -BOOL :: type i32 -WNDPROC :: type proc(hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT - -INVALID_HANDLE_VALUE :: (-1 as int) as HANDLE - -CS_VREDRAW :: 0x0001 -CS_HREDRAW :: 0x0002 -CS_OWNDC :: 0x0020 -CW_USEDEFAULT :: 0x80000000 - -WS_OVERLAPPED :: 0 -WS_MAXIMIZEBOX :: 0x00010000 -WS_MINIMIZEBOX :: 0x00020000 -WS_THICKFRAME :: 0x00040000 -WS_SYSMENU :: 0x00080000 -WS_CAPTION :: 0x00C00000 -WS_VISIBLE :: 0x10000000 -WS_OVERLAPPEDWINDOW :: WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX - -WM_DESTROY :: 0x0002 -WM_CLOSE :: 0x0010 -WM_QUIT :: 0x0012 -WM_KEYDOWN :: 0x0100 -WM_KEYUP :: 0x0101 - -PM_REMOVE :: 1 - -COLOR_BACKGROUND :: 1 as HBRUSH -BLACK_BRUSH :: 4 - -SM_CXSCREEN :: 0 -SM_CYSCREEN :: 1 - -SW_SHOW :: 5 - -POINT :: struct #ordered { - x, y: i32 -} - - -WNDCLASSEXA :: struct #ordered { - size, style: u32 - wnd_proc: WNDPROC - cls_extra, wnd_extra: i32 - instance: HINSTANCE - icon: HICON - cursor: HCURSOR - background: HBRUSH - menu_name, class_name: ^u8 - sm: HICON -} - -MSG :: struct #ordered { - hwnd: HWND - message: u32 - wparam: WPARAM - lparam: LPARAM - time: u32 - pt: POINT -} - -RECT :: struct #ordered { - left: i32 - top: i32 - right: i32 - bottom: i32 -} - - -GetLastError :: proc() -> i32 #foreign #dll_import -ExitProcess :: proc(exit_code: u32) #foreign #dll_import -GetDesktopWindow :: proc() -> HWND #foreign #dll_import -GetCursorPos :: proc(p: ^POINT) -> i32 #foreign #dll_import -ScreenToClient :: proc(h: HWND, p: ^POINT) -> i32 #foreign #dll_import -GetModuleHandleA :: proc(module_name: ^u8) -> HINSTANCE #foreign #dll_import -GetStockObject :: proc(fn_object: i32) -> HGDIOBJ #foreign #dll_import -PostQuitMessage :: proc(exit_code: i32) #foreign #dll_import -SetWindowTextA :: proc(hwnd: HWND, c_string: ^u8) -> BOOL #foreign #dll_import - -QueryPerformanceFrequency :: proc(result: ^i64) -> i32 #foreign #dll_import -QueryPerformanceCounter :: proc(result: ^i64) -> i32 #foreign #dll_import - -Sleep :: proc(ms: i32) -> i32 #foreign #dll_import - -OutputDebugStringA :: proc(c_str: ^u8) #foreign #dll_import - - -RegisterClassExA :: proc(wc: ^WNDCLASSEXA) -> ATOM #foreign #dll_import -CreateWindowExA :: proc(ex_style: u32, - class_name, title: ^u8, - style: u32, - x, y, w, h: i32, - parent: HWND, menu: HMENU, instance: HINSTANCE, - param: rawptr) -> HWND #foreign #dll_import - -ShowWindow :: proc(hwnd: HWND, cmd_show: i32) -> BOOL #foreign #dll_import -TranslateMessage :: proc(msg: ^MSG) -> BOOL #foreign #dll_import -DispatchMessageA :: proc(msg: ^MSG) -> LRESULT #foreign #dll_import -UpdateWindow :: proc(hwnd: HWND) -> BOOL #foreign #dll_import -PeekMessageA :: proc(msg: ^MSG, hwnd: HWND, - msg_filter_min, msg_filter_max, remove_msg: u32) -> BOOL #foreign #dll_import - -DefWindowProcA :: proc(hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT #foreign #dll_import - -AdjustWindowRect :: proc(rect: ^RECT, style: u32, menu: BOOL) -> BOOL #foreign #dll_import - - -GetQueryPerformanceFrequency :: proc() -> i64 { - r: i64 - QueryPerformanceFrequency(^r) - return r -} - -GetCommandLineA :: proc() -> ^u8 #foreign #dll_import -GetSystemMetrics :: proc(index: i32) -> i32 #foreign #dll_import -GetCurrentThreadId :: proc() -> u32 #foreign #dll_import - -// File Stuff - -CloseHandle :: proc(h: HANDLE) -> i32 #foreign #dll_import -GetStdHandle :: proc(h: i32) -> HANDLE #foreign #dll_import -CreateFileA :: proc(filename: ^u8, desired_access, share_mode: u32, - security: rawptr, - creation, flags_and_attribs: u32, template_file: HANDLE) -> HANDLE #foreign #dll_import -ReadFile :: proc(h: HANDLE, buf: rawptr, to_read: u32, bytes_read: ^i32, overlapped: rawptr) -> BOOL #foreign #dll_import -WriteFile :: proc(h: HANDLE, buf: rawptr, len: i32, written_result: ^i32, overlapped: rawptr) -> i32 #foreign #dll_import - -GetFileSizeEx :: proc(file_handle: HANDLE, file_size: ^i64) -> BOOL #foreign #dll_import - -FILE_SHARE_READ :: 0x00000001 -FILE_SHARE_WRITE :: 0x00000002 -FILE_SHARE_DELETE :: 0x00000004 -FILE_GENERIC_ALL :: 0x10000000 -FILE_GENERIC_EXECUTE :: 0x20000000 -FILE_GENERIC_WRITE :: 0x40000000 -FILE_GENERIC_READ :: 0x80000000 - -STD_INPUT_HANDLE :: -10 -STD_OUTPUT_HANDLE :: -11 -STD_ERROR_HANDLE :: -12 - -CREATE_NEW :: 1 -CREATE_ALWAYS :: 2 -OPEN_EXISTING :: 3 -OPEN_ALWAYS :: 4 -TRUNCATE_EXISTING :: 5 - - -HeapAlloc :: proc(h: HANDLE, flags: u32, bytes: int) -> rawptr #foreign #dll_import -HeapFree :: proc(h: HANDLE, flags: u32, memory: rawptr) -> BOOL #foreign #dll_import -GetProcessHeap :: proc() -> HANDLE #foreign #dll_import - - -HEAP_ZERO_MEMORY :: 0x00000008 - - - -// GDI - -BITMAPINFO :: struct #ordered { - HEADER :: struct #ordered { - size: u32 - width, height: i32 - planes, bit_count: i16 - compression: u32 - size_image: u32 - x_pels_per_meter: i32 - y_pels_per_meter: i32 - clr_used: u32 - clr_important: u32 - } - using header: HEADER - colors: [1]RGBQUAD -} - - -RGBQUAD :: struct #ordered { - blue, green, red, reserved: byte -} - -BI_RGB :: 0 -DIB_RGB_COLORS :: 0x00 -SRCCOPY : u32 : 0x00cc0020 - -StretchDIBits :: proc(hdc: HDC, - x_dst, y_dst, width_dst, height_dst: i32, - x_src, y_src, width_src, header_src: i32, - bits: rawptr, bits_info: ^BITMAPINFO, - usage: u32, - rop: u32) -> i32 #foreign #dll_import - - - - - - -// Windows OpenGL - -PFD_TYPE_RGBA :: 0 -PFD_TYPE_COLORINDEX :: 1 -PFD_MAIN_PLANE :: 0 -PFD_OVERLAY_PLANE :: 1 -PFD_UNDERLAY_PLANE :: -1 -PFD_DOUBLEBUFFER :: 1 -PFD_STEREO :: 2 -PFD_DRAW_TO_WINDOW :: 4 -PFD_DRAW_TO_BITMAP :: 8 -PFD_SUPPORT_GDI :: 16 -PFD_SUPPORT_OPENGL :: 32 -PFD_GENERIC_FORMAT :: 64 -PFD_NEED_PALETTE :: 128 -PFD_NEED_SYSTEM_PALETTE :: 0x00000100 -PFD_SWAP_EXCHANGE :: 0x00000200 -PFD_SWAP_COPY :: 0x00000400 -PFD_SWAP_LAYER_BUFFERS :: 0x00000800 -PFD_GENERIC_ACCELERATED :: 0x00001000 -PFD_DEPTH_DONTCARE :: 0x20000000 -PFD_DOUBLEBUFFER_DONTCARE :: 0x40000000 -PFD_STEREO_DONTCARE :: 0x80000000 - -HGLRC :: type HANDLE -PROC :: type proc() -wglCreateContextAttribsARBType :: type proc(hdc: HDC, hshareContext: rawptr, attribList: ^i32) -> HGLRC - - -PIXELFORMATDESCRIPTOR :: struct #ordered { - size, - version, - flags: u32 - - pixel_type, - color_bits, - red_bits, - red_shift, - green_bits, - green_shift, - blue_bits, - blue_shift, - alpha_bits, - alpha_shift, - accum_bits, - accum_red_bits, - accum_green_bits, - accum_blue_bits, - accum_alpha_bits, - depth_bits, - stencil_bits, - aux_buffers, - layer_type, - reserved: byte - - layer_mask, - visible_mask, - damage_mask: u32 -} - -GetDC :: proc(h: HANDLE) -> HDC #foreign -SetPixelFormat :: proc(hdc: HDC, pixel_format: i32, pfd: ^PIXELFORMATDESCRIPTOR ) -> BOOL #foreign #dll_import -ChoosePixelFormat :: proc(hdc: HDC, pfd: ^PIXELFORMATDESCRIPTOR) -> i32 #foreign #dll_import -SwapBuffers :: proc(hdc: HDC) -> BOOL #foreign #dll_import -ReleaseDC :: proc(wnd: HWND, hdc: HDC) -> i32 #foreign #dll_import - -WGL_CONTEXT_MAJOR_VERSION_ARB :: 0x2091 -WGL_CONTEXT_MINOR_VERSION_ARB :: 0x2092 -WGL_CONTEXT_PROFILE_MASK_ARB :: 0x9126 -WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB :: 0x0002 - -wglCreateContext :: proc(hdc: HDC) -> HGLRC #foreign #dll_import -wglMakeCurrent :: proc(hdc: HDC, hglrc: HGLRC) -> BOOL #foreign #dll_import -wglGetProcAddress :: proc(c_str: ^u8) -> PROC #foreign #dll_import -wglDeleteContext :: proc(hglrc: HGLRC) -> BOOL #foreign #dll_import - - - -GetKeyState :: proc(v_key: i32) -> i16 #foreign #dll_import -GetAsyncKeyState :: proc(v_key: i32) -> i16 #foreign #dll_import - -is_key_down :: proc(key: Key_Code) -> bool { - return GetAsyncKeyState(key as i32) < 0 -} - -Key_Code :: enum i32 { - LBUTTON = 0x01, - RBUTTON = 0x02, - CANCEL = 0x03, - MBUTTON = 0x04, - - BACK = 0x08, - TAB = 0x09, - - CLEAR = 0x0C, - RETURN = 0x0D, - - SHIFT = 0x10, - CONTROL = 0x11, - MENU = 0x12, - PAUSE = 0x13, - CAPITAL = 0x14, - - KANA = 0x15, - HANGEUL = 0x15, - HANGUL = 0x15, - JUNJA = 0x17, - FINAL = 0x18, - HANJA = 0x19, - KANJI = 0x19, - - ESCAPE = 0x1B, - - CONVERT = 0x1C, - NONCONVERT = 0x1D, - ACCEPT = 0x1E, - MODECHANGE = 0x1F, - - SPACE = 0x20, - PRIOR = 0x21, - NEXT = 0x22, - END = 0x23, - HOME = 0x24, - LEFT = 0x25, - UP = 0x26, - RIGHT = 0x27, - DOWN = 0x28, - SELECT = 0x29, - PRINT = 0x2A, - EXECUTE = 0x2B, - SNAPSHOT = 0x2C, - INSERT = 0x2D, - DELETE = 0x2E, - HELP = 0x2F, - - NUM0 = #rune "0", - NUM1 = #rune "1", - NUM2 = #rune "2", - NUM3 = #rune "3", - NUM4 = #rune "4", - NUM5 = #rune "5", - NUM6 = #rune "6", - NUM7 = #rune "7", - NUM8 = #rune "8", - NUM9 = #rune "9", - - A = #rune "A", - B = #rune "B", - C = #rune "C", - D = #rune "D", - E = #rune "E", - F = #rune "F", - G = #rune "G", - H = #rune "H", - I = #rune "I", - J = #rune "J", - K = #rune "K", - L = #rune "L", - M = #rune "M", - N = #rune "N", - O = #rune "O", - P = #rune "P", - Q = #rune "Q", - R = #rune "R", - S = #rune "S", - T = #rune "T", - U = #rune "U", - V = #rune "V", - W = #rune "W", - X = #rune "X", - Y = #rune "Y", - Z = #rune "Z", - - LWIN = 0x5B, - RWIN = 0x5C, - APPS = 0x5D, - - NUMPAD0 = 0x60, - NUMPAD1 = 0x61, - NUMPAD2 = 0x62, - NUMPAD3 = 0x63, - NUMPAD4 = 0x64, - NUMPAD5 = 0x65, - NUMPAD6 = 0x66, - NUMPAD7 = 0x67, - NUMPAD8 = 0x68, - NUMPAD9 = 0x69, - MULTIPLY = 0x6A, - ADD = 0x6B, - SEPARATOR = 0x6C, - SUBTRACT = 0x6D, - DECIMAL = 0x6E, - DIVIDE = 0x6F, - F1 = 0x70, - F2 = 0x71, - F3 = 0x72, - F4 = 0x73, - F5 = 0x74, - F6 = 0x75, - F7 = 0x76, - F8 = 0x77, - F9 = 0x78, - F10 = 0x79, - F11 = 0x7A, - F12 = 0x7B, - F13 = 0x7C, - F14 = 0x7D, - F15 = 0x7E, - F16 = 0x7F, - F17 = 0x80, - F18 = 0x81, - F19 = 0x82, - F20 = 0x83, - F21 = 0x84, - F22 = 0x85, - F23 = 0x86, - F24 = 0x87, - - NUMLOCK = 0x90, - SCROLL = 0x91, - - LSHIFT = 0xA0, - RSHIFT = 0xA1, - LCONTROL = 0xA2, - RCONTROL = 0xA3, - LMENU = 0xA4, - RMENU = 0xA5, - PROCESSKEY = 0xE5, - ATTN = 0xF6, - CRSEL = 0xF7, - EXSEL = 0xF8, - EREOF = 0xF9, - PLAY = 0xFA, - ZOOM = 0xFB, - NONAME = 0xFC, - PA1 = 0xFD, - OEM_CLEAR = 0xFE, -} - diff --git a/src/checker/checker.cpp b/src/checker/checker.cpp index 99d04799f..27c6d04b5 100644 --- a/src/checker/checker.cpp +++ b/src/checker/checker.cpp @@ -840,7 +840,11 @@ void init_type_info_types(Checker *c) { if (t_type_info == NULL) { String type_info_str = make_string("Type_Info"); Entity *e = current_scope_lookup_entity(c->global_scope, type_info_str); - GB_ASSERT_MSG(e != NULL, "Internal Compiler Error: Could not find type declaration for `Type_Info`"); + if (e == NULL) { + gb_printf_err("Internal Compiler Error: Could not find type declaration for `Type_Info`\n"); + gb_printf_err("Is `runtime.odin` missing from the `core` directory?\n"); + gb_exit(1); + } t_type_info = e->type; t_type_info_ptr = make_type_pointer(c->allocator, t_type_info); @@ -849,7 +853,10 @@ void init_type_info_types(Checker *c) { t_type_info_member = record->other_fields[0]->type; t_type_info_member_ptr = make_type_pointer(c->allocator, t_type_info_member); - GB_ASSERT_MSG(record->field_count == 16, "Internal Compiler Error: Invalid `Type_Info` layout"); + if (record->field_count != 16) { + gb_printf_err("Internal Compiler Error: Invalid `Type_Info` layout\n"); + gb_exit(1); + } t_type_info_named = record->fields[ 1]->type; t_type_info_integer = record->fields[ 2]->type; t_type_info_float = record->fields[ 3]->type; diff --git a/src/parser.cpp b/src/parser.cpp index ec6aea9dc..08383fa94 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -2741,6 +2741,45 @@ b32 try_add_import_path(Parser *p, String path, String rel_path, TokenPos pos) { return true; } +String get_fullpath_relative(gbAllocator a, String base_dir, String path) { + isize str_len = base_dir.len+path.len; + u8 *str = gb_alloc_array(gb_heap_allocator(), u8, str_len+1); + defer (gb_free(gb_heap_allocator(), str)); + + gb_memcopy(str, base_dir.text, base_dir.len); + gb_memcopy(str+base_dir.len, path.text, path.len); + str[str_len] = '\0'; + // HACK(bill): memory leak + char *path_str = gb_path_get_full_name(a, cast(char *)str); + return make_string(path_str); +} + +String get_fullpath_core(gbAllocator a, String path) { + char buf[300] = {}; + u32 buf_len = GetModuleFileNameA(GetModuleHandleA(NULL), buf, gb_size_of(buf)); + for (isize i = buf_len-1; i >= 0; i--) { + if (buf[i] == '\\' || + buf[i] == '/') { + break; + } + buf_len--; + } + + char core[] = "core/"; + isize core_len = gb_size_of(core)-1; + + isize str_len = buf_len + core_len + path.len; + u8 *str = gb_alloc_array(gb_heap_allocator(), u8, str_len+1); + defer (gb_free(gb_heap_allocator(), str)); + + gb_memcopy(str, buf, buf_len); + gb_memcopy(str+buf_len, core, core_len); + gb_memcopy(str+buf_len+core_len, path.text, path.len); + str[str_len] = '\0'; + // HACK(bill): memory leak + char *path_str = gb_path_get_full_name(a, cast(char *)str); + return make_string(path_str);} + // NOTE(bill): Returns true if it's added b32 try_add_foreign_system_library_path(Parser *p, String import_file) { gb_for_array(i, p->system_libraries) { @@ -2803,6 +2842,7 @@ void parse_file(Parser *p, AstFile *f) { } base_dir.len--; } + gbAllocator allocator = gb_heap_allocator(); // TODO(bill): Change this allocator f->decls = parse_stmt_list(f); @@ -2819,25 +2859,27 @@ void parse_file(Parser *p, AstFile *f) { String file_str = id->relpath.string; if (!is_import_path_valid(file_str)) { - syntax_error(ast_node_token(node), "Invalid `load` path"); + if (id->is_load) { + syntax_error(ast_node_token(node), "Invalid #load path"); + } else { + syntax_error(ast_node_token(node), "Invalid #import path"); + } continue; } - isize str_len = base_dir.len+file_str.len; - u8 *str = gb_alloc_array(gb_heap_allocator(), u8, str_len+1); - defer (gb_free(gb_heap_allocator(), str)); - - gb_memcopy(str, base_dir.text, base_dir.len); - gb_memcopy(str+base_dir.len, file_str.text, file_str.len); - str[str_len] = '\0'; - // HACK(bill): memory leak - char *path_str = gb_path_get_full_name(gb_heap_allocator(), cast(char *)str); - String import_file = make_string(path_str); + String import_file = {}; + String rel_path = get_fullpath_relative(allocator, base_dir, file_str); + import_file = rel_path; + if (!gb_file_exists(cast(char *)rel_path.text)) { // NOTE(bill): This should be null terminated + String abs_path = get_fullpath_core(allocator, file_str); + if (gb_file_exists(cast(char *)abs_path.text)) { + import_file = abs_path; + } + } id->fullpath = import_file; - if (!try_add_import_path(p, import_file, file_str, ast_node_token(node).pos)) { - // gb_free(gb_heap_allocator(), import_file.text); - } + try_add_import_path(p, import_file, file_str, ast_node_token(node).pos); + } else if (node->kind == AstNode_ForeignSystemLibrary) { auto *id = &node->ForeignSystemLibrary; String file_str = id->filepath.string; @@ -2862,13 +2904,11 @@ ParseFileError parse_files(Parser *p, char *init_filename) { gb_array_append(p->imports, init_imported_file); p->init_fullpath = init_fullpath; - // { - // // IMPORTANT TODO(bill): Don't embed this, do it relative to the .exe - // char *path = gb_path_get_full_name(gb_heap_allocator(), "W:/Odin/core/__runtime.odin"); - // String s = make_string(path); - // ImportedFile runtime_file = {s, s, init_pos}; - // gb_array_append(p->imports, runtime_file); - // } + { + String s = get_fullpath_core(gb_heap_allocator(), make_string("runtime.odin")); + ImportedFile runtime_file = {s, s, init_pos}; + gb_array_append(p->imports, runtime_file); + } gb_for_array(i, p->imports) { String import_path = p->imports[i].path; diff --git a/src/string.cpp b/src/string.cpp index 0e243f66e..496c81d26 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -13,8 +13,9 @@ typedef struct String { gb_inline String make_string(u8 *text, isize len) { String s; s.text = text; - if (len < 0) + if (len < 0) { len = gb_strlen(cast(char *)text); + } s.len = len; return s; } diff --git a/syntax.odin b/syntax.odin deleted file mode 100644 index 828e2ebf4..000000000 --- a/syntax.odin +++ /dev/null @@ -1,45 +0,0 @@ -main :: proc(args: []string) -> i32 { - if args.count < 2 { - io.println("Please specify a .odin file"); - return 1; - } - - for arg_index := 1; arg_index < args.count; arg_index++ { - arg := args[arg_index]; - filename := arg; - ext := filepath.path_extension(filename); - if (ext != "odin") { - io.println("File is not a .odin file"); - return 1; - } - output_name := filepath.change_extension(filename, "c"); - - parser: Parser; - err: Error; - parser, err = make_parser(filename); - if err { - handle_error(); - } - defer destroy_parser(*parser); - - root_node := parse_statement_list(*parser, null); - - code_generator: CodeGenerator; - code_generator, err = make_code_generator(*parser, root); - if err { - handle_error(); - } - defer destroy_code_generator(*code_generator); - - output: File; - output, err = file_create(output_nameu); - if err { - handle_error(); - } - defer file_close(*output); - - convert_to_c_code(*code_generator, root, *output); - } - - return 0; -};