diff --git a/module.jai b/module.jai index b65bfd8..226ca2d 100644 --- a/module.jai +++ b/module.jai @@ -150,6 +150,23 @@ Compiled_File :: struct { codegen_result_text : string; semantic_check_result : Semantic_Check_Result; + + vertex_entry_point : struct { + name : string; + + input : [..]Field; + } + + pixel_entry_point : struct { + name : string; + + return_value : Field; + } + + properties : Properties; + + max_constant_buffers :: 16; + cbuffers : Static_Array(Constant_Buffer, max_constant_buffers); } Compile_Result :: struct { @@ -286,7 +303,7 @@ type_variable_to_field :: (checker : *Semantic_Checker, variable : Type_Variable return type_variable_to_field(checker, from_handle(checker, variable)); } -type_variable_to_field :: (checker : *Semantic_Checker, variable : *Type_Variable) -> Field { +type_variable_to_field :: (type_variables : []Type_Variable, scope_stack : Scope_Stack, variable : *Type_Variable) -> Field { field : Field; field.name = variable.name; @@ -319,14 +336,14 @@ type_variable_to_field :: (checker : *Semantic_Checker, variable : *Type_Variabl case .Struct; { type.kind = Field_Kind.Struct; - find_result := find_symbol(checker, variable.typename, xx 1); + find_result := find_symbol(scope_stack, variable.typename, xx 1); assert(find_result != null, "Internal compiler error\n"); - type_var := from_handle(checker, find_result.type_variable); + type_var := from_handle(type_variables, find_result.type_variable); for i : 0..type_var.children.count - 1 { child := type_var.children[i]; - child_field := type_variable_to_field(checker, from_handle(checker, child)); + child_field := type_variable_to_field(type_variables, scope_stack, child); array_add(*type.children, child_field); } @@ -364,6 +381,14 @@ type_variable_to_field :: (checker : *Semantic_Checker, variable : *Type_Variabl return field; } +type_variable_to_field :: (type_variables : []Type_Variable, scope_stack : Scope_Stack, variable : Type_Variable_Handle) -> Field { + return type_variable_to_field(type_variables, scope_stack, from_handle(type_variables, variable)); +} + +type_variable_to_field :: (checker : *Semantic_Checker, variable : *Type_Variable) -> Field { + return type_variable_to_field(checker.result.type_variables, checker.result.scope_stack, variable); +} + compile_file :: (compiler : *Shader_Compiler, paths : []string) -> Compile_Result { result : Compile_Result; @@ -376,6 +401,90 @@ compile_file :: (compiler : *Shader_Compiler, paths : []string) -> Compile_Resul check(*result); codegen(*result); + for *file : result.files { + check_result := file.semantic_check_result; + if check_result.vertex_entry_point { + file.vertex_entry_point.name = check_result.vertex_entry_point.name; + + type_variable := from_handle(check_result.type_variables, check_result.vertex_entry_point.type_variable); + assert(type_variable.type == .Function); + + node := type_variable.source_node; + if node.children.count > 0 { + if node.children[0].kind == .FieldList { + field_list := node.children[0]; + for child : field_list.children { + tv := from_handle(check_result.type_variables, child.type_variable); + field := type_variable_to_field(check_result.type_variables, check_result.scope_stack, tv); + array_add(*file.vertex_entry_point.input, field); + } + } + } + } + + for buffer_variable : to_array(*check_result.constant_buffers) { + variable := from_handle(check_result.type_variables, buffer_variable); + + cb := array_add(*file.cbuffers); + + for i : 0..variable.children.count - 1 { + child := variable.children[i]; + field : Property_Field; + field.base_field = type_variable_to_field(check_result.type_variables, check_result.scope_stack, from_handle(check_result.type_variables, child)); + array_add(*cb.fields, field); + } + + cb.buffer_index = variable.resource_index; + } + + find_result := find_symbol(*check_result.scope_stack, check_result.property_name, xx 1); + if find_result { + property_variable := from_handle(check_result.type_variables, find_result.type_variable); + + for i : 0..property_variable.children.count - 1 { + child := property_variable.children[i]; + field := type_variable_to_field(check_result.type_variables, check_result.scope_stack, from_handle(check_result.type_variables, child)); + prop_field : Property_Field; + prop_field.base_field = field; + array_add(*file.properties.fields, prop_field); + } + file.properties.buffer_index = property_variable.resource_index; + } + + if check_result.pixel_entry_point { + file.pixel_entry_point.name = check_result.pixel_entry_point.name; + + type_variable := from_handle(check_result.type_variables, check_result.pixel_entry_point.type_variable); + assert(type_variable.type == .Function); + + field := type_variable_to_field(check_result.type_variables, check_result.scope_stack, type_variable.return_type_variable); + for hint : type_variable.source_node.hint_tokens { + field_hint : Field_Hint; + + if hint.ident_value == "position" { + // @Incomplete(nb): Should be a lookup table somewhere + field_hint.kind = .Position; + } else if starts_with(hint.ident_value, "target") { + // @Incomplete(nb): Should be a lookup table somewhere + index_str : string; + index_str.data = *hint.ident_value.data[7]; + index_str.count = 1; + + result, ok, remainder := string_to_int(index_str); + if ok { + field_hint.target_index = result; + } + field_hint.kind = .Target; + } else { + // @Incomplete(nb): custom hints + } + array_add(*field.hints, field_hint); + } + + file.pixel_entry_point.return_value = field; + } + } + return result; }