Repository: CrossGL/crosstl

Issue:
Add translator support for `Assignment Shift Left` token

Hints from issue comments:
@DeVcB13d: Hey @samthakur587 can I have this issue?


Solution patch:
diff --git a/crosstl/src/translator/codegen/directx_codegen.py b/crosstl/src/translator/codegen/directx_codegen.py
index 47eedd48..479a7462 100644
--- a/crosstl/src/translator/codegen/directx_codegen.py
+++ b/crosstl/src/translator/codegen/directx_codegen.py
@@ -367,5 +367,6 @@ def map_operator(self, op):
             "AND": "&&",
             "OR": "||",
             "EQUALS": "=",
+            "ASSIGN_SHIFT_LEFT": "<<=",
         }
         return op_map.get(op, op)
diff --git a/crosstl/src/translator/codegen/metal_codegen.py b/crosstl/src/translator/codegen/metal_codegen.py
index 2a258c92..1c5d2610 100644
--- a/crosstl/src/translator/codegen/metal_codegen.py
+++ b/crosstl/src/translator/codegen/metal_codegen.py
@@ -427,5 +427,6 @@ def map_operator(self, op):
             "AND": "&&",
             "OR": "||",
             "EQUALS": "=",
+            "ASSIGN_SHIFT_LEFT": "<<=",
         }
         return op_map.get(op, op)
diff --git a/crosstl/src/translator/codegen/opengl_codegen.py b/crosstl/src/translator/codegen/opengl_codegen.py
index 0a462c1a..52644b53 100644
--- a/crosstl/src/translator/codegen/opengl_codegen.py
+++ b/crosstl/src/translator/codegen/opengl_codegen.py
@@ -284,5 +284,6 @@ def map_operator(self, op):
             "AND": "&&",
             "OR": "||",
             "EQUALS": "=",
+            "ASSIGN_SHIFT_LEFT": "<<=",
         }
         return op_map.get(op, op)
diff --git a/crosstl/src/translator/parser.py b/crosstl/src/translator/parser.py
index d07c84ed..9c14fec9 100644
--- a/crosstl/src/translator/parser.py
+++ b/crosstl/src/translator/parser.py
@@ -644,7 +644,7 @@ def parse_assignment_or_function_call(self, update_condition=False):
             "ASSIGN_MOD",
             "BITWISE_SHIFT_RIGHT",
             "BITWISE_SHIFT_LEFT",
-            "ASSIGN_SHIFT_RIGHT",
+            "ASSIGN_SHIFT_LEFT" "ASSIGN_SHIFT_RIGHT",
         ]:
             return self.parse_assignment(name)
         elif self.current_token[0] == "INCREMENT":
@@ -705,7 +705,7 @@ def parse_variable_declaration(self, type_name, update_condition=False):
             "ASSIGN_MOD",
             "BITWISE_SHIFT_RIGHT",
             "BITWISE_SHIFT_LEFT",
-            "ASSIGN_SHIFT_RIGHT",
+            "ASSIGN_SHIFT_LEFT" "ASSIGN_SHIFT_RIGHT",
         ]:
             op = self.current_token[1]
             self.eat(self.current_token[0])
@@ -742,6 +742,7 @@ def parse_variable_declaration(self, type_name, update_condition=False):
             "ASSIGN_XOR",
             "ASSIGN_MOD",
             "ASSIGN_SHIFT_RIGHT",
+            "ASSIGN_SHIFT_LEFT",
         ):
             op = self.current_token[0]
             self.eat(op)
@@ -796,6 +797,7 @@ def parse_assignment(self, name):
             "BITWISE_SHIFT_RIGHT",
             "BITWISE_SHIFT_LEFT",
             "ASSIGN_SHIFT_RIGHT",
+            "ASSIGN_SHIFT_LEFT",
         ]:
             op = self.current_token[0]
             op_name = self.current_token[1]
@@ -961,6 +963,7 @@ def parse_expression(self):
             "BITWISE_SHIFT_RIGHT",
             "BITWISE_SHIFT_LEFT",
             "ASSIGN_SHIFT_RIGHT",
+            "ASSIGN_SHIFT_LEFT",
         ]:
             op = self.current_token[0]
             self.eat(op)


Test patch:
diff --git a/tests/test_translator/test_codegen/test_directx_codegen.py b/tests/test_translator/test_codegen/test_directx_codegen.py
index 8435bd6c..fcb9cabf 100644
--- a/tests/test_translator/test_codegen/test_directx_codegen.py
+++ b/tests/test_translator/test_codegen/test_directx_codegen.py
@@ -281,3 +281,41 @@ def test_function_call():
         print(code)
     except SyntaxError:
         pytest.fail("Struct parsing not implemented.")
+
+
+def test_assignment_shift_operators():
+    code = """
+    shader PerlinNoise {
+    vertex {
+        input vec3 position;
+        output vec2 vUV;
+
+        void main() {
+            vUV = position.xy * 10.0;
+            vUV.x <<= 1;
+            gl_Position = vec4(position, 1.0);
+        }
+    }
+
+    // Fragment Shader
+    fragment {
+        input vec2 vUV;
+        output vec4 fragColor;
+
+        void main() {
+            float noise = perlinNoise(vUV);
+            float height <<= noise * 10.0;
+            vec3 color = vec3(height / 10.0, 1.0 - height / 10.0, 0.0);
+            fragColor = vec4(color, 1.0);
+            }
+        }
+    }
+
+    """
+    try:
+        tokens = tokenize_code(code)
+        ast = parse_code(tokens)
+        code = generate_code(ast)
+        print(code)
+    except SyntaxError:
+        pytest.fail("Struct parsing not implemented.")
diff --git a/tests/test_translator/test_codegen/test_metal_codegen.py b/tests/test_translator/test_codegen/test_metal_codegen.py
index 75d1475d..c3194ace 100644
--- a/tests/test_translator/test_codegen/test_metal_codegen.py
+++ b/tests/test_translator/test_codegen/test_metal_codegen.py
@@ -283,3 +283,41 @@ def test_function_call():
         print(code)
     except SyntaxError:
         pytest.fail("Struct parsing not implemented.")
+
+
+def test_assignment_shift_operators():
+    code = """
+    shader PerlinNoise {
+    vertex {
+        input vec3 position;
+        output vec2 vUV;
+
+        void main() {
+            vUV = position.xy * 10.0;
+            vUV.x <<= 1;
+            gl_Position = vec4(position, 1.0);
+        }
+    }
+
+    // Fragment Shader
+    fragment {
+        input vec2 vUV;
+        output vec4 fragColor;
+
+        void main() {
+            float noise = perlinNoise(vUV);
+            float height <<= noise * 10.0;
+            vec3 color = vec3(height / 10.0, 1.0 - height / 10.0, 0.0);
+            fragColor = vec4(color, 1.0);
+            }
+        }
+    }
+
+    """
+    try:
+        tokens = tokenize_code(code)
+        ast = parse_code(tokens)
+        code = generate_code(ast)
+        print(code)
+    except SyntaxError:
+        pytest.fail("Struct parsing not implemented.")
diff --git a/tests/test_translator/test_codegen/test_opengl_codegen.py b/tests/test_translator/test_codegen/test_opengl_codegen.py
index a789e6ee..8977daa5 100644
--- a/tests/test_translator/test_codegen/test_opengl_codegen.py
+++ b/tests/test_translator/test_codegen/test_opengl_codegen.py
@@ -283,3 +283,41 @@ def test_function_call():
         print(code)
     except SyntaxError:
         pytest.fail("Struct parsing not implemented.")
+
+
+def test_assignment_shift_operators():
+    code = """
+    shader PerlinNoise {
+    vertex {
+        input vec3 position;
+        output vec2 vUV;
+
+        void main() {
+            vUV = position.xy * 10.0;
+            vUV.x <<= 1;
+            gl_Position = vec4(position, 1.0);
+        }
+    }
+
+    // Fragment Shader
+    fragment {
+        input vec2 vUV;
+        output vec4 fragColor;
+
+        void main() {
+            float noise = perlinNoise(vUV);
+            float height <<= noise * 10.0;
+            vec3 color = vec3(height / 10.0, 1.0 - height / 10.0, 0.0);
+            fragColor = vec4(color, 1.0);
+            }
+        }
+    }
+
+    """
+    try:
+        tokens = tokenize_code(code)
+        ast = parse_code(tokens)
+        code = generate_code(ast)
+        print(code)
+    except SyntaxError:
+        pytest.fail("Struct parsing not implemented.")