diff options
| author | gingerBill <bill@gingerbill.org> | 2022-03-19 13:03:14 +0000 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2022-03-19 13:03:14 +0000 |
| commit | 6d73c254b2338ab3ff4bc0a4ce8fc33f6d70a6b4 (patch) | |
| tree | dbaa6439da7efa09fe69772f584a239c986d3afd | |
| parent | 16bd6c7205a1eea264cc2daa077f4c7f096868af (diff) | |
| parent | ae6441182de5185812b9e5558b08ccaa3a877cdc (diff) | |
Merge branch 'master' into middle-end
| -rw-r--r-- | core/sys/win32/user32.odin | 2 | ||||
| -rw-r--r-- | core/sys/windows/types.odin | 2 | ||||
| -rw-r--r-- | core/unicode/utf8/utf8string/string.odin | 120 | ||||
| -rw-r--r-- | examples/all/all_main.odin | 2 | ||||
| -rw-r--r-- | src/check_expr.cpp | 79 | ||||
| -rw-r--r-- | src/check_type.cpp | 14 | ||||
| -rw-r--r-- | src/checker.cpp | 9 | ||||
| -rw-r--r-- | src/entity.cpp | 10 | ||||
| -rw-r--r-- | src/types.cpp | 1 |
9 files changed, 147 insertions, 92 deletions
diff --git a/core/sys/win32/user32.odin b/core/sys/win32/user32.odin index fdf6a91f6..44d1f7004 100644 --- a/core/sys/win32/user32.odin +++ b/core/sys/win32/user32.odin @@ -111,6 +111,8 @@ foreign user32 { @(link_name="SetWindowTextW") set_window_text_w :: proc(hwnd: Hwnd, c_string: Wstring) -> Bool --- @(link_name="RegisterClassA") register_class_a :: proc(wc: ^Wnd_Class_A) -> i16 --- @(link_name="RegisterClassW") register_class_w :: proc(wc: ^Wnd_Class_W) -> i16 --- + @(link_name="UnregisterClassA") unregister_class_a :: proc(class_name: cstring, instance: Hinstance) -> Bool --- + @(link_name="UnregisterClassW") unregister_class_w :: proc(class_name: Wstring, instance: Hinstance) -> Bool --- @(link_name="RegisterClassExA") register_class_ex_a :: proc(wc: ^Wnd_Class_Ex_A) -> i16 --- @(link_name="RegisterClassExW") register_class_ex_w :: proc(wc: ^Wnd_Class_Ex_W) -> i16 --- diff --git a/core/sys/windows/types.odin b/core/sys/windows/types.odin index 1407201d6..1ead165b4 100644 --- a/core/sys/windows/types.odin +++ b/core/sys/windows/types.odin @@ -578,7 +578,7 @@ PROCESS_INFORMATION :: struct { } // FYI: This is STARTUPINFOW, not STARTUPINFOA -STARTUPINFO :: struct #packed { +STARTUPINFO :: struct { cb: DWORD, lpReserved: LPWSTR, lpDesktop: LPWSTR, diff --git a/core/unicode/utf8/utf8string/string.odin b/core/unicode/utf8/utf8string/string.odin index 23e2eefc6..86267defb 100644 --- a/core/unicode/utf8/utf8string/string.odin +++ b/core/unicode/utf8/utf8string/string.odin @@ -16,140 +16,140 @@ String :: struct { } @(private) -_len :: builtin.len; // helper procedure +_len :: builtin.len // helper procedure init :: proc(s: ^String, contents: string) -> ^String { - s.contents = contents; - s.byte_pos = 0; - s.rune_pos = 0; + s.contents = contents + s.byte_pos = 0 + s.rune_pos = 0 for i in 0..<_len(contents) { if contents[i] >= utf8.RUNE_SELF { - s.rune_count = utf8.rune_count_in_string(contents); - _, s.width = utf8.decode_rune_in_string(contents); - s.non_ascii = i; - return s; + s.rune_count = utf8.rune_count_in_string(contents) + _, s.width = utf8.decode_rune_in_string(contents) + s.non_ascii = i + return s } } - s.rune_count = _len(contents); - s.width = 0; - s.non_ascii = _len(contents); - return s; + s.rune_count = _len(contents) + s.width = 0 + s.non_ascii = _len(contents) + return s } to_string :: proc(s: ^String) -> string { - return s.contents; + return s.contents } len :: proc(s: ^String) -> int { - return s.rune_count; + return s.rune_count } is_ascii :: proc(s: ^String) -> bool { - return s.width == 0; + return s.width == 0 } at :: proc(s: ^String, i: int, loc := #caller_location) -> (r: rune) { - runtime.bounds_check_error_loc(loc, i, s.rune_count); + runtime.bounds_check_error_loc(loc, i, s.rune_count) if i < s.non_ascii { - return rune(s.contents[i]); + return rune(s.contents[i]) } switch i { case 0: - r, s.width = utf8.decode_rune_in_string(s.contents); - s.rune_pos = 0; - s.byte_pos = 0; - return; + r, s.width = utf8.decode_rune_in_string(s.contents) + s.rune_pos = 0 + s.byte_pos = 0 + return case s.rune_count-1: - r, s.width = utf8.decode_rune_in_string(s.contents); - s.rune_pos = i; - s.byte_pos = _len(s.contents) - s.width; - return; + r, s.width = utf8.decode_rune_in_string(s.contents) + s.rune_pos = i + s.byte_pos = _len(s.contents) - s.width + return case s.rune_pos-1: - r, s.width = utf8.decode_rune_in_string(s.contents[0:s.byte_pos]); - s.rune_pos = i; - s.byte_pos -= s.width; - return; + r, s.width = utf8.decode_rune_in_string(s.contents[0:s.byte_pos]) + s.rune_pos = i + s.byte_pos -= s.width + return case s.rune_pos+1: - s.rune_pos = i; - s.byte_pos += s.width; - fallthrough; + s.rune_pos = i + s.byte_pos += s.width + fallthrough case s.rune_pos: - r, s.width = utf8.decode_rune_in_string(s.contents[s.byte_pos:]); - return; + r, s.width = utf8.decode_rune_in_string(s.contents[s.byte_pos:]) + return } // Linear scan - scan_forward := true; + scan_forward := true if i < s.rune_pos { if i < (s.rune_pos-s.non_ascii)/2 { - s.byte_pos, s.rune_pos = s.non_ascii, s.non_ascii; + s.byte_pos, s.rune_pos = s.non_ascii, s.non_ascii } else { - scan_forward = false; + scan_forward = false } } else if i-s.rune_pos < (s.rune_count-s.rune_pos)/2 { - // scan_forward = true; + // scan_forward = true } else { - s.byte_pos, s.rune_pos = _len(s.contents), s.rune_count; - scan_forward = false; + s.byte_pos, s.rune_pos = _len(s.contents), s.rune_count + scan_forward = false } if scan_forward { for { - r, s.width = utf8.decode_rune_in_string(s.contents[s.byte_pos:]); + r, s.width = utf8.decode_rune_in_string(s.contents[s.byte_pos:]) if s.rune_pos == i { - return; + return } - s.rune_pos += 1; - s.byte_pos += s.width; + s.rune_pos += 1 + s.byte_pos += s.width } } else { for { - r, s.width = utf8.decode_last_rune_in_string(s.contents[:s.byte_pos]); - s.rune_pos -= 1; - s.byte_pos -= s.width; + r, s.width = utf8.decode_last_rune_in_string(s.contents[:s.byte_pos]) + s.rune_pos -= 1 + s.byte_pos -= s.width if s.rune_pos == i { - return; + return } } } } slice :: proc(s: ^String, i, j: int, loc := #caller_location) -> string { - runtime.slice_expr_error_lo_hi_loc(loc, i, j, s.rune_count); + runtime.slice_expr_error_lo_hi_loc(loc, i, j, s.rune_count) if j < s.non_ascii { - return s.contents[i:j]; + return s.contents[i:j] } if i == j { - return ""; + return "" } - lo, hi: int; + lo, hi: int if i < s.non_ascii { - lo = i; + lo = i } else if i == s.rune_count { - lo = _len(s.contents); + lo = _len(s.contents) } else { - at(s, i, loc); - lo = s.byte_pos; + at(s, i, loc) + lo = s.byte_pos } if j == s.rune_count { - hi = _len(s.contents); + hi = _len(s.contents) } else { - at(s, j, loc); - hi = s.byte_pos; + at(s, j, loc) + hi = s.byte_pos } - return s.contents[lo:hi]; + return s.contents[lo:hi] } diff --git a/examples/all/all_main.odin b/examples/all/all_main.odin index 7d2082250..dafd29ab3 100644 --- a/examples/all/all_main.odin +++ b/examples/all/all_main.odin @@ -104,6 +104,7 @@ import time "core:time" import unicode "core:unicode" import utf8 "core:unicode/utf8" +import utf8string "core:unicode/utf8/utf8string" import utf16 "core:unicode/utf16" main :: proc(){} @@ -193,4 +194,5 @@ _ :: thread _ :: time _ :: unicode _ :: utf8 +_ :: utf8string _ :: utf16
\ No newline at end of file diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 937995df3..47cbd5354 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -4881,25 +4881,16 @@ bool is_expr_constant_zero(Ast *expr) { return false; } - -CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { - ast_node(ce, CallExpr, call); - GB_ASSERT(is_type_proc(proc_type)); - proc_type = base_type(proc_type); - TypeProc *pt = &proc_type->Proc; - +isize get_procedure_param_count_excluding_defaults(Type *pt, isize *param_count_) { + GB_ASSERT(pt != nullptr); + GB_ASSERT(pt->kind == Type_Proc); isize param_count = 0; isize param_count_excluding_defaults = 0; - bool variadic = pt->variadic; - bool vari_expand = (ce->ellipsis.pos.line != 0); - i64 score = 0; - bool show_error = show_error_mode == CallArgumentMode_ShowErrors; - - + bool variadic = pt->Proc.variadic; TypeTuple *param_tuple = nullptr; - if (pt->params != nullptr) { - param_tuple = &pt->params->Tuple; + if (pt->Proc.params != nullptr) { + param_tuple = &pt->Proc.params->Tuple; param_count = param_tuple->variables.count; if (variadic) { @@ -4939,6 +4930,31 @@ CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { } } + if (param_count_) *param_count_ = param_count; + return param_count_excluding_defaults; +} + + +CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { + ast_node(ce, CallExpr, call); + GB_ASSERT(is_type_proc(proc_type)); + proc_type = base_type(proc_type); + TypeProc *pt = &proc_type->Proc; + + isize param_count = 0; + isize param_count_excluding_defaults = get_procedure_param_count_excluding_defaults(proc_type, ¶m_count); + bool variadic = pt->variadic; + bool vari_expand = (ce->ellipsis.pos.line != 0); + i64 score = 0; + bool show_error = show_error_mode == CallArgumentMode_ShowErrors; + + + TypeTuple *param_tuple = nullptr; + if (pt->params != nullptr) { + param_tuple = &pt->params->Tuple; + } + + CallArgumentError err = CallArgumentError_None; Type *final_proc_type = proc_type; Entity *gen_entity = nullptr; @@ -5611,7 +5627,37 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type if (operand->mode == Addressing_ProcGroup) { check_entity_decl(c, operand->proc_group, nullptr, nullptr); - Array<Entity *> procs = proc_group_entities(c, *operand); + auto procs = proc_group_entities_cloned(c, *operand); + + if (procs.count > 1) { + isize max_arg_count = args.count; + for_array(i, args) { + // NOTE(bill): The only thing that may have multiple values + // will be a call expression (assuming `or_return` and `()` will be stripped) + Ast *arg = strip_or_return_expr(args[i]); + if (arg && arg->kind == Ast_CallExpr) { + max_arg_count = ISIZE_MAX; + break; + } + } + + for (isize proc_index = 0; proc_index < procs.count; /**/) { + Entity *proc = procs[proc_index]; + Type *pt = base_type(proc->type); + if (!(pt != nullptr && is_type_proc(pt))) { + continue; + } + + isize param_count = 0; + isize param_count_excluding_defaults = get_procedure_param_count_excluding_defaults(pt, ¶m_count); + + if (param_count_excluding_defaults > max_arg_count) { + array_unordered_remove(&procs, proc_index); + } else { + proc_index++; + } + } + } if (procs.count == 1) { Ast *ident = operand->expr; @@ -5641,6 +5687,7 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type return data; } + Entity **lhs = nullptr; isize lhs_count = -1; diff --git a/src/check_type.cpp b/src/check_type.cpp index ecb2c26ea..3c7f33a46 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -1960,20 +1960,6 @@ bool check_procedure_type(CheckerContext *ctx, Type *type, Ast *proc_type_node, if (params) param_count = params ->Tuple.variables.count; if (results) result_count = results->Tuple.variables.count; - if (param_count > 0) { - for_array(i, params->Tuple.variables) { - Entity *param = params->Tuple.variables[i]; - if (param->kind == Entity_Variable) { - ParameterValue pv = param->Variable.param_value; - if (pv.kind == ParameterValue_Constant && - pv.value.kind == ExactValue_Procedure) { - type->Proc.has_proc_default_values = true; - break; - } - } - } - } - if (result_count > 0) { Entity *first = results->Tuple.variables[0]; type->Proc.has_named_results = first->token.string != ""; diff --git a/src/checker.cpp b/src/checker.cpp index ea300afd9..53bba654d 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -2657,6 +2657,15 @@ Array<Entity *> proc_group_entities(CheckerContext *c, Operand o) { return procs; } +Array<Entity *> proc_group_entities_cloned(CheckerContext *c, Operand o) { + auto entities = proc_group_entities(c, o); + if (entities.count == 0) { + return {}; + } + return array_clone(permanent_allocator(), entities); +} + + void init_core_type_info(Checker *c) { diff --git a/src/entity.cpp b/src/entity.cpp index f88093f9d..60561a42f 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -118,6 +118,16 @@ struct ParameterValue { }; }; +bool has_parameter_value(ParameterValue const ¶m_value) { + if (param_value.kind != ParameterValue_Invalid) { + return true; + } + if (param_value.original_ast_expr != nullptr) { + return true; + } + return false; +} + enum EntityConstantFlags : u32 { EntityConstantFlag_ImplicitEnumValue = 1<<0, }; diff --git a/src/types.cpp b/src/types.cpp index 58ccdf5b9..ef770c846 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -186,7 +186,6 @@ struct TypeProc { bool c_vararg; bool is_polymorphic; bool is_poly_specialized; - bool has_proc_default_values; bool has_named_results; bool diverging; // no return bool return_by_pointer; |