More fixes to access and buffer compilation.

This commit is contained in:
2025-09-26 07:01:06 +02:00
parent 6528ca854b
commit 63a68b70b4
35 changed files with 401 additions and 119 deletions

130
Check.jai
View File

@@ -5,9 +5,12 @@
/////////////////////////////////////
//~ nbr: Error reporting TODOs
//
// [ ] Add a sentinel variable that works for from_handle
// [ ] Add and error for using keywords as names, or rename the dx11 keywords in the resulting hlsl shader.
// [ ] Add missing scope in for loop for loop iterator
// [ ] Maybe we remove the resource index on type variables, seems like we don't need it there.
// [ ] Add swizzling
// [ ] Add temp assignment fail check: (a + b).x = float2(0, 0);
// [x] Improve error reporting on mismatched overloads when types don't match, but arity does.
// [x] Improve error reporting for type mismatches in general. It seems like the expect node is not always correct.
@@ -472,12 +475,10 @@ Attempting to access a field on a primitive type '%'.
print_to_builder(*builder, "%\n", print_from_source_location(checker.ctx, node.source_location));
indent(*builder, 1);
node_variable := from_handle(checker, node.type_variable);
for 0..node.name.count - 1 {
append(*builder, " ");
}
print_token_pointer(*builder, node.source_location.begin);
// for 0..variable.source_node.name.count - 1 {
// append(*builder, " ");
// }
print_token_pointer(*builder, node.source_location.main_token);
append(*builder, "\n");
@@ -1081,10 +1082,31 @@ declare_buffer :: (checker : *Checker, node : *AST_Node) -> Type_Variable_Handle
variable.source_kind = .Declaration;
variable.name = node.name;
variable.element_type = declare_struct(checker, node); // Won't work entirely like this. At least we're going to need some access changes
find_result := find_symbol(checker, node.name, checker.current_scope);
if !find_result {
symbol : Defined_Symbol;
symbol.name = node.name;
symbol.source_node = node;
symbol.type_variable = handle;
add_symbol_to_scope(checker.state, *checker.ctx.scope_stack, checker.current_scope, node.name, symbol);
} else {
symbol_redeclaration(checker, node, find_result);
return 0;
}
buffer_struct_name := sprint("%_buffer_substruct___%", random_get(), node.name);
variable.element_type = declare_struct(checker, node, buffer_struct_name); // Won't work entirely like this. At least we're going to need some access changes
variable.resource_index = checker.current_buffer_index;
element := from_handle(checker, variable.element_type);
scope := get_scope(checker, element.scope);
scope.builtin = true;
variable.scope = element.scope;
checker.current_buffer_index += 1;
node.type_variable = handle;
array_add(*checker.ctx.buffers, handle);
return handle;
}
@@ -1139,7 +1161,7 @@ declare_function :: (checker : *Checker, node : *AST_Node, builtin : bool = fals
symbol.source_node = node;
symbol.type_variable = 0;
symbol.functions.allocator = get_current_scope(checker).allocator;
array_reserve(*symbol.functions, 32);
array_reserve(*symbol.functions, 4);
array_add(*symbol.functions, function);
add_symbol_to_scope(checker.state, *checker.ctx.scope_stack, checker.current_scope, name_to_check, symbol);
@@ -1202,7 +1224,8 @@ declare_function :: (checker : *Checker, node : *AST_Node, builtin : bool = fals
variable.scope = scope_handle;
}
for child : node.children {
for i : 0..node.children.count - 1 {
child := node.children[i];
if child.kind == .FieldList {
for field : child.children {
type_var := check_node(checker, field);
@@ -1573,6 +1596,33 @@ check_node :: (checker : *Checker, node : *AST_Node) -> Type_Variable_Handle {
return handle;
}
case .Access; {
lhs_handle := check_node(checker, node.children[0]);
if lhs_handle == 0 {
return 0;
}
lhs_variable := from_handle(checker, lhs_handle);
if lhs_variable.type != .Struct && lhs_variable.type != .CBuffer {
field_access_on_primitive_type(checker, node.children[0], lhs_handle);
return 0;
}
lookup_name := lhs_variable.typename;
struct_symbol := find_symbol(checker, lookup_name, checker.current_scope);
type_variable := from_handle(checker, struct_symbol.type_variable);
previous_scope := use_scope(checker, type_variable.scope);
member := node.children[1];
var := find_symbol(checker, member.name, type_variable.scope);
if var == null {
field_not_defined_on_struct(checker, member, struct_symbol);
return 0;
}
access := check_node(checker, member);
use_scope(checker, previous_scope);
return access;
}
case .Binary; {
lhs_var := check_node(checker, node.children[0]);
if lhs_var == 0 {
@@ -1587,7 +1637,14 @@ check_node :: (checker : *Checker, node : *AST_Node) -> Type_Variable_Handle {
lhs_type := from_handle(checker, lhs_var);
rhs_type := from_handle(checker, rhs_var);
variable.type = lhs_type.type;
if lhs_type.type == .Array {
element := from_handle(checker, lhs_type.element_type);
variable.type = element.type;
variable.typename = element.typename;
} else {
variable.type = lhs_type.type;
}
variable.typename = lhs_type.typename;
variable.scope = lhs_type.scope;
variable.source_node = node;
@@ -1621,9 +1678,16 @@ check_node :: (checker : *Checker, node : *AST_Node) -> Type_Variable_Handle {
}
}
case .TOKEN_ASSIGN; {
if !types_compatible(checker, lhs_var, rhs_var) {
type_mismatch(checker, node.parent, node.children[1], lhs_var, rhs_var);
return 0;
if lhs_type.type == .Array {
if !types_compatible(checker, lhs_type.element_type, rhs_var) {
type_mismatch(checker, node.parent, node.children[1], lhs_var, rhs_var);
return 0;
}
} else {
if !types_compatible(checker, lhs_var, rhs_var) {
type_mismatch(checker, node.parent, node.children[1], lhs_var, rhs_var);
return 0;
}
}
}
case .TOKEN_GREATER; #through;
@@ -1746,7 +1810,17 @@ is_valid_define :: (checker : *Checker, def : string) -> bool {
}
check_env_expression :: (checker : *Checker, expr : *AST_Node, directive : *AST_Node) -> bool {
if expr.kind == .Binary {
if expr.kind == .Access {
lhs := expr.children[0];
if lhs.kind == .Variable && lhs.name == "Env" {
rhs := expr.children[1];
return is_valid_define(checker, rhs.name);
} else {
return check_env_expression(checker, lhs, directive);
}
}
else if expr.kind == .Binary {
lhs := expr.children[0];
rhs := expr.children[1];
@@ -1759,6 +1833,7 @@ check_env_expression :: (checker : *Checker, expr : *AST_Node, directive : *AST_
return lhs_valid && rhs_valid;
}
} else if expr.kind == .Variable {
assert(false, "");
if expr.name == "Env" {
child := expr.children[0]; // The variable in the environment
@@ -1883,8 +1958,6 @@ types_compatible :: (checker : *Checker, lhs : Type_Variable_Handle, rhs : Type_
return rhs_var.type == lhs_var.type;
}
case .Struct; {
lhs_node := lhs_var.source_node;
rhs_node := rhs_var.source_node;
if rhs_var.type != .Struct && !param_matching {
if lhs_var.typename == {
case "float2"; #through;
@@ -2451,14 +2524,21 @@ pretty_print_scope :: (ctx : *Compiler_Context, current_scope : Scope_Handle, sc
pretty_print_struct(ctx, *scope_stack, current_scope, variables, builder, key, type_variable, 1);
append(builder, "\n");
}
case .Buffer; {
element := from_handle(variables, type_variable.element_type);
pretty_print_struct(ctx, *scope_stack, current_scope, variables, builder, key, element, 1);
append(builder, "\n");
}
case .Struct; {
if type_variable.typename.count > 0 && !type_variable.builtin && (type_variable.source_kind != .Declaration || type_variable.source_node.kind != .Struct) {
indent(builder, indentation + 1);
print_key(*scope_stack, current_scope, builder, key);
print_to_builder(builder, "%\n", type_variable.typename);
} else {
pretty_print_struct(ctx, *scope_stack, current_scope, variables, builder, key, type_variable, indentation);
append(builder, "\n");
if type_variable.source_node.kind != .Buffer {
if type_variable.typename.count > 0 && !type_variable.builtin && (type_variable.source_kind != .Declaration || type_variable.source_node.kind != .Struct) {
indent(builder, indentation + 1);
print_key(*scope_stack, current_scope, builder, key);
print_to_builder(builder, "%\n", type_variable.typename);
} else {
pretty_print_struct(ctx, *scope_stack, current_scope, variables, builder, key, type_variable, indentation);
append(builder, "\n");
}
}
}
case; {
@@ -2501,6 +2581,9 @@ print_type_variable :: (ctx : *Compiler_Context, builder : *String_Builder, vari
}
print_to_builder(builder, "%", node.name);
}
case .Access; {
}
case .Binary; {
left_most := node.children[0];
@@ -2582,3 +2665,4 @@ pretty_print_symbol_table :: (ctx : *Compiler_Context, allocator : Allocator) ->
#import "ncore";
#import "Hash_Table";
#import "String";
#import "Random";