Fix function overload resolution. Add static array not working.
This commit is contained in:
66
Codegen.jai
66
Codegen.jai
@@ -151,10 +151,9 @@ emit_function :: (state : *Codegen_State, node : *AST_Node, indentation : int, e
|
||||
|
||||
indent(state, indentation);
|
||||
|
||||
if function_variable.return_var {
|
||||
return_variable := h2tv(state.type_variables, function_variable.return_var);
|
||||
if function_variable.return_type_variable {
|
||||
return_variable := h2tv(state.type_variables, function_variable.return_type_variable);
|
||||
print_to_builder(*state.builder, "% ", type_to_string(return_variable));
|
||||
print("shiet: %\n", return_variable.*);
|
||||
} else {
|
||||
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) {
|
||||
if node.kind == {
|
||||
case .Function; {
|
||||
emit_function(state, node, 0);
|
||||
emit_field_list :: (state : *Codegen_State, field_list : *AST_Node, indentation : int) {
|
||||
for child : field_list.children {
|
||||
emit_node(state, child, 1);
|
||||
|
||||
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);
|
||||
|
||||
current_scope := state.current_scope;
|
||||
@@ -341,17 +342,46 @@ emit_declaration :: (state : *Codegen_State, node : *AST_Node) {
|
||||
append(*state.builder, " {");
|
||||
}
|
||||
|
||||
|
||||
for child : field_list.children {
|
||||
emit_node(state, child, 1);
|
||||
|
||||
if it_index < field_list.children.count {
|
||||
append(*state.builder, ";\n");
|
||||
}
|
||||
}
|
||||
emit_field_list(state, field_list, indentation);
|
||||
|
||||
append(*state.builder, "}\n\n");
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
// [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.
|
||||
|
||||
#load "static_array.jai";
|
||||
#import "Hash_Table";
|
||||
|
||||
VERTEX_MAIN_FUNCTION_PREFIX :: "vertex";
|
||||
@@ -61,13 +62,13 @@ Type_Variable :: struct {
|
||||
name : string;
|
||||
|
||||
//@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)
|
||||
scope : Scope_Handle;
|
||||
|
||||
//@Note(niels): For struct members
|
||||
field_parent : *AST_Node;
|
||||
struct_field_parent : *AST_Node;
|
||||
|
||||
typename : string;
|
||||
|
||||
@@ -170,6 +171,11 @@ Semantic_Check_Result :: struct {
|
||||
messages : [..]Compiler_Message;
|
||||
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;
|
||||
type_variables : [..]Type_Variable;
|
||||
}
|
||||
@@ -187,9 +193,6 @@ Semantic_Checker :: struct {
|
||||
|
||||
current_scope : Scope_Handle;
|
||||
|
||||
vertex_entry_point : *AST_Node;
|
||||
pixel_entry_point : *AST_Node;
|
||||
|
||||
// type_variables : [..]Type_Variable;
|
||||
constraints : [..]Type_Constraint;
|
||||
|
||||
@@ -701,7 +704,6 @@ new_type_variable :: (checker : *Semantic_Checker) -> *Type_Variable, Type_Varia
|
||||
return h2tv(checker, handle), handle;
|
||||
}
|
||||
|
||||
|
||||
add_child :: (variable : *Type_Variable, child : Type_Variable_Handle) {
|
||||
assert(variable.child_count < Type_Variable.MAX_TYPE_VARIABLE_CHILDREN);
|
||||
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) {
|
||||
checker.program_root = root;
|
||||
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.scope_stack.stack, 256);
|
||||
|
||||
@@ -791,14 +795,14 @@ proper_type_to_string :: (builder : *String_Builder, checker : *Semantic_Checker
|
||||
|
||||
append(builder, ")");
|
||||
|
||||
if var.return_var > 0 {
|
||||
if var.return_type_variable > 0 {
|
||||
append(builder, " -> ", );
|
||||
return_var := h2tv(checker, var.return_var);
|
||||
return_var := h2tv(checker, var.return_type_variable);
|
||||
if is_proper(return_var) {
|
||||
proper_type_to_string(builder, checker, return_var);
|
||||
} else {
|
||||
append(builder, "[[");
|
||||
print_type_variable(builder, checker, var.return_var);
|
||||
print_type_variable(builder, checker, var.return_type_variable);
|
||||
append(builder, "]]", );
|
||||
}
|
||||
} else {
|
||||
@@ -936,6 +940,7 @@ declare_cbuffer :: (checker : *Semantic_Checker, node : *AST_Node) -> Type_Varia
|
||||
var.type = .CBuffer;
|
||||
current_custom_buffer_index += 1;
|
||||
var.buffer_index = current_custom_buffer_index;
|
||||
array_add(*checker.result.constant_buffers, 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);
|
||||
|
||||
if node.vertex_entry_point {
|
||||
checker.vertex_entry_point = node;
|
||||
checker.result.vertex_entry_point = node;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@@ -1079,7 +1084,7 @@ declare_function :: (checker : *Semantic_Checker, node : *AST_Node, builtin : bo
|
||||
if builtin && node.token.ident_value.count > 0 {
|
||||
return_var, return_handle := new_type_variable(checker);
|
||||
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 {
|
||||
@@ -1128,8 +1133,8 @@ create_function_constraint :: (checker : *Semantic_Checker, node : *AST_Node) {
|
||||
if statement.kind == .Return {
|
||||
result_var := check_node(checker, statement);
|
||||
if result_var > 0 {
|
||||
variable.return_var = result_var;
|
||||
constraint.function.return_variable = variable.return_var;
|
||||
variable.return_type_variable= result_var;
|
||||
constraint.function.return_variable = variable.return_type_variable;
|
||||
}
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -1184,7 +1189,7 @@ create_equivalence_constraint :: (checker : *Semantic_Checker, lhs : Type_Variab
|
||||
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);
|
||||
// x : int;
|
||||
// x.d = 5;
|
||||
@@ -1192,7 +1197,7 @@ create_variable :: (checker : *Semantic_Checker, node : *AST_Node, field_parent
|
||||
if find_result {
|
||||
node.type_variable = 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 {
|
||||
variable.scope = checker.current_scope;
|
||||
@@ -1204,10 +1209,6 @@ create_variable :: (checker : *Semantic_Checker, node : *AST_Node, field_parent
|
||||
return 0;
|
||||
} else {
|
||||
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);
|
||||
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);
|
||||
|
||||
all_args_match = false;
|
||||
overload_found = false;
|
||||
} else {
|
||||
overload_found = all_args_match;
|
||||
}
|
||||
}
|
||||
|
||||
if overload_found {
|
||||
if function.return_var > 0 {
|
||||
return_var := h2tv(checker, function.return_var);
|
||||
if function.return_type_variable> 0 {
|
||||
return_var := h2tv(checker, function.return_type_variable);
|
||||
constrained_var := h2tv(checker, type_var);
|
||||
constrained_var.type = return_var.type;
|
||||
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.type = h2tv(checker, lhs_var).type;
|
||||
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);
|
||||
}
|
||||
@@ -1817,8 +1818,8 @@ pretty_print_function :: (checker : *Semantic_Checker, builder : *String_Builder
|
||||
}
|
||||
}
|
||||
|
||||
if function.return_var > 0 {
|
||||
print_to_builder(builder, ") -> %\n", type_to_string(h2tv(checker, function.return_var)));
|
||||
if function.return_type_variable> 0 {
|
||||
print_to_builder(builder, ") -> %\n", type_to_string(h2tv(checker, function.return_type_variable)));
|
||||
} else {
|
||||
append(builder, ")\n");
|
||||
}
|
||||
@@ -2015,8 +2016,8 @@ print_type_variable :: (builder : *String_Builder, variable : Type_Variable, che
|
||||
case .Function; #through;
|
||||
case .Struct; #through;
|
||||
case .Field; {
|
||||
if variable.field_parent {
|
||||
print_to_builder(builder, "%.", variable.field_parent.name);
|
||||
if variable.struct_field_parent {
|
||||
print_to_builder(builder, "%.", variable.struct_field_parent.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);
|
||||
}
|
||||
case .Call; {
|
||||
if variable.return_var {
|
||||
if variable.return_type_variable{
|
||||
assert(false);
|
||||
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);
|
||||
|
||||
26
module.jai
26
module.jai
@@ -111,9 +111,19 @@ Properties :: struct {
|
||||
buffer_index : u32;
|
||||
}
|
||||
|
||||
Constant_Buffer :: struct {
|
||||
register : int;
|
||||
|
||||
name : string;
|
||||
|
||||
fields : Property_Field;
|
||||
}
|
||||
|
||||
Shader_Variant_Collection :: struct {
|
||||
properties : Properties;
|
||||
|
||||
cbuffers : [..]Constant_Buffer;
|
||||
|
||||
variants : [..]Shader_Variant;
|
||||
}
|
||||
|
||||
@@ -334,10 +344,10 @@ compile_file :: (compiler : *Shader_Compiler, path : string) -> Compilation_Resu
|
||||
variant : Shader_Variant;
|
||||
variant.text = codegen_result.result_text;
|
||||
|
||||
if checker.vertex_entry_point {
|
||||
variant.vertex_entry_point.name = checker.vertex_entry_point.name;
|
||||
if checker.result.vertex_entry_point {
|
||||
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);
|
||||
|
||||
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);
|
||||
if find_result {
|
||||
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;
|
||||
}
|
||||
|
||||
if checker.pixel_entry_point {
|
||||
variant.pixel_entry_point.name = checker.pixel_entry_point.name;
|
||||
if checker.result.pixel_entry_point {
|
||||
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);
|
||||
|
||||
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 {
|
||||
field_hint : Field_Hint;
|
||||
|
||||
|
||||
29
static_array.jai
Normal file
29
static_array.jai
Normal 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;
|
||||
}
|
||||
@@ -1,4 +1,16 @@
|
||||
[1;37mtest/unknown_overload.shd:6,4: [31merror: [37mType mismatch. Expected float3 got float
|
||||
[1;37mtest/unknown_overload.shd:6,0: [31merror: [37mProcedure call did not match any of the possible overloads for 'foo'
|
||||
[96m found:
|
||||
foo(v, v);
|
||||
^^^
|
||||
|
||||
[97m While matching argument 1 in function call.
|
||||
[96m foo(v, v);
|
||||
^
|
||||
[97m Possible overloads:
|
||||
[96m foo :: (v1 : float3, v2 : float3) { (test/unknown_overload.shd:1)
|
||||
[96m foo :: (v1 : float2, v2 : float2, v3 : float2) { (test/unknown_overload.shd:2)
|
||||
|
||||
[36m[37m[1;37mtest/unknown_overload.shd:6,4: [31merror: [37mType mismatch. Expected float3 got float
|
||||
[96m found:
|
||||
foo(v, v);
|
||||
^
|
||||
@@ -18,16 +30,4 @@
|
||||
got:
|
||||
v : float = 2.0
|
||||
|
||||
[36m[37m[1;37mtest/unknown_overload.shd:6,0: [31merror: [37mProcedure call did not match any of the possible overloads for 'foo'
|
||||
[96m found:
|
||||
foo(v, v);
|
||||
^^^
|
||||
|
||||
[97m While matching argument 1 in function call.
|
||||
[96m foo(v, v);
|
||||
^
|
||||
[97m Possible overloads:
|
||||
[96m foo :: (v1 : float3, v2 : float3) { (test/unknown_overload.shd:1)
|
||||
[96m foo :: (v1 : float2, v2 : float2, v3 : float2) { (test/unknown_overload.shd:2)
|
||||
|
||||
[36m[37m
|
||||
@@ -1,14 +1,4 @@
|
||||
[1;37mtest/wrong_type_for_function.shd:11,24: [31merror: [37mType mismatch. Expected float got float2
|
||||
[96m found:
|
||||
color : float4 = float4(y, 1.0, 1.0, 1.0);
|
||||
^
|
||||
expected:
|
||||
float
|
||||
|
||||
got:
|
||||
y : float2 = foo()
|
||||
|
||||
[36m[37m[1;37mtest/wrong_type_for_function.shd:11,17: [31merror: [37mProcedure call did not match any of the possible overloads for 'float4'
|
||||
[1;37mtest/wrong_type_for_function.shd:11,17: [31merror: [37mProcedure call did not match any of the possible overloads for 'float4'
|
||||
[96m found:
|
||||
color : float4 = float4(y, 1.0, 1.0, 1.0);
|
||||
^^^^^^
|
||||
@@ -19,4 +9,14 @@
|
||||
[97m Possible overloads:
|
||||
[96m foreign float4 :: (float, float, float, float) -> float4; (test/wrong_type_for_function.shd:79)
|
||||
|
||||
[36m[37m[1;37mtest/wrong_type_for_function.shd:11,24: [31merror: [37mType mismatch. Expected float got float2
|
||||
[96m found:
|
||||
color : float4 = float4(y, 1.0, 1.0, 1.0);
|
||||
^
|
||||
expected:
|
||||
float
|
||||
|
||||
got:
|
||||
y : float2 = foo()
|
||||
|
||||
[36m[37m
|
||||
Reference in New Issue
Block a user