Started some fixes for array support. Not entirely there yet.

This commit is contained in:
2025-09-17 21:37:53 +02:00
parent 89904824bb
commit 50a404984d
8 changed files with 58 additions and 65 deletions

View File

@@ -257,9 +257,14 @@ pretty_print_binary :: (node : *AST_Node, indentation : int, builder : *String_B
indent(builder, indentation); indent(builder, indentation);
} }
append(builder, "("); append(builder, "(");
is_array_access := false;
if node.token.kind == .TOKEN_LEFTBRACKET {
print_to_builder(builder, "[]");
} else {
op := node.token; op := node.token;
print_to_builder(builder, op_to_string(op)); print_to_builder(builder, op_to_string(op));
}
append(builder, " "); append(builder, " ");
pretty_print_node(node.children[0], 0, builder); pretty_print_node(node.children[0], 0, builder);

View File

@@ -35,14 +35,13 @@ Type_Kind :: enum {
Unresolved_Expression; Unresolved_Expression;
Struct; Struct;
Properties;
CBuffer; CBuffer;
Array; Array;
} }
Source_Kind :: enum { Source_Kind :: enum {
Expression; Expression;
Declaration; // struct, properties, function, etc. Declaration; // struct, cbuffers, function, etc.
} }
Typenames :: string.[ Typenames :: string.[
@@ -75,7 +74,9 @@ Type_Variable :: struct {
struct_field_parent : *AST_Node; struct_field_parent : *AST_Node;
typename : string; typename : string;
is_array : bool; // is_array : bool;
element_type : Type_Kind;
element_typename : string;
MAX_TYPE_VARIABLE_CHILDREN :: 32; MAX_TYPE_VARIABLE_CHILDREN :: 32;
children : Static_Array(Type_Variable_Handle, MAX_TYPE_VARIABLE_CHILDREN); children : Static_Array(Type_Variable_Handle, MAX_TYPE_VARIABLE_CHILDREN);
@@ -108,7 +109,6 @@ Scope_Kind :: enum {
Global; Global;
Function; Function;
Struct; Struct;
Properties;
} }
Scope :: struct { Scope :: struct {
@@ -834,10 +834,6 @@ add_child :: (checker : *Checker, handle : Type_Variable_Handle, child : Type_Va
} }
init_semantic_checker :: (checker : *Checker, root : *AST_Node, path : string) { init_semantic_checker :: (checker : *Checker, root : *AST_Node, path : string) {
checker.current_buffer_index = 0;
checker.current_sampler_index = 0;
checker.current_texture_index = 0;
checker.program_root = root; checker.program_root = root;
checker.path = path; checker.path = path;
@@ -1260,14 +1256,13 @@ check_variable :: (checker : *Checker, node : *AST_Node, struct_field_parent : *
} }
if node.children.count > 0 { if node.children.count > 0 {
if variable.type != .Struct && variable.type != .Properties && variable.type != .CBuffer { if variable.type != .Struct && variable.type != .CBuffer {
field_access_on_primitive_type(checker, node, find_result.type_variable); field_access_on_primitive_type(checker, node, find_result.type_variable);
return 0; return 0;
} else if variable.type == .Array {
} else { } else {
lookup_name : string = variable.typename; lookup_name : string = variable.typename;
if variable.typename == "properties" {
lookup_name = variable.name;
}
struct_symbol := find_symbol(checker, lookup_name, checker.current_scope); struct_symbol := find_symbol(checker, lookup_name, checker.current_scope);
type_variable := from_handle(checker, struct_symbol.type_variable); type_variable := from_handle(checker, struct_symbol.type_variable);
@@ -1307,11 +1302,17 @@ check_field :: (checker : *Checker, node : *AST_Node) -> Type_Variable_Handle {
variable, handle := new_type_variable(checker); variable, handle := new_type_variable(checker);
variable.name = node.name; variable.name = node.name;
typename : string; 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);
} else {
variable.type = lookup_type(checker, checker.current_scope, node, *typename); variable.type = lookup_type(checker, checker.current_scope, node, *typename);
}
variable.is_array = node.array_field; if variable.type == .Array {
if variable.is_array {
size_node := node.children[0]; size_node := node.children[0];
size_var := check_node(checker, size_node); size_var := check_node(checker, size_node);
if from_handle(checker, size_var).type != .Int { if from_handle(checker, size_var).type != .Int {
@@ -1319,16 +1320,6 @@ check_field :: (checker : *Checker, node : *AST_Node) -> Type_Variable_Handle {
} }
} }
if variable.source_kind == .Declaration && variable.type == .Sampler {
variable.resource_index = checker.current_sampler_index;
checker.current_sampler_index += 1;
}
if variable.source_kind == .Declaration && variable.type == .Texture2D {
variable.resource_index = checker.current_texture_index;
checker.current_texture_index += 1;
}
variable.typename = typename; variable.typename = typename;
variable.source_node = node; variable.source_node = node;
variable.scope = checker.current_scope; variable.scope = checker.current_scope;
@@ -1348,20 +1339,33 @@ check_field :: (checker : *Checker, node : *AST_Node) -> Type_Variable_Handle {
symbol.source_node = node; symbol.source_node = node;
symbol.type_variable = handle; symbol.type_variable = handle;
add_symbol_to_scope(checker.state, *checker.ctx.scope_stack, checker.current_scope, node.name, symbol); add_symbol_to_scope(checker.state, *checker.ctx.scope_stack, checker.current_scope, node.name, symbol);
variable.source_kind = .Declaration;
} else { } else {
symbol_redeclaration(checker, node, find_result); symbol_redeclaration(checker, node, find_result);
return 0; return 0;
} }
} }
if node.token.ident_value.count > 0 { if variable.source_kind == .Declaration && variable.type == .Sampler {
variable.type = lookup_type(checker, checker.current_scope, node); variable.resource_index = checker.current_sampler_index;
checker.current_sampler_index += 1;
} }
if node.children.count > 0 { if variable.source_kind == .Declaration && variable.type == .Texture2D {
variable.resource_index = checker.current_texture_index;
checker.current_texture_index += 1;
}
if variable.type != .Array && node.children.count > 0 || variable.type == .Array && node.children.count > 1 {
rhs : Type_Variable_Handle; rhs : Type_Variable_Handle;
assert(node.children.count == 1); assert(node.children.count == 1);
for child : node.children { start_index := 0;
if variable.type == .Array {
start_index += 1;
}
for i : start_index..node.children.count - 1 {
child := node.children[i];
rhs = check_node(checker, child); rhs = check_node(checker, child);
} }
@@ -2219,9 +2223,6 @@ check :: (ctx : *Compiler_Context, allocator : Allocator = temp) {
checker : Checker; checker : Checker;
checker.current_buffer_index = 0;
checker.current_sampler_index = 0;
checker.current_texture_index = 0;
checker.ctx = ctx; checker.ctx = ctx;
init_semantic_checker(*checker, ctx.root, ctx.file.path); init_semantic_checker(*checker, ctx.root, ctx.file.path);
@@ -2261,7 +2262,7 @@ type_to_string :: (type_variable : Type_Variable) -> string {
return type_variable.typename; return type_variable.typename;
} }
case .Array; case .Array;
return "array"; // return "array";
} }
return ""; return "";
} }
@@ -2365,7 +2366,6 @@ pretty_print_scope :: (ctx : *Compiler_Context, current_scope : Scope_Handle, sc
pretty_print_function(*scope_stack, current_scope, variables, builder, key, type_variable, 1); pretty_print_function(*scope_stack, current_scope, variables, builder, key, type_variable, 1);
} }
case .CBuffer; #through; case .CBuffer; #through;
case .Properties; #through;
case .Struct; { case .Struct; {
if type_variable.typename.count > 0 && type_variable.source_kind != .Declaration { if type_variable.typename.count > 0 && type_variable.source_kind != .Declaration {
indent(builder, indentation + 1); indent(builder, indentation + 1);
@@ -2391,7 +2391,6 @@ pretty_print_scope :: (ctx : *Compiler_Context, current_scope : Scope_Handle, sc
pretty_print_function(*scope_stack, current_scope, variables, builder, key, type_variable, 1); pretty_print_function(*scope_stack, current_scope, variables, builder, key, type_variable, 1);
} }
case .CBuffer; #through; case .CBuffer; #through;
case .Properties; #through;
case .Struct; { case .Struct; {
if type_variable.typename.count > 0 && type_variable.source_kind != .Declaration { if type_variable.typename.count > 0 && type_variable.source_kind != .Declaration {
indent(builder, indentation + 1); indent(builder, indentation + 1);

16
Ink.jai
View File

@@ -227,22 +227,6 @@ run_compile_test :: (path : string, output_type : Output_Type = 0) -> Result, Co
print_to_builder(*sb, "[pixel entry point] - %\n", ctx.pixel_entry_point.name); print_to_builder(*sb, "[pixel entry point] - %\n", ctx.pixel_entry_point.name);
} }
if ctx.properties.fields.count > 0{
props := ctx.properties;
append(*sb, "[");
if ctx.property_name.count > 0 {
print_to_builder(*sb, "% :: ", ctx.property_name);
}
print_to_builder(*sb, "properties] - %\n", props.buffer_index);
indent(*sb, 1);
for field : props.fields {
append(*sb, "[field] - ");
pretty_print_field(*sb, *field.base_field);
}
}
for cb : ctx.cbuffers { for cb : ctx.cbuffers {
print_to_builder(*sb, "[constant_buffer] - % - %", cb.name, cb.buffer_index); print_to_builder(*sb, "[constant_buffer] - % - %", cb.name, cb.buffer_index);

View File

@@ -55,6 +55,7 @@ Token_Kind :: enum {
// Keywords // Keywords
TOKEN_BOOL; TOKEN_BOOL;
TOKEN_BUFFER;
TOKEN_CASE; TOKEN_CASE;
TOKEN_CBUFFER; TOKEN_CBUFFER;
@@ -91,7 +92,6 @@ Token_Kind :: enum {
TOKEN_OUT; TOKEN_OUT;
TOKEN_PIXEL; TOKEN_PIXEL;
// TOKEN_PROPERTIES;
TOKEN_RETURN; TOKEN_RETURN;
TOKEN_REGISTER; TOKEN_REGISTER;
@@ -216,6 +216,7 @@ identifier_kind :: (using lexer : *Lexer) -> Token_Kind {
identifier.count = length; identifier.count = length;
if identifier == "bool" return .TOKEN_BOOL; if identifier == "bool" return .TOKEN_BOOL;
if identifier == "buffer" return .TOKEN_BUFFER;
if identifier == "case" return .TOKEN_CASE; if identifier == "case" return .TOKEN_CASE;
if identifier == "columnmajor" return .TOKEN_COLUMNMAJOR; if identifier == "columnmajor" return .TOKEN_COLUMNMAJOR;
if identifier == "const" return .TOKEN_CONST; if identifier == "const" return .TOKEN_CONST;
@@ -243,7 +244,6 @@ identifier_kind :: (using lexer : *Lexer) -> Token_Kind {
if identifier == "optional" return .TOKEN_OPTIONAL; if identifier == "optional" return .TOKEN_OPTIONAL;
if identifier == "out" return .TOKEN_OUT; if identifier == "out" return .TOKEN_OUT;
if identifier == "pixel" return .TOKEN_PIXEL; if identifier == "pixel" return .TOKEN_PIXEL;
// if identifier == "properties" return .TOKEN_PROPERTIES;
if identifier == "return" return .TOKEN_RETURN; if identifier == "return" return .TOKEN_RETURN;
if identifier == "register" return .TOKEN_REGISTER; if identifier == "register" return .TOKEN_REGISTER;
if identifier == "struct" return .TOKEN_STRUCT; if identifier == "struct" return .TOKEN_STRUCT;

View File

@@ -727,13 +727,12 @@ array_access :: (parse_state : *Parse_State, left : *AST_Node) -> *AST_Node {
identifier := parse_state.ctx.tokens[parse_state.current_token_index - 3]; identifier := parse_state.ctx.tokens[parse_state.current_token_index - 3];
left_bracket := parse_state.ctx.tokens[parse_state.current_token_index - 2]; left_bracket := parse_state.ctx.tokens[parse_state.current_token_index - 2];
array_access := make_node(parse_state, .Unary); array_access := make_node(parse_state, .Binary);
array_access.token = left_bracket; array_access.token = left_bracket;
array_index := expression(parse_state); array_index := expression(parse_state);
add_child(array_access, left);
add_child(array_access, array_index); add_child(array_access, array_index);
add_child(left, array_access);
consume(parse_state, .TOKEN_RIGHTBRACKET, "Expected ']' after array index."); consume(parse_state, .TOKEN_RIGHTBRACKET, "Expected ']' after array index.");
source_location : Source_Range; source_location : Source_Range;
@@ -750,8 +749,8 @@ array_access :: (parse_state : *Parse_State, left : *AST_Node) -> *AST_Node {
} }
source_location.end = parse_state.previous; source_location.end = parse_state.previous;
left.source_location = source_location; array_access.source_location = source_location;
return left; return array_access;
} }
unary :: (parse_state : *Parse_State, left : *AST_Node) -> *AST_Node { unary :: (parse_state : *Parse_State, left : *AST_Node) -> *AST_Node {
@@ -1368,6 +1367,11 @@ function_declaration :: (parse_state : *Parse_State, identifier_token : *Token,
return node; return node;
} }
buffer :: (state : *Parse_State, identifier_token : *Token = null) -> *AST_Node {
internal_error_message(*state.ctx.messages, "Buffers are not yet implemented in the language.", state.ctx.file.path);
return null;
}
constant_buffer :: (parse_state : *Parse_State, identifier_token : *Token = null) -> *AST_Node { constant_buffer :: (parse_state : *Parse_State, identifier_token : *Token = null) -> *AST_Node {
node : *AST_Node = make_node(parse_state, .CBuffer); node : *AST_Node = make_node(parse_state, .CBuffer);
source_location : Source_Range; source_location : Source_Range;
@@ -1430,6 +1434,8 @@ const_declaration :: (parse_state : *Parse_State, identifier_token : *Token) ->
return function_declaration(parse_state, identifier_token, .None); return function_declaration(parse_state, identifier_token, .None);
} else if match(parse_state, .TOKEN_CONSTANT_BUFFER) { } else if match(parse_state, .TOKEN_CONSTANT_BUFFER) {
return constant_buffer(parse_state, identifier_token); return constant_buffer(parse_state, identifier_token);
} else if match(parse_state, .TOKEN_BUFFER) {
return buffer(parse_state, identifier_token);
} }
return error_node(parse_state, tprint("Couldn't parse constant declaration at token %\n", parse_state.current.*)); return error_node(parse_state, tprint("Couldn't parse constant declaration at token %\n", parse_state.current.*));
} }

View File

@@ -17,8 +17,6 @@ build :: () {
options := get_build_options(w); options := get_build_options(w);
options.write_added_strings = true;
args := options.compile_time_command_line; args := options.compile_time_command_line;
profile : bool = false; profile : bool = false;

View File

@@ -13,7 +13,7 @@
- [ ] Support compute shaders - [ ] Support compute shaders
- [x] Support #if at top level - [x] Support #if at top level
- [x] Support #if at block level - [x] Support #if at block level
- [ ] Remove properties block and just use hinted constant buffers instead - [x] Remove properties block and just use hinted constant buffers instead
``` ```
props :: constant_buffer @properties { props :: constant_buffer @properties {
[...] [...]
@@ -21,7 +21,8 @@
``` ```
- [ ] while loops - [ ] while loops
- [ ] for-each loops - [ ] for-each loops
- [ ] - [ ] add parameters to hints (meta properties, resource binding indices if needed)
- [ ] consider @entry(stage) syntax instead of the forced keyword
*/ */
add_define :: (env : *Environment, key : string) { add_define :: (env : *Environment, key : string) {

View File

@@ -1,5 +1,5 @@
vertex main :: () -> float4 @position { vertex main :: () -> float4 @position {
arr : [16].float4; arr : [16].float4;
arr[0] = float4(1,1,1); // arr[0] = float4(1,1,1);
return arr[0]; return arr[0];
} }