Browse Source

Fix _preload.odin; Add for in without parameters; Change sync.Mutex for windows

Ginger Bill 8 years ago
parent
commit
b201670f7a
6 changed files with 122 additions and 28 deletions
  1. 11 9
      core/_preload.odin
  2. 2 2
      core/os_windows.odin
  3. 30 1
      core/sync_windows.odin
  4. 58 12
      core/sys/windows.odin
  5. 18 1
      src/parser.cpp
  6. 3 3
      src/tokenizer.cpp

+ 11 - 9
core/_preload.odin

@@ -133,7 +133,8 @@ Allocator :: struct #ordered {
 
 
 
 
 Context :: struct #ordered {
 Context :: struct #ordered {
-	thread_id:  int,
+	thread_guid:  int,
+	thread_index: int,
 
 
 	allocator:  Allocator,
 	allocator:  Allocator,
 
 
@@ -229,8 +230,8 @@ __init_context_from_ptr :: proc(c: ^Context, other: ^Context) #cc_contextless {
 	if c.allocator.procedure == nil {
 	if c.allocator.procedure == nil {
 		c.allocator = default_allocator();
 		c.allocator = default_allocator();
 	}
 	}
-	if c.thread_id == 0 {
-		c.thread_id = os.current_thread_id();
+	if c.thread_guid == 0 {
+		c.thread_guid = os.current_thread_id();
 	}
 	}
 }
 }
 
 
@@ -240,8 +241,8 @@ __init_context :: proc(c: ^Context) #cc_contextless {
 	if c.allocator.procedure == nil {
 	if c.allocator.procedure == nil {
 		c.allocator = default_allocator();
 		c.allocator = default_allocator();
 	}
 	}
-	if c.thread_id == 0 {
-		c.thread_id = os.current_thread_id();
+	if c.thread_guid == 0 {
+		c.thread_guid = os.current_thread_id();
 	}
 	}
 }
 }
 
 
@@ -328,7 +329,7 @@ append :: proc(array: ^[dynamic]$T, args: ...T) -> int {
 
 
 pop :: proc(array: ^[]$T) -> T #cc_contextless {
 pop :: proc(array: ^[]$T) -> T #cc_contextless {
 	res: T;
 	res: T;
-	if array do return res;
+	if array != nil do return res;
 	assert(len(array) > 0);
 	assert(len(array) > 0);
 	res = array[len(array)-1];
 	res = array[len(array)-1];
 	^raw.Slice(array).len -= 1;
 	^raw.Slice(array).len -= 1;
@@ -337,7 +338,7 @@ pop :: proc(array: ^[]$T) -> T #cc_contextless {
 
 
 pop :: proc(array: ^[dynamic]$T) -> T #cc_contextless {
 pop :: proc(array: ^[dynamic]$T) -> T #cc_contextless {
 	res: T;
 	res: T;
-	if array do return res;
+	if array != nil do return res;
 	assert(len(array) > 0);
 	assert(len(array) > 0);
 	res = array[len(array)-1];
 	res = array[len(array)-1];
 	^raw.DynamicArray(array).len -= 1;
 	^raw.DynamicArray(array).len -= 1;
@@ -352,7 +353,7 @@ clear :: proc(array: ^[dynamic]$T) #cc_contextless #inline {
 }
 }
 clear :: proc(m: ^map[$K]$V) #cc_contextless #inline {
 clear :: proc(m: ^map[$K]$V) #cc_contextless #inline {
 	if m == nil do return;
 	if m == nil do return;
-	raw_map := ^raw.DynamicMap(array);
+	raw_map := ^raw.DynamicMap(m);
 	hashes  := ^raw.DynamicArray(&raw_map.hashes);
 	hashes  := ^raw.DynamicArray(&raw_map.hashes);
 	entries := ^raw.DynamicArray(&raw_map.entries);
 	entries := ^raw.DynamicArray(&raw_map.entries);
 	hashes.len  = 0;
 	hashes.len  = 0;
@@ -391,7 +392,8 @@ __get_map_header :: proc(m: ^map[$K]$V) -> __MapHeader #cc_contextless {
 		value: V,
 		value: V,
 	}
 	}
 
 
-	header.is_key_string = types.is_string(type_info(K));
+	_, is_string := type_info_base(type_info(K)).(^TypeInfo.String);
+	header.is_key_string = is_string;
 	header.entry_size    = size_of(Entry);
 	header.entry_size    = size_of(Entry);
 	header.entry_align   = align_of(Entry);
 	header.entry_align   = align_of(Entry);
 	header.value_offset  = offset_of(Entry, value);
 	header.value_offset  = offset_of(Entry, value);

+ 2 - 2
core/os_windows.odin

@@ -75,8 +75,8 @@ open :: proc(path: string, mode: int = O_RDONLY, perm: u32 = 0) -> (Handle, Errn
 	}
 	}
 
 
 	share_mode := u32(win32.FILE_SHARE_READ|win32.FILE_SHARE_WRITE);
 	share_mode := u32(win32.FILE_SHARE_READ|win32.FILE_SHARE_WRITE);
-	sa: ^win32.Security_Attributes = nil;
-	sa_inherit := win32.Security_Attributes{length = size_of(win32.Security_Attributes), inherit_handle = 1};
+	sa: ^win32.SecurityAttributes = nil;
+	sa_inherit := win32.SecurityAttributes{length = size_of(win32.SecurityAttributes), inherit_handle = 1};
 	if mode&O_CLOEXEC == 0 {
 	if mode&O_CLOEXEC == 0 {
 		sa = &sa_inherit;
 		sa = &sa_inherit;
 	}
 	}

+ 30 - 1
core/sync_windows.odin

@@ -7,12 +7,18 @@ Semaphore :: struct {
 	_handle: win32.Handle,
 	_handle: win32.Handle,
 }
 }
 
 
+/*
 Mutex :: struct {
 Mutex :: struct {
 	_semaphore: Semaphore,
 	_semaphore: Semaphore,
 	_counter:   i32,
 	_counter:   i32,
 	_owner:     i32,
 	_owner:     i32,
 	_recursion: i32,
 	_recursion: i32,
 }
 }
+*/
+
+Mutex :: struct {
+	_critical_section: win32.CriticalSection,
+}
 
 
 current_thread_id :: proc() -> i32 {
 current_thread_id :: proc() -> i32 {
 	return i32(win32.get_current_thread_id());
 	return i32(win32.get_current_thread_id());
@@ -37,6 +43,29 @@ semaphore_wait :: proc(s: ^Semaphore) {
 }
 }
 
 
 
 
+mutex_init :: proc(m: ^Mutex, spin_count := 0) {
+	win32.initialize_critical_section_and_spin_count(&m._critical_section, u32(spin_count));
+}
+
+mutex_destroy :: proc(m: ^Mutex) {
+	win32.delete_critical_section(&m._critical_section);
+}
+
+mutex_lock :: proc(m: ^Mutex) {
+	win32.enter_critical_section(&m._critical_section);
+}
+
+mutex_try_lock :: proc(m: ^Mutex) -> bool {
+	return win32.try_enter_critical_section(&m._critical_section) != 0;
+}
+
+mutex_unlock :: proc(m: ^Mutex) {
+	win32.leave_critical_section(&m._critical_section);
+}
+
+
+
+/*
 mutex_init :: proc(m: ^Mutex) {
 mutex_init :: proc(m: ^Mutex) {
 	atomics.store(&m._counter, 0);
 	atomics.store(&m._counter, 0);
 	atomics.store(&m._owner, current_thread_id());
 	atomics.store(&m._owner, current_thread_id());
@@ -90,4 +119,4 @@ mutex_unlock :: proc(m: ^Mutex) {
 		}
 		}
 	}
 	}
 }
 }
-
+*/

+ 58 - 12
core/sys/windows.odin

@@ -103,7 +103,7 @@ FindData :: struct #ordered {
     alternate_file_name: [14]u8,
     alternate_file_name: [14]u8,
 }
 }
 
 
-Security_Attributes :: struct #ordered {
+SecurityAttributes :: struct #ordered {
 	length:              u32,
 	length:              u32,
 	security_descriptor: rawptr,
 	security_descriptor: rawptr,
 	inherit_handle:      Bool,
 	inherit_handle:      Bool,
@@ -142,6 +142,30 @@ PixelFormatDescriptor :: struct #ordered {
 	damage_mask: u32,
 	damage_mask: u32,
 }
 }
 
 
+CriticalSection :: struct #ordered {
+	debug_info:      ^CriticalSectionDebug,
+
+	lock_count:      i32,
+	recursion_count: i32,
+	owning_thread:   Handle,
+	lock_semaphore:  Handle,
+	spin_count:      ^u32,
+}
+
+CriticalSectionDebug :: struct #ordered {
+	typ:                           u16,
+	creator_back_trace_index:      u16,
+	critical_section:              ^CriticalSection,
+	process_locks_list:            ^ListEntry,
+	entry_count:                   u32,
+	contention_count:              u32,
+	flags:                         u32,
+	creator_back_trace_index_high: u16,
+	spare_word:                    u16,
+}
+
+ListEntry :: struct #ordered {flink, blink: ^ListEntry};
+
 
 
 
 
 MAPVK_VK_TO_VSC    :: 0;
 MAPVK_VK_TO_VSC    :: 0;
@@ -154,6 +178,12 @@ MAPVK_VSC_TO_VK_EX :: 3;
 
 
 INVALID_HANDLE :: Handle(~int(0));
 INVALID_HANDLE :: Handle(~int(0));
 
 
+CREATE_SUSPENDED                  :: 0x00000004;
+STACK_SIZE_PARAM_IS_A_RESERVATION :: 0x00010000;
+WAIT_ABANDONED :: 0x00000080;
+WAIT_OBJECT_0  :: 0;
+WAIT_TIMEOUT   :: 0x00000102;
+WAIT_FAILED    :: 0xffffffff;
 
 
 CS_VREDRAW    :: 0x0001;
 CS_VREDRAW    :: 0x0001;
 CS_HREDRAW    :: 0x0002;
 CS_HREDRAW    :: 0x0002;
@@ -316,28 +346,44 @@ foreign kernel32 {
 	get_process_heap :: proc() -> Handle                                                                                       #cc_std #link_name "GetProcessHeap"               ---;
 	get_process_heap :: proc() -> Handle                                                                                       #cc_std #link_name "GetProcessHeap"               ---;
 
 
 
 
-	create_semaphore_a     :: proc(attributes: ^Security_Attributes, initial_count, maximum_count: i32, name: ^u8) -> Handle   #cc_std #link_name "CreateSemaphoreA"             ---;
+	create_semaphore_a     :: proc(attributes: ^SecurityAttributes, initial_count, maximum_count: i32, name: ^u8) -> Handle    #cc_std #link_name "CreateSemaphoreA"             ---;
 	release_semaphore      :: proc(semaphore: Handle, release_count: i32, previous_count: ^i32) -> Bool                        #cc_std #link_name "ReleaseSemaphore"             ---;
 	release_semaphore      :: proc(semaphore: Handle, release_count: i32, previous_count: ^i32) -> Bool                        #cc_std #link_name "ReleaseSemaphore"             ---;
 	wait_for_single_object :: proc(handle: Handle, milliseconds: u32) -> u32                                                   #cc_std #link_name "WaitForSingleObject"          ---;
 	wait_for_single_object :: proc(handle: Handle, milliseconds: u32) -> u32                                                   #cc_std #link_name "WaitForSingleObject"          ---;
 
 
 
 
-	interlocked_compare_exchange :: proc(dst: ^i32, exchange, comparand: i32) -> i32                                           #cc_std #link_name "InterlockedCompareExchange"   ---;
-	interlocked_exchange         :: proc(dst: ^i32, desired: i32) -> i32                                                       #cc_std #link_name "InterlockedExchange"          ---;
-	interlocked_exchange_add     :: proc(dst: ^i32, desired: i32) -> i32                                                       #cc_std #link_name "InterlockedExchangeAdd"       ---;
-	interlocked_and              :: proc(dst: ^i32, desired: i32) -> i32                                                       #cc_std #link_name "InterlockedAnd"               ---;
-	interlocked_or               :: proc(dst: ^i32, desired: i32) -> i32                                                       #cc_std #link_name "InterlockedOr"                ---;
+	interlocked_compare_exchange :: proc(dst: ^i32, exchange, comparand: i32) -> i32                                           #cc_c   #link_name "InterlockedCompareExchange"   ---;
+	interlocked_exchange         :: proc(dst: ^i32, desired: i32) -> i32                                                       #cc_c   #link_name "InterlockedExchange"          ---;
+	interlocked_exchange_add     :: proc(dst: ^i32, desired: i32) -> i32                                                       #cc_c   #link_name "InterlockedExchangeAdd"       ---;
+	interlocked_and              :: proc(dst: ^i32, desired: i32) -> i32                                                       #cc_c   #link_name "InterlockedAnd"               ---;
+	interlocked_or               :: proc(dst: ^i32, desired: i32) -> i32                                                       #cc_c   #link_name "InterlockedOr"                ---;
 
 
-	interlocked_compare_exchange64 :: proc(dst: ^i64, exchange, comparand: i64) -> i64                                         #cc_std #link_name "InterlockedCompareExchange64" ---;
-	interlocked_exchange64         :: proc(dst: ^i64, desired: i64) -> i64                                                     #cc_std #link_name "InterlockedExchange64"        ---;
-	interlocked_exchange_add64     :: proc(dst: ^i64, desired: i64) -> i64                                                     #cc_std #link_name "InterlockedExchangeAdd64"     ---;
-	interlocked_and64              :: proc(dst: ^i64, desired: i64) -> i64                                                     #cc_std #link_name "InterlockedAnd64"             ---;
-	interlocked_or64               :: proc(dst: ^i64, desired: i64) -> i64                                                     #cc_std #link_name "InterlockedOr64"              ---;
+	interlocked_compare_exchange64 :: proc(dst: ^i64, exchange, comparand: i64) -> i64                                         #cc_c   #link_name "InterlockedCompareExchange64" ---;
+	interlocked_exchange64         :: proc(dst: ^i64, desired: i64) -> i64                                                     #cc_c   #link_name "InterlockedExchange64"        ---;
+	interlocked_exchange_add64     :: proc(dst: ^i64, desired: i64) -> i64                                                     #cc_c   #link_name "InterlockedExchangeAdd64"     ---;
+	interlocked_and64              :: proc(dst: ^i64, desired: i64) -> i64                                                     #cc_c   #link_name "InterlockedAnd64"             ---;
+	interlocked_or64               :: proc(dst: ^i64, desired: i64) -> i64                                                     #cc_c   #link_name "InterlockedOr64"              ---;
 
 
 	mm_pause           :: proc()                                                                                               #cc_std #link_name "_mm_pause"                    ---;
 	mm_pause           :: proc()                                                                                               #cc_std #link_name "_mm_pause"                    ---;
 	read_write_barrier :: proc()                                                                                               #cc_std #link_name "ReadWriteBarrier"             ---;
 	read_write_barrier :: proc()                                                                                               #cc_std #link_name "ReadWriteBarrier"             ---;
 	write_barrier      :: proc()                                                                                               #cc_std #link_name "WriteBarrier"                 ---;
 	write_barrier      :: proc()                                                                                               #cc_std #link_name "WriteBarrier"                 ---;
 	read_barrier       :: proc()                                                                                               #cc_std #link_name "ReadBarrier"                  ---;
 	read_barrier       :: proc()                                                                                               #cc_std #link_name "ReadBarrier"                  ---;
 
 
+	create_thread        :: proc(thread_attributes: ^SecurityAttributes, stack_size: int, start_routine: rawptr,
+	                             parameter: rawptr, creation_flags: u32, thread_id: ^u32) -> Handle                            #cc_std #link_name "CreateThread"                 ---;
+	resume_thread        :: proc(thread: Handle) -> u32                                                                        #cc_std #link_name "ResumeThread"                 ---;
+	get_thread_priority  :: proc(thread: Handle) -> i32                                                                        #cc_std #link_name "GetThreadPriority"            ---;
+	set_thread_priority  :: proc(thread: Handle, priority: i32) -> Bool                                                        #cc_std #link_name "SetThreadPriority"            ---;
+	get_exit_code_thread :: proc(thread: Handle, exit_code: ^u32) -> Bool                                                      #cc_std #link_name "GetExitCodeThread"            ---;
+
+	initialize_critical_section                :: proc(critical_section: ^CriticalSection)                                     #cc_std #link_name "InitializeCriticalSection"             ---;
+	initialize_critical_section_and_spin_count :: proc(critical_section: ^CriticalSection, spin_count: u32)                    #cc_std #link_name "InitializeCriticalSectionAndSpinCount" ---;
+	delete_critical_section                    :: proc(critical_section: ^CriticalSection)                                     #cc_std #link_name "DeleteCriticalSection"                 ---;
+	set_critical_section_spin_count            :: proc(critical_section: ^CriticalSection, spin_count: u32) -> u32             #cc_std #link_name "SetCriticalSectionSpinCount"           ---;
+	try_enter_critical_section                 :: proc(critical_section: ^CriticalSection) -> Bool                             #cc_std #link_name "TryEnterCriticalSection"               ---;
+	enter_critical_section                     :: proc(critical_section: ^CriticalSection)                                     #cc_std #link_name "EnterCriticalSection"                  ---;
+	leave_critical_section                     :: proc(critical_section: ^CriticalSection)                                     #cc_std #link_name "LeaveCriticalSection"                  ---;
+
+	create_event_a :: proc(event_attributes: ^SecurityAttributes, manual_reset, initial_state: Bool, name: ^u8) -> Handle      #cc_std #link_name "CreateEventA"                 ---;
 
 
 	load_library_a   :: proc(c_str: ^u8) -> Hmodule                                                                            #cc_std #link_name "LoadLibraryA"                 ---;
 	load_library_a   :: proc(c_str: ^u8) -> Hmodule                                                                            #cc_std #link_name "LoadLibraryA"                 ---;
 	free_library     :: proc(h: Hmodule)                                                                                       #cc_std #link_name "FreeLibrary"                  ---;
 	free_library     :: proc(h: Hmodule)                                                                                       #cc_std #link_name "FreeLibrary"                  ---;

+ 18 - 1
src/parser.cpp

@@ -3992,7 +3992,25 @@ AstNode *parse_for_stmt(AstFile *f) {
 	if (f->curr_token.kind != Token_OpenBrace &&
 	if (f->curr_token.kind != Token_OpenBrace &&
 	    f->curr_token.kind != Token_do) {
 	    f->curr_token.kind != Token_do) {
 		isize prev_level = f->expr_level;
 		isize prev_level = f->expr_level;
+		defer (f->expr_level = prev_level);
 		f->expr_level = -1;
 		f->expr_level = -1;
+
+		if (f->curr_token.kind == Token_in) {
+			Token in_token = expect_token(f, Token_in);
+			AstNode *rhs = nullptr;
+			bool prev_allow_range = f->allow_range;
+			f->allow_range = true;
+			rhs = parse_expr(f, false);
+			f->allow_range = prev_allow_range;
+
+			if (allow_token(f, Token_do)) {
+				body = convert_stmt_to_body(f, parse_stmt(f));
+			} else {
+				body = parse_block_stmt(f, false);
+			}
+			return ast_range_stmt(f, token, nullptr, nullptr, in_token, rhs, body);
+		}
+
 		if (f->curr_token.kind != Token_Semicolon) {
 		if (f->curr_token.kind != Token_Semicolon) {
 			cond = parse_simple_stmt(f, StmtAllowFlag_In);
 			cond = parse_simple_stmt(f, StmtAllowFlag_In);
 			if (cond->kind == AstNode_AssignStmt && cond->AssignStmt.op.kind == Token_in) {
 			if (cond->kind == AstNode_AssignStmt && cond->AssignStmt.op.kind == Token_in) {
@@ -4014,7 +4032,6 @@ AstNode *parse_for_stmt(AstFile *f) {
 			}
 			}
 		}
 		}
 
 
-		f->expr_level = prev_level;
 	}
 	}
 
 
 	if (allow_token(f, Token_do)) {
 	if (allow_token(f, Token_do)) {

+ 3 - 3
src/tokenizer.cpp

@@ -94,14 +94,14 @@ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \
 	TOKEN_KIND(Token_if,                     "if"),                     \
 	TOKEN_KIND(Token_if,                     "if"),                     \
 	TOKEN_KIND(Token_else,                   "else"),                   \
 	TOKEN_KIND(Token_else,                   "else"),                   \
 	TOKEN_KIND(Token_for,                    "for"),                    \
 	TOKEN_KIND(Token_for,                    "for"),                    \
-	TOKEN_KIND(Token_in,                     "in"),                     \
 	TOKEN_KIND(Token_match,                  "match"),                  \
 	TOKEN_KIND(Token_match,                  "match"),                  \
+	TOKEN_KIND(Token_in,                     "in"),                     \
+	TOKEN_KIND(Token_do,                     "do"),                     \
 	TOKEN_KIND(Token_case,                   "case"),                   \
 	TOKEN_KIND(Token_case,                   "case"),                   \
 	TOKEN_KIND(Token_break,                  "break"),                  \
 	TOKEN_KIND(Token_break,                  "break"),                  \
 	TOKEN_KIND(Token_continue,               "continue"),               \
 	TOKEN_KIND(Token_continue,               "continue"),               \
 	TOKEN_KIND(Token_fallthrough,            "fallthrough"),            \
 	TOKEN_KIND(Token_fallthrough,            "fallthrough"),            \
 	TOKEN_KIND(Token_defer,                  "defer"),                  \
 	TOKEN_KIND(Token_defer,                  "defer"),                  \
-	TOKEN_KIND(Token_do,                     "do"),                     \
 	TOKEN_KIND(Token_return,                 "return"),                 \
 	TOKEN_KIND(Token_return,                 "return"),                 \
 	TOKEN_KIND(Token_proc,                   "proc"),                   \
 	TOKEN_KIND(Token_proc,                   "proc"),                   \
 	TOKEN_KIND(Token_macro,                  "macro"),                  \
 	TOKEN_KIND(Token_macro,                  "macro"),                  \
@@ -111,9 +111,9 @@ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \
 	TOKEN_KIND(Token_enum,                   "enum"),                   \
 	TOKEN_KIND(Token_enum,                   "enum"),                   \
 	TOKEN_KIND(Token_bit_field,              "bit_field"),              \
 	TOKEN_KIND(Token_bit_field,              "bit_field"),              \
 	TOKEN_KIND(Token_vector,                 "vector"),                 \
 	TOKEN_KIND(Token_vector,                 "vector"),                 \
+	TOKEN_KIND(Token_map,                    "map"),                    \
 	TOKEN_KIND(Token_static,                 "static"),                 \
 	TOKEN_KIND(Token_static,                 "static"),                 \
 	TOKEN_KIND(Token_dynamic,                "dynamic"),                \
 	TOKEN_KIND(Token_dynamic,                "dynamic"),                \
-	TOKEN_KIND(Token_map,                    "map"),                    \
 	TOKEN_KIND(Token_using,                  "using"),                  \
 	TOKEN_KIND(Token_using,                  "using"),                  \
 	TOKEN_KIND(Token_context,                "context"),                \
 	TOKEN_KIND(Token_context,                "context"),                \
 	TOKEN_KIND(Token_push_context,           "push_context"),           \
 	TOKEN_KIND(Token_push_context,           "push_context"),           \