diff --git a/Test.jai b/Ink.jai similarity index 96% rename from Test.jai rename to Ink.jai index f7bcf6b..94bc073 100644 --- a/Test.jai +++ b/Ink.jai @@ -1,10 +1,14 @@ ///////////////////////////////////// -//~ nbr: General improvements -// -// [x] Print out all failed tests in a list at the end -// [ ] Use new compiler API with Compile_Result and Compiled_File instead -// [ ] Use unix (posix? bash? ascii?) color codes for errors -// [ ] Print golden file as green and new output as red +/*~ nbr: General improvements +- [x] Print out all failed tests in a list at the end +- [x] Use new compiler API with Compile_Result and Compiled_File instead +- [ ] Use unix (posix? bash? ascii?) color codes for errors +- [ ] Print golden file as green and new output as red +- [ ] Rename to Ink.jai +- [ ] Add -test option. -test does the same as test.exe used to do +- [ ] Add -fuzz option to run fuzzer (add args later) +- [ ] Add -output option to output the compiled file. Issue with this is the generated data can't be output like that. Would require serialization. +*/ #import "Basic"; #import "File"; @@ -578,8 +582,6 @@ evaluate_result :: (result : Result) { } main :: () { - lexer : Lexer; - args := get_command_line_arguments(); suites : [..]Test_Suite; @@ -587,6 +589,7 @@ main :: () { Argument_Parse_State :: enum { None; + Compile; Run_Suite; Run_Test; } diff --git a/Parsing.jai b/Parsing.jai index 196e103..54e6f0e 100644 --- a/Parsing.jai +++ b/Parsing.jai @@ -134,6 +134,7 @@ record_error :: (parse_state : *Parse_State, token : Token, message : string, re source_location.begin.source = source_location.begin.source - source_location.begin.column; source_location.main_token = token; + snap := snapshot_state(parse_state); advance_to_sync_point(parse_state); error.report_source_location = report_source_location; @@ -142,6 +143,8 @@ record_error :: (parse_state : *Parse_State, token : Token, message : string, re parse_state.result.had_error = true; array_add(*parse_state.result.messages, error); + + rewind_to_snapshot(parse_state, snap); } generate_source_location_from_token :: (state : *Parse_State, token : Token) -> Source_Range { @@ -241,6 +244,26 @@ else_without_if :: (state : *Parse_State) { record_error(state, token, final_message, false); } +unable_to_parse_statement :: (state : *Parse_State, token : Token, message : string = "") { + builder : String_Builder; + init_string_builder(*builder,, temp); + + print_to_builder(*builder, "Unable to parse statement here. %\n", message); + + location : Source_Range = generate_source_location_from_token(state, token); + + indent(*builder, 1); + cyan(*builder); + print_to_builder(*builder, "%\n", print_from_source_location(location)); + + + indent(*builder, 1); + print_token_pointer(*builder, token); + + final_message := builder_to_string(*builder); + record_error(state, token, final_message, false); +} + expected_expression :: (state : *Parse_State, token : Token, message : string) { builder : String_Builder; init_string_builder(*builder,, temp); @@ -444,9 +467,9 @@ precedence :: (parse_state : *Parse_State, precedence : Precedence, message : st tok_s.data = prev.source; tok_s.count = prev.length; if message { - expected_expression(parse_state, parse_state.previous, tprint("Expected expression after '%'. %", tok_s, message)); + expected_expression(parse_state, prev, tprint("Expected expression after '%'. %", tok_s, message)); } else { - expected_expression(parse_state, parse_state.previous, tprint("Expected expression after '%'.", tok_s)); + expected_expression(parse_state, prev, tprint("Expected expression after '%'.", tok_s)); } return error_node(parse_state, "Expected expression."); @@ -859,9 +882,10 @@ statement :: (parse_state : *Parse_State) -> *AST_Node { source_location : Source_Range; source_location.begin = parse_state.previous; - if_cond := expression(parse_state); + if_cond := expression(parse_state, "Expected if condition."); add_child(node, if_cond); source_location.end = parse_state.previous; + advance_to_sync_point(parse_state); if_body := block(parse_state); add_child(node, if_body); @@ -903,18 +927,42 @@ statement :: (parse_state : *Parse_State) -> *AST_Node { advance(parse_state); consume(parse_state, .TOKEN_COLON, "Expect ':' after for loop iterator."); + snap := snapshot_state(parse_state); + begin_iter := expression(parse_state, "Expected beginning of iterator."); + if begin_iter.kind == .Error { + unable_to_parse_statement(parse_state, source_location.begin); + rewind_to_snapshot(parse_state, snap); + if parse_state.current.kind == .TOKEN_LEFTBRACE { + block(parse_state); + } + return error_node(parse_state, "'for' without well-formed iterator expression."); + } add_child(node, begin_iter); consume(parse_state, .TOKEN_DOTDOT, "Expect '..' after for loop iter left hand side."); - end_iter := expression(parse_state, "Expected end of iterator"); + snap = snapshot_state(parse_state); + end_iter := expression(parse_state, "Expected end of iterator."); + if end_iter.kind == .Error { + unable_to_parse_statement(parse_state, source_location.begin); + rewind_to_snapshot(parse_state, snap); + + if parse_state.current.kind == .TOKEN_LEFTBRACE { + + block(parse_state); + } + return error_node(parse_state, "'for' without well-formed iterator expression."); + } add_child(node, end_iter); - for_body := block(parse_state); - add_child(node, for_body); - - // consume(parse_state, .TOKEN_RIGHTBRACE, "Expect '}' after for body."); + if check(parse_state, .TOKEN_LEFTBRACE) { + for_body := block(parse_state); + add_child(node, for_body); + } else { + unable_to_parse_statement(parse_state, source_location.begin, "'for' currently expects a brace-enclosed block as a body."); + return error_node(parse_state, "'for' currently expects a brace-enclosed block as a body."); + } node.source_location = source_location; diff --git a/first.jai b/first.jai index b4abb2f..4b46b3d 100644 --- a/first.jai +++ b/first.jai @@ -3,14 +3,14 @@ #import "Compiler"; build :: () { - w := compiler_create_workspace("Shader Compiler Test Build"); + w := compiler_create_workspace("Ink Build"); if !w { print("Workspace creation failed.\n"); return; } - EXECUTABLE_NAME :: "test"; - MAIN_FILE :: "Test.jai"; + EXECUTABLE_NAME :: "ink"; + MAIN_FILE :: "Ink.jai"; options := get_build_options(w); diff --git a/module.jai b/module.jai index ec60c73..a0b44d5 100644 --- a/module.jai +++ b/module.jai @@ -119,7 +119,8 @@ Constant_Buffer :: struct { fields : Static_Array(Property_Field, 16); - hint : Field_Hint; // optional hint... + // hints : Field_Hint; // optional hint... + hints : [..]Field_Hint; buffer_index : u32; } @@ -358,7 +359,7 @@ type_variable_to_field :: (type_variables : []Type_Variable, scope_stack : Scope } field_hint.kind = .Target; } else { - field_hint.custom_hint_name = copy_string(hint.ident_value); + field_hint.custom_hint_name = hint.ident_value; field_hint.kind = .Custom; } array_add(*field.hints, field_hint); @@ -414,21 +415,28 @@ generate_output_data :: (result : *Compile_Result) { } 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); + } } - find_result := find_symbol(*result.scope_stack, result.property_name, xx 1); - if find_result { - property_variable := from_handle(result.type_variables, find_result.type_variable); + find_result := find_symbol(*result.scope_stack, result.property_name, xx 1); + if find_result { + property_variable := from_handle(result.type_variables, find_result.type_variable); - for i : 0..property_variable.children.count - 1 { - child := property_variable.children[i]; - field := type_variable_to_field(result.type_variables, result.scope_stack, from_handle(result.type_variables, child)); - prop_field : Property_Field; - prop_field.base_field = field; - array_add(*result.properties.fields, prop_field); - } - result.properties.buffer_index = property_variable.resource_index; + for i : 0..property_variable.children.count - 1 { + child := property_variable.children[i]; + field := type_variable_to_field(result.type_variables, result.scope_stack, from_handle(result.type_variables, child)); + prop_field : Property_Field; + prop_field.base_field = field; + array_add(*result.properties.fields, prop_field); } + result.properties.buffer_index = property_variable.resource_index; + } if result.pixel_entry_point.node { diff --git a/test/for_no_iter.ink b/test/for_no_iter.ink index 43ecb70..3c91504 100644 --- a/test/for_no_iter.ink +++ b/test/for_no_iter.ink @@ -1,6 +1,6 @@ vertex main :: () { x := 0.0; - for i : { + for i : 0.. { x += 2.0; } } diff --git a/test/parse/for_i_loop.golden b/test/parse/for_i_loop.golden new file mode 100644 index 0000000..9ad7f7a --- /dev/null +++ b/test/parse/for_i_loop.golden @@ -0,0 +1,6 @@ +(program + (fun vertex vs_main + [] + (:= x 0) + (for i : 0..10 + (+= x 1)))) \ No newline at end of file diff --git a/test/parse/for_i_one_liner.golden b/test/parse/for_i_one_liner.golden new file mode 100644 index 0000000..6a295fd --- /dev/null +++ b/test/parse/for_i_one_liner.golden @@ -0,0 +1,4 @@ +test/for_i_one_liner.ink:3,0: error: Unable to parse statement here. 'for' currently expects a brace-enclosed block as a body. + for i : 0..10 x += 2.0; + ^^^ + \ No newline at end of file diff --git a/test/parse/for_no_iter.golden b/test/parse/for_no_iter.golden new file mode 100644 index 0000000..08e472d --- /dev/null +++ b/test/parse/for_no_iter.golden @@ -0,0 +1,9 @@ +test/for_no_iter.ink:3,9: error: Expected expression after '..'. Expected end of iterator. + for i : 0.. { + x += 2.0; + ^^ +test/for_no_iter.ink:3,0: error: Unable to parse statement here. + for i : 0.. { + x += 2.0; + ^^^ + \ No newline at end of file diff --git a/test/parse/if_if_if.golden b/test/parse/if_if_if.golden index c63be74..ab9d7b0 100644 --- a/test/parse/if_if_if.golden +++ b/test/parse/if_if_if.golden @@ -1,4 +1,4 @@ -test/if_if_if.ink:2,3: error: Expected expression after 'if'. +test/if_if_if.ink:2,0: error: Expected expression after 'if'. Expected if condition. if if if 0 > 100 { - ^^ + ^^  \ No newline at end of file diff --git a/test/parse_all.suite b/test/parse_all.suite index 1a7e38b..6a9f0dc 100644 --- a/test/parse_all.suite +++ b/test/parse_all.suite @@ -10,6 +10,7 @@ test/field_assignment.ink parse test/field_without_type_specifier.ink parse test/float_if_cond.ink parse test/float_suffix.ink parse +test/for_i_loop.ink parse test/function_call.ink parse test/function_call_out_of_order_declaration.ink parse test/function_call_return.ink parse