More fixes to access and buffer compilation.
This commit is contained in:
130
Check.jai
130
Check.jai
@@ -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";
|
||||
|
||||
Reference in New Issue
Block a user