diff options
| author | gingerBill <gingerBill@users.noreply.github.com> | 2017-02-01 20:31:57 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-02-01 20:31:57 +0000 |
| commit | c6133587d1bdf7ae723beb8c3a3b27b472bf2d7a (patch) | |
| tree | fd080deab099e74ec5f50841c6a8b5b5b8b5c3c4 /src | |
| parent | 4e7082a68dd5261c3c36eccf92a62a0ce84995a8 (diff) | |
| parent | 5516e80ab775d1100beca7847e10520eae4b151c (diff) | |
Merge pull request #16 from zhiayang/master
Basic, but sketchy, but somewhat usable, non-windows support
Diffstat (limited to 'src')
| -rw-r--r-- | src/build.c | 92 | ||||
| -rw-r--r-- | src/check_decl.c | 2 | ||||
| -rw-r--r-- | src/check_expr.c | 6 | ||||
| -rw-r--r-- | src/check_stmt.c | 1 | ||||
| -rw-r--r-- | src/checker.c | 48 | ||||
| -rw-r--r-- | src/entity.c | 61 | ||||
| -rw-r--r-- | src/exact_value.c | 1 | ||||
| -rw-r--r-- | src/gb/gb.h | 23 | ||||
| -rw-r--r-- | src/main.c | 63 | ||||
| -rw-r--r-- | src/parser.c | 1 | ||||
| -rw-r--r-- | src/string.c | 61 | ||||
| -rw-r--r-- | src/timings.c | 36 | ||||
| -rw-r--r-- | src/types.c | 2 |
13 files changed, 325 insertions, 72 deletions
diff --git a/src/build.c b/src/build.c index f929dcc6d..2b69b3718 100644 --- a/src/build.c +++ b/src/build.c @@ -22,6 +22,7 @@ typedef struct BuildContext { String const WIN32_SEPARATOR_STRING = {cast(u8 *)"\\", 1}; String const NIX_SEPARATOR_STRING = {cast(u8 *)"/", 1}; +#if defined(WINDOWS) String odin_root_dir(void) { String path = global_module_path; Array(wchar_t) path_buf; @@ -71,6 +72,83 @@ String odin_root_dir(void) { return path; } +#elif defined(GB_SYSTEM_OSX) + +#include <mach-o/dyld.h> + +String odin_root_dir(void) { + String path = global_module_path; + Array(char) path_buf; + isize len, i; + gbTempArenaMemory tmp; + wchar_t *text; + + if (global_module_path_set) { + return global_module_path; + } + + array_init_count(&path_buf, heap_allocator(), 300); + + len = 0; + for (;;) { + int sz = path_buf.count; + int res = _NSGetExecutablePath(&path_buf.e[0], &sz); + if(res == 0) { + len = sz; + break; + } else { + array_resize(&path_buf, sz + 1); + } + } + + + tmp = gb_temp_arena_memory_begin(&string_buffer_arena); + text = gb_alloc_array(string_buffer_allocator, u8, len + 1); + gb_memmove(text, &path_buf.e[0], len); + + path = make_string(text, len); + for (i = path.len-1; i >= 0; i--) { + u8 c = path.text[i]; + if (c == '/' || c == '\\') { + break; + } + path.len--; + } + + global_module_path = path; + global_module_path_set = true; + + gb_temp_arena_memory_end(tmp); + + // array_free(&path_buf); + + return path; +} +#else +#error Implement system +#endif + + + + + + + + + + + + + + + + + + + + + +#if defined(GB_SYSTEM_WINDOWS) String path_to_fullpath(gbAllocator a, String s) { gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&string_buffer_arena); String16 string16 = string_to_string16(string_buffer_allocator, s); @@ -86,6 +164,17 @@ String path_to_fullpath(gbAllocator a, String s) { gb_temp_arena_memory_end(tmp); return result; } +#elif defined(GB_SYSTEM_OSX) || defined(GB_SYSTEM_UNIX) +String path_to_fullpath(gbAllocator a, String s) { + char* p = realpath(s.text, 0); + // GB_ASSERT(p && "file does not exist"); + if(!p) return make_string_c(""); + + return make_string(p, strlen(p)); +} +#else +#error Implement system +#endif String get_fullpath_relative(gbAllocator a, String base_dir, String path) { @@ -154,6 +243,9 @@ void init_build_context(BuildContext *bc) { #if defined(GB_SYSTEM_WINDOWS) bc->ODIN_OS = str_lit("windows"); bc->ODIN_ARCH = str_lit("amd64"); +#elif defined(GB_SYSTEM_OSX) + bc->ODIN_OS = str_lit("osx"); + bc->ODIN_ARCH = str_lit("amd64"); #else #error Implement system #endif diff --git a/src/check_decl.c b/src/check_decl.c index 51655d445..6233a0bc0 100644 --- a/src/check_decl.c +++ b/src/check_decl.c @@ -69,7 +69,7 @@ void check_init_variables(Checker *c, Entity **lhs, isize lhs_count, AstNodeArra AstNode *rhs = inits.e[i]; Operand o = {0}; check_multi_expr(c, &o, rhs); - if (o.type->kind != Type_Tuple) { + if (o.type == NULL || o.type->kind != Type_Tuple) { array_add(&operands, o); } else { TypeTuple *tuple = &o.type->Tuple; diff --git a/src/check_expr.c b/src/check_expr.c index c8b1c3175..6b09c3a82 100644 --- a/src/check_expr.c +++ b/src/check_expr.c @@ -225,6 +225,9 @@ i64 check_distance_between_types(Checker *c, Operand *operand, Type *type) { return -1; } +#ifndef _MAX +#define _MAX(x, y) ((x) > (y) ? (x) : (y)) +#endif bool check_is_assignable_to_with_score(Checker *c, Operand *operand, Type *type, i64 *score_) { i64 score = 0; @@ -232,7 +235,8 @@ bool check_is_assignable_to_with_score(Checker *c, Operand *operand, Type *type, bool ok = distance >= 0; if (ok) { // TODO(bill): A decent score function - score = max(1000000 - distance*distance, 0); + // score = max(1000000 - distance*distance, 0); + score = _MAX(1000000 - distance*distance, 0); } if (score_) *score_ = score; return ok; diff --git a/src/check_stmt.c b/src/check_stmt.c index 8ff5c3b2e..470848115 100644 --- a/src/check_stmt.c +++ b/src/check_stmt.c @@ -724,6 +724,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { } skip_expr: + ; // again, declaring a variable immediately after a label... weird. AstNode *lhs[2] = {rs->value, rs->index}; Type * rhs[2] = {val, idx}; diff --git a/src/checker.c b/src/checker.c index 7d3ca0d82..ef26b20c2 100644 --- a/src/checker.c +++ b/src/checker.c @@ -118,47 +118,6 @@ typedef enum StmtFlag { Stmt_GiveAllowed = 1<<3, } StmtFlag; -typedef enum BuiltinProcId { - BuiltinProc_Invalid, - - BuiltinProc_new, - BuiltinProc_new_slice, - BuiltinProc_free, - - BuiltinProc_reserve, - BuiltinProc_append, - - BuiltinProc_size_of, - BuiltinProc_size_of_val, - BuiltinProc_align_of, - BuiltinProc_align_of_val, - BuiltinProc_offset_of, - BuiltinProc_offset_of_val, - BuiltinProc_type_of_val, - - BuiltinProc_type_info, - BuiltinProc_type_info_of_val, - - BuiltinProc_compile_assert, - BuiltinProc_assert, - BuiltinProc_panic, - - BuiltinProc_copy, - // BuiltinProc_append, - - BuiltinProc_swizzle, - - // BuiltinProc_ptr_offset, - // BuiltinProc_ptr_sub, - BuiltinProc_slice_ptr, - - BuiltinProc_min, - BuiltinProc_max, - BuiltinProc_abs, - BuiltinProc_clamp, - - BuiltinProc_Count, -} BuiltinProcId; typedef struct BuiltinProc { String name; isize arg_count; @@ -205,13 +164,6 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_Count] = { {STR_LIT("clamp"), 3, false, Expr_Expr}, }; -typedef enum ImplicitValueId { - ImplicitValue_Invalid, - - ImplicitValue_context, - - ImplicitValue_Count, -} ImplicitValueId; typedef struct ImplicitValueInfo { String name; String backing_name; diff --git a/src/entity.c b/src/entity.c index 3ca709aa4..30ad8f053 100644 --- a/src/entity.c +++ b/src/entity.c @@ -1,8 +1,65 @@ typedef struct Scope Scope; typedef struct Checker Checker; typedef struct Type Type; -typedef enum BuiltinProcId BuiltinProcId; -typedef enum ImplicitValueId ImplicitValueId; +// typedef enum BuiltinProcId BuiltinProcId; +// typedef enum ImplicitValueId ImplicitValueId; + + + +typedef enum BuiltinProcId { + BuiltinProc_Invalid, + + BuiltinProc_new, + BuiltinProc_new_slice, + BuiltinProc_free, + + BuiltinProc_reserve, + BuiltinProc_append, + + BuiltinProc_size_of, + BuiltinProc_size_of_val, + BuiltinProc_align_of, + BuiltinProc_align_of_val, + BuiltinProc_offset_of, + BuiltinProc_offset_of_val, + BuiltinProc_type_of_val, + + BuiltinProc_type_info, + BuiltinProc_type_info_of_val, + + BuiltinProc_compile_assert, + BuiltinProc_assert, + BuiltinProc_panic, + + BuiltinProc_copy, + // BuiltinProc_append, + + BuiltinProc_swizzle, + + // BuiltinProc_ptr_offset, + // BuiltinProc_ptr_sub, + BuiltinProc_slice_ptr, + + BuiltinProc_min, + BuiltinProc_max, + BuiltinProc_abs, + BuiltinProc_clamp, + + BuiltinProc_Count, +} BuiltinProcId; + + +typedef enum ImplicitValueId { + ImplicitValue_Invalid, + + ImplicitValue_context, + + ImplicitValue_Count, +} ImplicitValueId; + + + + #define ENTITY_KINDS \ ENTITY_KIND(Invalid) \ diff --git a/src/exact_value.c b/src/exact_value.c index 83add68f4..7c48d126b 100644 --- a/src/exact_value.c +++ b/src/exact_value.c @@ -416,6 +416,7 @@ ExactValue exact_binary_operator_value(TokenKind op, ExactValue x, ExactValue y) } error: + ; // MSVC accepts this??? apparently you cannot declare variables immediately after labels... ExactValue error_value = {0}; // gb_printf_err("Invalid binary operation: %s\n", token_kind_to_string(op)); return error_value; diff --git a/src/gb/gb.h b/src/gb/gb.h index 304f782b2..5d204605a 100644 --- a/src/gb/gb.h +++ b/src/gb/gb.h @@ -276,6 +276,8 @@ extern "C" { #include <stdarg.h> #include <stddef.h> + + #if defined(GB_SYSTEM_WINDOWS) #if !defined(GB_NO_WINDOWS_H) #define NOMINMAX 1 @@ -296,6 +298,7 @@ extern "C" { #include <errno.h> #include <fcntl.h> #include <pthread.h> + #define _IOSC11_SOURCE #include <stdlib.h> // NOTE(bill): malloc on linux #include <sys/mman.h> #if !defined(GB_SYSTEM_OSX) @@ -4819,14 +4822,17 @@ GB_ALLOCATOR_PROC(gb_heap_allocator_proc) { #else // TODO(bill): *nix version that's decent case gbAllocation_Alloc: { - ptr = aligned_alloc(alignment, size); + // ptr = aligned_alloc(alignment, size); + + posix_memalign(&ptr, alignment, size); + if (flags & gbAllocatorFlag_ClearToZero) { gb_zero_size(ptr, size); } } break; case gbAllocation_Free: { - free(gb_allocation_header(old_memory)); + // free(old_memory); } break; case gbAllocation_Resize: { @@ -7754,7 +7760,18 @@ char *gb_path_get_full_name(gbAllocator a, char const *path) { return gb_alloc_str_len(a, buf, len+1); #else // TODO(bill): Make work on *nix, etc. - return gb_alloc_str_len(a, path, gb_strlen(path)); + char* p = realpath(path, 0); + GB_ASSERT(p && "file does not exist"); + + isize len = gb_strlen(p); + + // bill... gb_alloc_str_len refused to work for this... + char* ret = gb_alloc(a, sizeof(char) * len + 1); + gb_memmove(ret, p, len); + ret[len] = 0; + free(p); + + return ret; #endif } diff --git a/src/main.c b/src/main.c index b35f399eb..4a2c3aaac 100644 --- a/src/main.c +++ b/src/main.c @@ -16,8 +16,10 @@ extern "C" { #include "ir_print.c" // #include "vm.c" +#if defined(GB_SYSTEM_WINDOWS) + // NOTE(bill): `name` is used in debugging and profiling modes -i32 win32_exec_command_line_app(char *name, bool is_silent, char *fmt, ...) { +i32 system_exec_command_line_app(char *name, bool is_silent, char *fmt, ...) { STARTUPINFOW start_info = {gb_size_of(STARTUPINFOW)}; PROCESS_INFORMATION pi = {0}; char cmd_line[4096] = {0}; @@ -59,6 +61,53 @@ i32 win32_exec_command_line_app(char *name, bool is_silent, char *fmt, ...) { gb_temp_arena_memory_end(tmp); return exit_code; } +#elif defined(GB_SYSTEM_OSX) || defined(GB_SYSTEM_UNIX) +i32 system_exec_command_line_app(char *name, bool is_silent, char *fmt, ...) { + + char cmd_line[4096] = {0}; + isize cmd_len; + va_list va; + String cmd; + i32 exit_code = 0; + + va_start(va, fmt); + cmd_len = gb_snprintf_va(cmd_line, gb_size_of(cmd_line), fmt, va); + va_end(va); + + exit_code = system(cmd.text); + + // pid_t pid = fork(); + // int status = 0; + + // if(pid == 0) { + // // in child, pid == 0. + // int ret = execvp(cmd.text, (char* const*) cmd.text); + + // if(ret == -1) { + // gb_printf_err("Failed to execute command:\n\t%s\n", cmd_line); + + // // we're in the child, so returning won't do us any good -- just quit. + // exit(-1); + // } + + // // unreachable + // abort(); + // } else { + // // wait for child to finish, then we can continue cleanup + + // int s = 0; + // waitpid(pid, &s, 0); + + // status = WEXITSTATUS(s); + // } + + // exit_code = status; +} +#endif + + + + void print_usage_line(i32 indent, char *fmt, ...) { while (indent --> 0) { @@ -190,7 +239,7 @@ int main(int argc, char **argv) { // prof_print_all(); -#if 1 + #if 1 timings_start_section(&timings, str_lit("llvm-opt")); char const *output_name = ir_gen.output_file.filename; @@ -202,7 +251,7 @@ int main(int argc, char **argv) { i32 exit_code = 0; // For more passes arguments: http://llvm.org/docs/Passes.html - exit_code = win32_exec_command_line_app("llvm-opt", false, + exit_code = system_exec_command_line_app("llvm-opt", false, "\"%.*sbin/opt\" \"%s\" -o \"%.*s\".bc " "-mem2reg " "-memcpyopt " @@ -217,10 +266,10 @@ int main(int argc, char **argv) { return exit_code; } - #if 1 + #if 0 timings_start_section(&timings, str_lit("llvm-llc")); // For more arguments: http://llvm.org/docs/CommandGuide/llc.html - exit_code = win32_exec_command_line_app("llvm-llc", false, + exit_code = system_exec_command_line_app("llvm-llc", false, "\"%.*sbin/llc\" \"%.*s.bc\" -filetype=obj -O%d " "%.*s " // "-debug-pass=Arguments " @@ -255,7 +304,7 @@ int main(int argc, char **argv) { link_settings = "/ENTRY:mainCRTStartup"; } - exit_code = win32_exec_command_line_app("msvc-link", true, + exit_code = system_exec_command_line_app("msvc-link", true, "link \"%.*s\".obj -OUT:\"%.*s.%s\" %s " "/defaultlib:libcmt " "/nologo /incremental:no /opt:ref /subsystem:CONSOLE " @@ -273,7 +322,7 @@ int main(int argc, char **argv) { // timings_print_all(&timings); if (run_output) { - win32_exec_command_line_app("odin run", false, "%.*s.exe", cast(int)base_name_len, output_name); + system_exec_command_line_app("odin run", false, "%.*s.exe", cast(int)base_name_len, output_name); } #endif #endif diff --git a/src/parser.c b/src/parser.c index 4f058777e..33cfd1078 100644 --- a/src/parser.c +++ b/src/parser.c @@ -3731,6 +3731,7 @@ ParseFileError parse_files(Parser *p, char *init_filename) { String import_rel_path = imported_file.rel_path; TokenPos pos = imported_file.pos; AstFile file = {0}; + ParseFileError err = init_ast_file(&file, import_path); if (err != ParseFile_None) { diff --git a/src/string.c b/src/string.c index 69dbf1b58..2f8da20a8 100644 --- a/src/string.c +++ b/src/string.c @@ -165,6 +165,54 @@ bool string_contains_char(String s, u8 c) { return false; } + + + + + + + + +#if defined(GB_SYSTEM_WINDOWS) + + int convert_multibyte_to_widechar(char* multibyte_input, int input_length, wchar_t* output, int output_size) + { + return MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, multibyte_input, input_length, output, output_size); + } + + int convert_widechar_to_multibyte(wchar_t* widechar_input, int input_length, char* output, int output_size) + { + return WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, widechar_input, input_length, output, output_size, NULL, NULL); + } +} +#elif defined(GB_SYSTEM_UNIX) || defined(GB_SYSTEM_OSX) + + #include <iconv.h> + + int convert_multibyte_to_widechar(char* multibyte_input, int input_length, wchar_t* output, int output_size) + { + iconv_t conv = iconv_open("WCHAR_T", "UTF-8"); + size_t result = iconv(conv, (char**) &multibyte_input, &input_length, (char**) &output, &output_size); + iconv_close(conv); + + return (int) result; + } + + int convert_widechar_to_multibyte(wchar_t* widechar_input, int input_length, char* output, int output_size) + { + iconv_t conv = iconv_open("UTF-8", "WCHAR_T"); + size_t result = iconv(conv, (char**) &widechar_input, &input_length, (char**) &output, &output_size); + iconv_close(conv); + + return (int) result; + } +#else +#error Implement system +#endif + + + + // TODO(bill): Make this non-windows specific String16 string_to_string16(gbAllocator a, String s) { int len, len1; @@ -174,16 +222,14 @@ String16 string_to_string16(gbAllocator a, String s) { return make_string16(NULL, 0); } - len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, - cast(char *)s.text, s.len, NULL, 0); + len = convert_multibyte_to_widechar(cast(char *)s.text, s.len, NULL, 0); if (len == 0) { return make_string16(NULL, 0); } text = gb_alloc_array(a, wchar_t, len+1); - len1 = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, - cast(char *)s.text, s.len, text, len); + len1 = convert_multibyte_to_widechar(cast(char *)s.text, s.len, text, len); if (len1 == 0) { gb_free(a, text); return make_string16(NULL, 0); @@ -201,16 +247,14 @@ String string16_to_string(gbAllocator a, String16 s) { return make_string(NULL, 0); } - len = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, - s.text, s.len, NULL, 0, NULL, NULL); + len = convert_widechar_to_multibyte(s.text, s.len, NULL, 0); if (len == 0) { return make_string(NULL, 0); } text = gb_alloc_array(a, u8, len+1); - len1 = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, - s.text, s.len, cast(char *)text, len, NULL, NULL); + len1 = convert_widechar_to_multibyte(s.text, s.len, cast(char *)text, len); if (len1 == 0) { gb_free(a, text); return make_string(NULL, 0); @@ -236,7 +280,6 @@ String string16_to_string(gbAllocator a, String16 s) { - bool unquote_char(String s, u8 quote, Rune *rune, bool *multiple_bytes, String *tail_string) { u8 c; diff --git a/src/timings.c b/src/timings.c index a934414ec..b31fd0738 100644 --- a/src/timings.c +++ b/src/timings.c @@ -11,6 +11,7 @@ typedef struct Timings { } Timings; +#if defined(GB_SYSTEM_WINDOWS) u64 win32_time_stamp_time_now(void) { LARGE_INTEGER counter; QueryPerformanceCounter(&counter); @@ -26,10 +27,43 @@ u64 win32_time_stamp__freq(void) { return win32_perf_count_freq.QuadPart; } +#elif defined(GB_SYSTEM_OSX) || defined(GB_SYSTEM_UNIX) +#include <time.h> + +u64 unix_time_stamp_time_now(void) { + struct timespec ts; + clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts); + + return (ts.tv_sec * 1000000000) + ts.tv_nsec; +} + +u64 unix_time_stamp__freq(void) { + gb_local_persist u64 freq = 0; + + if (freq == 0) { + struct timespec ts; + clock_getres(CLOCK_PROCESS_CPUTIME_ID, &ts); + + // that would be an absurd resolution (or lack thereof) + GB_ASSERT(ts.tv_sec == 0); + + freq = cast(u64) ((1.0 / ts.tv_nsec) * 1000000000.0); + + GB_ASSERT(freq != 0); + } + + return freq; +} + +#else +#error Implement system +#endif u64 time_stamp_time_now(void) { #if defined(GB_SYSTEM_WINDOWS) return win32_time_stamp_time_now(); +#elif defined(GB_SYSTEM_OSX) || defined(GB_SYSTEM_UNIX) + return unix_time_stamp_time_now(); #else #error time_stamp_time_now #endif @@ -38,6 +72,8 @@ u64 time_stamp_time_now(void) { u64 time_stamp__freq(void) { #if defined(GB_SYSTEM_WINDOWS) return win32_time_stamp__freq(); +#elif defined(GB_SYSTEM_OSX) || defined(GB_SYSTEM_UNIX) + return unix_time_stamp__freq(); #else #error time_stamp__freq #endif diff --git a/src/types.c b/src/types.c index 185438c03..b3e96eb79 100644 --- a/src/types.c +++ b/src/types.c @@ -1348,7 +1348,7 @@ void type_path_pop(TypePath *tp) { i64 type_size_of(BaseTypeSizes s, gbAllocator allocator, Type *t); i64 type_align_of(BaseTypeSizes s, gbAllocator allocator, Type *t); -i64 type_offset_of(BaseTypeSizes s, gbAllocator allocator, Type *t, i64 index); +i64 type_offset_of(BaseTypeSizes s, gbAllocator allocator, Type *t, isize index); i64 type_size_of_internal (BaseTypeSizes s, gbAllocator allocator, Type *t, TypePath *path); i64 type_align_of_internal(BaseTypeSizes s, gbAllocator allocator, Type *t, TypePath *path); |