Repository: CrossGL/crosstl

Issue:
Add support for double data type at opengl backend
<!-- BOT_STATE: {"assignee": "ashwith2427", "assigned_at": "2024-12-26T13:57:23.808531+00:00", "reminder_sent": false, "unassigned": false} -->

Discussion:
gjyotin305: @NripeshN PTAL

Patch:
diff --git a/crosstl/backend/DirectX/DirectxLexer.py b/crosstl/backend/DirectX/DirectxLexer.py
index 210ae54..b6003c1 100644
--- a/crosstl/backend/DirectX/DirectxLexer.py
+++ b/crosstl/backend/DirectX/DirectxLexer.py
@@ -10,6 +10,7 @@ TOKENS = [
     ("SAMPLER_STATE", r"\bSamplerState\b"),
     ("FVECTOR", r"\bfloat[2-4]\b"),
     ("FLOAT", r"\bfloat\b"),
+    ("DOUBLE", r"\bdouble\b"),
     ("INT", r"\bint\b"),
     ("UINT", r"\buint\b"),
     ("BOOL", r"\bbool\b"),
@@ -77,6 +78,7 @@ KEYWORDS = {
     "float2": "FVECTOR",
     "float3": "FVECTOR",
     "float4": "FVECTOR",
+    "double": "DOUBLE",
     "int": "INT",
     "uint": "UINT",
     "bool": "BOOL",
diff --git a/crosstl/backend/DirectX/DirectxParser.py b/crosstl/backend/DirectX/DirectxParser.py
index d6fd7ff..e7c0309 100644
--- a/crosstl/backend/DirectX/DirectxParser.py
+++ b/crosstl/backend/DirectX/DirectxParser.py
@@ -60,6 +60,7 @@ class HLSLParser:
             elif self.current_token[0] in [
                 "VOID",
                 "FLOAT",
+                "DOUBLE",
                 "FVECTOR",
                 "IDENTIFIER",
                 "TEXTURE2D",
@@ -196,6 +197,7 @@ class HLSLParser:
     def parse_statement(self):
         if self.current_token[0] in [
             "FLOAT",
+            "DOUBLE",
             "FVECTOR",
             "INT",
             "UINT",
@@ -221,6 +223,7 @@ class HLSLParser:
     def parse_variable_declaration_or_assignment(self):
         if self.current_token[0] in [
             "FLOAT",
+            "DOUBLE",
             "FVECTOR",
             "INT",
             "UINT",
@@ -349,7 +352,7 @@ class HLSLParser:
         self.eat("LPAREN")
 
         # Parse initialization
-        if self.current_token[0] in ["INT", "FLOAT", "FVECTOR"]:
+        if self.current_token[0] in ["INT", "FLOAT", "FVECTOR", "DOUBLE"]:
             type_name = self.current_token[1]
             self.eat(self.current_token[0])
             var_name = self.current_token[1]
@@ -511,7 +514,7 @@ class HLSLParser:
         return self.parse_primary()
 
     def parse_primary(self):
-        if self.current_token[0] in ["IDENTIFIER", "FLOAT", "FVECTOR"]:
+        if self.current_token[0] in ["IDENTIFIER", "FLOAT", "FVECTOR", "DOUBLE"]:
             if self.current_token[0] == "IDENTIFIER":
                 name = self.current_token[1]
                 self.eat("IDENTIFIER")
@@ -520,7 +523,7 @@ class HLSLParser:
                 elif self.current_token[0] == "DOT":
                     return self.parse_member_access(name)
                 return VariableNode("", name)
-            if self.current_token[0] in ["FLOAT", "FVECTOR"]:
+            if self.current_token[0] in ["FLOAT", "FVECTOR", "DOUBLE"]:
                 type_name = self.current_token[1]
                 self.eat(self.current_token[0])
                 if self.current_token[0] == "LPAREN":
diff --git a/crosstl/backend/Opengl/OpenglLexer.py b/crosstl/backend/Opengl/OpenglLexer.py
index bd9a24b..5a1a18a 100644
--- a/crosstl/backend/Opengl/OpenglLexer.py
+++ b/crosstl/backend/Opengl/OpenglLexer.py
@@ -15,6 +15,7 @@ TOKENS = [
     ("MATRIX", r"\bmat[234](x[234])?\b"),
     ("FLOAT", r"\bfloat\b"),
     ("INT", r"\bint\b"),
+    ("DOUBLE", r"\bdouble\b"),
     ("UINT", r"\buint\b"),
     ("BOOL", r"\bbool\b"),
     ("VOID", r"\bvoid\b"),
@@ -83,6 +84,7 @@ KEYWORDS = {
     "uint": "UINT",
     "bool": "BOOL",
     "void": "VOID",
+    "double": "DOUBLE",
     "return": "RETURN",
     "else if": "ELSE_IF",
     "if": "IF",
diff --git a/crosstl/backend/Opengl/OpenglParser.py b/crosstl/backend/Opengl/OpenglParser.py
index 44aeb31..f2d15ec 100644
--- a/crosstl/backend/Opengl/OpenglParser.py
+++ b/crosstl/backend/Opengl/OpenglParser.py
@@ -55,6 +55,7 @@ class GLSLParser:
                 "VOID",
                 "FLOAT",
                 "INT",
+                "DOUBLE",
                 "VECTOR",
                 "MATRIX",
                 "IDENTIFIER",
@@ -118,7 +119,7 @@ class GLSLParser:
 
     def parse_global_variable(self):
         type_name = ""
-        if self.current_token[0] in ["FLOAT", "INT", "MATRIX", "VECTOR"]:
+        if self.current_token[0] in ["FLOAT", "INT", "DOUBLE", "MATRIX", "VECTOR"]:
             type_name = self.current_token[1]
             self.eat(self.current_token[0])
         if self.current_token[0] == "IDENTIFIER":


Test patch:
diff --git a/tests/test_backend/test_directx/test_codegen.py b/tests/test_backend/test_directx/test_codegen.py
index 89e2ff3..199c4b8 100644
--- a/tests/test_backend/test_directx/test_codegen.py
+++ b/tests/test_backend/test_directx/test_codegen.py
@@ -575,5 +575,30 @@ def test_switch_case_codegen():
         pytest.fail("Switch-case parsing or code generation not implemented.")
 
 
+def test_double_dtype_codegen():
+    code = """
+            PSOutput PSMain(PSInput input) {
+                PSOutput output;
+                output.out_color = float4(0.0, 0.0, 0.0, 1.0);
+                double value1 = 3.14159; // First double value
+                double value2 = 2.71828; // Second double value
+                double result = value1 + value2; // Adding two doubles
+                if (result > 6.0) {
+                    output.out_color = float4(1.0, 0.0, 0.0, 1.0); // Set color to red
+                } else {
+                    output.out_color = float4(0.0, 1.0, 0.0, 1.0); // Set color to green
+                }
+                return output;
+            }
+        """
+    try:
+        tokens = tokenize_code(code)
+        ast = parse_code(tokens)
+        generated_code = generate_code(ast)
+        print(generated_code)
+    except SyntaxError:
+        pytest.fail("double dtype parsing or code generation not implemented.")
+
+
 if __name__ == "__main__":
     pytest.main()
diff --git a/tests/test_backend/test_directx/test_lexer.py b/tests/test_backend/test_directx/test_lexer.py
index 04761ac..aa785b9 100644
--- a/tests/test_backend/test_directx/test_lexer.py
+++ b/tests/test_backend/test_directx/test_lexer.py
@@ -228,5 +228,27 @@ def test_switch_case_tokenization():
         pytest.fail("switch-case tokenization not implemented.")
 
 
+def test_double_dtype_tokenization():
+    code = """
+            PSOutput PSMain(PSInput input) {
+                PSOutput output;
+                output.out_color = float4(0.0, 0.0, 0.0, 1.0);
+                double value1 = 3.14159; // First double value
+                double value2 = 2.71828; // Second double value
+                double result = value1 + value2; // Adding two doubles
+                if (result > 6.0) {
+                    output.out_color = float4(1.0, 0.0, 0.0, 1.0); // Set color to red
+                } else {
+                    output.out_color = float4(0.0, 1.0, 0.0, 1.0); // Set color to green
+                }
+                return output;
+            }
+        """
+    try:
+        tokenize_code(code)
+    except SyntaxError:
+        pytest.fail("double dtype tokenization is not implemented.")
+
+
 if __name__ == "__main__":
     pytest.main()
diff --git a/tests/test_backend/test_directx/test_parser.py b/tests/test_backend/test_directx/test_parser.py
index 15f8415..efb59d2 100644
--- a/tests/test_backend/test_directx/test_parser.py
+++ b/tests/test_backend/test_directx/test_parser.py
@@ -332,5 +332,28 @@ def test_switch_case_parsing():
         pytest.fail("switch-case parsing not implemented.")
 
 
+def test_double_dtype_parsing():
+    code = """
+            PSOutput PSMain(PSInput input) {
+                PSOutput output;
+                output.out_color = float4(0.0, 0.0, 0.0, 1.0);
+                double value1 = 3.14159; // First double value
+                double value2 = 2.71828; // Second double value
+                double result = value1 + value2; // Adding two doubles
+                if (result > 6.0) {
+                    output.out_color = float4(1.0, 0.0, 0.0, 1.0); // Set color to red
+                } else {
+                    output.out_color = float4(0.0, 1.0, 0.0, 1.0); // Set color to green
+                }
+                return output;
+            }
+        """
+    try:
+        tokens = tokenize_code(code)
+        parse_code(tokens)
+    except SyntaxError:
+        pytest.fail("double dtype not implemented.")
+
+
 if __name__ == "__main__":
     pytest.main()
diff --git a/tests/test_backend/test_opengl/test_codegen.py b/tests/test_backend/test_opengl/test_codegen.py
index 09c1d73..bbb83b3 100644
--- a/tests/test_backend/test_opengl/test_codegen.py
+++ b/tests/test_backend/test_opengl/test_codegen.py
@@ -187,5 +187,22 @@ def test_function_call():
         pytest.fail("Struct parsing not implemented.")
 
 
+def test_double_dtype_codegen():
+    code = """
+    double ComputeArea(double radius) {
+        double pi = 3.14159265359;
+        double area = pi * radius * radius;
+        return area;
+    }
+    """
+    try:
+        tokens = tokenize_code(code)
+        ast = parse_code(tokens)
+        code = generate_code(ast)
+        print(code)
+    except SyntaxError:
+        pytest.fail("double tokenization not implemented")
+
+
 if __name__ == "__main__":
     pytest.main()
diff --git a/tests/test_backend/test_opengl/test_lexer.py b/tests/test_backend/test_opengl/test_lexer.py
index 0074222..fa72f51 100644
--- a/tests/test_backend/test_opengl/test_lexer.py
+++ b/tests/test_backend/test_opengl/test_lexer.py
@@ -102,7 +102,6 @@ def test_function_call_tokenization():
         vec3 color = vec3(height / 10.0, 1.0 - height / 10.0, 0.0);
         fragColor = vec4(color, 1.0);
     }
-    
     """
     try:
         tokenize_code(code)
@@ -110,5 +109,19 @@ def test_function_call_tokenization():
         pytest.fail("Function call tokenization not implemented.")
 
 
+def test_double_dtype_tokenization():
+    code = """
+    double ComputeArea(double radius) {
+        double pi = 3.14159265359;
+        double area = pi * radius * radius;
+        return area;
+    }
+    """
+    try:
+        tokenize_code(code)
+    except SyntaxError:
+        pytest.fail("double tokenization not implemented")
+
+
 if __name__ == "__main__":
     pytest.main()
diff --git a/tests/test_backend/test_opengl/test_parser.py b/tests/test_backend/test_opengl/test_parser.py
index 44748ca..661ccc2 100644
--- a/tests/test_backend/test_opengl/test_parser.py
+++ b/tests/test_backend/test_opengl/test_parser.py
@@ -182,5 +182,20 @@ def test_function_call():
         pytest.fail("Struct parsing not implemented.")
 
 
+def test_double_dtype_tokenization():
+    code = """
+    double ComputeArea(double radius) {
+        double pi = 3.14159265359;
+        double area = pi * radius * radius;
+        return area;
+    }
+    """
+    try:
+        tokens = tokenize_code(code)
+        parse_code(tokens)
+    except SyntaxError:
+        pytest.fail("double tokenization not implemented")
+
+
 if __name__ == "__main__":
     pytest.main()