From 45ea54cf9396b72fa2c36a4ee6613decca4195df Mon Sep 17 00:00:00 2001 From: Niels Bross Date: Sat, 18 Jan 2025 22:22:16 +0100 Subject: [PATCH] Fixed some error handling for invalid if statements. Started if codegen. --- AST.jai | 7 +- Codegen.jai | 20 ++++++ Parsing.jai | 81 +++++++++++++++++++--- Semantic_Analysis.jai | 6 +- test/else_if_after_else.ink | 10 +++ test/if_cond_assign.ink | 6 ++ test/if_if_if.ink | 6 ++ test/lex/else_if_after_else.golden | 39 +++++++++++ test/lex/float_if_cond.golden | 35 ++++++++++ test/lex/if_cond_assign.golden | 37 ++++++++++ test/lex/if_if_if.golden | 39 +++++++++++ test/lex_all.suite | 4 ++ test/parse/else_if_after_else.golden | 4 ++ test/parse/float_if_cond.golden | 6 ++ test/parse/if_cond_assign.golden | 6 ++ test/parse/if_if_if.golden | 4 ++ test/parse_all.suite | 4 ++ test/semant/float_if_cond.golden | 6 ++ test/semant/if_cond_assign.golden | 6 ++ test/semant/simple_if.golden | 6 ++ test/semant/simple_if_else.golden | 6 ++ test/semant/wrong_type_for_function.golden | 15 +++- test/semant_all.suite | 2 + 23 files changed, 344 insertions(+), 11 deletions(-) create mode 100644 test/else_if_after_else.ink create mode 100644 test/if_cond_assign.ink create mode 100644 test/if_if_if.ink create mode 100644 test/lex/else_if_after_else.golden create mode 100644 test/lex/float_if_cond.golden create mode 100644 test/lex/if_cond_assign.golden create mode 100644 test/lex/if_if_if.golden create mode 100644 test/parse/else_if_after_else.golden create mode 100644 test/parse/float_if_cond.golden create mode 100644 test/parse/if_cond_assign.golden create mode 100644 test/parse/if_if_if.golden create mode 100644 test/semant/float_if_cond.golden create mode 100644 test/semant/if_cond_assign.golden create mode 100644 test/semant/simple_if.golden create mode 100644 test/semant/simple_if_else.golden diff --git a/AST.jai b/AST.jai index 8abc868..f38c9dc 100644 --- a/AST.jai +++ b/AST.jai @@ -149,7 +149,12 @@ Children_Print_Flags :: enum_flags { } pretty_print_block :: (node : *AST_Node, indentation : int, builder : *String_Builder, skip_indent := false) { - pretty_print_children(node, indentation, builder, flags = .NewLine | .Dont_Skip_Indent_On_First); + if node.children.count == 0 { + indent(builder, indentation); + append(builder, "()"); + } else { + pretty_print_children(node, indentation, builder, flags = .NewLine | .Dont_Skip_Indent_On_First); + } } pretty_print_children :: (parent : *AST_Node, indentation : int, builder : *String_Builder, flags : Children_Print_Flags = .Separator, skip_indent := false) { diff --git a/Codegen.jai b/Codegen.jai index 8fe0512..e03eaea 100644 --- a/Codegen.jai +++ b/Codegen.jai @@ -374,6 +374,7 @@ emit_node :: (state : *Codegen_State, node : *AST_Node, indentation : int) { emit_field(state, node, indentation); } case .Block; { + assert(false, "Not implemented yet: block"); } case .Variable; { @@ -436,9 +437,28 @@ emit_node :: (state : *Codegen_State, node : *AST_Node, indentation : int) { append(*state.builder, "return "); emit_node(state, node.children[0], 0); } + case .If; { + indent(*state.builder, indentation); + append(*state.builder, "if "); + + cond := node.children[0]; + emit_node(state, cond, 0); + + body := node.children[1]; + emit_block(state, body, 0); + + if node.children.count == 2 { + emit_else(state, node.children[2]); + } + } } } +emit_else :: (state : *Codegen_State, node : *AST_Node) { + append(*state.builder, "else "); + emit_node(state, node.children[0], 0); +} + emit_field_list :: (state : *Codegen_State, field_list : *AST_Node, indentation : int) { for child : field_list.children { emit_node(state, child, 1); diff --git a/Parsing.jai b/Parsing.jai index b2503bb..aae0c36 100644 --- a/Parsing.jai +++ b/Parsing.jai @@ -213,6 +213,50 @@ unexpected_token :: (state : *Parse_State, token : Token, message : string) { record_error(state, token, final_message, false); } +else_if_without_if :: (state : *Parse_State) { + builder : String_Builder; + init_string_builder(*builder,, temp); + + append(*builder, "'else if' without 'if'\n"); + + token := state.previous; + + 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); + white(*builder); + + final_message := builder_to_string(*builder); + record_error(state, token, final_message, false); +} + +else_without_if :: (state : *Parse_State) { + builder : String_Builder; + init_string_builder(*builder,, temp); + + append(*builder, "'else' without 'if'\n"); + + token := state.previous; + + 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); + white(*builder); + + 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); @@ -395,7 +439,10 @@ precedence :: (parse_state : *Parse_State, precedence : Precedence) -> *AST_Node prefix_rule := get_rule(parse_state.previous.kind).prefix; if prefix_rule == null { - expected_expression(parse_state, parse_state.current, "Expected expression."); + tok_s : string; + tok_s.data = parse_state.previous.source; + tok_s.count = parse_state.previous.length; + expected_expression(parse_state, parse_state.previous, tprint("Expected expression after '%'.", tok_s)); // @Incomplete: Add error node here? return error_node(parse_state, "Expected expression."); } @@ -405,7 +452,11 @@ precedence :: (parse_state : *Parse_State, precedence : Precedence) -> *AST_Node while precedence <= get_rule(parse_state.current.kind).precedence { advance(parse_state); if parse_state.current.kind == .TOKEN_EOF { - expected_expression(parse_state, parse_state.current, "Reached end of file. Expected expression."); + tok_s : string; + tok_s.data = parse_state.previous.source; + tok_s.count = parse_state.previous.length; + expected_expression(parse_state, parse_state.current, tprint("Reached end of file. Expected expression after '%'.", tok_s)); + // expected_expression(parse_state, parse_state.current, "Reached end of file. Expected expression."); // @Incomplete: Add error node here? return null; } @@ -791,15 +842,12 @@ statement :: (parse_state : *Parse_State) -> *AST_Node { source_location : Source_Range; source_location.begin = parse_state.previous; - if_expression := expression(parse_state); - add_child(node, if_expression); - // consume(parse_state, .TOKEN_LEFTBRACE, "Expect '{' after if-condition."); + if_cond := expression(parse_state); + add_child(node, if_cond); source_location.end = parse_state.previous; if_body := block(parse_state); - if if_body.children.count > 0 { - add_child(node, if_body); - } + add_child(node, if_body); if match(parse_state, .TOKEN_ELSE) { else_node := else_statement(parse_state); @@ -809,6 +857,23 @@ statement :: (parse_state : *Parse_State) -> *AST_Node { node.source_location = source_location; return node; + } else if match(parse_state, .TOKEN_ELSE) { + if check(parse_state, .TOKEN_IF) { + else_if_without_if(parse_state); + advance_to_sync_point(parse_state); + if check(parse_state, .TOKEN_LEFTBRACE) { + return block(parse_state); + } + return error_node(parse_state, "'else if' without 'if'."); + } else { + else_without_if(parse_state); + advance_to_sync_point(parse_state); + if check(parse_state, .TOKEN_LEFTBRACE) { + return block(parse_state); + } + + return error_node(parse_state, "'else' without 'if'."); + } } else { return expression_statement(parse_state); } diff --git a/Semantic_Analysis.jai b/Semantic_Analysis.jai index 61625e3..14e3f16 100644 --- a/Semantic_Analysis.jai +++ b/Semantic_Analysis.jai @@ -524,7 +524,11 @@ if_condition_has_to_be_boolean_type :: (checker : *Semantic_Checker, usage_site indent(*builder, 1); var := from_handle(checker, handle); - print_to_builder(*builder, "% has type %\n", print_from_source_location(*usage_site.children[0].source_location), proper_type_to_string(checker, var)); + + usage_child := usage_site.children[0]; + usage_loc := usage_child.source_location; + + print_to_builder(*builder, "% has type %\n", print_from_source_location(*usage_loc), proper_type_to_string(checker, var)); message := builder_to_string(*builder,, temp); record_error(checker, message, usage_site.source_location, false); diff --git a/test/else_if_after_else.ink b/test/else_if_after_else.ink new file mode 100644 index 0000000..be4360d --- /dev/null +++ b/test/else_if_after_else.ink @@ -0,0 +1,10 @@ +vertex main :: (pos : float3 @position) -> float4 @position { + if 0 > 100 { + + } else { + + } else if 0 > 200 { + + } + return float4(0.0); +} diff --git a/test/if_cond_assign.ink b/test/if_cond_assign.ink new file mode 100644 index 0000000..7baa0fa --- /dev/null +++ b/test/if_cond_assign.ink @@ -0,0 +1,6 @@ +vertex main :: (pos : float3 @position) -> float4 @position { + if 0 = 100 { + return float4(pos, 1.0); + } + return float4(0.0); +} diff --git a/test/if_if_if.ink b/test/if_if_if.ink new file mode 100644 index 0000000..71e196e --- /dev/null +++ b/test/if_if_if.ink @@ -0,0 +1,6 @@ +vertex main :: (pos : float3 @position) -> float4 @position { + if if if 0 > 100 { + return float4(pos, 1.0); + } + return float4(0.0); +} diff --git a/test/lex/else_if_after_else.golden b/test/lex/else_if_after_else.golden new file mode 100644 index 0000000..8e04b09 --- /dev/null +++ b/test/lex/else_if_after_else.golden @@ -0,0 +1,39 @@ +{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_IDENTIFIER; ; index = 16 ; length = 3 line = 1 ; column = 16 ; value ='pos'; } +{kind = TOKEN_COLON; ; index = 20 ; length = 1 line = 1 ; column = 20 ; value =':'; } +{kind = TOKEN_IDENTIFIER; ; index = 22 ; length = 6 line = 1 ; column = 22 ; value ='float3'; } +{kind = TOKEN_AT; ; index = 29 ; length = 1 line = 1 ; column = 29 ; value ='@'; } +{kind = TOKEN_IDENTIFIER; ; index = 30 ; length = 8 line = 1 ; column = 30 ; value ='position'; } +{kind = TOKEN_RIGHTPAREN; ; index = 38 ; length = 1 line = 1 ; column = 38 ; value =')'; } +{kind = TOKEN_ARROW; ; index = 40 ; length = 2 line = 1 ; column = 40 ; value ='->'; } +{kind = TOKEN_IDENTIFIER; ; index = 43 ; length = 6 line = 1 ; column = 43 ; value ='float4'; } +{kind = TOKEN_AT; ; index = 50 ; length = 1 line = 1 ; column = 50 ; value ='@'; } +{kind = TOKEN_IDENTIFIER; ; index = 51 ; length = 8 line = 1 ; column = 51 ; value ='position'; } +{kind = TOKEN_LEFTBRACE; ; index = 60 ; length = 1 line = 1 ; column = 60 ; value ='{'; } +{kind = TOKEN_IF; ; index = 64 ; length = 2 line = 2 ; column = 0 ; value ='if'; } +{kind = TOKEN_INTLITERAL; ; index = 67 ; length = 1 line = 2 ; column = 3 ; value ='0'; } +{kind = TOKEN_GREATER; ; index = 69 ; length = 1 line = 2 ; column = 5 ; value ='>'; } +{kind = TOKEN_INTLITERAL; ; index = 71 ; length = 3 line = 2 ; column = 7 ; value ='100'; } +{kind = TOKEN_LEFTBRACE; ; index = 75 ; length = 1 line = 2 ; column = 11 ; value ='{'; } +{kind = TOKEN_RIGHTBRACE; ; index = 83 ; length = 1 line = 4 ; column = 0 ; value ='}'; } +{kind = TOKEN_ELSE; ; index = 85 ; length = 4 line = 4 ; column = 2 ; value ='else'; } +{kind = TOKEN_LEFTBRACE; ; index = 90 ; length = 1 line = 4 ; column = 7 ; value ='{'; } +{kind = TOKEN_RIGHTBRACE; ; index = 99 ; length = 1 line = 6 ; column = 4 ; value ='}'; } +{kind = TOKEN_ELSE; ; index = 101 ; length = 4 line = 6 ; column = 6 ; value ='else'; } +{kind = TOKEN_IF; ; index = 106 ; length = 2 line = 6 ; column = 11 ; value ='if'; } +{kind = TOKEN_INTLITERAL; ; index = 109 ; length = 1 line = 6 ; column = 14 ; value ='0'; } +{kind = TOKEN_GREATER; ; index = 111 ; length = 1 line = 6 ; column = 16 ; value ='>'; } +{kind = TOKEN_INTLITERAL; ; index = 113 ; length = 3 line = 6 ; column = 18 ; value ='200'; } +{kind = TOKEN_LEFTBRACE; ; index = 117 ; length = 1 line = 6 ; column = 22 ; value ='{'; } +{kind = TOKEN_RIGHTBRACE; ; index = 123 ; length = 1 line = 8 ; column = 0 ; value ='}'; } +{kind = TOKEN_RETURN; ; index = 127 ; length = 6 line = 9 ; column = 0 ; value ='return'; } +{kind = TOKEN_IDENTIFIER; ; index = 134 ; length = 6 line = 9 ; column = 7 ; value ='float4'; } +{kind = TOKEN_LEFTPAREN; ; index = 140 ; length = 1 line = 9 ; column = 13 ; value ='('; } +{kind = TOKEN_FLOATLITERAL; ; index = 141 ; length = 3 line = 9 ; column = 14 ; value ='0'; } +{kind = TOKEN_RIGHTPAREN; ; index = 144 ; length = 1 line = 9 ; column = 17 ; value =')'; } +{kind = TOKEN_SEMICOLON; ; index = 145 ; length = 1 line = 9 ; column = 18 ; value =';'; } +{kind = TOKEN_RIGHTBRACE; ; index = 148 ; length = 1 line = 10 ; column = 0 ; value ='}'; } +{kind = TOKEN_EOF; ; index = 151 ; length = 0 line = 11 ; column = 0 ; value =''; } diff --git a/test/lex/float_if_cond.golden b/test/lex/float_if_cond.golden new file mode 100644 index 0000000..38f1583 --- /dev/null +++ b/test/lex/float_if_cond.golden @@ -0,0 +1,35 @@ +{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_IDENTIFIER; ; index = 16 ; length = 3 line = 1 ; column = 16 ; value ='pos'; } +{kind = TOKEN_COLON; ; index = 20 ; length = 1 line = 1 ; column = 20 ; value =':'; } +{kind = TOKEN_IDENTIFIER; ; index = 22 ; length = 6 line = 1 ; column = 22 ; value ='float3'; } +{kind = TOKEN_AT; ; index = 29 ; length = 1 line = 1 ; column = 29 ; value ='@'; } +{kind = TOKEN_IDENTIFIER; ; index = 30 ; length = 8 line = 1 ; column = 30 ; value ='position'; } +{kind = TOKEN_RIGHTPAREN; ; index = 38 ; length = 1 line = 1 ; column = 38 ; value =')'; } +{kind = TOKEN_ARROW; ; index = 40 ; length = 2 line = 1 ; column = 40 ; value ='->'; } +{kind = TOKEN_IDENTIFIER; ; index = 43 ; length = 6 line = 1 ; column = 43 ; value ='float4'; } +{kind = TOKEN_AT; ; index = 50 ; length = 1 line = 1 ; column = 50 ; value ='@'; } +{kind = TOKEN_IDENTIFIER; ; index = 51 ; length = 8 line = 1 ; column = 51 ; value ='position'; } +{kind = TOKEN_LEFTBRACE; ; index = 60 ; length = 1 line = 1 ; column = 60 ; value ='{'; } +{kind = TOKEN_IF; ; index = 64 ; length = 2 line = 2 ; column = 0 ; value ='if'; } +{kind = TOKEN_FLOATLITERAL; ; index = 67 ; length = 3 line = 2 ; column = 3 ; value ='1'; } +{kind = TOKEN_LEFTBRACE; ; index = 71 ; length = 1 line = 2 ; column = 7 ; value ='{'; } +{kind = TOKEN_RETURN; ; index = 76 ; length = 6 line = 3 ; column = 0 ; value ='return'; } +{kind = TOKEN_IDENTIFIER; ; index = 83 ; length = 6 line = 3 ; column = 7 ; value ='float4'; } +{kind = TOKEN_LEFTPAREN; ; index = 89 ; length = 1 line = 3 ; column = 13 ; value ='('; } +{kind = TOKEN_IDENTIFIER; ; index = 90 ; length = 3 line = 3 ; column = 14 ; value ='pos'; } +{kind = TOKEN_COMMA; ; index = 93 ; length = 1 line = 3 ; column = 17 ; value =','; } +{kind = TOKEN_FLOATLITERAL; ; index = 95 ; length = 3 line = 3 ; column = 19 ; value ='1'; } +{kind = TOKEN_RIGHTPAREN; ; index = 98 ; length = 1 line = 3 ; column = 22 ; value =')'; } +{kind = TOKEN_SEMICOLON; ; index = 99 ; length = 1 line = 3 ; column = 23 ; value =';'; } +{kind = TOKEN_RIGHTBRACE; ; index = 103 ; length = 1 line = 4 ; column = 0 ; value ='}'; } +{kind = TOKEN_RETURN; ; index = 107 ; length = 6 line = 5 ; column = 0 ; value ='return'; } +{kind = TOKEN_IDENTIFIER; ; index = 114 ; length = 6 line = 5 ; column = 7 ; value ='float4'; } +{kind = TOKEN_LEFTPAREN; ; index = 120 ; length = 1 line = 5 ; column = 13 ; value ='('; } +{kind = TOKEN_FLOATLITERAL; ; index = 121 ; length = 3 line = 5 ; column = 14 ; value ='0'; } +{kind = TOKEN_RIGHTPAREN; ; index = 124 ; length = 1 line = 5 ; column = 17 ; value =')'; } +{kind = TOKEN_SEMICOLON; ; index = 125 ; length = 1 line = 5 ; column = 18 ; value =';'; } +{kind = TOKEN_RIGHTBRACE; ; index = 128 ; length = 1 line = 6 ; column = 0 ; value ='}'; } +{kind = TOKEN_EOF; ; index = 131 ; length = 0 line = 7 ; column = 0 ; value =''; } diff --git a/test/lex/if_cond_assign.golden b/test/lex/if_cond_assign.golden new file mode 100644 index 0000000..be22abf --- /dev/null +++ b/test/lex/if_cond_assign.golden @@ -0,0 +1,37 @@ +{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_IDENTIFIER; ; index = 16 ; length = 3 line = 1 ; column = 16 ; value ='pos'; } +{kind = TOKEN_COLON; ; index = 20 ; length = 1 line = 1 ; column = 20 ; value =':'; } +{kind = TOKEN_IDENTIFIER; ; index = 22 ; length = 6 line = 1 ; column = 22 ; value ='float3'; } +{kind = TOKEN_AT; ; index = 29 ; length = 1 line = 1 ; column = 29 ; value ='@'; } +{kind = TOKEN_IDENTIFIER; ; index = 30 ; length = 8 line = 1 ; column = 30 ; value ='position'; } +{kind = TOKEN_RIGHTPAREN; ; index = 38 ; length = 1 line = 1 ; column = 38 ; value =')'; } +{kind = TOKEN_ARROW; ; index = 40 ; length = 2 line = 1 ; column = 40 ; value ='->'; } +{kind = TOKEN_IDENTIFIER; ; index = 43 ; length = 6 line = 1 ; column = 43 ; value ='float4'; } +{kind = TOKEN_AT; ; index = 50 ; length = 1 line = 1 ; column = 50 ; value ='@'; } +{kind = TOKEN_IDENTIFIER; ; index = 51 ; length = 8 line = 1 ; column = 51 ; value ='position'; } +{kind = TOKEN_LEFTBRACE; ; index = 60 ; length = 1 line = 1 ; column = 60 ; value ='{'; } +{kind = TOKEN_IF; ; index = 64 ; length = 2 line = 2 ; column = 0 ; value ='if'; } +{kind = TOKEN_INTLITERAL; ; index = 67 ; length = 1 line = 2 ; column = 3 ; value ='0'; } +{kind = TOKEN_ASSIGN; ; index = 69 ; length = 1 line = 2 ; column = 5 ; value ='='; } +{kind = TOKEN_INTLITERAL; ; index = 71 ; length = 3 line = 2 ; column = 7 ; value ='100'; } +{kind = TOKEN_LEFTBRACE; ; index = 75 ; length = 1 line = 2 ; column = 11 ; value ='{'; } +{kind = TOKEN_RETURN; ; index = 80 ; length = 6 line = 3 ; column = 0 ; value ='return'; } +{kind = TOKEN_IDENTIFIER; ; index = 87 ; length = 6 line = 3 ; column = 7 ; value ='float4'; } +{kind = TOKEN_LEFTPAREN; ; index = 93 ; length = 1 line = 3 ; column = 13 ; value ='('; } +{kind = TOKEN_IDENTIFIER; ; index = 94 ; length = 3 line = 3 ; column = 14 ; value ='pos'; } +{kind = TOKEN_COMMA; ; index = 97 ; length = 1 line = 3 ; column = 17 ; value =','; } +{kind = TOKEN_FLOATLITERAL; ; index = 99 ; length = 3 line = 3 ; column = 19 ; value ='1'; } +{kind = TOKEN_RIGHTPAREN; ; index = 102 ; length = 1 line = 3 ; column = 22 ; value =')'; } +{kind = TOKEN_SEMICOLON; ; index = 103 ; length = 1 line = 3 ; column = 23 ; value =';'; } +{kind = TOKEN_RIGHTBRACE; ; index = 107 ; length = 1 line = 4 ; column = 0 ; value ='}'; } +{kind = TOKEN_RETURN; ; index = 111 ; length = 6 line = 5 ; column = 0 ; value ='return'; } +{kind = TOKEN_IDENTIFIER; ; index = 118 ; length = 6 line = 5 ; column = 7 ; value ='float4'; } +{kind = TOKEN_LEFTPAREN; ; index = 124 ; length = 1 line = 5 ; column = 13 ; value ='('; } +{kind = TOKEN_FLOATLITERAL; ; index = 125 ; length = 3 line = 5 ; column = 14 ; value ='0'; } +{kind = TOKEN_RIGHTPAREN; ; index = 128 ; length = 1 line = 5 ; column = 17 ; value =')'; } +{kind = TOKEN_SEMICOLON; ; index = 129 ; length = 1 line = 5 ; column = 18 ; value =';'; } +{kind = TOKEN_RIGHTBRACE; ; index = 132 ; length = 1 line = 6 ; column = 0 ; value ='}'; } +{kind = TOKEN_EOF; ; index = 135 ; length = 0 line = 7 ; column = 0 ; value =''; } diff --git a/test/lex/if_if_if.golden b/test/lex/if_if_if.golden new file mode 100644 index 0000000..476a91c --- /dev/null +++ b/test/lex/if_if_if.golden @@ -0,0 +1,39 @@ +{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_IDENTIFIER; ; index = 16 ; length = 3 line = 1 ; column = 16 ; value ='pos'; } +{kind = TOKEN_COLON; ; index = 20 ; length = 1 line = 1 ; column = 20 ; value =':'; } +{kind = TOKEN_IDENTIFIER; ; index = 22 ; length = 6 line = 1 ; column = 22 ; value ='float3'; } +{kind = TOKEN_AT; ; index = 29 ; length = 1 line = 1 ; column = 29 ; value ='@'; } +{kind = TOKEN_IDENTIFIER; ; index = 30 ; length = 8 line = 1 ; column = 30 ; value ='position'; } +{kind = TOKEN_RIGHTPAREN; ; index = 38 ; length = 1 line = 1 ; column = 38 ; value =')'; } +{kind = TOKEN_ARROW; ; index = 40 ; length = 2 line = 1 ; column = 40 ; value ='->'; } +{kind = TOKEN_IDENTIFIER; ; index = 43 ; length = 6 line = 1 ; column = 43 ; value ='float4'; } +{kind = TOKEN_AT; ; index = 50 ; length = 1 line = 1 ; column = 50 ; value ='@'; } +{kind = TOKEN_IDENTIFIER; ; index = 51 ; length = 8 line = 1 ; column = 51 ; value ='position'; } +{kind = TOKEN_LEFTBRACE; ; index = 60 ; length = 1 line = 1 ; column = 60 ; value ='{'; } +{kind = TOKEN_IF; ; index = 64 ; length = 2 line = 2 ; column = 0 ; value ='if'; } +{kind = TOKEN_IF; ; index = 67 ; length = 2 line = 2 ; column = 3 ; value ='if'; } +{kind = TOKEN_IF; ; index = 70 ; length = 2 line = 2 ; column = 6 ; value ='if'; } +{kind = TOKEN_INTLITERAL; ; index = 73 ; length = 1 line = 2 ; column = 9 ; value ='0'; } +{kind = TOKEN_GREATER; ; index = 75 ; length = 1 line = 2 ; column = 11 ; value ='>'; } +{kind = TOKEN_INTLITERAL; ; index = 77 ; length = 3 line = 2 ; column = 13 ; value ='100'; } +{kind = TOKEN_LEFTBRACE; ; index = 81 ; length = 1 line = 2 ; column = 17 ; value ='{'; } +{kind = TOKEN_RETURN; ; index = 86 ; length = 6 line = 3 ; column = 0 ; value ='return'; } +{kind = TOKEN_IDENTIFIER; ; index = 93 ; length = 6 line = 3 ; column = 7 ; value ='float4'; } +{kind = TOKEN_LEFTPAREN; ; index = 99 ; length = 1 line = 3 ; column = 13 ; value ='('; } +{kind = TOKEN_IDENTIFIER; ; index = 100 ; length = 3 line = 3 ; column = 14 ; value ='pos'; } +{kind = TOKEN_COMMA; ; index = 103 ; length = 1 line = 3 ; column = 17 ; value =','; } +{kind = TOKEN_FLOATLITERAL; ; index = 105 ; length = 3 line = 3 ; column = 19 ; value ='1'; } +{kind = TOKEN_RIGHTPAREN; ; index = 108 ; length = 1 line = 3 ; column = 22 ; value =')'; } +{kind = TOKEN_SEMICOLON; ; index = 109 ; length = 1 line = 3 ; column = 23 ; value =';'; } +{kind = TOKEN_RIGHTBRACE; ; index = 113 ; length = 1 line = 4 ; column = 0 ; value ='}'; } +{kind = TOKEN_RETURN; ; index = 117 ; length = 6 line = 5 ; column = 0 ; value ='return'; } +{kind = TOKEN_IDENTIFIER; ; index = 124 ; length = 6 line = 5 ; column = 7 ; value ='float4'; } +{kind = TOKEN_LEFTPAREN; ; index = 130 ; length = 1 line = 5 ; column = 13 ; value ='('; } +{kind = TOKEN_FLOATLITERAL; ; index = 131 ; length = 3 line = 5 ; column = 14 ; value ='0'; } +{kind = TOKEN_RIGHTPAREN; ; index = 134 ; length = 1 line = 5 ; column = 17 ; value =')'; } +{kind = TOKEN_SEMICOLON; ; index = 135 ; length = 1 line = 5 ; column = 18 ; value =';'; } +{kind = TOKEN_RIGHTBRACE; ; index = 138 ; length = 1 line = 6 ; column = 0 ; value ='}'; } +{kind = TOKEN_EOF; ; index = 141 ; length = 0 line = 7 ; column = 0 ; value =''; } diff --git a/test/lex_all.suite b/test/lex_all.suite index b4e73d5..26a696d 100644 --- a/test/lex_all.suite +++ b/test/lex_all.suite @@ -2,17 +2,21 @@ test/assign_arithmetic_expression.ink lex test/basic_property_and_return_value.ink lex test/complicated_computation.ink lex test/constant_buffer.ink lex +test/else_if_after_else.ink lex test/empty_struct.ink lex test/empty_vertex_main.ink lex test/empty_vertex_main_with_position_parameter.ink lex test/field_assignment.ink lex test/field_without_type_specifier.ink lex test/float_suffix.ink lex +test/float_if_cond.ink lex test/function_call.ink lex test/function_call_out_of_order_declaration.ink lex test/function_call_return.ink lex test/functions_with_same_name.ink lex test/function_with_int_return.ink lex +test/if_cond_assign.ink lex +test/if_if_if.ink lex test/inferred_types.ink lex test/meta_block.ink lex test/multiple_functions.ink lex diff --git a/test/parse/else_if_after_else.golden b/test/parse/else_if_after_else.golden new file mode 100644 index 0000000..e7796d4 --- /dev/null +++ b/test/parse/else_if_after_else.golden @@ -0,0 +1,4 @@ +test/else_if_after_else.ink:6,6: error: 'else if' without 'if' +  } else if 0 > 200 { + ^^^^ + \ No newline at end of file diff --git a/test/parse/float_if_cond.golden b/test/parse/float_if_cond.golden new file mode 100644 index 0000000..19b9cad --- /dev/null +++ b/test/parse/float_if_cond.golden @@ -0,0 +1,6 @@ +(program + (fun vertex vs_main -> float4 (@position) + [(:= pos float3 (@position))] + (if 1 + (return (float4 pos 1))) + (return (float4 0)))) \ No newline at end of file diff --git a/test/parse/if_cond_assign.golden b/test/parse/if_cond_assign.golden new file mode 100644 index 0000000..508188f --- /dev/null +++ b/test/parse/if_cond_assign.golden @@ -0,0 +1,6 @@ +(program + (fun vertex vs_main -> float4 (@position) + [(:= pos float3 (@position))] + (if (= 0 100) + (return (float4 pos 1))) + (return (float4 0)))) \ No newline at end of file diff --git a/test/parse/if_if_if.golden b/test/parse/if_if_if.golden new file mode 100644 index 0000000..c63be74 --- /dev/null +++ b/test/parse/if_if_if.golden @@ -0,0 +1,4 @@ +test/if_if_if.ink:2,3: error: Expected expression after 'if'. + if if if 0 > 100 { + ^^ + \ No newline at end of file diff --git a/test/parse_all.suite b/test/parse_all.suite index 30b4b93..f43cd0e 100644 --- a/test/parse_all.suite +++ b/test/parse_all.suite @@ -2,17 +2,21 @@ test/assign_arithmetic_expression.ink parse test/basic_property_and_return_value.ink parse test/complicated_computation.ink parse test/constant_buffer.ink parse +test/else_if_after_else.ink parse test/empty_struct.ink parse test/empty_vertex_main.ink parse test/empty_vertex_main_with_position_parameter.ink parse test/field_assignment.ink parse test/field_without_type_specifier.ink parse +test/float_if_cond.ink parse test/float_suffix.ink parse test/function_call.ink parse test/function_call_out_of_order_declaration.ink parse test/function_call_return.ink parse test/functions_with_same_name.ink parse test/function_with_int_return.ink parse +test/if_cond_assign.ink parse +test/if_if_if.ink parse test/inferred_types.ink parse test/meta_block.ink parse test/multiple_functions.ink parse diff --git a/test/semant/float_if_cond.golden b/test/semant/float_if_cond.golden new file mode 100644 index 0000000..3cdaf2b --- /dev/null +++ b/test/semant/float_if_cond.golden @@ -0,0 +1,6 @@ +test/float_if_cond.ink:0,0: error: Type of expression in if condition has to be bool. + if 1.0 + ^^^ + 1.0 has type float + + \ No newline at end of file diff --git a/test/semant/if_cond_assign.golden b/test/semant/if_cond_assign.golden new file mode 100644 index 0000000..2fa9f46 --- /dev/null +++ b/test/semant/if_cond_assign.golden @@ -0,0 +1,6 @@ +test/if_cond_assign.ink:0,0: error: Type of expression in if condition has to be bool. + if 0 = 100 + ^^^^^^ + if 0 = 100 { has type int + + \ No newline at end of file diff --git a/test/semant/simple_if.golden b/test/semant/simple_if.golden new file mode 100644 index 0000000..7d9b85d --- /dev/null +++ b/test/semant/simple_if.golden @@ -0,0 +1,6 @@ +scope (global) [ + [vertex__vs_main] : (pos : float3) -> float4 + scope (vertex__vs_main) [ + [pos] : float3 + ] +] diff --git a/test/semant/simple_if_else.golden b/test/semant/simple_if_else.golden new file mode 100644 index 0000000..7d9b85d --- /dev/null +++ b/test/semant/simple_if_else.golden @@ -0,0 +1,6 @@ +scope (global) [ + [vertex__vs_main] : (pos : float3) -> float4 + scope (vertex__vs_main) [ + [pos] : float3 + ] +] diff --git a/test/semant/wrong_type_for_function.golden b/test/semant/wrong_type_for_function.golden index 7f42213..f9d22c8 100644 --- a/test/semant/wrong_type_for_function.golden +++ b/test/semant/wrong_type_for_function.golden @@ -7,7 +7,20 @@  color : float4 = float4(y, 1.0, 1.0, 1.0); ^  Possible overloads: - foreign float4 :: (float, float, float, float) -> float4; (test/wrong_type_for_function.ink:78) + foreign float4 :: (float, float, float, float) -> float4; (test/wrong_type_for_function.ink:86) + foreign float4 :: (float4) -> float4; (test/wrong_type_for_function.ink:87) + foreign float4 :: (float2, float2) -> float4; (test/wrong_type_for_function.ink:88) + foreign float4 :: (float2, float, float) -> float4; (test/wrong_type_for_function.ink:89) + foreign float4 :: (float, float2, float) -> float4; (test/wrong_type_for_function.ink:90) + foreign float4 :: (float, float2, float) -> float4; (test/wrong_type_for_function.ink:90) + foreign float4 :: (float, float, float2) -> float4; (test/wrong_type_for_function.ink:91) + foreign float4 :: (float, float, float2) -> float4; (test/wrong_type_for_function.ink:91) + foreign float4 :: (float3, float) -> float4; (test/wrong_type_for_function.ink:92) + foreign float4 :: (float3, float) -> float4; (test/wrong_type_for_function.ink:92) + foreign float4 :: (float, float3) -> float4; (test/wrong_type_for_function.ink:93) + foreign float4 :: (float, float3) -> float4; (test/wrong_type_for_function.ink:93) + foreign float4 :: (float) -> float4; (test/wrong_type_for_function.ink:94) + foreign float4 :: (float) -> float4; (test/wrong_type_for_function.ink:94) test/wrong_type_for_function.ink:11,24: error: Type mismatch. Expected float got float2  found: diff --git a/test/semant_all.suite b/test/semant_all.suite index 0108363..d0bd7b9 100644 --- a/test/semant_all.suite +++ b/test/semant_all.suite @@ -1,3 +1,4 @@ + test/assign_arithmetic_expression.ink semant test/basic_property_and_return_value.ink semant test/complicated_computation.ink semant @@ -11,6 +12,7 @@ test/function_call_out_of_order_declaration.ink semant test/function_call_return.ink semant test/functions_with_same_name.ink semant test/function_with_int_return.ink semant +test/if_cond_assign.ink semant test/inferred_types.ink semant test/multiple_functions.ink semant test/multiple_semicolons_everywhere.ink semant