Ifdefs, moved semantic to check, fixed error reporting for builtins

This commit is contained in:
2025-09-16 11:04:57 +02:00
parent f99f86bc37
commit 7fefe0ecf6
71 changed files with 739 additions and 385 deletions

View File

@@ -1,11 +1,20 @@
#load "Lexing.jai";
#load "Error.jai";
#load "Parsing.jai";
#load "Semantic_Analysis.jai";
#load "Check.jai";
#load "Codegen.jai";
#import "File_Utilities";
/* TODO
- [ ] Remove builtin stringbuilding and replace it with ad-hoc string building when error reporting. In that case we are already building a string anyway, so we can just pass in the string builder
- [ ] Support structured buffers (ro, rw, w)
- [ ] Support mesh and amplification shaders
- [ ] Support compute shaders
- [ ] Support #if
*/
add_define :: (env : *Environment, key : string) {
for define : env.defines {
if define == key {
@@ -55,10 +64,33 @@ Hint_Kind :: enum {
Position;
UV;
Target;
Output_Position;
Custom;
}
Hint_Names :: #run -> [(cast(int)Hint_Kind.Target) + 1]string {
names : [(cast(int)Hint_Kind.Target) + 1]string;
names[Hint_Kind.Position] = "position";
names[Hint_Kind.UV] = "uv";
names[Hint_Kind.Target] = "target";
return names;
}
lookup_hint :: (name : string) -> Hint_Kind {
if name == "position" {
return Hint_Kind.Position;
} else if name == "uv" {
return Hint_Kind.UV;
} else if starts_with(name, "target") {
return Hint_Kind.Target;
} else if name == "outposition" {
return Hint_Kind.Output_Position;
}
return .None;
}
Field_Hint :: struct {
kind : Hint_Kind;
@@ -99,21 +131,11 @@ Constant_Buffer :: struct {
fields : Static_Array(Property_Field, 16);
// hints : Field_Hint; // optional hint...
hints : [..]Field_Hint;
buffer_index : u32;
}
Shader_Variant_Collection :: struct {
properties : Properties;
max_constant_buffers :: 16;
cbuffers : Static_Array(Constant_Buffer, max_constant_buffers);
variants : [..]Shader_Variant;
}
Input_File :: struct {
source : string;
path : string;
@@ -149,7 +171,7 @@ Compiler_Context :: struct {
return_value : Field;
}
properties : Properties; //@Note(niels): We'll deprecate this in favor of just marking a constant buffer how you'd want to use it
properties : Properties; //@Note(niels): We'll deprecate this in favor of just marking a constant buffer with a hint on how you'd want to use it
max_constant_buffers :: 16;
@@ -159,7 +181,7 @@ Compiler_Context :: struct {
messages : [..]Compiler_Message;
}
#add_context scratch_allocators : [2]Allocator;
#add_context scratch_allocators : [2]Allocator;
#add_context scratch_id : int = 0;
init_context_allocators :: () {
@@ -294,7 +316,7 @@ pretty_print_field :: (builder : *String_Builder, field : *Field) {
}
}
type_variable_to_field :: (checker : *Semantic_Checker, variable : Type_Variable_Handle) -> Field {
type_variable_to_field :: (checker : *Checker, variable : Type_Variable_Handle) -> Field {
return type_variable_to_field(checker, from_handle(checker, variable));
}
@@ -349,13 +371,11 @@ type_variable_to_field :: (type_variables : []Type_Variable, scope_stack : Scope
for hint : variable.source_node.hint_tokens {
field_hint : Field_Hint;
if hint.ident_value == "position" {
// @Incomplete(nb): Should be a lookup table somewhere
if lookup_hint(hint.ident_value) == .Position {
field_hint.kind = .Position;
} else if hint.ident_value == "uv" {
} else if lookup_hint(hint.ident_value) == .UV {
field_hint.kind = .UV;
} else if starts_with(hint.ident_value, "target") {
// @Incomplete(nb): Should be a lookup table somewhere
} else if lookup_hint(hint.ident_value) == .Target {
index_str : string;
index_str.data = *hint.ident_value.data[7];
index_str.count = 1;
@@ -381,7 +401,7 @@ type_variable_to_field :: (type_variables : []Type_Variable, scope_stack : Scope
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 {
type_variable_to_field :: (checker : *Checker, variable : *Type_Variable) -> Field {
return type_variable_to_field(checker.ctx.type_variables, checker.ctx.scope_stack, variable);
}
@@ -445,38 +465,36 @@ generate_output_data :: (ctx : *Compiler_Context) {
ctx.properties.buffer_index = property_variable.resource_index;
}
if ctx.pixel_entry_point.node {
ctx.pixel_entry_point.name = ctx.pixel_entry_point.node.name;
type_variable := from_handle(ctx.type_variables, ctx.pixel_entry_point.node.type_variable);
assert(type_variable.type == .Function);
field := type_variable_to_field(ctx.type_variables, ctx.scope_stack, type_variable.return_type_variable);
for hint : type_variable.source_node.hint_tokens {
field_hint : Field_Hint;
if type_variable.return_type_variable > 0 {
field := type_variable_to_field(ctx.type_variables, ctx.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;
if lookup_hint(hint.ident_value) == .Position {
field_hint.kind = .Position;
} else if lookup_hint(hint.ident_value) == .Target {
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
}
field_hint.kind = .Target;
} else {
// @Incomplete(nb): custom hints
array_add(*field.hints, field_hint);
}
array_add(*field.hints, field_hint);
}
ctx.pixel_entry_point.return_value = field;
ctx.pixel_entry_point.return_value = field;
}
}
}