From 42c5baa8464bfc79ff3c21bb2e23b948bb0c1de3 Mon Sep 17 00:00:00 2001 From: Niels Bross Date: Mon, 20 Jan 2025 22:20:47 +0100 Subject: [PATCH] if else if else if if else if else --- Codegen.jai | 74 +++++++++++++++++++++++++----- Semantic_Analysis.jai | 6 +++ test/codegen/nested_if.golden | 18 ++++++++ test/codegen/simple_else_if.golden | 17 +++++++ test/codegen/simple_if.golden | 10 ++++ test/codegen/simple_if_else.golden | 13 ++++++ test/codegen_all.suite | 1 + test/lex/nested_if.golden | 64 ++++++++++++++++++++++++++ test/lex_all.suite | 1 + test/nested_if.ink | 11 +++++ test/parse/nested_if.golden | 9 ++++ test/parse_all.suite | 1 + test/semant/nested_if.golden | 6 +++ test/semant_all.suite | 1 + 14 files changed, 220 insertions(+), 12 deletions(-) create mode 100644 test/codegen/nested_if.golden create mode 100644 test/codegen/simple_else_if.golden create mode 100644 test/codegen/simple_if.golden create mode 100644 test/codegen/simple_if_else.golden create mode 100644 test/lex/nested_if.golden create mode 100644 test/nested_if.ink create mode 100644 test/parse/nested_if.golden create mode 100644 test/semant/nested_if.golden diff --git a/Codegen.jai b/Codegen.jai index e03eaea..5a980a7 100644 --- a/Codegen.jai +++ b/Codegen.jai @@ -37,6 +37,25 @@ Codegen_Result :: struct { result_text : string; // @Incomplete(nb): Result for now, should likely be far more sophisticated. } +Reserved_HLSL_Words :: string.[ + "texture", + "sampler", + "matrix", + "line", + "precise", + "shared", + "triangle", + "triangleadj", +]; + +Reserved_MLSL_Words :: string.[ + "" +]; + +Reserved_GLSL_Words :: string.[ + "" +]; + init_codegen_state :: (state : *Codegen_State, root : *AST_Node, checker_result : Semantic_Check_Result, output_language : Output_Language) { state.root = root; state.scope_stack = checker_result.scope_stack; @@ -50,7 +69,7 @@ indent :: (state : *Codegen_State, indentation : int) { for 1..indentation append(*state.builder, " "); } -dx11_type_to_string :: (type_variable : Type_Variable) -> string { +hlsl_type_to_string :: (type_variable : Type_Variable) -> string { if type_variable.type == { case .Invalid; return "{{invalid}}"; @@ -92,7 +111,7 @@ emit_field :: (state : *Codegen_State, node : *AST_Node, indentation : int) { indent(state, indentation); - print_to_builder(*state.builder, "% ", dx11_type_to_string(field)); + print_to_builder(*state.builder, "% ", hlsl_type_to_string(field)); if field.struct_field_parent { parent_tv := from_handle(state.type_variables, field.struct_field_parent.type_variable); @@ -111,13 +130,19 @@ emit_field :: (state : *Codegen_State, node : *AST_Node, indentation : int) { print_to_builder(*state.builder, " : register(t%)", field.resource_index); } - for i :0..node.children.count - 1 { - child := node.children[i]; + if node.children.count == 1 { + child := node.children[0]; print_to_builder(*state.builder, " = "); emit_node(state, child, 0); + } + if node.parent.kind == .Block { + append(*state.builder, ";"); + } + + for i :0..field.children.count - 1 { child := from_handle(state.type_variables, field.children[i]); emit_node(state, child.source_node, 0); @@ -140,7 +165,7 @@ emit_block :: (state : *Codegen_State, node : *AST_Node, indentation : int) { emit_node(state, statement, indentation); if it_index < node.children.count { - append(*state.builder, ";\n"); + append(*state.builder, "\n"); } } } @@ -256,7 +281,7 @@ emit_function :: (state : *Codegen_State, node : *AST_Node, indentation : int, e if function_variable.return_type_variable { return_variable := from_handle(state.type_variables, function_variable.return_type_variable); - print_to_builder(*state.builder, "% ", dx11_type_to_string(return_variable)); + print_to_builder(*state.builder, "% ", hlsl_type_to_string(return_variable)); } else { append(*state.builder, "void "); } @@ -428,6 +453,7 @@ emit_node :: (state : *Codegen_State, node : *AST_Node, indentation : int) { } case .Expression_Statement; { emit_node(state, node.children[0], indentation); + append(*state.builder, ";"); } case .Call; { emit_call(state, node, indentation); @@ -436,27 +462,51 @@ emit_node :: (state : *Codegen_State, node : *AST_Node, indentation : int) { indent(*state.builder, indentation); append(*state.builder, "return "); emit_node(state, node.children[0], 0); + append(*state.builder, ";"); } case .If; { - indent(*state.builder, indentation); + if node.parent.kind != .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); + append(*state.builder, "\n"); + indent(*state.builder, indentation); + append(*state.builder, "{\n"); - if node.children.count == 2 { - emit_else(state, node.children[2]); + emit_block(state, body, indentation + 1); + + indent(*state.builder, indentation); + append(*state.builder, "}\n"); + + if node.children.count == 3 { + emit_else(state, node.children[2], indentation); } } } } -emit_else :: (state : *Codegen_State, node : *AST_Node) { +emit_else :: (state : *Codegen_State, node : *AST_Node, indentation : int) { + indent(*state.builder, indentation); append(*state.builder, "else "); - emit_node(state, node.children[0], 0); + + if node.kind == .If { + emit_node(state, node, indentation); + } else if node.kind == .Block { + append(*state.builder, "\n"); + indent(*state.builder, indentation); + append(*state.builder, "{\n"); + + emit_block(state, node, indentation + 1); + + indent(*state.builder, indentation); + append(*state.builder, "}"); + } } emit_field_list :: (state : *Codegen_State, field_list : *AST_Node, indentation : int) { diff --git a/Semantic_Analysis.jai b/Semantic_Analysis.jai index 14e3f16..b515ae5 100644 --- a/Semantic_Analysis.jai +++ b/Semantic_Analysis.jai @@ -1502,6 +1502,12 @@ check_node :: (checker : *Semantic_Checker, node : *AST_Node) -> Type_Variable_H if_condition_has_to_be_boolean_type(checker, node, cond_var); } } + + body_var := check_block(checker, node.children[1]); + + if node.children.count == 3 { + else_var := check_node(checker, node.children[2]); + } } case .Variable; { return create_variable(checker, node); diff --git a/test/codegen/nested_if.golden b/test/codegen/nested_if.golden new file mode 100644 index 0000000..828f34e --- /dev/null +++ b/test/codegen/nested_if.golden @@ -0,0 +1,18 @@ +float4 vs_main(float3 pos : POSITION) : SV_POSITION +{ + if (pos.x > 100) + { + if (pos.x > 50) + { + return float4(pos, 1.0f); + } + else + { + return float4(1.0f); + } + return float4(pos, 1.0f); + } + + return float4(0.0f); +} + diff --git a/test/codegen/simple_else_if.golden b/test/codegen/simple_else_if.golden new file mode 100644 index 0000000..c9197f6 --- /dev/null +++ b/test/codegen/simple_else_if.golden @@ -0,0 +1,17 @@ +float4 vs_main(float3 pos : POSITION) : SV_POSITION +{ + if (pos.x > 100) + { + return float4(pos, 1.0f); + } + else if (pos.x > 50) + { + return float4(pos, 1.0f); + } + else + { + return float4(1.0f); + } + return float4(0.0f); +} + diff --git a/test/codegen/simple_if.golden b/test/codegen/simple_if.golden new file mode 100644 index 0000000..05588f3 --- /dev/null +++ b/test/codegen/simple_if.golden @@ -0,0 +1,10 @@ +float4 vs_main(float3 pos : POSITION) : SV_POSITION +{ + if (0 > 100) + { + return float4(pos, 1.0f); + } + + return float4(0.0f); +} + diff --git a/test/codegen/simple_if_else.golden b/test/codegen/simple_if_else.golden new file mode 100644 index 0000000..a59b39f --- /dev/null +++ b/test/codegen/simple_if_else.golden @@ -0,0 +1,13 @@ +float4 vs_main(float3 pos : POSITION) : SV_POSITION +{ + if (0 > 100) + { + return float4(pos, 1.0f); + } + else + { + return float4(1.0f); + } + return float4(0.0f); +} + diff --git a/test/codegen_all.suite b/test/codegen_all.suite index 1dd698b..3108a84 100644 --- a/test/codegen_all.suite +++ b/test/codegen_all.suite @@ -13,6 +13,7 @@ test/inferred_types.ink codegen test/meta_block.ink codegen test/multiple_functions.ink codegen 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/property_rename.ink codegen diff --git a/test/lex/nested_if.golden b/test/lex/nested_if.golden new file mode 100644 index 0000000..8a8e101 --- /dev/null +++ b/test/lex/nested_if.golden @@ -0,0 +1,64 @@ +{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_IDENTIFIER; ; index = 67 ; length = 3 line = 2 ; column = 3 ; value ='pos'; } +{kind = TOKEN_DOT; ; index = 70 ; length = 1 line = 2 ; column = 6 ; value ='.'; } +{kind = TOKEN_IDENTIFIER; ; index = 71 ; length = 1 line = 2 ; column = 7 ; value ='x'; } +{kind = TOKEN_GREATER; ; index = 73 ; length = 1 line = 2 ; column = 9 ; value ='>'; } +{kind = TOKEN_INTLITERAL; ; index = 75 ; length = 3 line = 2 ; column = 11 ; value ='100'; } +{kind = TOKEN_LEFTBRACE; ; index = 79 ; length = 1 line = 2 ; column = 15 ; value ='{'; } +{kind = TOKEN_IF; ; index = 84 ; length = 2 line = 3 ; column = 0 ; value ='if'; } +{kind = TOKEN_IDENTIFIER; ; index = 87 ; length = 3 line = 3 ; column = 3 ; value ='pos'; } +{kind = TOKEN_DOT; ; index = 90 ; length = 1 line = 3 ; column = 6 ; value ='.'; } +{kind = TOKEN_IDENTIFIER; ; index = 91 ; length = 1 line = 3 ; column = 7 ; value ='x'; } +{kind = TOKEN_GREATER; ; index = 93 ; length = 1 line = 3 ; column = 9 ; value ='>'; } +{kind = TOKEN_INTLITERAL; ; index = 95 ; length = 2 line = 3 ; column = 11 ; value ='50'; } +{kind = TOKEN_LEFTBRACE; ; index = 98 ; length = 1 line = 3 ; column = 14 ; value ='{'; } +{kind = TOKEN_RETURN; ; index = 104 ; length = 6 line = 4 ; column = 0 ; value ='return'; } +{kind = TOKEN_IDENTIFIER; ; index = 111 ; length = 6 line = 4 ; column = 7 ; value ='float4'; } +{kind = TOKEN_LEFTPAREN; ; index = 117 ; length = 1 line = 4 ; column = 13 ; value ='('; } +{kind = TOKEN_IDENTIFIER; ; index = 118 ; length = 3 line = 4 ; column = 14 ; value ='pos'; } +{kind = TOKEN_COMMA; ; index = 121 ; length = 1 line = 4 ; column = 17 ; value =','; } +{kind = TOKEN_FLOATLITERAL; ; index = 123 ; length = 3 line = 4 ; column = 19 ; value ='1'; } +{kind = TOKEN_RIGHTPAREN; ; index = 126 ; length = 1 line = 4 ; column = 22 ; value =')'; } +{kind = TOKEN_SEMICOLON; ; index = 127 ; length = 1 line = 4 ; column = 23 ; value =';'; } +{kind = TOKEN_RIGHTBRACE; ; index = 132 ; length = 1 line = 5 ; column = 0 ; value ='}'; } +{kind = TOKEN_ELSE; ; index = 134 ; length = 4 line = 5 ; column = 2 ; value ='else'; } +{kind = TOKEN_LEFTBRACE; ; index = 139 ; length = 1 line = 5 ; column = 7 ; value ='{'; } +{kind = TOKEN_RETURN; ; index = 145 ; length = 6 line = 6 ; column = 0 ; value ='return'; } +{kind = TOKEN_IDENTIFIER; ; index = 152 ; length = 6 line = 6 ; column = 7 ; value ='float4'; } +{kind = TOKEN_LEFTPAREN; ; index = 158 ; length = 1 line = 6 ; column = 13 ; value ='('; } +{kind = TOKEN_FLOATLITERAL; ; index = 159 ; length = 3 line = 6 ; column = 14 ; value ='1'; } +{kind = TOKEN_RIGHTPAREN; ; index = 162 ; length = 1 line = 6 ; column = 17 ; value =')'; } +{kind = TOKEN_SEMICOLON; ; index = 163 ; length = 1 line = 6 ; column = 18 ; value =';'; } +{kind = TOKEN_RIGHTBRACE; ; index = 168 ; length = 1 line = 7 ; column = 0 ; value ='}'; } +{kind = TOKEN_RETURN; ; index = 173 ; length = 6 line = 8 ; column = 0 ; value ='return'; } +{kind = TOKEN_IDENTIFIER; ; index = 180 ; length = 6 line = 8 ; column = 7 ; value ='float4'; } +{kind = TOKEN_LEFTPAREN; ; index = 186 ; length = 1 line = 8 ; column = 13 ; value ='('; } +{kind = TOKEN_IDENTIFIER; ; index = 187 ; length = 3 line = 8 ; column = 14 ; value ='pos'; } +{kind = TOKEN_COMMA; ; index = 190 ; length = 1 line = 8 ; column = 17 ; value =','; } +{kind = TOKEN_FLOATLITERAL; ; index = 192 ; length = 3 line = 8 ; column = 19 ; value ='1'; } +{kind = TOKEN_RIGHTPAREN; ; index = 195 ; length = 1 line = 8 ; column = 22 ; value =')'; } +{kind = TOKEN_SEMICOLON; ; index = 196 ; length = 1 line = 8 ; column = 23 ; value =';'; } +{kind = TOKEN_RIGHTBRACE; ; index = 200 ; length = 1 line = 9 ; column = 0 ; value ='}'; } +{kind = TOKEN_RETURN; ; index = 205 ; length = 6 line = 10 ; column = 0 ; value ='return'; } +{kind = TOKEN_IDENTIFIER; ; index = 212 ; length = 6 line = 10 ; column = 7 ; value ='float4'; } +{kind = TOKEN_LEFTPAREN; ; index = 218 ; length = 1 line = 10 ; column = 13 ; value ='('; } +{kind = TOKEN_FLOATLITERAL; ; index = 219 ; length = 3 line = 10 ; column = 14 ; value ='0'; } +{kind = TOKEN_RIGHTPAREN; ; index = 222 ; length = 1 line = 10 ; column = 17 ; value =')'; } +{kind = TOKEN_SEMICOLON; ; index = 223 ; length = 1 line = 10 ; column = 18 ; value =';'; } +{kind = TOKEN_RIGHTBRACE; ; index = 226 ; length = 1 line = 11 ; column = 0 ; value ='}'; } +{kind = TOKEN_EOF; ; index = 229 ; length = 0 line = 12 ; column = 0 ; value =''; } diff --git a/test/lex_all.suite b/test/lex_all.suite index 26a696d..613e14d 100644 --- a/test/lex_all.suite +++ b/test/lex_all.suite @@ -21,6 +21,7 @@ test/inferred_types.ink lex test/meta_block.ink lex test/multiple_functions.ink lex test/multiple_semicolons_everywhere.ink lex +test/nested_if.ink lex test/non_bool_cond.ink lex test/pass_and_access_struct_fields_in_functions.ink lex test/passthrough.ink lex diff --git a/test/nested_if.ink b/test/nested_if.ink new file mode 100644 index 0000000..6ab592b --- /dev/null +++ b/test/nested_if.ink @@ -0,0 +1,11 @@ +vertex main :: (pos : float3 @position) -> float4 @position { + if pos.x > 100 { + if pos.x > 50 { + return float4(pos, 1.0); + } else { + return float4(1.0); + } + return float4(pos, 1.0); + } + return float4(0.0); +} diff --git a/test/parse/nested_if.golden b/test/parse/nested_if.golden new file mode 100644 index 0000000..80608cf --- /dev/null +++ b/test/parse/nested_if.golden @@ -0,0 +1,9 @@ +(program + (fun vertex vs_main -> float4 (@position) + [(:= pos float3 (@position))] + (if (> pos.x 100) + (if (> pos.x 50) + (return (float4 pos 1)) + (return (float4 1))) + (return (float4 pos 1))) + (return (float4 0)))) \ No newline at end of file diff --git a/test/parse_all.suite b/test/parse_all.suite index f43cd0e..1a7e38b 100644 --- a/test/parse_all.suite +++ b/test/parse_all.suite @@ -21,6 +21,7 @@ test/inferred_types.ink parse test/meta_block.ink parse test/multiple_functions.ink parse test/multiple_semicolons_everywhere.ink parse +test/nested_if.ink parse test/non_bool_cond.ink parse test/pass_and_access_struct_fields_in_functions.ink parse test/passthrough.ink parse diff --git a/test/semant/nested_if.golden b/test/semant/nested_if.golden new file mode 100644 index 0000000..7d9b85d --- /dev/null +++ b/test/semant/nested_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_all.suite b/test/semant_all.suite index d0bd7b9..feb7162 100644 --- a/test/semant_all.suite +++ b/test/semant_all.suite @@ -16,6 +16,7 @@ test/if_cond_assign.ink semant test/inferred_types.ink semant test/multiple_functions.ink semant test/multiple_semicolons_everywhere.ink semant +test/nested_if.ink semant test/non_bool_cond.ink semant test/pass_and_access_struct_fields_in_functions.ink semant test/passthrough.ink semant