Repository: CrossGL/crosstl
Pull request #149 (2024-09-06 15:03:25)

Added translator support for Assignment Shift Left token
### PR Description
Added the translator support for Assignment Shift Left token

Modified the codegen files at translator frontend below and parser

### Related Issue
closes  #117  

### shader Sample


```crossgl
    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);
            }
        }
    }

```


### Checklist
- [x] Have you added the necessary tests?
- [ ] Only modified the files mentioned in the related issue(s)?
- [x] Are all tests passing?





Patch:
diff --git a/crosstl/src/translator/codegen/directx_codegen.py b/crosstl/src/translator/codegen/directx_codegen.py
index 47eedd4..479a746 100644
--- a/crosstl/src/translator/codegen/directx_codegen.py
+++ b/crosstl/src/translator/codegen/directx_codegen.py
@@ -367,5 +367,6 @@ class HLSLCodeGen:
             "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 2a258c9..1c5d261 100644
--- a/crosstl/src/translator/codegen/metal_codegen.py
+++ b/crosstl/src/translator/codegen/metal_codegen.py
@@ -427,5 +427,6 @@ class MetalCodeGen:
             "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 0a462c1..52644b5 100644
--- a/crosstl/src/translator/codegen/opengl_codegen.py
+++ b/crosstl/src/translator/codegen/opengl_codegen.py
@@ -284,5 +284,6 @@ class GLSLCodeGen:
             "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 d07c84e..9c14fec 100644
--- a/crosstl/src/translator/parser.py
+++ b/crosstl/src/translator/parser.py
@@ -644,7 +644,7 @@ class Parser:
             "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 @@ class Parser:
             "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 @@ class Parser:
             "ASSIGN_XOR",
             "ASSIGN_MOD",
             "ASSIGN_SHIFT_RIGHT",
+            "ASSIGN_SHIFT_LEFT",
         ):
             op = self.current_token[0]
             self.eat(op)
@@ -796,6 +797,7 @@ class Parser:
             "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 @@ class Parser:
             "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 8435bd6..fcb9cab 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 75d1475..c3194ac 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 a789e6e..8977daa 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.")