Fix function overload resolution. Add static array not working.

This commit is contained in:
2024-06-25 08:54:02 +02:00
parent d2614b3ba9
commit 3bbbc1d556
6 changed files with 161 additions and 89 deletions

View File

@@ -151,10 +151,9 @@ emit_function :: (state : *Codegen_State, node : *AST_Node, indentation : int, e
indent(state, indentation); indent(state, indentation);
if function_variable.return_var { if function_variable.return_type_variable {
return_variable := h2tv(state.type_variables, function_variable.return_var); return_variable := h2tv(state.type_variables, function_variable.return_type_variable);
print_to_builder(*state.builder, "% ", type_to_string(return_variable)); print_to_builder(*state.builder, "% ", type_to_string(return_variable));
print("shiet: %\n", return_variable.*);
} else { } else {
append(*state.builder, "void "); append(*state.builder, "void ");
} }
@@ -319,15 +318,17 @@ emit_node :: (state : *Codegen_State, node : *AST_Node, indentation : int) {
} }
} }
emit_declaration :: (state : *Codegen_State, node : *AST_Node) { emit_field_list :: (state : *Codegen_State, field_list : *AST_Node, indentation : int) {
if node.kind == { for child : field_list.children {
case .Function; { emit_node(state, child, 1);
emit_function(state, node, 0);
if it_index < field_list.children.count {
append(*state.builder, ";\n");
} }
case .Properties; {
emit_properties(state, node, 0);
} }
case .Struct; { }
emit_struct :: (state : *Codegen_State, node : *AST_Node, indentation : int) {
print_to_builder(*state.builder, "struct %", node.name); print_to_builder(*state.builder, "struct %", node.name);
current_scope := state.current_scope; current_scope := state.current_scope;
@@ -341,17 +342,46 @@ emit_declaration :: (state : *Codegen_State, node : *AST_Node) {
append(*state.builder, " {"); append(*state.builder, " {");
} }
emit_field_list(state, field_list, indentation);
for child : field_list.children {
emit_node(state, child, 1);
if it_index < field_list.children.count {
append(*state.builder, ";\n");
}
}
append(*state.builder, "}\n\n"); append(*state.builder, "}\n\n");
state.current_scope = current_scope; state.current_scope = current_scope;
}
emit_cbuffer :: (state : *Codegen_State, node : *AST_Node, indentation : int) {
variable := h2tv(state.type_variables, node.type_variable);
print_to_builder(*state.builder, "cbuffer % : register(b%)", variable.name, variable.buffer_index);
current_scope := state.current_scope;
state.current_scope = h2tv(state.type_variables, node.type_variable).scope;
field_list := node.children[0];
if field_list.children.count > 0 {
append(*state.builder, "\n{\n");
} else {
append(*state.builder, " {");
}
emit_field_list(state, field_list, indentation);
append(*state.builder, "}\n\n");
state.current_scope = current_scope;
}
emit_declaration :: (state : *Codegen_State, node : *AST_Node) {
if node.kind == {
case .Function; {
emit_function(state, node, 0);
}
case .Properties; {
emit_properties(state, node, 0);
}
case .CBuffer; {
emit_cbuffer(state, node, 0);
}
case .Struct; {
emit_struct(state, node, 0);
} }
} }
} }

View File

@@ -8,6 +8,7 @@
// [x] Improve error reporting on mismatched overloads when types don't match, but arity does // [x] Improve error reporting on mismatched overloads when types don't match, but arity does
// [ ] Improve error reporting for type mismatches in general. It seems like the expect node is no always correct. // [ ] Improve error reporting for type mismatches in general. It seems like the expect node is no always correct.
#load "static_array.jai";
#import "Hash_Table"; #import "Hash_Table";
VERTEX_MAIN_FUNCTION_PREFIX :: "vertex"; VERTEX_MAIN_FUNCTION_PREFIX :: "vertex";
@@ -61,13 +62,13 @@ Type_Variable :: struct {
name : string; name : string;
//@Note(niels) For functions //@Note(niels) For functions
return_var : Type_Variable_Handle; return_type_variable : Type_Variable_Handle;
//@Note(niels) The scope this variable creates (function, struct, global) //@Note(niels) The scope this variable creates (function, struct, global)
scope : Scope_Handle; scope : Scope_Handle;
//@Note(niels): For struct members //@Note(niels): For struct members
field_parent : *AST_Node; struct_field_parent : *AST_Node;
typename : string; typename : string;
@@ -170,6 +171,11 @@ Semantic_Check_Result :: struct {
messages : [..]Compiler_Message; messages : [..]Compiler_Message;
had_error : bool; had_error : bool;
vertex_entry_point : *AST_Node;
pixel_entry_point : *AST_Node;
constant_buffers : Static_Array(Type_Variable_Handle, 16);
scope_stack : Scope_Stack; scope_stack : Scope_Stack;
type_variables : [..]Type_Variable; type_variables : [..]Type_Variable;
} }
@@ -187,9 +193,6 @@ Semantic_Checker :: struct {
current_scope : Scope_Handle; current_scope : Scope_Handle;
vertex_entry_point : *AST_Node;
pixel_entry_point : *AST_Node;
// type_variables : [..]Type_Variable; // type_variables : [..]Type_Variable;
constraints : [..]Type_Constraint; constraints : [..]Type_Constraint;
@@ -701,7 +704,6 @@ new_type_variable :: (checker : *Semantic_Checker) -> *Type_Variable, Type_Varia
return h2tv(checker, handle), handle; return h2tv(checker, handle), handle;
} }
add_child :: (variable : *Type_Variable, child : Type_Variable_Handle) { add_child :: (variable : *Type_Variable, child : Type_Variable_Handle) {
assert(variable.child_count < Type_Variable.MAX_TYPE_VARIABLE_CHILDREN); assert(variable.child_count < Type_Variable.MAX_TYPE_VARIABLE_CHILDREN);
variable.children[variable.child_count] = child; variable.children[variable.child_count] = child;
@@ -718,6 +720,8 @@ add_child :: (checker : *Semantic_Checker, handle : Type_Variable_Handle, child
init_semantic_checker :: (checker : *Semantic_Checker, root : *AST_Node, path : string) { init_semantic_checker :: (checker : *Semantic_Checker, root : *AST_Node, path : string) {
checker.program_root = root; checker.program_root = root;
checker.path = path; checker.path = path;
// @Incomplete(niels): Use other allocator and/or add static array with convenience functions
array_reserve(*checker.result.type_variables, 2048); array_reserve(*checker.result.type_variables, 2048);
array_reserve(*checker.result.scope_stack.stack, 256); array_reserve(*checker.result.scope_stack.stack, 256);
@@ -791,14 +795,14 @@ proper_type_to_string :: (builder : *String_Builder, checker : *Semantic_Checker
append(builder, ")"); append(builder, ")");
if var.return_var > 0 { if var.return_type_variable > 0 {
append(builder, " -> ", ); append(builder, " -> ", );
return_var := h2tv(checker, var.return_var); return_var := h2tv(checker, var.return_type_variable);
if is_proper(return_var) { if is_proper(return_var) {
proper_type_to_string(builder, checker, return_var); proper_type_to_string(builder, checker, return_var);
} else { } else {
append(builder, "[["); append(builder, "[[");
print_type_variable(builder, checker, var.return_var); print_type_variable(builder, checker, var.return_type_variable);
append(builder, "]]", ); append(builder, "]]", );
} }
} else { } else {
@@ -936,6 +940,7 @@ declare_cbuffer :: (checker : *Semantic_Checker, node : *AST_Node) -> Type_Varia
var.type = .CBuffer; var.type = .CBuffer;
current_custom_buffer_index += 1; current_custom_buffer_index += 1;
var.buffer_index = current_custom_buffer_index; var.buffer_index = current_custom_buffer_index;
array_add(*checker.result.constant_buffers, type_var);
return type_var; return type_var;
} }
@@ -980,11 +985,11 @@ declare_function :: (checker : *Semantic_Checker, node : *AST_Node, builtin : bo
name_to_check := get_actual_function_name(node); name_to_check := get_actual_function_name(node);
if node.vertex_entry_point { if node.vertex_entry_point {
checker.vertex_entry_point = node; checker.result.vertex_entry_point = node;
} }
if node.pixel_entry_point { if node.pixel_entry_point {
checker.pixel_entry_point = node; checker.result.pixel_entry_point = node;
} }
find_result := find_symbol(checker, name_to_check, checker.current_scope); find_result := find_symbol(checker, name_to_check, checker.current_scope);
@@ -1079,7 +1084,7 @@ declare_function :: (checker : *Semantic_Checker, node : *AST_Node, builtin : bo
if builtin && node.token.ident_value.count > 0 { if builtin && node.token.ident_value.count > 0 {
return_var, return_handle := new_type_variable(checker); return_var, return_handle := new_type_variable(checker);
return_var.type = get_type_from_identifier(checker, checker.current_scope, node, *return_var.typename); return_var.type = get_type_from_identifier(checker, checker.current_scope, node, *return_var.typename);
h2tv(checker, handle).return_var = return_handle; h2tv(checker, handle).return_type_variable= return_handle;
} }
if !builtin { if !builtin {
@@ -1128,8 +1133,8 @@ create_function_constraint :: (checker : *Semantic_Checker, node : *AST_Node) {
if statement.kind == .Return { if statement.kind == .Return {
result_var := check_node(checker, statement); result_var := check_node(checker, statement);
if result_var > 0 { if result_var > 0 {
variable.return_var = result_var; variable.return_type_variable= result_var;
constraint.function.return_variable = variable.return_var; constraint.function.return_variable = variable.return_type_variable;
} }
} else { } else {
result_var := check_node(checker, statement); result_var := check_node(checker, statement);
@@ -1142,7 +1147,7 @@ create_function_constraint :: (checker : *Semantic_Checker, node : *AST_Node) {
} }
} }
if node.token.ident_value.count > 0 && !variable.return_var { if node.token.ident_value.count > 0 && !variable.return_type_variable{
not_all_control_paths_return_value(checker, node); not_all_control_paths_return_value(checker, node);
} }
@@ -1184,7 +1189,7 @@ create_equivalence_constraint :: (checker : *Semantic_Checker, lhs : Type_Variab
return cast(Type_Constraint_Handle)checker.constraints.count; return cast(Type_Constraint_Handle)checker.constraints.count;
} }
create_variable :: (checker : *Semantic_Checker, node : *AST_Node, field_parent : *AST_Node = null) -> Type_Variable_Handle { create_variable :: (checker : *Semantic_Checker, node : *AST_Node, struct_field_parent : *AST_Node = null) -> Type_Variable_Handle {
find_result := find_symbol(checker, node.name, checker.current_scope); find_result := find_symbol(checker, node.name, checker.current_scope);
// x : int; // x : int;
// x.d = 5; // x.d = 5;
@@ -1192,7 +1197,7 @@ create_variable :: (checker : *Semantic_Checker, node : *AST_Node, field_parent
if find_result { if find_result {
node.type_variable = find_result.type_variable; node.type_variable = find_result.type_variable;
variable := h2tv(checker, find_result.type_variable); variable := h2tv(checker, find_result.type_variable);
variable.field_parent = field_parent; variable.struct_field_parent = struct_field_parent;
if get_scope(checker, checker.current_scope).kind == .Struct { if get_scope(checker, checker.current_scope).kind == .Struct {
variable.scope = checker.current_scope; variable.scope = checker.current_scope;
@@ -1204,10 +1209,6 @@ create_variable :: (checker : *Semantic_Checker, node : *AST_Node, field_parent
return 0; return 0;
} else { } else {
lookup_name : string = variable.typename; lookup_name : string = variable.typename;
// if variable.typename == "properties" {
// lookup_name = variable.name;
// }
print("Lookup: %\n", lookup_name);
struct_symbol := find_symbol(checker, lookup_name, checker.current_scope); struct_symbol := find_symbol(checker, lookup_name, checker.current_scope);
type_variable := h2tv(checker, struct_symbol.type_variable); type_variable := h2tv(checker, struct_symbol.type_variable);
@@ -1368,18 +1369,18 @@ create_call_constraint :: (checker : *Semantic_Checker, node : *AST_Node, type_v
array_add(*mismatches, mismatch); array_add(*mismatches, mismatch);
all_args_match = false; all_args_match = false;
overload_found = false;
} else { } else {
overload_found = all_args_match; overload_found = all_args_match;
} }
} }
if overload_found { if overload_found {
if function.return_var > 0 { if function.return_type_variable> 0 {
return_var := h2tv(checker, function.return_var); return_var := h2tv(checker, function.return_type_variable);
constrained_var := h2tv(checker, type_var); constrained_var := h2tv(checker, type_var);
constrained_var.type = return_var.type; constrained_var.type = return_var.type;
constrained_var.typename = return_var.typename; constrained_var.typename = return_var.typename;
print("%\n", constrained_var.typename);
} }
} }
} }
@@ -1436,7 +1437,7 @@ check_node :: (checker : *Semantic_Checker, node : *AST_Node) -> Type_Variable_H
proper_variable, rhs_handle := new_type_variable(checker); proper_variable, rhs_handle := new_type_variable(checker);
proper_variable.type = h2tv(checker, lhs_var).type; proper_variable.type = h2tv(checker, lhs_var).type;
proper_variable.source_node = h2tv(checker, lhs_var).source_node; proper_variable.source_node = h2tv(checker, lhs_var).source_node;
proper_variable.field_parent = h2tv(checker, lhs_var).field_parent; proper_variable.struct_field_parent = h2tv(checker, lhs_var).struct_field_parent;
create_equivalence_constraint(checker, handle, rhs_handle, node); create_equivalence_constraint(checker, handle, rhs_handle, node);
} }
@@ -1817,8 +1818,8 @@ pretty_print_function :: (checker : *Semantic_Checker, builder : *String_Builder
} }
} }
if function.return_var > 0 { if function.return_type_variable> 0 {
print_to_builder(builder, ") -> %\n", type_to_string(h2tv(checker, function.return_var))); print_to_builder(builder, ") -> %\n", type_to_string(h2tv(checker, function.return_type_variable)));
} else { } else {
append(builder, ")\n"); append(builder, ")\n");
} }
@@ -2015,8 +2016,8 @@ print_type_variable :: (builder : *String_Builder, variable : Type_Variable, che
case .Function; #through; case .Function; #through;
case .Struct; #through; case .Struct; #through;
case .Field; { case .Field; {
if variable.field_parent { if variable.struct_field_parent {
print_to_builder(builder, "%.", variable.field_parent.name); print_to_builder(builder, "%.", variable.struct_field_parent.name);
} }
print_to_builder(builder, "%", node.name); print_to_builder(builder, "%", node.name);
@@ -2041,10 +2042,10 @@ print_type_variable :: (builder : *String_Builder, variable : Type_Variable, che
print_from_source_location(builder, source_location); print_from_source_location(builder, source_location);
} }
case .Call; { case .Call; {
if variable.return_var { if variable.return_type_variable{
assert(false); assert(false);
print_to_builder(builder, "%", variable.typename); print_to_builder(builder, "%", variable.typename);
print_type_variable(builder, checker, variable.return_var); print_type_variable(builder, checker, variable.return_type_variable);
} }
print_to_builder(builder, "%(", node.name); print_to_builder(builder, "%(", node.name);

View File

@@ -111,9 +111,19 @@ Properties :: struct {
buffer_index : u32; buffer_index : u32;
} }
Constant_Buffer :: struct {
register : int;
name : string;
fields : Property_Field;
}
Shader_Variant_Collection :: struct { Shader_Variant_Collection :: struct {
properties : Properties; properties : Properties;
cbuffers : [..]Constant_Buffer;
variants : [..]Shader_Variant; variants : [..]Shader_Variant;
} }
@@ -334,10 +344,10 @@ compile_file :: (compiler : *Shader_Compiler, path : string) -> Compilation_Resu
variant : Shader_Variant; variant : Shader_Variant;
variant.text = codegen_result.result_text; variant.text = codegen_result.result_text;
if checker.vertex_entry_point { if checker.result.vertex_entry_point {
variant.vertex_entry_point.name = checker.vertex_entry_point.name; variant.vertex_entry_point.name = checker.result.vertex_entry_point.name;
type_variable := h2tv(*checker, checker.vertex_entry_point.type_variable); type_variable := h2tv(*checker, checker.result.vertex_entry_point.type_variable);
assert(type_variable.type == .Function); assert(type_variable.type == .Function);
node := type_variable.source_node; node := type_variable.source_node;
@@ -354,6 +364,8 @@ compile_file :: (compiler : *Shader_Compiler, path : string) -> Compilation_Resu
} }
} }
find_result := find_symbol(*check_result.scope_stack, "properties", xx 1); find_result := find_symbol(*check_result.scope_stack, "properties", xx 1);
if find_result { if find_result {
property_variable := h2tv(check_result.type_variables, find_result.type_variable); property_variable := h2tv(check_result.type_variables, find_result.type_variable);
@@ -368,13 +380,13 @@ compile_file :: (compiler : *Shader_Compiler, path : string) -> Compilation_Resu
result.collection.properties.buffer_index = property_variable.buffer_index; result.collection.properties.buffer_index = property_variable.buffer_index;
} }
if checker.pixel_entry_point { if checker.result.pixel_entry_point {
variant.pixel_entry_point.name = checker.pixel_entry_point.name; variant.pixel_entry_point.name = checker.result.pixel_entry_point.name;
type_variable := h2tv(*checker, checker.pixel_entry_point.type_variable); type_variable := h2tv(*checker, checker.result.pixel_entry_point.type_variable);
assert(type_variable.type == .Function); assert(type_variable.type == .Function);
field := type_variable_to_field(*checker, type_variable.return_var); field := type_variable_to_field(*checker, type_variable.return_type_variable);
for hint : type_variable.source_node.hint_tokens { for hint : type_variable.source_node.hint_tokens {
field_hint : Field_Hint; field_hint : Field_Hint;

29
static_array.jai Normal file
View File

@@ -0,0 +1,29 @@
Static_Array :: struct ($T : Type, $N : s64) {
array : [N] T;
capacity : s64 = N;
count : s64;
}
// operator [] :: (array : Static_Array($T, $N), index : int) -> T {
// assert(index < array.count);
// return array.array[index];
// }
// operator []= :: (array : *Static_Array($T, $N), index : int, value : T) {
// assert(index < array.count);
// array.array[index] = value;
// }
operator *[] :: (array : *Static_Array($T, $N), index : int) -> *T {
assert(index < array.count);
return *(array.array[index]);
}
array_add :: (array : *Static_Array($T, $N), item : T) {
assert(array.count + 1 < array.capacity);
print("%\n", array[array.count]);
array[array.count] = item;
array.count += 1;
}

View File

@@ -1,4 +1,16 @@
test/unknown_overload.shd:6,4: error: Type mismatch. Expected float3 got float test/unknown_overload.shd:6,0: error: Procedure call did not match any of the possible overloads for 'foo'
 found:
foo(v, v);
^^^
 While matching argument 1 in function call.
 foo(v, v);
^
 Possible overloads:
 foo :: (v1 : float3, v2 : float3) { (test/unknown_overload.shd:1)
 foo :: (v1 : float2, v2 : float2, v3 : float2) { (test/unknown_overload.shd:2)
test/unknown_overload.shd:6,4: error: Type mismatch. Expected float3 got float
 found:  found:
foo(v, v); foo(v, v);
^ ^
@@ -18,16 +30,4 @@
got: got:
v : float = 2.0 v : float = 2.0
test/unknown_overload.shd:6,0: error: Procedure call did not match any of the possible overloads for 'foo'
 found:
foo(v, v);
^^^
 While matching argument 1 in function call.
 foo(v, v);
^
 Possible overloads:
 foo :: (v1 : float3, v2 : float3) { (test/unknown_overload.shd:1)
 foo :: (v1 : float2, v2 : float2, v3 : float2) { (test/unknown_overload.shd:2)
 

View File

@@ -1,14 +1,4 @@
test/wrong_type_for_function.shd:11,24: error: Type mismatch. Expected float got float2 test/wrong_type_for_function.shd:11,17: error: Procedure call did not match any of the possible overloads for 'float4'
 found:
color : float4 = float4(y, 1.0, 1.0, 1.0);
^
expected:
float
got:
y : float2 = foo()
test/wrong_type_for_function.shd:11,17: error: Procedure call did not match any of the possible overloads for 'float4'
 found:  found:
color : float4 = float4(y, 1.0, 1.0, 1.0); color : float4 = float4(y, 1.0, 1.0, 1.0);
^^^^^^ ^^^^^^
@@ -19,4 +9,14 @@
 Possible overloads:  Possible overloads:
 foreign float4 :: (float, float, float, float) -> float4; (test/wrong_type_for_function.shd:79)  foreign float4 :: (float, float, float, float) -> float4; (test/wrong_type_for_function.shd:79)
test/wrong_type_for_function.shd:11,24: error: Type mismatch. Expected float got float2
 found:
color : float4 = float4(y, 1.0, 1.0, 1.0);
^
expected:
float
got:
y : float2 = foo()