From 0c0e31db385e4161991b9d1a41b86a3e1dc1eb79 Mon Sep 17 00:00:00 2001 From: Niels Bross Date: Mon, 29 Sep 2025 22:22:00 +0200 Subject: [PATCH] Fix lvalue/rvalue binaries. Fix structured buffer output. --- Check.jai | 88 ++++++++++++++++++----------- Codegen.jai | 8 +-- Ink.jai | 39 ++++++++----- Parsing.jai | 22 +------- module.jai | 69 ++++++++++++++-------- test/check/for_index_outside.golden | 4 ++ test/check/rvalue_binary.golden | 8 +++ test/check/temp_access.golden | 6 ++ test/check_all.suite | 2 + test/codegen/rvalue_binary.golden | 7 +++ test/codegen_all.suite | 1 + test/compile_all.suite | 1 + test/for_index_outside.ink | 7 +++ test/lex/double_access.golden | 2 +- test/lex/large_block.golden | 2 +- test/lex/rvalue_binary.golden | 27 +++++++++ test/lex/temp_access.golden | 26 +++++++++ test/lex_all.suite | 2 + test/parse/rvalue_binary.golden | 6 ++ test/parse/temp_access.golden | 6 ++ test/parse_all.suite | 2 + test/rvalue_binary.ink | 6 ++ test/temp_access.ink | 6 ++ 23 files changed, 244 insertions(+), 103 deletions(-) create mode 100644 test/check/for_index_outside.golden create mode 100644 test/check/rvalue_binary.golden create mode 100644 test/check/temp_access.golden create mode 100644 test/codegen/rvalue_binary.golden create mode 100644 test/for_index_outside.ink create mode 100644 test/lex/rvalue_binary.golden create mode 100644 test/lex/temp_access.golden create mode 100644 test/parse/rvalue_binary.golden create mode 100644 test/parse/temp_access.golden create mode 100644 test/rvalue_binary.ink create mode 100644 test/temp_access.ink diff --git a/Check.jai b/Check.jai index 4b1d90a..20a261f 100644 --- a/Check.jai +++ b/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; } diff --git a/Codegen.jai b/Codegen.jai index 6fa1060..05f1120 100644 --- a/Codegen.jai +++ b/Codegen.jai @@ -401,7 +401,7 @@ emit_node :: (state : *Codegen_State, node : *AST_Node, indentation : int) { indent(*state.builder, indentation); if node.token.kind != .TOKEN_ASSIGN && node.token.kind != .TOKEN_LEFTBRACKET { - if node.parent.kind == .Binary && node.parent.token.kind != .TOKEN_ASSIGN { + if (node.parent.kind == .Binary && node.parent.token.kind != .TOKEN_ASSIGN) || node.parent.kind == .Access { append(*state.builder, "("); } } @@ -422,10 +422,8 @@ emit_node :: (state : *Codegen_State, node : *AST_Node, indentation : int) { emit_node(state, rhs, 0); } - - if node.token.kind != .TOKEN_ASSIGN && node.token.kind != .TOKEN_LEFTBRACKET { - if node.parent.kind == .Binary && node.parent.token.kind != .TOKEN_ASSIGN { + if (node.parent.kind == .Binary && node.parent.token.kind != .TOKEN_ASSIGN) || node.parent.kind == .Access { append(*state.builder, ")"); } } @@ -577,10 +575,8 @@ emit_buffer :: (state : *Codegen_State, node : *AST_Node, indentation : int) { element := from_handle(state.ctx.type_variables, variable.element_type); emit_struct(state, node, indentation, element.typename); - // print_to_builder(*state.builder, "struct %\n", element.name); print_to_builder(*state.builder, "StructuredBuffer<%> % : register(t%);\n\n", element.typename, variable.name, variable.resource_index); - } emit_declaration :: (state : *Codegen_State, node : *AST_Node) { diff --git a/Ink.jai b/Ink.jai index c3ad749..40acd46 100644 --- a/Ink.jai +++ b/Ink.jai @@ -227,24 +227,33 @@ 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); } - for cb : ctx.cbuffers { - print_to_builder(*sb, "[constant_buffer] - % - %", cb.name, cb.buffer_index); + for buf : ctx.buffers { + if buf.kind == { + case .Constant; { + print_to_builder(*sb, "[constant_buffer] - % - %", buf.name, buf.buffer_index); + + } + case .Structured; { + print_to_builder(*sb, "[buffer] - % - %", buf.name, buf.buffer_index); + } - if cb.hints.count > 0 { - for hint : cb.hints { - print_to_builder(*sb, " (@%)", hint.custom_hint_name); + if buf.hints.count > 0 { + for hint : buf.hints { + print_to_builder(*sb, " (@%)", hint.custom_hint_name); + } + } + + append(*sb, "\n"); + + indent(*sb, 1); + for field : buf.fields { + append(*sb, "[field] - "); + pretty_print_field(*sb, *field); + append(*sb, "\n"); + indent(*sb, 1); } } - - append(*sb, "\n"); - - indent(*sb, 1); - for field : cb.fields { - append(*sb, "[field] - "); - pretty_print_field(*sb, *field); - append(*sb, "\n"); - indent(*sb, 1); - } + } result.info_text = builder_to_string(*sb); diff --git a/Parsing.jai b/Parsing.jai index 7d8b41f..21a0188 100644 --- a/Parsing.jai +++ b/Parsing.jai @@ -1,13 +1,3 @@ -#import "Flat_Pool"; - -// #load "qpwodkqopwkd.jai"; - -/** -* TODO: -* if parsing -* for/while loop parsing -**/ - //////////////////////////// //@nb - Parse_state state Parse_State :: struct { @@ -19,15 +9,6 @@ Parse_State :: struct { ctx : *Compiler_Context; } -//////////////////////////// -//@nb - Result and error handling -Parse_Error_Kind :: enum { - Parse_Error_Type_Missing; - Parse_Error_Expected_Expression; - Parse_Error_Empty_Block; - Parse_Error_Unexpected_Token; -} - //////////////////////////// //@nb - Parsing helper types Separator_Type :: enum { @@ -871,6 +852,7 @@ dot :: (parse_state : *Parse_State, left : *AST_Node) -> *AST_Node { node := make_node(parse_state, .Binary); node.token = parse_state.previous; + node.source_location = generate_source_location_from_token(parse_state, node.token); add_child(node, access); add_child(node, expression(parse_state)); return node; @@ -1439,8 +1421,6 @@ declaration :: (parse_state : *Parse_State) -> *AST_Node { consume(parse_state, .TOKEN_DOUBLECOLON, "Expect '::' after pixel entry point declaration."); decl_node = function_declaration(parse_state, identifier, .Pixel); - } else if check(parse_state, .TOKEN_LEFTPAREN) { - decl_node = call(parse_state, null); } else if check(parse_state, .TOKEN_DIRECTIVE) { decl_node = directive(parse_state); skip_statement = true; diff --git a/module.jai b/module.jai index af15024..c33b1cb 100644 --- a/module.jai +++ b/module.jai @@ -128,7 +128,13 @@ Entry_Point :: struct { return_value : Field; } -Constant_Buffer :: struct { +Buffer_Kind :: enum { + Constant; + Structured; +} + +Buffer :: struct { + kind : Buffer_Kind; name : string; fields : Static_Array(Field, 16); @@ -154,8 +160,8 @@ Compiler_Context :: struct { codegen_result_text : string; - constant_buffers : Static_Array(Type_Variable_Handle, 16); - buffers : Static_Array(Type_Variable_Handle, 16); + typed_buffers : Static_Array(Type_Variable_Handle, 32); + // structured_buffers : Static_Array(Type_Variable_Handle, 16); scope_stack : Scope_Stack; type_variables : [..]Type_Variable; @@ -172,9 +178,9 @@ Compiler_Context :: struct { return_value : Field; } - max_constant_buffers :: 16; + max_buffers :: 32; - cbuffers : Static_Array(Constant_Buffer, max_constant_buffers); + buffers : Static_Array(Buffer, max_buffers); had_error : bool; messages : [..]Compiler_Message; @@ -403,6 +409,37 @@ type_variable_to_field :: (ctx : *Compiler_Context, variable : Type_Variable_Han return type_variable_to_field(ctx, from_handle(ctx.type_variables, variable)); } +generate_buffer :: (ctx : *Compiler_Context, type_handle : Type_Variable_Handle, buffers : *Static_Array) { + variable := from_handle(ctx.type_variables, type_handle); + + buffer := array_add(buffers); + + if variable.type == { + case .CBuffer; { + buffer.kind = .Constant; + } + case .Buffer; { + buffer.kind = .Structured; + } + } + buffer.name = variable.name; + + for i : 0..variable.children.count - 1 { + child := variable.children[i]; + field : Field = type_variable_to_field(ctx, from_handle(ctx.type_variables, child)); + array_add(*buffer.fields, field); + } + + buffer.buffer_index = variable.resource_index; + + for hint : variable.source_node.hint_tokens { + field_hint : Field_Hint; + field_hint.custom_hint_name = hint.ident_value; + field_hint.kind = .Custom; + array_add(*buffer.hints, field_hint); + } +} + generate_output_data :: (ctx : *Compiler_Context) { if ctx.had_error { return; @@ -427,26 +464,8 @@ generate_output_data :: (ctx : *Compiler_Context) { } } - for buffer_variable : ctx.constant_buffers { - variable := from_handle(ctx.type_variables, buffer_variable); - - cb := array_add(*ctx.cbuffers); - cb.name = variable.name; - - for i : 0..variable.children.count - 1 { - child := variable.children[i]; - field : Field = type_variable_to_field(ctx, from_handle(ctx.type_variables, child)); - array_add(*cb.fields, field); - } - - cb.buffer_index = variable.resource_index; - - for hint : variable.source_node.hint_tokens { - field_hint : Field_Hint; - field_hint.custom_hint_name = hint.ident_value; - field_hint.kind = .Custom; - array_add(*cb.hints, field_hint); - } + for buffer_variable : ctx.typed_buffers { + generate_buffer(ctx, buffer_variable, *ctx.buffers); } if ctx.pixel_entry_point.node { diff --git a/test/check/for_index_outside.golden b/test/check/for_index_outside.golden new file mode 100644 index 0000000..8642679 --- /dev/null +++ b/test/check/for_index_outside.golden @@ -0,0 +1,4 @@ +test/for_index_outside.ink:6,0: error: Use of undeclared symbol 'i' + i += 1; + ^ + \ No newline at end of file diff --git a/test/check/rvalue_binary.golden b/test/check/rvalue_binary.golden new file mode 100644 index 0000000..4d5b770 --- /dev/null +++ b/test/check/rvalue_binary.golden @@ -0,0 +1,8 @@ +scope (global) [ + [vertex__vs_main] : () + scope (vertex__vs_main) [ + [b] : float2 + [x] : float + [a] : float2 + ] +] diff --git a/test/check/temp_access.golden b/test/check/temp_access.golden new file mode 100644 index 0000000..0237713 --- /dev/null +++ b/test/check/temp_access.golden @@ -0,0 +1,6 @@ +test/temp_access.ink:5,10: error: Cannot assign to an lvalue. + (a + b).x = 2.0; + ^^^^^^^^^^^ + + + \ No newline at end of file diff --git a/test/check_all.suite b/test/check_all.suite index bb2defe..7f153a9 100644 --- a/test/check_all.suite +++ b/test/check_all.suite @@ -28,12 +28,14 @@ test/non_bool_cond.ink check test/pass_and_access_struct_fields_in_functions.ink check test/passthrough.ink check test/redeclared_variable.ink check +test/rvalue_binary.ink check test/simple_else_if.ink check test/simple_if_else.ink check test/simple_if.ink check test/simple_struct_access.ink check test/struct_access_primitive_type.ink check test/struct_within_struct.ink check +test/temp_access.ink check test/type_as_variable_name.ink check test/unary.ink check test/undeclared_function.ink check diff --git a/test/codegen/rvalue_binary.golden b/test/codegen/rvalue_binary.golden new file mode 100644 index 0000000..65b101c --- /dev/null +++ b/test/codegen/rvalue_binary.golden @@ -0,0 +1,7 @@ +void vs_main() +{ + float2 a; + float2 b; + float x = (a + b).x; +} + diff --git a/test/codegen_all.suite b/test/codegen_all.suite index dee580a..d1e0be4 100644 --- a/test/codegen_all.suite +++ b/test/codegen_all.suite @@ -20,6 +20,7 @@ test/multiple_semicolons_everywhere.ink codegen test/nested_if.ink codegen test/pass_and_access_struct_fields_in_functions.ink codegen test/passthrough.ink codegen +test/rvalue_binary.ink codegen test/simple_else_if.ink codegen test/simple_if_else.ink codegen test/simple_if.ink codegen diff --git a/test/compile_all.suite b/test/compile_all.suite index e183372..075e834 100644 --- a/test/compile_all.suite +++ b/test/compile_all.suite @@ -20,6 +20,7 @@ test/multiple_functions.ink compile test/multiple_semicolons_everywhere.ink compile test/pass_and_access_struct_fields_in_functions.ink compile test/passthrough.ink compile +test/rvalue_binary.ink compile test/simple_else_if.ink compile test/simple_if_else.ink compile test/simple_if.ink compile diff --git a/test/for_index_outside.ink b/test/for_index_outside.ink new file mode 100644 index 0000000..59edbef --- /dev/null +++ b/test/for_index_outside.ink @@ -0,0 +1,7 @@ +vertex main :: () { + for i : 0..10 { + x : float; + } + + i += 1; +} diff --git a/test/lex/double_access.golden b/test/lex/double_access.golden index 5be793d..4a5cee4 100644 --- a/test/lex/double_access.golden +++ b/test/lex/double_access.golden @@ -1,6 +1,6 @@ {kind = TOKEN_IDENTIFIER; ; index = 0 ; length = 1 line = 1 ; column = 0 ; value ='p'; } {kind = TOKEN_DOUBLECOLON; ; index = 2 ; length = 2 line = 1 ; column = 2 ; value ='::'; } -{kind = TOKEN_IDENTIFIER; ; index = 5 ; length = 15 line = 1 ; column = 5 ; value ='constant_buffer'; } +{kind = TOKEN_CONSTANT_BUFFER; ; index = 5 ; length = 15 line = 1 ; column = 5 ; value ='Constant_Buffer'; } {kind = TOKEN_LEFTBRACE; ; index = 21 ; length = 1 line = 1 ; column = 21 ; value ='{'; } {kind = TOKEN_IDENTIFIER; ; index = 25 ; length = 1 line = 2 ; column = 0 ; value ='v'; } {kind = TOKEN_COLON; ; index = 27 ; length = 1 line = 2 ; column = 2 ; value =':'; } diff --git a/test/lex/large_block.golden b/test/lex/large_block.golden index 93bf2d8..978d90e 100644 --- a/test/lex/large_block.golden +++ b/test/lex/large_block.golden @@ -1,6 +1,6 @@ {kind = TOKEN_IDENTIFIER; ; index = 0 ; length = 1 line = 1 ; column = 0 ; value ='p'; } {kind = TOKEN_DOUBLECOLON; ; index = 2 ; length = 2 line = 1 ; column = 2 ; value ='::'; } -{kind = TOKEN_IDENTIFIER; ; index = 5 ; length = 15 line = 1 ; column = 5 ; value ='constant_buffer'; } +{kind = TOKEN_CONSTANT_BUFFER; ; index = 5 ; length = 15 line = 1 ; column = 5 ; value ='Constant_Buffer'; } {kind = TOKEN_AT; ; index = 21 ; length = 1 line = 1 ; column = 21 ; value ='@'; } {kind = TOKEN_IDENTIFIER; ; index = 22 ; length = 10 line = 1 ; column = 22 ; value ='properties'; } {kind = TOKEN_LEFTBRACE; ; index = 33 ; length = 1 line = 1 ; column = 33 ; value ='{'; } diff --git a/test/lex/rvalue_binary.golden b/test/lex/rvalue_binary.golden new file mode 100644 index 0000000..bd6d0eb --- /dev/null +++ b/test/lex/rvalue_binary.golden @@ -0,0 +1,27 @@ +{kind = TOKEN_VERTEX; ; index = 0 ; length = 6 line = 1 ; column = 0 ; value ='vertex'; } +{kind = TOKEN_IDENTIFIER; ; index = 7 ; length = 4 line = 1 ; column = 7 ; value ='main'; } +{kind = TOKEN_DOUBLECOLON; ; index = 12 ; length = 2 line = 1 ; column = 12 ; value ='::'; } +{kind = TOKEN_LEFTPAREN; ; index = 15 ; length = 1 line = 1 ; column = 15 ; value ='('; } +{kind = TOKEN_RIGHTPAREN; ; index = 16 ; length = 1 line = 1 ; column = 16 ; value =')'; } +{kind = TOKEN_LEFTBRACE; ; index = 18 ; length = 1 line = 1 ; column = 18 ; value ='{'; } +{kind = TOKEN_IDENTIFIER; ; index = 22 ; length = 1 line = 2 ; column = 0 ; value ='a'; } +{kind = TOKEN_COLON; ; index = 24 ; length = 1 line = 2 ; column = 2 ; value =':'; } +{kind = TOKEN_IDENTIFIER; ; index = 26 ; length = 6 line = 2 ; column = 4 ; value ='float2'; } +{kind = TOKEN_SEMICOLON; ; index = 32 ; length = 1 line = 2 ; column = 10 ; value =';'; } +{kind = TOKEN_IDENTIFIER; ; index = 36 ; length = 1 line = 3 ; column = 0 ; value ='b'; } +{kind = TOKEN_COLON; ; index = 38 ; length = 1 line = 3 ; column = 2 ; value =':'; } +{kind = TOKEN_IDENTIFIER; ; index = 40 ; length = 6 line = 3 ; column = 4 ; value ='float2'; } +{kind = TOKEN_SEMICOLON; ; index = 46 ; length = 1 line = 3 ; column = 10 ; value =';'; } +{kind = TOKEN_IDENTIFIER; ; index = 52 ; length = 1 line = 5 ; column = 0 ; value ='x'; } +{kind = TOKEN_COLON; ; index = 54 ; length = 1 line = 5 ; column = 2 ; value =':'; } +{kind = TOKEN_ASSIGN; ; index = 55 ; length = 1 line = 5 ; column = 3 ; value ='='; } +{kind = TOKEN_LEFTPAREN; ; index = 57 ; length = 1 line = 5 ; column = 5 ; value ='('; } +{kind = TOKEN_IDENTIFIER; ; index = 58 ; length = 1 line = 5 ; column = 6 ; value ='a'; } +{kind = TOKEN_PLUS; ; index = 60 ; length = 1 line = 5 ; column = 8 ; value ='+'; } +{kind = TOKEN_IDENTIFIER; ; index = 62 ; length = 1 line = 5 ; column = 10 ; value ='b'; } +{kind = TOKEN_RIGHTPAREN; ; index = 63 ; length = 1 line = 5 ; column = 11 ; value =')'; } +{kind = TOKEN_DOT; ; index = 64 ; length = 1 line = 5 ; column = 12 ; value ='.'; } +{kind = TOKEN_IDENTIFIER; ; index = 65 ; length = 1 line = 5 ; column = 13 ; value ='x'; } +{kind = TOKEN_SEMICOLON; ; index = 66 ; length = 1 line = 5 ; column = 14 ; value =';'; } +{kind = TOKEN_RIGHTBRACE; ; index = 69 ; length = 1 line = 6 ; column = 0 ; value ='}'; } +{kind = TOKEN_EOF; ; index = 72 ; length = 0 line = 7 ; column = 0 ; value =''; } diff --git a/test/lex/temp_access.golden b/test/lex/temp_access.golden new file mode 100644 index 0000000..b8722ee --- /dev/null +++ b/test/lex/temp_access.golden @@ -0,0 +1,26 @@ +{kind = TOKEN_VERTEX; ; index = 0 ; length = 6 line = 1 ; column = 0 ; value ='vertex'; } +{kind = TOKEN_IDENTIFIER; ; index = 7 ; length = 4 line = 1 ; column = 7 ; value ='main'; } +{kind = TOKEN_DOUBLECOLON; ; index = 12 ; length = 2 line = 1 ; column = 12 ; value ='::'; } +{kind = TOKEN_LEFTPAREN; ; index = 15 ; length = 1 line = 1 ; column = 15 ; value ='('; } +{kind = TOKEN_RIGHTPAREN; ; index = 16 ; length = 1 line = 1 ; column = 16 ; value =')'; } +{kind = TOKEN_LEFTBRACE; ; index = 18 ; length = 1 line = 1 ; column = 18 ; value ='{'; } +{kind = TOKEN_IDENTIFIER; ; index = 22 ; length = 1 line = 2 ; column = 0 ; value ='a'; } +{kind = TOKEN_COLON; ; index = 24 ; length = 1 line = 2 ; column = 2 ; value =':'; } +{kind = TOKEN_IDENTIFIER; ; index = 26 ; length = 6 line = 2 ; column = 4 ; value ='float2'; } +{kind = TOKEN_SEMICOLON; ; index = 32 ; length = 1 line = 2 ; column = 10 ; value =';'; } +{kind = TOKEN_IDENTIFIER; ; index = 36 ; length = 1 line = 3 ; column = 0 ; value ='b'; } +{kind = TOKEN_COLON; ; index = 38 ; length = 1 line = 3 ; column = 2 ; value =':'; } +{kind = TOKEN_IDENTIFIER; ; index = 40 ; length = 6 line = 3 ; column = 4 ; value ='float2'; } +{kind = TOKEN_SEMICOLON; ; index = 46 ; length = 1 line = 3 ; column = 10 ; value =';'; } +{kind = TOKEN_LEFTPAREN; ; index = 52 ; length = 1 line = 5 ; column = 0 ; value ='('; } +{kind = TOKEN_IDENTIFIER; ; index = 53 ; length = 1 line = 5 ; column = 1 ; value ='a'; } +{kind = TOKEN_PLUS; ; index = 55 ; length = 1 line = 5 ; column = 3 ; value ='+'; } +{kind = TOKEN_IDENTIFIER; ; index = 57 ; length = 1 line = 5 ; column = 5 ; value ='b'; } +{kind = TOKEN_RIGHTPAREN; ; index = 58 ; length = 1 line = 5 ; column = 6 ; value =')'; } +{kind = TOKEN_DOT; ; index = 59 ; length = 1 line = 5 ; column = 7 ; value ='.'; } +{kind = TOKEN_IDENTIFIER; ; index = 60 ; length = 1 line = 5 ; column = 8 ; value ='x'; } +{kind = TOKEN_ASSIGN; ; index = 62 ; length = 1 line = 5 ; column = 10 ; value ='='; } +{kind = TOKEN_FLOATLITERAL; ; index = 64 ; length = 3 line = 5 ; column = 12 ; value ='2'; } +{kind = TOKEN_SEMICOLON; ; index = 67 ; length = 1 line = 5 ; column = 15 ; value =';'; } +{kind = TOKEN_RIGHTBRACE; ; index = 70 ; length = 1 line = 6 ; column = 0 ; value ='}'; } +{kind = TOKEN_EOF; ; index = 73 ; length = 0 line = 7 ; column = 0 ; value =''; } diff --git a/test/lex_all.suite b/test/lex_all.suite index a7ad7f3..70625bf 100644 --- a/test/lex_all.suite +++ b/test/lex_all.suite @@ -36,12 +36,14 @@ test/non_bool_cond.ink lex test/pass_and_access_struct_fields_in_functions.ink lex test/passthrough.ink lex test/redeclared_variable.ink lex +test/rvalue_binary.ink lex test/simple_else_if.ink lex test/simple_if_else.ink lex test/simple_if.ink lex test/simple_struct_access.ink lex test/struct_access_primitive_type.ink lex test/struct_within_struct.ink lex +test/temp_access.ink lex test/type_as_variable_name.ink lex test/unary.ink lex test/undeclared_function.ink lex diff --git a/test/parse/rvalue_binary.golden b/test/parse/rvalue_binary.golden new file mode 100644 index 0000000..9528bb6 --- /dev/null +++ b/test/parse/rvalue_binary.golden @@ -0,0 +1,6 @@ +(program + (fun vertex vs_main + [] + (:= a float2) + (:= b float2) + (:= x (+ a b).x))) \ No newline at end of file diff --git a/test/parse/temp_access.golden b/test/parse/temp_access.golden new file mode 100644 index 0000000..bbb84d3 --- /dev/null +++ b/test/parse/temp_access.golden @@ -0,0 +1,6 @@ +(program + (fun vertex vs_main + [] + (:= a float2) + (:= b float2) + (= (+ a b).x 2))) \ No newline at end of file diff --git a/test/parse_all.suite b/test/parse_all.suite index e35fd1c..d273418 100644 --- a/test/parse_all.suite +++ b/test/parse_all.suite @@ -36,12 +36,14 @@ test/non_bool_cond.ink parse test/pass_and_access_struct_fields_in_functions.ink parse test/passthrough.ink parse test/redeclared_variable.ink parse +test/rvalue_binary.ink parse test/simple_else_if.ink parse test/simple_if_else.ink parse test/simple_if.ink parse test/simple_struct_access.ink parse test/struct_access_primitive_type.ink parse test/struct_within_struct.ink parse +test/temp_access.ink parse test/type_as_variable_name.ink parse test/unary.ink parse test/undeclared_function.ink parse diff --git a/test/rvalue_binary.ink b/test/rvalue_binary.ink new file mode 100644 index 0000000..1812fb3 --- /dev/null +++ b/test/rvalue_binary.ink @@ -0,0 +1,6 @@ +vertex main :: () { + a : float2; + b : float2; + + x := (a + b).x; +} diff --git a/test/temp_access.ink b/test/temp_access.ink new file mode 100644 index 0000000..d10ca44 --- /dev/null +++ b/test/temp_access.ink @@ -0,0 +1,6 @@ +vertex main :: () { + a : float2; + b : float2; + + (a + b).x = 2.0; +}