Repository: CrossGL/crosstl
Pull request #216 (2024-12-19 00:22:09)

Chore: Add barebone for Mojo and Vulkan


Patch:
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 5cfc4fd..ebfdf3e 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1,5 +1,1 @@
-* @NripeshN
-
-crosstl/**/* @samthakur587 @vaatsalya123
-
-tests/**/* @samthakur587
+* @NripeshN @vaatsalya123
diff --git a/crosstl/_crosstl.py b/crosstl/_crosstl.py
index e07ce12..704e2e0 100644
--- a/crosstl/_crosstl.py
+++ b/crosstl/_crosstl.py
@@ -7,6 +7,8 @@ from .backend.DirectX import *
 from .backend.Metal import *
 from .backend.Opengl import *
 from .backend.slang import *
+from .backend.Vulkan import *
+from .backend.Mojo import *
 
 
 def translate(file_path: str, backend: str = "cgl", save_shader: str = None) -> str:
@@ -41,6 +43,12 @@ def translate(file_path: str, backend: str = "cgl", save_shader: str = None) ->
     elif file_path.endswith(".slang"):
         lexer = SlangLexer(shader_code)
         parser = SlangParser(lexer.tokens)
+    elif file_path.endswith(".spv"):
+        lexer = VulkanLexer(shader_code)
+        parser = VulkanParser(lexer.tokens)
+    elif file_path.endswith(".mojo"):
+        lexer = MojoLexer(shader_code)
+        parser = MojoParser(lexer.tokens)
     else:
         raise ValueError(f"Unsupported shader file type: {file_path}")
 
diff --git a/crosstl/backend/Mojo/MojoAst.py b/crosstl/backend/Mojo/MojoAst.py
index af4f85e..112cb78 100644
--- a/crosstl/backend/Mojo/MojoAst.py
+++ b/crosstl/backend/Mojo/MojoAst.py
@@ -1,6 +1,3 @@
-# Ref from Modular docs.
-
-
 class MojoASTNode:
     pass
 
diff --git a/crosstl/backend/Mojo/MojoLexer.py b/crosstl/backend/Mojo/MojoLexer.py
index 0e45202..355b8e9 100644
--- a/crosstl/backend/Mojo/MojoLexer.py
+++ b/crosstl/backend/Mojo/MojoLexer.py
@@ -104,17 +104,3 @@ class MojoLexer:
                 )
 
         self.tokens.append(("EOF", ""))
-
-
-# Temp test sorry aha
-code = """
-struct MyStruct:
-    let x: Int
-    var y: Float
-    fn add() -> Int:
-        return self.x + y
-"""
-
-lexer = MojoLexer(code)
-for token in lexer.tokens:
-    print(token)
diff --git a/crosstl/backend/Mojo/MojoParser.py b/crosstl/backend/Mojo/MojoParser.py
index e8ddbd2..64cf50e 100644
--- a/crosstl/backend/Mojo/MojoParser.py
+++ b/crosstl/backend/Mojo/MojoParser.py
@@ -1,5 +1,5 @@
-from MojoLexer import *
-from MojoAst import *
+from .MojoLexer import *
+from .MojoAst import *
 
 
 class MojoParser:
@@ -600,32 +600,3 @@ class MojoParser:
                     self.eat("COMMA")
             self.eat("RPAREN")
         return DecoratorNode(name, args)
-
-
-# Temp test
-code = """
-import MyModule as mm
-
-@decorator_example
-class ExampleClass(BaseClass):
-    let x: Int
-    var y: Float = 0.0
-
-    fn add_values(self, a: Int, b: Float) -> Float:
-        return a + b + self.y
-
-
-struct ExampleStruct:
-    let z: Float
-
-fn main():
-    let instance = ExampleClass(x: 10)
-    let result = instance.add_values(5 , 3.2)
-    return result
-"""
-
-lexer = MojoLexer(code)
-parser = MojoParser(lexer.tokens)
-ast = parser.parse()
-
-print(ast)
diff --git a/crosstl/backend/Mojo/__init__.py b/crosstl/backend/Mojo/__init__.py
new file mode 100644
index 0000000..1e7d61b
--- /dev/null
+++ b/crosstl/backend/Mojo/__init__.py
@@ -0,0 +1,3 @@
+from .MojoAst import *
+from .MojoLexer import *
+from .MojoParser import *
diff --git a/crosstl/backend/Opengl/__init__.py b/crosstl/backend/Opengl/__init__.py
index f23b48c..bec5dd8 100644
--- a/crosstl/backend/Opengl/__init__.py
+++ b/crosstl/backend/Opengl/__init__.py
@@ -1,3 +1,4 @@
+from .OpenglAst import *
 from .OpenglLexer import *
 from .OpenglParser import *
 from .openglCrossglCodegen import *
diff --git a/crosstl/backend/Vulkan/VulkanParser.py b/crosstl/backend/Vulkan/VulkanParser.py
index 6e88f60..8b2247c 100644
--- a/crosstl/backend/Vulkan/VulkanParser.py
+++ b/crosstl/backend/Vulkan/VulkanParser.py
@@ -1,5 +1,5 @@
-from VulkanLexer import *
-from VulkanAst import *
+from .VulkanLexer import *
+from .VulkanAst import *
 
 
 class VulkanParser:
diff --git a/crosstl/backend/Vulkan/__init__.py b/crosstl/backend/Vulkan/__init__.py
new file mode 100644
index 0000000..413cb9f
--- /dev/null
+++ b/crosstl/backend/Vulkan/__init__.py
@@ -0,0 +1,3 @@
+from .VulkanAst import *
+from .VulkanLexer import *
+from .VulkanParser import *
diff --git a/crosstl/translator/codegen/mojo_codegen.py b/crosstl/translator/codegen/mojo_codegen.py
new file mode 100644
index 0000000..d9a9dd6
--- /dev/null
+++ b/crosstl/translator/codegen/mojo_codegen.py
@@ -0,0 +1,22 @@
+from ..ast import (
+    AssignmentNode,
+    BinaryOpNode,
+    ForNode,
+    FunctionCallNode,
+    IfNode,
+    MemberAccessNode,
+    ReturnNode,
+    StructNode,
+    TernaryOpNode,
+    UnaryOpNode,
+    VariableNode,
+)
+
+
+# ToDO: Implement the MojoCodeGen class
+class MojoCodeGen:
+    def __init__(self):
+        pass
+
+    def generate(self, ast):
+        pass


Test patch:
diff --git a/.github/workflows/backend-tests.yml b/.github/workflows/backend-tests.yml
index 8231702..ae96e81 100644
--- a/.github/workflows/backend-tests.yml
+++ b/.github/workflows/backend-tests.yml
@@ -13,7 +13,7 @@ jobs:
     runs-on: ${{ matrix.OS }}
     strategy:
       matrix:
-        backend: [directx, metal, opengl, 'slang'] # ToDO: Add mojo to the list
+        backend: [directx, metal, opengl, 'slang', 'vulkan', 'mojo']
         python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13']
         OS: [ubuntu-latest, windows-latest, macOS-latest]
       fail-fast: false
diff --git a/.github/workflows/translator-tests.yml b/.github/workflows/translator-tests.yml
index b183139..69c8b8b 100644
--- a/.github/workflows/translator-tests.yml
+++ b/.github/workflows/translator-tests.yml
@@ -13,7 +13,7 @@ jobs:
     runs-on: ${{ matrix.OS }}
     strategy:
       matrix:
-        component: ['directx', 'metal', 'opengl', 'slang' ,'general']  # ToDo: Add 'mojo' to the list
+        component: ['directx', 'metal', 'opengl', 'slang' , 'vulkan', 'mojo', 'general']
         python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13']
         OS: [ubuntu-latest, windows-latest, macOS-latest]
       fail-fast: false
diff --git a/tests/test_backend/test_mojo/__init__.py b/tests/test_backend/test_mojo/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/test_backend/test_mojo/test_codegen.py b/tests/test_backend/test_mojo/test_codegen.py
new file mode 100644
index 0000000..173f817
--- /dev/null
+++ b/tests/test_backend/test_mojo/test_codegen.py
@@ -0,0 +1,34 @@
+from crosstl.backend.Mojo import MojoLexer
+from crosstl.backend.Mojo import MojoParser
+import pytest
+from typing import List
+
+
+def generate_code(ast_node):
+    """Test the code generator
+    Args:
+        ast_node: The abstract syntax tree generated from the code
+    Returns:
+        str: The generated code from the abstract syntax tree
+    """
+
+
+def tokenize_code(code: str) -> List:
+    """Helper function to tokenize code."""
+    lexer = MojoLexer(code)
+    return lexer.tokens
+
+
+def parse_code(tokens: List):
+    """Helper function to parse tokens into an AST."""
+    parser = MojoParser(tokens)
+    return parser.parse()
+
+
+# ToDO: Implement the tests
+def test_struct():
+    pass
+
+
+if __name__ == "__main__":
+    pytest.main()
diff --git a/tests/test_backend/test_mojo/test_lexer.py b/tests/test_backend/test_mojo/test_lexer.py
new file mode 100644
index 0000000..6c24905
--- /dev/null
+++ b/tests/test_backend/test_mojo/test_lexer.py
@@ -0,0 +1,18 @@
+import pytest
+from typing import List
+from crosstl.backend.Mojo.MojoLexer import MojoLexer
+
+
+def tokenize_code(code: str) -> List:
+    """Helper function to tokenize code."""
+    lexer = MojoLexer(code)
+    return lexer.tokens
+
+
+# ToDO: Implement the tests
+def test_struct():
+    pass
+
+
+if __name__ == "__main__":
+    pytest.main()
diff --git a/tests/test_backend/test_mojo/test_parser.py b/tests/test_backend/test_mojo/test_parser.py
new file mode 100644
index 0000000..36953cd
--- /dev/null
+++ b/tests/test_backend/test_mojo/test_parser.py
@@ -0,0 +1,31 @@
+import pytest
+from typing import List
+from crosstl.backend.Mojo.MojoLexer import MojoLexer
+from crosstl.backend.Mojo import MojoParser
+
+
+def parse_code(tokens: List):
+    """Test the parser
+    Args:
+        tokens (List): The list of tokens generated from the lexer
+
+    Returns:
+        ASTNode: The abstract syntax tree generated from the code
+    """
+    parser = MojoParser(tokens)
+    return parser.parse()
+
+
+def tokenize_code(code: str) -> List:
+    """Helper function to tokenize code."""
+    lexer = MojoLexer(code)
+    return lexer.tokens
+
+
+# ToDO: Implement the tests
+def test_struct():
+    pass
+
+
+if __name__ == "__main__":
+    pytest.main()
diff --git a/tests/test_backend/test_vulkan/__init__.py b/tests/test_backend/test_vulkan/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/test_backend/test_vulkan/test_codegen.py b/tests/test_backend/test_vulkan/test_codegen.py
new file mode 100644
index 0000000..6e2c91c
--- /dev/null
+++ b/tests/test_backend/test_vulkan/test_codegen.py
@@ -0,0 +1,34 @@
+from crosstl.backend.Vulkan import VulkanLexer
+from crosstl.backend.Vulkan import VulkanParser
+import pytest
+from typing import List
+
+
+def generate_code(ast_node):
+    """Test the code generator
+    Args:
+        ast_node: The abstract syntax tree generated from the code
+    Returns:
+        str: The generated code from the abstract syntax tree
+    """
+
+
+def tokenize_code(code: str) -> List:
+    """Helper function to tokenize code."""
+    lexer = VulkanLexer(code)
+    return lexer.tokens
+
+
+def parse_code(tokens: List):
+    """Helper function to parse tokens into an AST."""
+    parser = VulkanParser(tokens)
+    return parser.parse()
+
+
+# ToDO: Implement the tests
+def test_struct():
+    pass
+
+
+if __name__ == "__main__":
+    pytest.main()
diff --git a/tests/test_backend/test_vulkan/test_lexer.py b/tests/test_backend/test_vulkan/test_lexer.py
new file mode 100644
index 0000000..8222148
--- /dev/null
+++ b/tests/test_backend/test_vulkan/test_lexer.py
@@ -0,0 +1,18 @@
+import pytest
+from typing import List
+from crosstl.backend.Vulkan.VulkanLexer import VulkanLexer
+
+
+def tokenize_code(code: str) -> List:
+    """Helper function to tokenize code."""
+    lexer = VulkanLexer(code)
+    return lexer.tokens
+
+
+# ToDO: Implement the tests
+def test_struct():
+    pass
+
+
+if __name__ == "__main__":
+    pytest.main()
diff --git a/tests/test_backend/test_vulkan/test_parser.py b/tests/test_backend/test_vulkan/test_parser.py
new file mode 100644
index 0000000..736e78b
--- /dev/null
+++ b/tests/test_backend/test_vulkan/test_parser.py
@@ -0,0 +1,31 @@
+import pytest
+from typing import List
+from crosstl.backend.Vulkan.VulkanLexer import VulkanLexer
+from crosstl.backend.Vulkan import VulkanParser
+
+
+def parse_code(tokens: List):
+    """Test the parser
+    Args:
+        tokens (List): The list of tokens generated from the lexer
+
+    Returns:
+        ASTNode: The abstract syntax tree generated from the code
+    """
+    parser = VulkanParser(tokens)
+    return parser.parse()
+
+
+def tokenize_code(code: str) -> List:
+    """Helper function to tokenize code."""
+    lexer = VulkanLexer(code)
+    return lexer.tokens
+
+
+# ToDO: Implement the tests
+def test_struct():
+    pass
+
+
+if __name__ == "__main__":
+    pytest.main()
diff --git a/tests/test_translator/test_codegen/test_mojo_codegen.py b/tests/test_translator/test_codegen/test_mojo_codegen.py
new file mode 100644
index 0000000..402e9ee
--- /dev/null
+++ b/tests/test_translator/test_codegen/test_mojo_codegen.py
@@ -0,0 +1,43 @@
+from crosstl.translator.lexer import Lexer
+import pytest
+from typing import List
+from crosstl.translator.parser import Parser
+from crosstl.translator.codegen.mojo_codegen import MojoCodeGen
+
+
+def tokenize_code(code: str) -> List:
+    """Helper function to tokenize code."""
+    lexer = Lexer(code)
+    return lexer.tokens
+
+
+def parse_code(tokens: List):
+    """Helper function to parse tokens into an AST.
+
+    Args:
+        tokens (List): The list of tokens to parse
+    Returns:
+        AST: The abstract syntax tree generated from the parser
+    """
+    parser = Parser(tokens)
+    return parser.parse()
+
+
+def generate_code(ast_node):
+    """Test the code generator
+    Args:
+        ast_node: The abstract syntax tree generated from the code
+    Returns:
+        str: The generated code from the abstract syntax tree
+    """
+    codegen = MojoCodeGen()
+    return codegen.generate(ast_node)
+
+
+# ToDO: Implement the tests
+def test_struct():
+    pass
+
+
+if __name__ == "__main__":
+    pytest.main()
diff --git a/tests/test_translator/test_codegen/test_vulkan_codegen.py b/tests/test_translator/test_codegen/test_vulkan_codegen.py
new file mode 100644
index 0000000..6730b52
--- /dev/null
+++ b/tests/test_translator/test_codegen/test_vulkan_codegen.py
@@ -0,0 +1,43 @@
+from crosstl.translator.lexer import Lexer
+import pytest
+from typing import List
+from crosstl.translator.parser import Parser
+from crosstl.translator.codegen.vulkan_codegen import VulkanSPIRVCodeGen
+
+
+def tokenize_code(code: str) -> List:
+    """Helper function to tokenize code."""
+    lexer = Lexer(code)
+    return lexer.tokens
+
+
+def parse_code(tokens: List):
+    """Helper function to parse tokens into an AST.
+
+    Args:
+        tokens (List): The list of tokens to parse
+    Returns:
+        AST: The abstract syntax tree generated from the parser
+    """
+    parser = Parser(tokens)
+    return parser.parse()
+
+
+def generate_code(ast_node):
+    """Test the code generator
+    Args:
+        ast_node: The abstract syntax tree generated from the code
+    Returns:
+        str: The generated code from the abstract syntax tree
+    """
+    codegen = VulkanSPIRVCodeGen()
+    return codegen.generate(ast_node)
+
+
+# ToDO: Implement the tests
+def test_struct():
+    pass
+
+
+if __name__ == "__main__":
+    pytest.main()