A bunch of array fixes and some buffer stuff that doesn't quite work yet
This commit is contained in:
151
Check.jai
151
Check.jai
@@ -36,6 +36,7 @@ Type_Kind :: enum {
|
||||
|
||||
Struct;
|
||||
CBuffer;
|
||||
Buffer;
|
||||
Array;
|
||||
}
|
||||
|
||||
@@ -64,6 +65,8 @@ Type_Variable :: struct {
|
||||
|
||||
name : string;
|
||||
|
||||
|
||||
|
||||
//@Note(niels) For functions
|
||||
return_type_variable : Type_Variable_Handle;
|
||||
|
||||
@@ -74,9 +77,8 @@ Type_Variable :: struct {
|
||||
struct_field_parent : *AST_Node;
|
||||
|
||||
typename : string;
|
||||
// is_array : bool;
|
||||
element_type : Type_Kind;
|
||||
element_typename : string;
|
||||
element_type : Type_Variable_Handle;
|
||||
element_count : int;
|
||||
|
||||
MAX_TYPE_VARIABLE_CHILDREN :: 32;
|
||||
children : Static_Array(Type_Variable_Handle, MAX_TYPE_VARIABLE_CHILDREN);
|
||||
@@ -109,6 +111,7 @@ Scope_Kind :: enum {
|
||||
Global;
|
||||
Function;
|
||||
Struct;
|
||||
Block;
|
||||
}
|
||||
|
||||
Scope :: struct {
|
||||
@@ -539,11 +542,11 @@ type_mismatch :: (checker : *Checker, usage_site : *AST_Node, expect_node : *AST
|
||||
child_handle := got_var.children[i];
|
||||
child := from_handle(checker, child_handle);
|
||||
|
||||
print_to_builder(*builder, "% : %", child.name, type_to_string(child));
|
||||
print_to_builder(*builder, "% : %", child.name, type_to_string(checker.ctx.type_variables, child));
|
||||
}
|
||||
}
|
||||
|
||||
print_to_builder(*builder, "Type mismatch. Expected % got %\n", type_to_string(expect_var), type_to_string(got_var));
|
||||
print_to_builder(*builder, "Type mismatch. Expected % got %\n", type_to_string(checker.ctx.type_variables, expect_var), type_to_string(checker.ctx.type_variables, got_var));
|
||||
|
||||
cyan(*builder);
|
||||
location := usage_site.source_location;
|
||||
@@ -813,7 +816,16 @@ new_builtin_function :: (checker : *Checker, name : string, args : []Arg, return
|
||||
|
||||
if return_arg.typename.count > 0 {
|
||||
return_var, return_handle := new_type_variable(checker);
|
||||
return_var.type = lookup_type(checker, checker.current_scope, return_arg.typename, *return_var.typename);
|
||||
symb : Defined_Symbol;
|
||||
return_var.type = lookup_type(checker, checker.current_scope, return_arg.typename, *return_var.typename, *symb);
|
||||
if symb.type_variable > 0 {
|
||||
symb_var := from_handle(checker, symb.type_variable);
|
||||
if symb_var.type == .Array || symb_var.type == .Buffer {
|
||||
return_var.element_type = symb_var.element_type;
|
||||
// return_var.element_typename = symb_var.element_typename;
|
||||
return_var.element_count = symb_var.element_count;
|
||||
}
|
||||
}
|
||||
from_handle(checker, handle).return_type_variable = return_handle;
|
||||
}
|
||||
|
||||
@@ -911,7 +923,6 @@ proper_type_to_string :: (ctx : *Compiler_Context, builder : *String_Builder, va
|
||||
}
|
||||
|
||||
append(builder, ")");
|
||||
|
||||
if var.return_type_variable > 0 {
|
||||
append(builder, " -> ", );
|
||||
return_var := from_handle(variables, var.return_type_variable);
|
||||
@@ -955,7 +966,7 @@ proper_type_to_string :: (ctx : *Compiler_Context, variables : []Type_Variable,
|
||||
return "______not proper type______";
|
||||
}
|
||||
|
||||
lookup_type :: (checker : *Checker, scope : Scope_Handle, type_string : string, typename : *string = null) -> Type_Kind {
|
||||
lookup_type :: (scope_stack : Scope_Stack, variables : []Type_Variable, scope : Scope_Handle, type_string : string, typename : *string = null, out_symbol : *Defined_Symbol = null) -> Type_Kind {
|
||||
if type_string == {
|
||||
case Typenames[Type_Kind.Int]; return .Int;
|
||||
case Typenames[Type_Kind.Half]; return .Half;
|
||||
@@ -964,10 +975,13 @@ lookup_type :: (checker : *Checker, scope : Scope_Handle, type_string : string,
|
||||
case Typenames[Type_Kind.Sampler]; return .Sampler;
|
||||
case Typenames[Type_Kind.Texture2D]; return .Texture2D;
|
||||
}
|
||||
|
||||
symbol := find_symbol(checker, type_string, scope);
|
||||
|
||||
symbol := find_symbol(scope_stack, type_string, scope);
|
||||
if symbol {
|
||||
symbol_var := from_handle(checker, symbol.type_variable);
|
||||
if out_symbol {
|
||||
out_symbol.* = symbol.*;
|
||||
}
|
||||
symbol_var := from_handle(variables, symbol.type_variable);
|
||||
if symbol_var.type == .Struct {
|
||||
if typename {
|
||||
typename.* = symbol_var.typename;
|
||||
@@ -981,15 +995,21 @@ lookup_type :: (checker : *Checker, scope : Scope_Handle, type_string : string,
|
||||
return .Invalid;
|
||||
}
|
||||
|
||||
lookup_type :: (checker : *Checker, scope : Scope_Handle, type_string : string, typename : *string = null, out_symbol : *Defined_Symbol = null) -> Type_Kind {
|
||||
return lookup_type(checker.ctx.scope_stack, checker.ctx.type_variables, scope, type_string, typename, out_symbol);
|
||||
}
|
||||
|
||||
lookup_type :: (checker : *Checker, scope : Scope_Handle, node : *AST_Node, typename : *string = null) -> Type_Kind {
|
||||
type_string := node.token.ident_value;
|
||||
return lookup_type(checker, scope, type_string, typename);
|
||||
}
|
||||
|
||||
check_block :: (checker : *Checker, node : *AST_Node) {
|
||||
push_scope(checker, kind = Scope_Kind.Block);
|
||||
for child : node.children {
|
||||
check_node(checker, child);
|
||||
}
|
||||
pop_scope(checker);
|
||||
}
|
||||
|
||||
declare_struct :: (checker : *Checker, node : *AST_Node, name : string) -> Type_Variable_Handle {
|
||||
@@ -1049,6 +1069,20 @@ declare_cbuffer :: (checker : *Checker, node : *AST_Node) -> Type_Variable_Handl
|
||||
return type_var;
|
||||
}
|
||||
|
||||
declare_buffer :: (checker : *Checker, node : *AST_Node) -> Type_Variable_Handle {
|
||||
variable, handle := new_type_variable(checker);
|
||||
variable.type = .Buffer;
|
||||
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
|
||||
|
||||
variable.resource_index = checker.current_buffer_index;
|
||||
checker.current_buffer_index += 1;
|
||||
array_add(*checker.ctx.buffers, handle);
|
||||
return handle;
|
||||
}
|
||||
|
||||
get_actual_function_name :: (node : *AST_Node) -> string {
|
||||
name_to_check := node.name;
|
||||
if node.vertex_entry_point {
|
||||
@@ -1256,7 +1290,7 @@ check_variable :: (checker : *Checker, node : *AST_Node, struct_field_parent : *
|
||||
}
|
||||
|
||||
if node.children.count > 0 {
|
||||
if variable.type != .Struct && variable.type != .CBuffer {
|
||||
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 {
|
||||
@@ -1303,11 +1337,14 @@ check_field :: (checker : *Checker, node : *AST_Node) -> Type_Variable_Handle {
|
||||
variable.name = node.name;
|
||||
typename : string;
|
||||
|
||||
|
||||
// variable.is_array = node.array_field;
|
||||
if node.array_field {
|
||||
variable.type = .Array;
|
||||
variable.element_type = lookup_type(checker, checker.current_scope, node, *variable.element_typename);
|
||||
element_type, element_handle := new_type_variable(checker);
|
||||
element_type.type = lookup_type(checker, checker.current_scope, node, *element_type.typename);
|
||||
element_type.scope = checker.current_scope;
|
||||
|
||||
variable.element_type = element_handle;
|
||||
variable.element_count = node.children[0].integer_value;
|
||||
} else {
|
||||
variable.type = lookup_type(checker, checker.current_scope, node, *typename);
|
||||
}
|
||||
@@ -1553,6 +1590,11 @@ check_node :: (checker : *Checker, node : *AST_Node) -> Type_Variable_Handle {
|
||||
add_child(variable, rhs_var);
|
||||
|
||||
if node.token.kind == {
|
||||
case .TOKEN_LEFTBRACKET; {
|
||||
element := from_handle(checker, lhs_type.element_type);
|
||||
variable.type = element.type;
|
||||
variable.typename = element.typename;
|
||||
}
|
||||
case .TOKEN_PLUS; #through;
|
||||
case .TOKEN_MINUS; #through;
|
||||
case .TOKEN_STAR; #through;
|
||||
@@ -1598,10 +1640,13 @@ check_node :: (checker : *Checker, node : *AST_Node) -> Type_Variable_Handle {
|
||||
case .For; {
|
||||
loop_iterator := node.token;
|
||||
|
||||
scope, scope_handle := push_scope(checker, kind = .Block);
|
||||
|
||||
symbol : Defined_Symbol;
|
||||
symbol.name = loop_iterator.ident_value;
|
||||
symbol.source_node = node;
|
||||
variable, handle := new_type_variable(checker);
|
||||
variable.scope = scope_handle;
|
||||
variable.name = symbol.name;
|
||||
typename : string;
|
||||
variable.type = .Int;
|
||||
@@ -1621,6 +1666,7 @@ check_node :: (checker : *Checker, node : *AST_Node) -> Type_Variable_Handle {
|
||||
}
|
||||
|
||||
check_block(checker, node.children[2]);
|
||||
pop_scope(checker);
|
||||
}
|
||||
case .If; {
|
||||
cond_var := check_node(checker, node.children[0]);
|
||||
@@ -1774,6 +1820,8 @@ check_declaration :: (checker : *Checker, declaration : *AST_Node) {
|
||||
declare_cbuffer(checker, declaration);
|
||||
} else if declaration.kind == .If_Directive {
|
||||
check_if_directive(checker, declaration);
|
||||
} else if declaration.kind == .Buffer {
|
||||
declare_buffer(checker, declaration);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2242,8 +2290,7 @@ check :: (ctx : *Compiler_Context, allocator : Allocator = temp) {
|
||||
// Pretty printing
|
||||
|
||||
#scope_file
|
||||
|
||||
type_to_string :: (type_variable : Type_Variable) -> string {
|
||||
type_to_string :: (variables : []Type_Variable, type_variable : Type_Variable, allocator := context.allocator) -> string {
|
||||
if type_variable.type == {
|
||||
case .Invalid;
|
||||
return "{{invalid}}";
|
||||
@@ -2261,8 +2308,10 @@ type_to_string :: (type_variable : Type_Variable) -> string {
|
||||
case .Struct; {
|
||||
return type_variable.typename;
|
||||
}
|
||||
case .Buffer; #through;
|
||||
case .Array;
|
||||
// return "array";
|
||||
element_type := from_handle(variables, type_variable.element_type);
|
||||
return sprint("[%].%", type_variable.element_count, type_to_string(variables, element_type));
|
||||
}
|
||||
return "";
|
||||
}
|
||||
@@ -2295,7 +2344,7 @@ pretty_print_function :: (scope_stack : *Scope_Stack, current_scope : Scope_Hand
|
||||
if tv.builtin {
|
||||
print_to_builder(builder, "%", tv.name);
|
||||
} else {
|
||||
print_to_builder(builder, "% : %", tv.name, type_to_string(tv));
|
||||
print_to_builder(builder, "% : %", tv.name, type_to_string(variables, tv));
|
||||
}
|
||||
} else {
|
||||
pretty_print_function(scope_stack, current_scope, variables, builder, "", tv, 0);
|
||||
@@ -2309,30 +2358,35 @@ pretty_print_function :: (scope_stack : *Scope_Stack, current_scope : Scope_Hand
|
||||
}
|
||||
|
||||
if function.return_type_variable> 0 {
|
||||
print_to_builder(builder, ") -> %\n", type_to_string(from_handle(variables, function.return_type_variable)));
|
||||
print_to_builder(builder, ") -> %\n", type_to_string(variables, from_handle(variables, function.return_type_variable)));
|
||||
} else {
|
||||
append(builder, ")\n");
|
||||
}
|
||||
}
|
||||
|
||||
pretty_print_struct :: (scope_stack : *Scope_Stack, current_scope : Scope_Handle, variables : []Type_Variable, builder : *String_Builder, name : string, struct_type : Type_Variable, indentation : int) {
|
||||
pretty_print_struct :: (ctx : *Compiler_Context, scope_stack : *Scope_Stack, current_scope : Scope_Handle, variables : []Type_Variable, builder : *String_Builder, name : string, struct_field : Type_Variable, indentation : int) {
|
||||
indent(builder, indentation);
|
||||
print_key(scope_stack, current_scope, builder, name);
|
||||
|
||||
append(builder, "{");
|
||||
|
||||
struct_symbol : Defined_Symbol;
|
||||
lookup_type(scope_stack, variables, current_scope, struct_field.typename, null, *struct_symbol);
|
||||
struct_type := from_handle(variables, struct_symbol.type_variable);
|
||||
|
||||
for 0..struct_type.children.count - 1 {
|
||||
child_handle := struct_type.children[it];
|
||||
child := from_handle(variables, child_handle);
|
||||
print_to_builder(builder, child.name);
|
||||
append(builder, " : ");
|
||||
print_to_builder(builder, type_to_string(child));
|
||||
print_to_builder(builder, type_to_string(variables, child));
|
||||
|
||||
if it < struct_type.children.count - 1 {
|
||||
append(builder, ", ");
|
||||
}
|
||||
}
|
||||
|
||||
append(builder, "}\n");
|
||||
append(builder, "}");
|
||||
}
|
||||
|
||||
pretty_print_scope :: (ctx : *Compiler_Context, current_scope : Scope_Handle, scope_stack : Scope_Stack, variables : []Type_Variable, scope : *Scope, builder : *String_Builder, indentation : int = 0) {
|
||||
@@ -2347,7 +2401,20 @@ pretty_print_scope :: (ctx : *Compiler_Context, current_scope : Scope_Handle, sc
|
||||
if scope.name.count > 0 {
|
||||
print_to_builder(builder, "%", scope.name);
|
||||
} else {
|
||||
append(builder, "global");
|
||||
if scope.kind == {
|
||||
case .Global; {
|
||||
append(builder, "global");
|
||||
}
|
||||
case .Block; {
|
||||
append(builder, "block");
|
||||
}
|
||||
case .Function; {
|
||||
append(builder, "function");
|
||||
}
|
||||
case .Struct; {
|
||||
append(builder, "struct");
|
||||
}
|
||||
}
|
||||
}
|
||||
append(builder, ") [");
|
||||
if scope.table.count > 0 {
|
||||
@@ -2365,23 +2432,6 @@ pretty_print_scope :: (ctx : *Compiler_Context, current_scope : Scope_Handle, sc
|
||||
case .Function; {
|
||||
pretty_print_function(*scope_stack, current_scope, variables, builder, key, type_variable, 1);
|
||||
}
|
||||
case .CBuffer; #through;
|
||||
case .Struct; {
|
||||
if type_variable.typename.count > 0 && type_variable.source_kind != .Declaration {
|
||||
indent(builder, indentation + 1);
|
||||
print_key(*scope_stack, current_scope, builder, key);
|
||||
print_type_variable(ctx, builder, variables, type_variable);
|
||||
append(builder, "\n");
|
||||
// print_to_builder(builder, "%\n", type_variable.typename);
|
||||
} else {
|
||||
pretty_print_struct(*scope_stack, current_scope, variables, builder, key, type_variable, 1);
|
||||
}
|
||||
}
|
||||
case; {
|
||||
indent(builder, indentation + 1);
|
||||
print_key(*scope_stack, current_scope, builder, key);
|
||||
print_to_builder(builder, "%\n", type_to_string(type_variable));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -2390,32 +2440,35 @@ pretty_print_scope :: (ctx : *Compiler_Context, current_scope : Scope_Handle, sc
|
||||
case .Function; {
|
||||
pretty_print_function(*scope_stack, current_scope, variables, builder, key, type_variable, 1);
|
||||
}
|
||||
case .CBuffer; #through;
|
||||
case .CBuffer; {
|
||||
pretty_print_struct(ctx, *scope_stack, current_scope, variables, builder, key, type_variable, 1);
|
||||
append(builder, "\n");
|
||||
}
|
||||
case .Struct; {
|
||||
if type_variable.typename.count > 0 && type_variable.source_kind != .Declaration {
|
||||
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(*scope_stack, current_scope, variables, builder, key, type_variable, 1);
|
||||
pretty_print_struct(ctx, *scope_stack, current_scope, variables, builder, key, type_variable, indentation);
|
||||
append(builder, "\n");
|
||||
}
|
||||
}
|
||||
case; {
|
||||
indent(builder, indentation + 1);
|
||||
print_key(*scope_stack, current_scope, builder, key);
|
||||
print_to_builder(builder, "%\n", type_to_string(type_variable));
|
||||
print_to_builder(builder, "%\n", type_to_string(variables, type_variable));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
for child : scope.children {
|
||||
child_scope := *scope_stack.stack[child - 1];
|
||||
pretty_print_scope(ctx, current_scope, *scope_stack, variables, child_scope, builder, indentation + 1);
|
||||
}
|
||||
|
||||
if scope.table.count > 0 {
|
||||
if (scope.table.count > 0 || scope.children.count > 0) {
|
||||
indent(builder, indentation);
|
||||
}
|
||||
append(builder, "]\n");
|
||||
@@ -2424,7 +2477,7 @@ pretty_print_scope :: (ctx : *Compiler_Context, current_scope : Scope_Handle, sc
|
||||
print_type_variable :: (ctx : *Compiler_Context, builder : *String_Builder, variables : []Type_Variable, variable : Type_Variable) {
|
||||
if variable.builtin {
|
||||
if variable.type != .Function || variable.type != .Struct {
|
||||
print_to_builder(builder, "%", type_to_string(variable));
|
||||
print_to_builder(builder, "%", type_to_string(variables, variable));
|
||||
} else {
|
||||
print_to_builder(builder, "%", variable.name);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user