From c5bc4c57eba6f052907f2545d32c5b1af2c8bf22 Mon Sep 17 00:00:00 2001 From: Aditya Narayanan S <125679153+adityanarayanan343@users.noreply.github.com> Date: Thu, 29 Aug 2024 14:04:05 +0530 Subject: [PATCH] Added else if Conditional Statements to the Metal backend #34 (#39) * Added else if Conditional Statements to the Metal backend #34 * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fix: Fixed the code for the mentioned issues #34 * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Minor Fixes * Fixed and Ran tests for issue #34 * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Minor Fixes for else_if in MetalCrossGLCodeGen. * Added If test condition * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Minor Fixes * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fixing else if output for test cases * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Minor Fixes * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fix: Fixed Parser * Fixed MetalParser.py * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fix: Made requested changes for the MetalParser.py * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fix : Made the changes in Metalparser.py * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Minor Fixes * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fix: fixed multiple else if statement generation --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: samthakur587 --- .DS_Store | Bin 0 -> 6148 bytes crosstl/src/backend/Metal/MetalAst.py | 8 +-- .../src/backend/Metal/MetalCrossGLCodeGen.py | 21 +++++-- crosstl/src/backend/Metal/MetalLexer.py | 2 + crosstl/src/backend/Metal/MetalParser.py | 25 ++++++-- tests/test_backend/test_metal/test_codegen.py | 58 ++++++++++++++++++ tests/test_backend/test_metal/test_lexer.py | 29 ++++++++- tests/test_backend/test_metal/test_parser.py | 29 +++++++++ 8 files changed, 154 insertions(+), 18 deletions(-) create mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..69de13bc78bf45ebb6050bbf67b78be53c41594f GIT binary patch literal 6148 zcmeHKI|>3p3{6x}u(7n9D|mxJ^aNf&)N*0LPrsGt@@T$%5M{Lz8+n1`&1Ca-m{)8z zBBIO7VIeXTkqO*Tt`_=c&&_)_$czHvc*jZ3(i~3vX4m$r-zSVamc1OM1^bELHtz|{ zQUNMJ1*iZOpaNehV7(VMnFcaa0V+TR9tzm^p}-AmVi)M24g?cu=ZI3SS$go ziCrKvFbyg&sG1{&1|9j5bv3aI47z9zADSm?PAKZ9 + using namespace metal; + struct Vertex_INPUT { + float3 position [[attribute(0)]]; + }; + + struct Vertex_OUTPUT { + float4 position [[position]]; + float2 vUV; + }; + + vertex Vertex_OUTPUT vertex_main(Vertex_INPUT input [[stage_in]]) { + Vertex_OUTPUT output; + output.position = float4(input.position, 1.0); + if (input.position.x == input.position.y) { + output.vUV = float2(0.0, 0.0);} + + else if (input.position.x > input.position.y) { + output.vUV = float2(1.0, 1.0); + } + else if (input.position.x < input.position.y) { + output.vUV = float2(-1.0, -1.0); + } + else { + output.vUV = float2(0.0, 0.0); + } + return output; + } + + struct Fragment_INPUT { + float2 vUV [[stage_in]]; + }; + + struct Fragment_OUTPUT { + float4 fragColor [[color(0)]]; + }; + + fragment Fragment_OUTPUT fragment_main(Fragment_INPUT input [[stage_in]]) { + Fragment_OUTPUT output; + if (input.vUV.x == input.vUV.y) { + output.fragColor = float4(0.0, 1.0, 0.0, 1.0); + } else if (input.vUV.x > input.vUV.y) { + output.fragColor = float4(1.0, 0.0, 0.0, 1.0); + } else { + output.fragColor = float4(0.0, 0.0, 1.0, 1.0); + } + return output; + } + """ + + tokens = tokenize_code(code) + ast = parse_code(tokens) + generated_code = generate_code(ast) + print(generated_code) + + if __name__ == "__main__": pytest.main() diff --git a/tests/test_backend/test_metal/test_lexer.py b/tests/test_backend/test_metal/test_lexer.py index 154f7d69..9ade73a4 100644 --- a/tests/test_backend/test_metal/test_lexer.py +++ b/tests/test_backend/test_metal/test_lexer.py @@ -6,7 +6,7 @@ def tokenize_code(code: str) -> List: """Helper function to tokenize code.""" lexer = MetalLexer(code) - return lexer.tokenize() + return lexer.tokens def test_struct_tokenization(): @@ -20,8 +20,10 @@ def test_struct_tokenization(): float2 vUV; }; """ - tokens = tokenize_code(code) - print(tokens) + try: + tokenize_code(code) + except SyntaxError: + pytest.fail("Struct tokenization not implemented.") def test_if_tokenization(): @@ -103,5 +105,26 @@ def test_function_call_tokenization(): pytest.fail("Function call tokenization not implemented.") +def test_if_else_tokenization(): + code = """ + float perlinNoise(float2 p) { + if (p.x == p.y) { + return 0.0; + } + else if (p.x == 0.0) { + return 1.0; + } + + else { + return fract(sin(dot(p, float2(12.9898, 78.233))) * 43758.5453); + } + } + """ + try: + tokenize_code(code) + except SyntaxError: + pytest.fail("If-else statement tokenization not implemented.") + + if __name__ == "__main__": pytest.main() diff --git a/tests/test_backend/test_metal/test_parser.py b/tests/test_backend/test_metal/test_parser.py index 0ee06d58..f3beef03 100644 --- a/tests/test_backend/test_metal/test_parser.py +++ b/tests/test_backend/test_metal/test_parser.py @@ -124,5 +124,34 @@ def test_function_call(): pytest.fail("Struct parsing not implemented.") +def test_if_else(): + code = """ + float perlinNoise(float2 p) { + if (p.x == p.y) { + return 0.0; + } + if (p.x > p.y) { + return 1.0; + } + else if (p.x > p.y) { + return 1.0; + } + + else if (p.x < p.y) { + return -1.0; + } + + else { + return fract(sin(dot(p, float2(12.9898, 78.233))) * 43758.5453); + } + } + """ + try: + tokens = tokenize_code(code) + parse_code(tokens) + except SyntaxError: + pytest.fail("If-else statement parsing not implemented.") + + if __name__ == "__main__": pytest.main()