Fix lvalue/rvalue binaries. Fix structured buffer output.
This commit is contained in:
88
Check.jai
88
Check.jai
@@ -8,7 +8,6 @@
|
||||
// [ ] 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.
|
||||
@@ -157,6 +156,8 @@ Checker :: struct {
|
||||
|
||||
ctx : *Compiler_Context;
|
||||
|
||||
checking_lvalue : bool;
|
||||
|
||||
current_buffer_index : u32 = 0;
|
||||
current_sampler_index : u32 = 0;
|
||||
current_texture_index : u32 = 0;
|
||||
@@ -421,6 +422,43 @@ Error: Undeclared identifier 'name'.
|
||||
record_error(checker, message, node.source_location, false);
|
||||
}
|
||||
|
||||
cannot_assign_to_lvalue :: (checker : *Checker, node : *AST_Node) {
|
||||
/*
|
||||
Cannot assign to an lvalue.
|
||||
|
||||
(a + b).x = 2.0;
|
||||
*/
|
||||
|
||||
builder : String_Builder;
|
||||
init_string_builder(*builder,, temp);
|
||||
|
||||
append(*builder, "Cannot assign to an lvalue.\n");
|
||||
|
||||
cyan(*builder);
|
||||
indent(*builder, 1);
|
||||
|
||||
location := node.source_location;
|
||||
|
||||
begin : Token = node.token;
|
||||
begin.index -= begin.column;
|
||||
begin.length += begin.column;
|
||||
begin.source -= begin.column;
|
||||
begin.column = 0;
|
||||
|
||||
location.begin = begin;
|
||||
|
||||
print("%\n", location.main_token.kind);
|
||||
print_to_builder(*builder, "%\n", print_from_source_location(checker.ctx, location));
|
||||
// print_to_builder(*builder, "%\n", print_from_source_location(checker.ctx, node.source_location));
|
||||
indent(*builder, 1);
|
||||
print_token_pointer(*builder, location.begin);
|
||||
newline(*builder);
|
||||
newline(*builder);
|
||||
|
||||
message := builder_to_string(*builder);
|
||||
record_error(checker, message, node.source_location, false);
|
||||
}
|
||||
|
||||
field_not_defined_on_struct :: (checker : *Checker, node : *AST_Node, struct_symbol : *Defined_Symbol) {
|
||||
/*
|
||||
Field '%' is not defined in struct '%'.
|
||||
@@ -1072,7 +1110,7 @@ declare_cbuffer :: (checker : *Checker, node : *AST_Node) -> Type_Variable_Handl
|
||||
var.type = .CBuffer;
|
||||
var.resource_index = checker.current_buffer_index;
|
||||
checker.current_buffer_index += 1;
|
||||
array_add(*checker.ctx.constant_buffers, type_var);
|
||||
array_add(*checker.ctx.typed_buffers, type_var);
|
||||
return type_var;
|
||||
}
|
||||
|
||||
@@ -1081,6 +1119,7 @@ declare_buffer :: (checker : *Checker, node : *AST_Node) -> Type_Variable_Handle
|
||||
variable.type = .Buffer;
|
||||
variable.source_kind = .Declaration;
|
||||
variable.name = node.name;
|
||||
variable.source_node = node;
|
||||
|
||||
find_result := find_symbol(checker, node.name, checker.current_scope);
|
||||
if !find_result {
|
||||
@@ -1107,7 +1146,7 @@ declare_buffer :: (checker : *Checker, node : *AST_Node) -> Type_Variable_Handle
|
||||
|
||||
node.type_variable = handle;
|
||||
|
||||
array_add(*checker.ctx.buffers, handle);
|
||||
array_add(*checker.ctx.typed_buffers, handle);
|
||||
return handle;
|
||||
}
|
||||
|
||||
@@ -1304,43 +1343,13 @@ check_function :: (checker : *Checker, node : *AST_Node) {
|
||||
}
|
||||
}
|
||||
|
||||
check_variable :: (checker : *Checker, node : *AST_Node, struct_field_parent : *AST_Node = null) -> Type_Variable_Handle {
|
||||
check_variable :: (checker : *Checker, node : *AST_Node) -> Type_Variable_Handle {
|
||||
find_result := find_symbol(checker, node.name, checker.current_scope);
|
||||
// x : int;
|
||||
// x.d = 5;
|
||||
|
||||
if find_result {
|
||||
node.type_variable = find_result.type_variable;
|
||||
variable := from_handle(checker, find_result.type_variable);
|
||||
variable.struct_field_parent = struct_field_parent;
|
||||
|
||||
if get_scope(checker, checker.current_scope).kind == .Struct {
|
||||
variable.scope = checker.current_scope;
|
||||
}
|
||||
|
||||
if node.children.count > 0 {
|
||||
if variable.type != .Struct && variable.type != .CBuffer && variable.type != .Buffer {
|
||||
field_access_on_primitive_type(checker, node, find_result.type_variable);
|
||||
return 0;
|
||||
} else if variable.type == .Array {
|
||||
|
||||
} else {
|
||||
lookup_name : string = 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);
|
||||
child := node.children[0];
|
||||
var := find_symbol(checker, child.name, type_variable.scope);
|
||||
if var == null {
|
||||
field_not_defined_on_struct(checker, child, struct_symbol);
|
||||
return 0;
|
||||
}
|
||||
access := check_variable(checker, child, node);
|
||||
use_scope(checker, previous_scope);
|
||||
return access;
|
||||
}
|
||||
}
|
||||
return find_result.type_variable;
|
||||
}
|
||||
|
||||
@@ -1607,6 +1616,7 @@ check_node :: (checker : *Checker, node : *AST_Node) -> Type_Variable_Handle {
|
||||
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);
|
||||
@@ -1624,7 +1634,17 @@ check_node :: (checker : *Checker, node : *AST_Node) -> Type_Variable_Handle {
|
||||
return access;
|
||||
}
|
||||
case .Binary; {
|
||||
if checker.checking_lvalue {
|
||||
cannot_assign_to_lvalue(checker, node.parent.parent);
|
||||
return 0;
|
||||
}
|
||||
prev_checking_lvalue := checker.checking_lvalue;
|
||||
if node.token.kind == .TOKEN_ASSIGN {
|
||||
checker.checking_lvalue = true;
|
||||
}
|
||||
lhs_var := check_node(checker, node.children[0]);
|
||||
checker.checking_lvalue = prev_checking_lvalue;
|
||||
|
||||
if lhs_var == 0 {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user