Repository: CrossGL/crosstl
Pull request #286 (2025-06-30 00:33:11)

HIP V0 support


Patch:
diff --git a/.github/scripts/docs_crawler.py b/.github/scripts/docs_crawler.py
deleted file mode 100755
index e2756bc..0000000
--- a/.github/scripts/docs_crawler.py
+++ /dev/null
@@ -1,838 +0,0 @@
-#!/usr/bin/env python3
-"""
-Documentation Crawler for Shader Languages
-
-This script crawls official documentation sites for various shader languages,
-extracts information about functions, types, operators, and other features,
-and stores the structured data for further analysis.
-"""
-
-import os
-import re
-import json
-import time
-import argparse
-import logging
-from pathlib import Path
-from concurrent.futures import ThreadPoolExecutor, as_completed
-from datetime import datetime
-from typing import Dict, List, Optional, Any
-
-import requests
-import aiohttp
-from bs4 import BeautifulSoup
-from selenium import webdriver
-from selenium.webdriver.chrome.options import Options
-from selenium.webdriver.chrome.service import Service
-from selenium.webdriver.common.by import By
-from selenium.webdriver.support.ui import WebDriverWait
-from selenium.webdriver.support import expected_conditions as EC
-from webdriver_manager.chrome import ChromeDriverManager
-from markdownify import markdownify
-import nltk
-from nltk.tokenize import sent_tokenize
-import spacy
-
-# Setup logging
-logging.basicConfig(
-    level=logging.INFO,
-    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
-    handlers=[
-        logging.FileHandler(".github/docs_crawler.log"),
-        logging.StreamHandler(),
-    ],
-)
-logger = logging.getLogger("docs_crawler")
-
-# Ensure cache directories exist
-os.makedirs(".cache/docs", exist_ok=True)
-os.makedirs(".cache/analysis", exist_ok=True)
-os.makedirs(".github/logs", exist_ok=True)
-
-# Load NLP models
-try:
-    nlp = spacy.load("en_core_web_lg")
-except OSError:
-    logger.warning("Spacy model not found, downloading...")
-    os.system("python -m spacy download en_core_web_lg")
-    nlp = spacy.load("en_core_web_lg")
-
-# Documentation sources configuration
-DOCUMENTATION_SOURCES = {
-    "metal": {
-        "base_url": (
-            "https://developer.apple.com/documentation/metal/metal_shading_language"
-        ),
-        "function_paths": [
-            "/mathematical_functions",
-            "/relational_functions",
-            "/geometric_functions",
-            "/texture_functions",
-        ],
-        "type_paths": [
-            "/data_types",
-            "/vector_and_matrix_data_types",
-        ],
-        "operator_paths": [
-            "/operators",
-        ],
-        "function_selector": "a.link.symbol-name",
-        "dynamic_loading": True,
-        "requires_js": True,
-        "authentication": False,
-    },
-    "directx": {
-        "base_url": "https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl",
-        "function_paths": [
-            "/dx-graphics-hlsl-intrinsic-functions",
-        ],
-        "type_paths": [
-            "/dx-graphics-hlsl-data-types",
-        ],
-        "operator_paths": [
-            "/dx-graphics-hlsl-operators",
-        ],
-        "function_selector": (
-            'h2[id^="intrinsic-functions"], h3[id^="intrinsic-functions"]'
-        ),
-        "dynamic_loading": False,
-        "requires_js": False,
-        "authentication": False,
-    },
-    "opengl": {
-        "base_url": "https://www.khronos.org/registry/OpenGL-Refpages/gl4/",
-        "function_paths": [
-            "html/indexflat.php",
-        ],
-        "type_paths": [
-            "html/glsl.html",
-        ],
-        "operator_paths": [
-            "html/glsl.html",
-        ],
-        "function_selector": "li a",
-        "dynamic_loading": False,
-        "requires_js": False,
-        "authentication": False,
-    },
-    "vulkan": {
-        "base_url": (
-            "https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html"
-        ),
-        "function_paths": [
-            "#spirvenv-capabilities-shaderintrinsics",
-        ],
-        "type_paths": [
-            "#spirvenv-types",
-        ],
-        "operator_paths": [
-            "#spirvenv-operators",
-        ],
-        "function_selector": "code",
-        "dynamic_loading": False,
-        "requires_js": False,
-        "authentication": False,
-    },
-    "slang": {
-        "base_url": "https://shader-slang.com/slang/docs/reference/",
-        "function_paths": [
-            "stdlib-math.html",
-            "stdlib-vector.html",
-            "stdlib-matrix.html",
-        ],
-        "type_paths": [
-            "types.html",
-        ],
-        "operator_paths": [
-            "operators.html",
-        ],
-        "function_selector": "code",
-        "dynamic_loading": False,
-        "requires_js": False,
-        "authentication": False,
-    },
-    "mojo": {
-        "base_url": "https://docs.modular.com/mojo/stdlib",
-        "function_paths": [
-            "builtin.html",
-            "math.html",
-        ],
-        "type_paths": [
-            "dtype.html",
-        ],
-        "operator_paths": [
-            "operator.html",
-        ],
-        "function_selector": "h3.function",
-        "dynamic_loading": True,
-        "requires_js": True,
-        "authentication": False,
-    },
-}
-
-
-class DocCrawler:
-    """Base class for document crawlers"""
-
-    def __init__(self, language: str):
-        self.language = language
-        self.config = DOCUMENTATION_SOURCES[language]
-        self.cache_dir = Path(f".cache/docs/{language}")
-        self.cache_dir.mkdir(parents=True, exist_ok=True)
-        self.analysis_dir = Path(".cache/analysis")
-        self.analysis_dir.mkdir(parents=True, exist_ok=True)
-
-        # Setup browser if needed
-        self.browser = None
-        if self.config["requires_js"]:
-            self._setup_browser()
-
-    def _setup_browser(self):
-        """Initialize a headless browser for JavaScript rendering"""
-        options = Options()
-        options.add_argument("--headless")
-        options.add_argument("--no-sandbox")
-        options.add_argument("--disable-dev-shm-usage")
-        options.add_argument("--disable-gpu")
-
-        service = Service(ChromeDriverManager().install())
-        self.browser = webdriver.Chrome(service=service, options=options)
-
-    def _get_page(self, url: str) -> str:
-        """Get HTML content from a URL, using browser or requests as needed"""
-        cache_file = self.cache_dir / f"{hash(url)}.html"
-
-        # Check if cached version exists
-        if cache_file.exists():
-            logger.info(f"Using cached version of {url}")
-            return cache_file.read_text(encoding="utf-8")
-
-        logger.info(f"Fetching {url}")
-
-        if self.config["requires_js"]:
-            self.browser.get(url)
-            # Wait for page to load
-            WebDriverWait(self.browser, 10).until(
-                EC.presence_of_element_located((By.TAG_NAME, "body"))
-            )
-
-            # Handle dynamic loading if needed
-            if self.config["dynamic_loading"]:
-                # Scroll to load more content
-                self.browser.execute_script(
-                    "window.scrollTo(0, document.body.scrollHeight);"
-                )
-                time.sleep(2)
-
-            html = self.browser.page_source
-        else:
-            response = requests.get(url)
-            response.raise_for_status()
-            html = response.text
-
-        # Cache the result
-        cache_file.write_text(html, encoding="utf-8")
-        return html
-
-    def extract_functions(self) -> List[Dict[str, Any]]:
-        """Extract function information from documentation"""
-        all_functions = []
-
-        for path in self.config["function_paths"]:
-            url = self.config["base_url"] + path
-            html = self._get_page(url)
-            soup = BeautifulSoup(html, "html.parser")
-
-            # Extract function elements based on language-specific configuration
-            function_elements = soup.select(self.config["function_selector"])
-
-            for element in function_elements:
-                function_info = self._parse_function_element(element)
-                if function_info:
-                    all_functions.append(function_info)
-
-        return all_functions
-
-    def extract_types(self) -> List[Dict[str, Any]]:
-        """Extract type information from documentation"""
-        all_types = []
-
-        for path in self.config["type_paths"]:
-            url = self.config["base_url"] + path
-            html = self._get_page(url)
-            soup = BeautifulSoup(html, "html.parser")
-
-            # Type extraction is language-specific, implemented in subclasses
-            all_types.extend(self._parse_type_page(soup))
-
-        return all_types
-
-    def extract_operators(self) -> List[Dict[str, Any]]:
-        """Extract operator information from documentation"""
-        all_operators = []
-
-        for path in self.config["operator_paths"]:
-            url = self.config["base_url"] + path
-            html = self._get_page(url)
-            soup = BeautifulSoup(html, "html.parser")
-
-            # Operator extraction is language-specific, implemented in subclasses
-            all_operators.extend(self._parse_operator_page(soup))
-
-        return all_operators
-
-    def _parse_function_element(self, element) -> Optional[Dict[str, Any]]:
-        """Parse a function element to extract name, signature, description, etc."""
-        # Base implementation, should be overridden in subclasses
-        try:
-            function_name = element.get_text().strip()
-            if not function_name:
-                return None
-
-            # Get parent element for potential description
-            parent = element.parent
-            description = ""
-            if parent:
-                # Look for a paragraph after the function name
-                next_sibling = parent.find_next_sibling("p")
-                if next_sibling:
-                    description = next_sibling.get_text().strip()
-
-            return {
-                "name": function_name,
-                "signature": function_name,
-                "description": description,
-                "parameters": [],
-                "return_type": "",
-                "url": element.get("href") if element.name == "a" else "",
-                "source": self.language,
-            }
-        except Exception as e:
-            logger.error(f"Error parsing function element: {e}")
-            return None
-
-    def _parse_type_page(self, soup) -> List[Dict[str, Any]]:
-        """Parse a type documentation page"""
-        # Base implementation, should be overridden in subclasses
-        return []
-
-    def _parse_operator_page(self, soup) -> List[Dict[str, Any]]:
-        """Parse an operator documentation page"""
-        # Base implementation, should be overridden in subclasses
-        return []
-
-    def download_all(self):
-        """Download all documentation pages for caching"""
-        urls = []
-
-        # Collect all URLs to download
-        for path_list in [
-            self.config["function_paths"],
-            self.config["type_paths"],
-            self.config["operator_paths"],
-        ]:
-            for path in path_list:
-                urls.append(self.config["base_url"] + path)
-
-        # Download pages in parallel
-        with ThreadPoolExecutor(max_workers=5) as executor:
-            future_to_url = {executor.submit(self._get_page, url): url for url in urls}
-            for future in as_completed(future_to_url):
-                url = future_to_url[future]
-                try:
-                    future.result()
-                    logger.info(f"Downloaded {url}")
-                except Exception as e:
-                    logger.error(f"Error downloading {url}: {e}")
-
-    def analyze(self):
-        """Analyze documentation and save structured data"""
-        logger.info(f"Analyzing {self.language} documentation...")
-
-        data = {
-            "language": self.language,
-            "timestamp": datetime.now().isoformat(),
-            "functions": self.extract_functions(),
-            "types": self.extract_types(),
-            "operators": self.extract_operators(),
-        }
-
-        # Save to JSON file
-        output_file = self.analysis_dir / f"{self.language}.json"
-        with open(output_file, "w", encoding="utf-8") as f:
-            json.dump(data, f, indent=2)
-
-        logger.info(f"Analysis complete. Saved to {output_file}")
-        return data
-
-    def close(self):
-        """Close browser if used"""
-        if self.browser:
-            self.browser.quit()
-
-
-# Language-specific crawler implementations
-
-
-class MetalCrawler(DocCrawler):
-    """Metal Shading Language documentation crawler"""
-
-    def _parse_function_element(self, element) -> Optional[Dict[str, Any]]:
-        try:
-            # Metal documentation has a specific structure
-            function_name = element.get_text().strip()
-
-            # Find the description
-            description_div = element.find_parent("div").find_next_sibling("div")
-            description = description_div.get_text().strip() if description_div else ""
-
-            # Try to find the function signature
-            signature = function_name
-            signature_element = element.find_parent("div").find("code")
-            if signature_element:
-                signature = signature_element.get_text().strip()
-
-            # Parse parameters and return type from signature
-            parameters = []
-            return_type = ""
-
-            # Regex to extract return type and parameters
-            signature_match = re.search(r"(\w+)\s+(\w+)\((.*?)\)", signature)
-            if signature_match:
-                return_type = signature_match.group(1)
-                parameters_str = signature_match.group(3)
-
-                # Parse parameters
-                if parameters_str:
-                    param_parts = parameters_str.split(",")
-                    for part in param_parts:
-                        part = part.strip()
-                        if part:
-                            param_type, param_name = part.rsplit(" ", 1)
-                            parameters.append(
-                                {"name": param_name, "type": param_type.strip()}
-                            )
-
-            return {
-                "name": function_name,
-                "signature": signature,
-                "description": description,
-                "parameters": parameters,
-                "return_type": return_type,
-                "url": (
-                    self.config["base_url"] + element.get("href")
-                    if element.name == "a" and element.get("href")
-                    else ""
-                ),
-                "source": self.language,
-            }
-        except Exception as e:
-            logger.error(f"Error parsing Metal function element: {e}")
-            return None
-
-    def _parse_type_page(self, soup) -> List[Dict[str, Any]]:
-        types = []
-        # Look for type definitions in data_types page
-        type_elements = soup.select("h3.jump-target")
-
-        for elem in type_elements:
-            type_name = elem.get_text().strip()
-            description_elem = elem.find_next_sibling("p")
-            description = (
-                description_elem.get_text().strip() if description_elem else ""
-            )
-
-            types.append(
-                {"name": type_name, "description": description, "source": self.language}
-            )
-
-        return types
-
-    def _parse_operator_page(self, soup) -> List[Dict[str, Any]]:
-        operators = []
-        # Find operator tables
-        operator_tables = soup.select("table")
-
-        for table in operator_tables:
-            # Get table headers
-            headers = [th.get_text().strip() for th in table.select("th")]
-
-            # Process each row
-            for row in table.select("tr"):
-                cells = row.select("td")
-                if not cells:
-                    continue
-
-                operator_data = {}
-                for i, cell in enumerate(cells):
-                    if i < len(headers):
-                        operator_data[headers[i].lower()] = cell.get_text().strip()
-
-                if "operator" in operator_data:
-                    operators.append(
-                        {
-                            "symbol": operator_data.get("operator", ""),
-                            "name": operator_data.get(
-                                "name", operator_data.get("operator", "")
-                            ),
-                            "description": operator_data.get("description", ""),
-                            "example": operator_data.get("example", ""),
-                            "source": self.language,
-                        }
-                    )
-
-        return operators
-
-
-class DirectXCrawler(DocCrawler):
-    """DirectX HLSL documentation crawler"""
-
-    def _parse_function_element(self, element) -> Optional[Dict[str, Any]]:
-        try:
-            function_name = element.get_text().strip()
-
-            # Skip non-function headers
-            if not re.match(r"^[a-zA-Z0-9_]+$", function_name):
-                return None
-
-            # Find description
-            description = ""
-            next_elem = element.find_next_sibling()
-            if next_elem and next_elem.name == "p":
-                description = next_elem.get_text().strip()
-
-            # Try to find code example with signature
-            code_elem = None
-            curr_elem = element
-            for _ in range(5):  # Check next 5 siblings
-                curr_elem = curr_elem.find_next_sibling()
-                if curr_elem and curr_elem.name == "pre":
-                    code_elem = curr_elem
-                    break
-
-            signature = function_name
-            parameters = []
-            return_type = ""
-
-            if code_elem:
-                code_text = code_elem.get_text().strip()
-                # Parse the signature
-                sig_match = re.search(r"(\w+)\s+(\w+)\s*\((.*?)\)", code_text)
-                if sig_match:
-                    return_type = sig_match.group(1)
-                    function_name = sig_match.group(2)  # Update function name
-                    signature = code_text
-
-                    # Parse parameters
-                    params_text = sig_match.group(3)
-                    if params_text:
-                        param_parts = params_text.split(",")
-                        for part in param_parts:
-                            part = part.strip()
-                            if part:
-                                param_match = re.match(r"(\w+)\s+(\w+)", part)
-                                if param_match:
-                                    param_type = param_match.group(1)
-                                    param_name = param_match.group(2)
-                                    parameters.append(
-                                        {"name": param_name, "type": param_type}
-                                    )
-
-            return {
-                "name": function_name,
-                "signature": signature,
-                "description": description,
-                "parameters": parameters,
-                "return_type": return_type,
-                "url": (
-                    f"{self.config['base_url']}/dx-graphics-hlsl-intrinsic-functions#{function_name.lower()}"
-                ),
-                "source": self.language,
-            }
-        except Exception as e:
-            logger.error(f"Error parsing DirectX function element: {e}")
-            return None
-
-    def _parse_type_page(self, soup) -> List[Dict[str, Any]]:
-        types = []
-        # Find type sections
-        type_sections = soup.select("h3")
-
-        for section in type_sections:
-            section_id = section.get("id", "")
-            if "type" in section_id.lower():
-                type_name = section.get_text().strip()
-                description = ""
-
-                # Get description from next paragraph
-                next_elem = section.find_next_sibling("p")
-                if next_elem:
-                    description = next_elem.get_text().strip()
-
-                types.append(
-                    {
-                        "name": type_name,
-                        "description": description,
-                        "source": self.language,
-                    }
-                )
-
-        return types
-
-    def _parse_operator_page(self, soup) -> List[Dict[str, Any]]:
-        operators = []
-        # Find operator tables
-        operator_sections = soup.select("h2")
-
-        for section in operator_sections:
-            if "operator" in section.get_text().lower():
-                # Find tables in this section
-                tables = section.find_next_siblings("table")
-
-                for table in tables:
-                    rows = table.select("tr")
-                    if not rows:
-                        continue
-
-                    # Get headers from first row
-                    headers = [
-                        th.get_text().strip().lower() for th in rows[0].select("th")
-                    ]
-
-                    # Process data rows
-                    for row in rows[1:]:
-                        cells = row.select("td")
-                        if not cells:
-                            continue
-
-                        operator_data = {}
-                        for i, cell in enumerate(cells):
-                            if i < len(headers):
-                                operator_data[headers[i]] = cell.get_text().strip()
-
-                        operators.append(
-                            {
-                                "symbol": operator_data.get("operator", ""),
-                                "name": operator_data.get(
-                                    "name", operator_data.get("operator", "")
-                                ),
-                                "description": operator_data.get("description", ""),
-                                "example": operator_data.get("example", ""),
-                                "source": self.language,
-                            }
-                        )
-
-        return operators
-
-
-class OpenGLCrawler(DocCrawler):
-    """OpenGL GLSL documentation crawler"""
-
-    def _parse_function_element(self, element) -> Optional[Dict[str, Any]]:
-        try:
-            if not element.name == "a":
-                return None
-
-            href = element.get("href", "")
-            if not href or not href.endswith(".xml"):
-                return None
-
-            function_name = element.get_text().strip()
-
-            # Follow the link to get function details
-            function_url = (
-                f"{self.config['base_url']}/html/{href.replace('.xml', '.html')}"
-            )
-            function_html = self._get_page(function_url)
-            function_soup = BeautifulSoup(function_html, "html.parser")
-
-            # Extract function details
-            synopsis = function_soup.select_one(".refsynopsisdiv")
-            signature = ""
-            if synopsis:
-                signature_elem = synopsis.select_one("pre.funcsynopsis")
-                if signature_elem:
-                    signature = signature_elem.get_text().strip()
-
-            # Extract description
-            description = ""
-            desc_div = function_soup.select_one(".refsect1 .para")
-            if desc_div:
-                description = desc_div.get_text().strip()
-
-            # Parse parameters and return type
-            parameters = []
-            return_type = ""
-
-            if signature:
-                # Parse return type and function name
-                sig_match = re.search(r"(\w+)\s+(\w+)\s*\((.*?)\)", signature)
-                if sig_match:
-                    return_type = sig_match.group(1)
-                    function_name = sig_match.group(2)
-                    params_text = sig_match.group(3)
-
-                    # Parse parameters
-                    if params_text and params_text != "void":
-                        param_parts = params_text.split(",")
-                        for part in param_parts:
-                            part = part.strip()
-                            if part:
-                                param_match = re.match(r"(\w+)\s+(\w+)", part)
-                                if param_match:
-                                    param_type = param_match.group(1)
-                                    param_name = param_match.group(2)
-                                    parameters.append(
-                                        {"name": param_name, "type": param_type}
-                                    )
-
-            return {
-                "name": function_name,
-                "signature": signature,
-                "description": description,
-                "parameters": parameters,
-                "return_type": return_type,
-                "url": function_url,
-                "source": self.language,
-            }
-        except Exception as e:
-            logger.error(f"Error parsing OpenGL function element: {e}")
-            return None
-
-    def _parse_type_page(self, soup) -> List[Dict[str, Any]]:
-        types = []
-        # Find data type sections
-        type_sections = soup.select("h2, h3")
-
-        current_section = ""
-        for section in type_sections:
-            section_text = section.get_text().lower()
-            if "data type" in section_text:
-                current_section = section.get_text().strip()
-                continue
-
-            if current_section and section.name == "h3":
-                type_name = section.get_text().strip()
-
-                # Get description
-                description = ""
-                next_elem = section.find_next_sibling("p")
-                if next_elem:
-                    description = next_elem.get_text().strip()
-
-                types.append(
-                    {
-                        "name": type_name,
-                        "description": description,
-                        "category": current_section,
-                        "source": self.language,
-                    }
-                )
-
-        return types
-
-    def _parse_operator_page(self, soup) -> List[Dict[str, Any]]:
-        operators = []
-        # Find operator sections
-        operator_sections = soup.select("h2, h3")
-
-        in_operator_section = False
-        for section in operator_sections:
-            section_text = section.get_text().lower()
-
-            # Check if we're in the operators section
-            if "operator" in section_text and section.name == "h2":
-                in_operator_section = True
-                continue
-            elif section.name == "h2":
-                in_operator_section = False
-
-            if in_operator_section and section.name == "h3":
-                operator_name = section.get_text().strip()
-
-                # Get description
-                description = ""
-                next_elem = section.find_next_sibling("p")
-                if next_elem:
-                    description = next_elem.get_text().strip()
-
-                # Extract operator symbol from name or description
-                symbol = ""
-                symbol_match = re.search(
-                    r"(\+|\-|\*|\/|\%|\=|\!|\<|\>|\&|\||\^|\~)+", operator_name
-                )
-                if symbol_match:
-                    symbol = symbol_match.group(0)
-
-                operators.append(
-                    {
-                        "symbol": symbol,
-                        "name": operator_name,
-                        "description": description,
-                        "source": self.language,
-                    }
-                )
-
-        return operators
-
-
-# Factory method to get the appropriate crawler
-def get_crawler(language: str) -> DocCrawler:
-    """Get a language-specific crawler instance"""
-    if language not in DOCUMENTATION_SOURCES:
-        raise ValueError(f"Unsupported language: {language}")
-
-    if language == "metal":
-        return MetalCrawler(language)
-    elif language == "directx":
-        return DirectXCrawler(language)
-    elif language == "opengl":
-        return OpenGLCrawler(language)
-    else:
-        # Use the base crawler for other languages
-        return DocCrawler(language)
-
-
-def main():
-    """Main entry point"""
-    parser = argparse.ArgumentParser(
-        description="Documentation Crawler for Shader Languages"
-    )
-    parser.add_argument("--language", "-l", required=True, help="Language to analyze")
-    parser.add_argument(
-        "--download-only",
-        action="store_true",
-        help="Only download documentation without analysis",
-    )
-    parser.add_argument(
-        "--analyze-only", action="store_true", help="Only analyze without downloading"
-    )
-
-    args = parser.parse_args()
-
-    if args.language not in DOCUMENTATION_SOURCES:
-        logger.error(f"Unsupported language: {args.language}")
-        return 1
-
-    crawler = get_crawler(args.language)
-
-    try:
-        if args.download_only:
-            logger.info(f"Downloading documentation for {args.language}...")
-            crawler.download_all()
-        elif args.analyze_only:
-            logger.info(f"Analyzing documentation for {args.language}...")
-            crawler.analyze()
-        else:
-            # Both download and analyze
-            logger.info(f"Processing documentation for {args.language}...")
-            crawler.download_all()
-            crawler.analyze()
-    finally:
-        crawler.close()
-
-    return 0
-
-
-if __name__ == "__main__":
-    exit(main())
diff --git a/.github/scripts/feature_discovery.py b/.github/scripts/feature_discovery.py
deleted file mode 100755
index e9cd076..0000000
--- a/.github/scripts/feature_discovery.py
+++ /dev/null
@@ -1,298 +0,0 @@
-#!/usr/bin/env python3
-"""
-Feature Discovery Script for CrossGL Translator
-
-This script analyzes the supported features across different backends
-and creates GitHub issues for missing implementations.
-"""
-
-import os
-import re
-from github import Github
-from github.GithubException import GithubException
-
-# Reference backends to compare against
-REFERENCE_BACKENDS = ["metal", "directx", "opengl", "vulkan", "slang", "mojo"]
-
-# Backend directories
-BACKEND_DIRS = {
-    "metal": "crosstl/backend/Metal",
-    "directx": "crosstl/backend/DirectX",
-    "opengl": "crosstl/backend/Opengl",
-    "vulkan": "crosstl/backend/Vulkan",
-    "slang": "crosstl/backend/slang",
-    "mojo": "crosstl/backend/Mojo",
-}
-
-# Codegen files
-CODEGEN_FILES = {
-    "metal": "crosstl/translator/codegen/metal_codegen.py",
-    "directx": "crosstl/translator/codegen/directx_codegen.py",
-    "opengl": "crosstl/translator/codegen/opengl_codegen.py",
-    "vulkan": "crosstl/translator/codegen/vulkan_codegen.py",
-    "slang": "crosstl/translator/codegen/slang_codegen.py",
-    "mojo": "crosstl/translator/codegen/mojo_codegen.py",
-}
-
-# Types of features to search for
-FEATURE_TYPES = {
-    "functions": r"def\s+(\w+)\s*\(",  # Match function definitions
-    "operators": (
-        r"(visit_(?:Binary|Unary)Op).*?operator\s*==\s*['\"]([+\-*/%<>=!&|^~]+)['\"]"
-    ),  # Match operators
-    "types": (
-        r"(?:visit_TypeDecl|process_type)\(.*?['\"](\w+)['\"]"  # Match type declarations
-    ),
-}
-
-
-def get_features_from_file(file_path, feature_type):
-    """Extract features of a particular type from a file."""
-    if not os.path.exists(file_path):
-        return set()
-
-    with open(file_path, "r") as f:
-        content = f.read()
-
-    pattern = FEATURE_TYPES[feature_type]
-    if feature_type == "operators":
-        # For operators, we need the second group from the regex
-        return {match.group(2) for match in re.finditer(pattern, content, re.DOTALL)}
-    else:
-        # For functions and types, we need the first group
-        return {match.group(1) for match in re.finditer(pattern, content, re.DOTALL)}
-
-
-def get_features_for_backend(backend):
-    """Get all implemented features for a backend."""
-    features = {"functions": set(), "operators": set(), "types": set()}
-
-    # Check the main codegen file
-    codegen_file = CODEGEN_FILES.get(backend)
-    if codegen_file and os.path.exists(codegen_file):
-        for feature_type in FEATURE_TYPES:
-            features[feature_type].update(
-                get_features_from_file(codegen_file, feature_type)
-            )
-
-    # Check backend directory
-    backend_dir = BACKEND_DIRS.get(backend)
-    if backend_dir and os.path.exists(backend_dir):
-        for root, _, files in os.walk(backend_dir):
-            for file in files:
-                if file.endswith(".py"):
-                    file_path = os.path.join(root, file)
-                    for feature_type in FEATURE_TYPES:
-                        features[feature_type].update(
-                            get_features_from_file(file_path, feature_type)
-                        )
-
-    return features
-
-
-def find_missing_features():
-    """Find missing features across all backends."""
-    all_features = {
-        backend: get_features_for_backend(backend) for backend in REFERENCE_BACKENDS
-    }
-
-    # Aggregate all possible features across all backends
-    all_possible_features = {
-        feature_type: (
-            set().union(
-                *(
-                    backend_features[feature_type]
-                    for backend_features in all_features.values()
-                )
-            )
-        )
-        for feature_type in FEATURE_TYPES
-    }
-
-    # Find missing features for each backend
-    missing_features = {}
-    for backend in REFERENCE_BACKENDS:
-        missing_features[backend] = {
-            feature_type: (
-                all_possible_features[feature_type]
-                - all_features[backend][feature_type]
-            )
-            for feature_type in FEATURE_TYPES
-        }
-
-    return missing_features
-
-
-def get_feature_documentation(feature, feature_type, backend):
-    """
-    Attempt to get documentation for a feature from the implemented backends.
-    This would search for docstrings or comments near the feature implementation.
-    """
-    # This is a simplified version - in a real implementation, you would
-    # parse docstrings and comments from source files where the feature is implemented
-    for ref_backend in REFERENCE_BACKENDS:
-        if ref_backend == backend:
-            continue
-
-        # Check if this backend has implemented the feature
-        features = get_features_for_backend(ref_backend)
-        if feature in features[feature_type]:
-            # Check codegen file first
-            codegen_file = CODEGEN_FILES.get(ref_backend)
-            if codegen_file and os.path.exists(codegen_file):
-                with open(codegen_file, "r") as f:
-                    content = f.read()
-
-                # Look for function/method definition with feature name
-                if feature_type == "functions":
-                    method_pattern = r"def\s+(?:visit_)?(\w+)\s*\(.*?\).*?(?:\"\"\"|\'\'\')(.*?)(?:\"\"\"|\'\'\')|\#(.*?)$"
-                    for match in re.finditer(
-                        method_pattern, content, re.DOTALL | re.MULTILINE
-                    ):
-                        if match.group(
-                            1
-                        ) == feature or f"visit_{feature}" == match.group(1):
-                            doc = match.group(2) or match.group(3)
-                            if doc:
-                                return f"Documentation from {ref_backend}:\n\n{doc.strip()}"
-
-    return f"No documentation found for {feature} in any backend implementation."
-
-
-def create_github_issues(missing_features):
-    """Create GitHub issues for missing features."""
-    github_token = os.environ.get("GITHUB_TOKEN")
-    if not github_token:
-        print("GITHUB_TOKEN environment variable is not set. Cannot create issues.")
-        return
-
-    repo_name = os.environ.get("GITHUB_REPOSITORY", "CrossGL/CrossGL-Translator")
-    gh = Github(github_token)
-    repo = gh.get_repo(repo_name)
-
-    # Create or get the main TODO issue
-    main_issue_title = "🚀 CrossGL Translator Feature Implementation TODO"
-    main_issue_body = """
-# CrossGL Translator Feature Implementation Tracking
-
-This issue tracks missing features across different backends in the CrossGL Translator.
-Each missing feature has its own issue linked below, organized by backend.
-
-This issue is automatically updated daily by the Feature Discovery workflow.
-
-## Missing Features by Backend
-    """
-
-    main_issue = None
-    # Try to find existing main issue
-    for issue in repo.get_issues(state="open"):
-        if issue.title == main_issue_title:
-            main_issue = issue
-            break
-
-    if not main_issue:
-        main_issue = repo.create_issue(
-            title=main_issue_title,
-            body=main_issue_body,
-            labels=["todo", "enhancement", "good first issue"],
-        )
-
-    # Process and create issues for each missing feature
-    backend_sections = {}
-    for backend in REFERENCE_BACKENDS:
-        backend_sections[backend] = f"\n### {backend.capitalize()} Backend\n\n"
-
-        for feature_type in FEATURE_TYPES:
-            missing = missing_features[backend][feature_type]
-            if missing:
-                backend_sections[
-                    backend
-                ] += f"\n#### Missing {feature_type.capitalize()}\n\n"
-
-                for feature in sorted(missing):
-                    # Check if issue already exists
-                    feature_issue_title = (
-                        f"[{backend.upper()}] Implement {feature_type[:-1]} '{feature}'"
-                    )
-                    existing_issue = None
-                    for issue in repo.get_issues(state="open"):
-                        if issue.title == feature_issue_title:
-                            existing_issue = issue
-                            break
-
-                    if not existing_issue:
-                        # Get documentation from other backends if available
-                        docs = get_feature_documentation(feature, feature_type, backend)
-
-                        issue_body = f"""
-# Missing {feature_type[:-1]} in {backend.capitalize()} Backend
-
-The {feature} {feature_type[:-1]} is implemented in one or more other backends, but is missing in {backend}.
-
-## Documentation
-
-{docs}
-
-## Implementation Task
-
-Implement the {feature} {feature_type[:-1]} in the {backend} backend.
-
-## Relevant Files
-
-- {CODEGEN_FILES.get(backend)}
-- {BACKEND_DIRS.get(backend)}
-"""
-
-                        try:
-                            new_issue = repo.create_issue(
-                                title=feature_issue_title,
-                                body=issue_body,
-                                labels=[
-                                    backend,
-                                    feature_type[:-1],
-                                    "enhancement",
-                                    "good first issue",
-                                ],
-                            )
-                            backend_sections[
-                                backend
-                            ] += f"- [ ] [{feature}](#{new_issue.number})\n"
-                        except GithubException as e:
-                            print(f"Error creating issue for {feature}: {e}")
-                            continue
-                    else:
-                        backend_sections[
-                            backend
-                        ] += f"- [ ] [{feature}](#{existing_issue.number})\n"
-
-    # Update main issue with new content
-    updated_body = main_issue_body
-    for backend, section in backend_sections.items():
-        if "#### Missing" in section:  # Only add sections with actual missing features
-            updated_body += section
-
-    main_issue.edit(body=updated_body)
-    print(f"Updated main issue: {main_issue.html_url}")
-
-
-def main():
-    """Main function to discover features and create issues."""
-    print("Starting feature discovery...")
-
-    missing_features = find_missing_features()
-
-    # Print summary
-    for backend in REFERENCE_BACKENDS:
-        total_missing = sum(len(missing_features[backend][ft]) for ft in FEATURE_TYPES)
-        print(f"{backend}: {total_missing} missing features")
-        for feature_type in FEATURE_TYPES:
-            print(f"  - {feature_type}: {len(missing_features[backend][feature_type])}")
-
-    # Create issues
-    create_github_issues(missing_features)
-
-    print("Feature discovery completed successfully.")
-
-
-if __name__ == "__main__":
-    main()
diff --git a/.github/scripts/generate_report.py b/.github/scripts/generate_report.py
deleted file mode 100755
index 93f9a40..0000000
--- a/.github/scripts/generate_report.py
+++ /dev/null
@@ -1,696 +0,0 @@
-#!/usr/bin/env python3
-"""
-Report Generator for CrossGL Translator Implementation Status
-
-This script generates comprehensive reports on the implementation status
-of different shader language features in the CrossGL Translator.
-"""
-
-import os
-import json
-import re
-import logging
-from pathlib import Path
-from datetime import datetime
-from typing import Dict, Set, Any
-import matplotlib.pyplot as plt
-import numpy as np
-import pandas as pd
-from jinja2 import Template
-
-# Setup logging
-logging.basicConfig(
-    level=logging.INFO,
-    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
-    handlers=[
-        logging.FileHandler(".github/logs/report_generator.log"),
-        logging.StreamHandler(),
-    ],
-)
-logger = logging.getLogger("report_generator")
-
-# Ensure directories exist
-os.makedirs(".cache/analysis", exist_ok=True)
-os.makedirs(".cache/reports", exist_ok=True)
-os.makedirs(".github/logs", exist_ok=True)
-
-# Implementation status
-IMPLEMENTATION_STATUS = {
-    "MISSING": 0,  # Not implemented at all
-    "PARTIAL": 1,  # Partially implemented
-    "COMPLETE": 2,  # Fully implemented
-}
-
-# Category types
-FEATURE_CATEGORIES = ["functions", "operators", "types"]
-
-# Language-specific settings (same as in issue_generator.py)
-LANGUAGE_SETTINGS = {
-    "metal": {
-        "name": "Metal Shading Language",
-        "doc_url": (
-            "https://developer.apple.com/documentation/metal/metal_shading_language"
-        ),
-        "priority": 1,
-    },
-    "directx": {
-        "name": "DirectX HLSL",
-        "doc_url": "https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl",
-        "priority": 2,
-    },
-    "opengl": {
-        "name": "OpenGL GLSL",
-        "doc_url": "https://www.khronos.org/registry/OpenGL-Refpages/gl4/",
-        "priority": 3,
-    },
-    "vulkan": {
-        "name": "Vulkan SPIR-V",
-        "doc_url": (
-            "https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html"
-        ),
-        "priority": 4,
-    },
-    "slang": {
-        "name": "Slang",
-        "doc_url": "https://shader-slang.com/slang/docs/reference/",
-        "priority": 5,
-    },
-    "mojo": {
-        "name": "Mojo",
-        "doc_url": "https://docs.modular.com/mojo/stdlib",
-        "priority": 6,
-    },
-}
-
-
-class CrossGLAnalyzer:
-    """Analyzes the CrossGL codebase to detect implemented features"""
-
-    def __init__(self):
-        self.crosstl_dir = Path("crosstl")
-        self.backends_dir = self.crosstl_dir / "backend"
-        self.translator_dir = self.crosstl_dir / "translator"
-        self.codegen_dir = self.translator_dir / "codegen"
-
-        self.implemented_features = {
-            "functions": self._get_implemented_functions(),
-            "operators": self._get_implemented_operators(),
-            "types": self._get_implemented_types(),
-        }
-
-    def _get_implemented_functions(self) -> Dict[str, Set[str]]:
-        """Get all implemented functions per backend"""
-        implemented = {lang: set() for lang in LANGUAGE_SETTINGS.keys()}
-
-        # Check codegen files for function implementations
-        for lang in implemented.keys():
-            backend_dir = self.backends_dir / lang.capitalize()
-            codegen_file = self.codegen_dir / f"{lang}_codegen.py"
-
-            if not backend_dir.exists() or not codegen_file.exists():
-                continue
-
-            # Extract functions from codegen files
-            if codegen_file.exists():
-                with open(codegen_file, "r") as f:
-                    content = f.read()
-
-                    # Look for function definitions and visit_* methods
-                    for match in re.finditer(r"def\s+(?:visit_)?(\w+)", content):
-                        function_name = match.group(1)
-                        # Filter out common methods that aren't actual shader functions
-                        if not function_name.startswith(("__", "visit_", "generate")):
-                            implemented[lang].add(function_name)
-
-            # Look through backend directory
-            if backend_dir.exists():
-                for py_file in backend_dir.glob("**/*.py"):
-                    with open(py_file, "r") as f:
-                        content = f.read()
-
-                        # Look for function definitions specific to this language
-                        for match in re.finditer(r"def\s+(\w+)", content):
-                            function_name = match.group(1)
-                            # Filter out common methods that aren't actual shader functions
-                            if not function_name.startswith("__"):
-                                implemented[lang].add(function_name)
-
-        return implemented
-
-    def _get_implemented_operators(self) -> Dict[str, Set[str]]:
-        """Get all implemented operators per backend"""
-        implemented = {lang: set() for lang in LANGUAGE_SETTINGS.keys()}
-
-        # Extract operators from codegen files
-        for lang in implemented.keys():
-            codegen_file = self.codegen_dir / f"{lang}_codegen.py"
-
-            if not codegen_file.exists():
-                continue
-
-            with open(codegen_file, "r") as f:
-                content = f.read()
-
-                # Look for operator handling in visit_BinaryOp, visit_UnaryOp, etc.
-                for match in re.finditer(
-                    r'(?:visit_(?:Binary|Unary)Op).*?operator\s*==\s*[\'"]([+\-*/%<>=!&|^~]+)[\'"]',
-                    content,
-                    re.DOTALL,
-                ):
-                    operator = match.group(1)
-                    implemented[lang].add(operator)
-
-        return implemented
-
-    def _get_implemented_types(self) -> Dict[str, Set[str]]:
-        """Get all implemented types per backend"""
-        implemented = {lang: set() for lang in LANGUAGE_SETTINGS.keys()}
-
-        # Extract types from codegen and backend files
-        for lang in implemented.keys():
-            codegen_file = self.codegen_dir / f"{lang}_codegen.py"
-
-            if not codegen_file.exists():
-                continue
-
-            with open(codegen_file, "r") as f:
-                content = f.read()
-
-                # Look for type processing
-                for match in re.finditer(
-                    r'(?:visit_TypeDecl|process_type)\(.*?[\'"](\w+)[\'"]', content
-                ):
-                    type_name = match.group(1)
-                    implemented[lang].add(type_name)
-
-        return implemented
-
-    def get_implementation_status(
-        self, feature_type: str, feature_name: str, language: str
-    ) -> int:
-        """Check if a feature is implemented for a specific language"""
-        if language not in self.implemented_features[feature_type]:
-            return IMPLEMENTATION_STATUS["MISSING"]
-
-        if feature_name in self.implemented_features[feature_type][language]:
-            return IMPLEMENTATION_STATUS["COMPLETE"]
-
-        # Check for partial implementation (e.g., function exists but with different signature)
-        if feature_type == "functions":
-            # Check if a similar function exists
-            similar_functions = {
-                func
-                for func in self.implemented_features[feature_type][language]
-                if feature_name.lower() in func.lower()
-            }
-            if similar_functions:
-                return IMPLEMENTATION_STATUS["PARTIAL"]
-
-        return IMPLEMENTATION_STATUS["MISSING"]
-
-
-class ReportGenerator:
-    """Generates implementation status reports"""
-
-    def __init__(self):
-        self.analyzer = CrossGLAnalyzer()
-        self.analysis_dir = Path(".cache/analysis")
-        self.reports_dir = Path(".cache/reports")
-        self.reports_dir.mkdir(parents=True, exist_ok=True)
-
-        # Load analysis data
-        self.analysis_data = self._load_analysis_data()
-
-    def _load_analysis_data(self) -> Dict[str, Dict]:
-        """Load all analysis data files"""
-        data = {}
-
-        for analysis_file in self.analysis_dir.glob("*.json"):
-            language = analysis_file.stem
-            with open(analysis_file, "r") as f:
-                data[language] = json.load(f)
-
-        return data
-
-    def generate_summary_report(self) -> Dict[str, Any]:
-        """Generate a summary of implementation status across all languages"""
-        summary = {
-            "timestamp": datetime.now().isoformat(),
-            "languages": {},
-            "overall_progress": 0.0,
-        }
-
-        total_features = 0
-        total_implemented = 0
-
-        for language, language_data in self.analysis_data.items():
-            language_summary = {
-                "name": LANGUAGE_SETTINGS[language]["name"],
-                "categories": {},
-                "progress": 0.0,
-                "total_features": 0,
-                "implemented_features": 0,
-                "partial_features": 0,
-                "missing_features": 0,
-            }
-
-            language_total = 0
-            language_implemented = 0
-            language_partial = 0
-
-            for category in FEATURE_CATEGORIES:
-                if category not in language_data:
-                    continue
-
-                features = language_data[category]
-                category_total = len(features)
-                category_implemented = 0
-                category_partial = 0
-                category_missing = 0
-
-                for feature in features:
-                    status = self.analyzer.get_implementation_status(
-                        category, feature["name"], language
-                    )
-                    if status == IMPLEMENTATION_STATUS["COMPLETE"]:
-                        category_implemented += 1
-                    elif status == IMPLEMENTATION_STATUS["PARTIAL"]:
-                        category_partial += 1
-                    else:
-                        category_missing += 1
-
-                # Calculate progress (complete = 1.0, partial = 0.5)
-                category_progress = (
-                    (category_implemented + 0.5 * category_partial) / category_total
-                    if category_total > 0
-                    else 1.0
-                )
-
-                language_summary["categories"][category] = {
-                    "total": category_total,
-                    "implemented": category_implemented,
-                    "partial": category_partial,
-                    "missing": category_missing,
-                    "progress": category_progress,
-                }
-
-                language_total += category_total
-                language_implemented += category_implemented
-                language_partial += category_partial
-
-            # Calculate language progress
-            language_summary["total_features"] = language_total
-            language_summary["implemented_features"] = language_implemented
-            language_summary["partial_features"] = language_partial
-            language_summary["missing_features"] = (
-                language_total - language_implemented - language_partial
-            )
-            language_summary["progress"] = (
-                (language_implemented + 0.5 * language_partial) / language_total
-                if language_total > 0
-                else 1.0
-            )
-
-            summary["languages"][language] = language_summary
-
-            total_features += language_total
-            total_implemented += language_implemented + 0.5 * language_partial
-
-        # Calculate overall progress
-        summary["overall_progress"] = (
-            total_implemented / total_features if total_features > 0 else 1.0
-        )
-        summary["total_features"] = total_features
-        summary["total_implemented"] = total_implemented
-
-        return summary
-
-    def generate_detailed_report(self, language: str) -> Dict[str, Any]:
-        """Generate a detailed report for a specific language"""
-        if language not in self.analysis_data:
-            logger.warning(f"No analysis data found for {language}")
-            return {}
-
-        language_data = self.analysis_data[language]
-
-        detailed_report = {
-            "language": language,
-            "name": LANGUAGE_SETTINGS[language]["name"],
-            "timestamp": datetime.now().isoformat(),
-            "categories": {},
-        }
-
-        for category in FEATURE_CATEGORIES:
-            if category not in language_data:
-                continue
-
-            features = language_data[category]
-            feature_details = []
-
-            for feature in features:
-                status = self.analyzer.get_implementation_status(
-                    category, feature["name"], language
-                )
-                status_text = (
-                    "Implemented"
-                    if status == IMPLEMENTATION_STATUS["COMPLETE"]
-                    else (
-                        "Partial"
-                        if status == IMPLEMENTATION_STATUS["PARTIAL"]
-                        else "Missing"
-                    )
-                )
-
-                feature_details.append(
-                    {
-                        "name": feature["name"],
-                        "status": status_text,
-                        "status_code": status,
-                        "description": feature.get("description", ""),
-                        "signature": feature.get("signature", ""),
-                        "url": feature.get("url", ""),
-                    }
-                )
-
-            # Sort by status (missing first, then partial, then implemented)
-            feature_details.sort(key=lambda f: f["status_code"])
-
-            detailed_report["categories"][category] = feature_details
-
-        return detailed_report
-
-    def generate_html_report(self, summary: Dict[str, Any]) -> str:
-        """Generate an HTML report from the summary data"""
-        template_html = """
-        <!DOCTYPE html>
-        <html lang="en">
-        <head>
-            <meta charset="UTF-8">
-            <meta name="viewport" content="width=device-width, initial-scale=1.0">
-            <title>CrossGL Translator Implementation Status</title>
-            <style>
-                body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 1200px; margin: 0 auto; padding: 20px; }
-                h1, h2, h3 { color: #444; }
-                .progress-bar { background-color: #f1f1f1; height: 20px; border-radius: 10px; overflow: hidden; margin: 10px 0; }
-                .progress-bar-fill { height: 100%; background-color: #4CAF50; float: left; }
-                .progress-bar-partial { height: 100%; background-color: #FFC107; float: left; }
-                .summary-table { width: 100%; border-collapse: collapse; margin: 20px 0; }
-                .summary-table th, .summary-table td { border: 1px solid #ddd; padding: 8px; text-align: left; }
-                .summary-table th { background-color: #f2f2f2; }
-                .summary-table tr:nth-child(even) { background-color: #f9f9f9; }
-                .chart-container { width: 100%; height: 400px; margin: 20px 0; }
-                .category-section { margin-top: 30px; }
-                .timestamp { color: #888; font-size: 0.8em; margin-top: 40px; }
-            </style>
-        </head>
-        <body>
-            <h1>CrossGL Translator Implementation Status</h1>
-            <p>Overall implementation progress: {{ "%.1f"|format(summary.overall_progress * 100) }}%</p>
-            
-            <div class="progress-bar">
-                <div class="progress-bar-fill" style="width: {{ summary.overall_progress * 100 }}%;"></div>
-            </div>
-            
-            <h2>Summary by Language</h2>
-            <table class="summary-table">
-                <tr>
-                    <th>Language</th>
-                    <th>Progress</th>
-                    <th>Total Features</th>
-                    <th>Implemented</th>
-                    <th>Partial</th>
-                    <th>Missing</th>
-                </tr>
-                {% for lang_code, lang_data in summary.languages.items() %}
-                <tr>
-                    <td><a href="details_{{ lang_code }}.html">{{ lang_data.name }}</a></td>
-                    <td>
-                        <div class="progress-bar" style="margin: 0;">
-                            <div class="progress-bar-fill" style="width: {{ lang_data.implemented_features / lang_data.total_features * 100 if lang_data.total_features > 0 else 0 }}%;"></div>
-                            <div class="progress-bar-partial" style="width: {{ lang_data.partial_features / lang_data.total_features * 100 if lang_data.total_features > 0 else 0 }}%;"></div>
-                        </div>
-                        {{ "%.1f"|format(lang_data.progress * 100) }}%
-                    </td>
-                    <td>{{ lang_data.total_features }}</td>
-                    <td>{{ lang_data.implemented_features }}</td>
-                    <td>{{ lang_data.partial_features }}</td>
-                    <td>{{ lang_data.missing_features }}</td>
-                </tr>
-                {% endfor %}
-            </table>
-            
-            <h2>Implementation by Category</h2>
-            {% for lang_code, lang_data in summary.languages.items() %}
-            <div class="category-section">
-                <h3>{{ lang_data.name }}</h3>
-                <table class="summary-table">
-                    <tr>
-                        <th>Category</th>
-                        <th>Progress</th>
-                        <th>Total</th>
-                        <th>Implemented</th>
-                        <th>Partial</th>
-                        <th>Missing</th>
-                    </tr>
-                    {% for cat_name, cat_data in lang_data.categories.items() %}
-                    <tr>
-                        <td>{{ cat_name.title() }}</td>
-                        <td>
-                            <div class="progress-bar" style="margin: 0;">
-                                <div class="progress-bar-fill" style="width: {{ cat_data.implemented / cat_data.total * 100 if cat_data.total > 0 else 0 }}%;"></div>
-                                <div class="progress-bar-partial" style="width: {{ cat_data.partial / cat_data.total * 100 if cat_data.total > 0 else 0 }}%;"></div>
-                            </div>
-                            {{ "%.1f"|format(cat_data.progress * 100) }}%
-                        </td>
-                        <td>{{ cat_data.total }}</td>
-                        <td>{{ cat_data.implemented }}</td>
-                        <td>{{ cat_data.partial }}</td>
-                        <td>{{ cat_data.missing }}</td>
-                    </tr>
-                    {% endfor %}
-                </table>
-            </div>
-            {% endfor %}
-            
-            <p class="timestamp">Report generated on {{ summary.timestamp }}</p>
-        </body>
-        </html>
-        """
-
-        template = Template(template_html)
-        return template.render(summary=summary)
-
-    def generate_detailed_html_report(
-        self, language: str, detailed_report: Dict[str, Any]
-    ) -> str:
-        """Generate a detailed HTML report for a specific language"""
-        template_html = """
-        <!DOCTYPE html>
-        <html lang="en">
-        <head>
-            <meta charset="UTF-8">
-            <meta name="viewport" content="width=device-width, initial-scale=1.0">
-            <title>{{ report.name }} Implementation Details</title>
-            <style>
-                body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 1200px; margin: 0 auto; padding: 20px; }
-                h1, h2, h3 { color: #444; }
-                .nav-links { margin: 20px 0; }
-                .feature-table { width: 100%; border-collapse: collapse; margin: 20px 0; }
-                .feature-table th, .feature-table td { border: 1px solid #ddd; padding: 8px; text-align: left; }
-                .feature-table th { background-color: #f2f2f2; }
-                .feature-table tr:nth-child(even) { background-color: #f9f9f9; }
-                .status-implemented { color: #4CAF50; }
-                .status-partial { color: #FF9800; }
-                .status-missing { color: #F44336; }
-                .timestamp { color: #888; font-size: 0.8em; margin-top: 40px; }
-                .signature { font-family: monospace; background-color: #f8f8f8; padding: 8px; border-radius: 4px; white-space: pre-wrap; }
-                .description { max-width: 400px; }
-            </style>
-        </head>
-        <body>
-            <div class="nav-links">
-                <a href="index.html">← Back to Summary</a>
-            </div>
-            
-            <h1>{{ report.name }} Implementation Details</h1>
-            
-            {% for category, features in report.categories.items() %}
-            <h2>{{ category.title() }}</h2>
-            <table class="feature-table">
-                <tr>
-                    <th>Feature</th>
-                    <th>Status</th>
-                    <th>Signature</th>
-                    <th>Description</th>
-                </tr>
-                {% for feature in features %}
-                <tr>
-                    <td>
-                        {% if feature.url %}
-                        <a href="{{ feature.url }}" target="_blank">{{ feature.name }}</a>
-                        {% else %}
-                        {{ feature.name }}
-                        {% endif %}
-                    </td>
-                    <td class="status-{{ feature.status.lower() }}">{{ feature.status }}</td>
-                    <td>
-                        {% if feature.signature %}
-                        <div class="signature">{{ feature.signature }}</div>
-                        {% endif %}
-                    </td>
-                    <td class="description">{{ feature.description }}</td>
-                </tr>
-                {% endfor %}
-            </table>
-            {% endfor %}
-            
-            <p class="timestamp">Report generated on {{ report.timestamp }}</p>
-        </body>
-        </html>
-        """
-
-        template = Template(template_html)
-        return template.render(report=detailed_report)
-
-    def generate_visualizations(self, summary: Dict[str, Any]):
-        """Generate visualization charts for the reports"""
-        reports_dir = self.reports_dir
-
-        # 1. Overall progress bar chart by language
-        languages = []
-        implemented = []
-        partial = []
-        missing = []
-
-        for lang_code, lang_data in summary["languages"].items():
-            languages.append(LANGUAGE_SETTINGS[lang_code]["name"])
-            implemented.append(lang_data["implemented_features"])
-            partial.append(lang_data["partial_features"])
-            missing.append(lang_data["missing_features"])
-
-        # Create stacked bar chart
-        fig, ax = plt.subplots(figsize=(12, 6))
-
-        bar_width = 0.8
-        ind = np.arange(len(languages))
-
-        p1 = ax.bar(ind, implemented, bar_width, color="#4CAF50", label="Implemented")
-        p2 = ax.bar(
-            ind,
-            partial,
-            bar_width,
-            bottom=implemented,
-            color="#FFC107",
-            label="Partial",
-        )
-        p3 = ax.bar(
-            ind,
-            missing,
-            bar_width,
-            bottom=np.array(implemented) + np.array(partial),
-            color="#F44336",
-            label="Missing",
-        )
-
-        ax.set_title("Implementation Status by Language")
-        ax.set_ylabel("Number of Features")
-        ax.set_xticks(ind)
-        ax.set_xticklabels(languages, rotation=45, ha="right")
-        ax.legend()
-
-        plt.tight_layout()
-        plt.savefig(reports_dir / "implementation_by_language.png", dpi=300)
-        plt.close()
-
-        # 2. Progress by category (radar chart)
-        categories = FEATURE_CATEGORIES
-
-        # Prepare data
-        fig = plt.figure(figsize=(10, 8))
-
-        # Number of variables
-        N = len(categories)
-
-        # Compute angles for each category
-        angles = [n / float(N) * 2 * np.pi for n in range(N)]
-        angles += angles[:1]  # Close the loop
-
-        # Initialize the radar plot
-        ax = plt.subplot(111, polar=True)
-
-        # Draw progress for each language
-        for lang_code, lang_data in summary["languages"].items():
-            values = []
-            for category in categories:
-                if category in lang_data["categories"]:
-                    values.append(lang_data["categories"][category]["progress"])
-                else:
-                    values.append(0)
-
-            # Close the loop
-            values += values[:1]
-
-            # Plot values
-            ax.plot(
-                angles,
-                values,
-                linewidth=2,
-                linestyle="solid",
-                label=LANGUAGE_SETTINGS[lang_code]["name"],
-            )
-            ax.fill(angles, values, alpha=0.1)
-
-        # Set ticks and labels
-        plt.xticks(angles[:-1], categories)
-
-        # Add legend
-        plt.legend(loc="upper right", bbox_to_anchor=(0.1, 0.1))
-
-        plt.savefig(reports_dir / "category_radar_chart.png", dpi=300)
-        plt.close()
-
-    def generate_all_reports(self):
-        """Generate all reports and visualizations"""
-        logger.info("Generating implementation status reports...")
-
-        # Generate summary report
-        summary = self.generate_summary_report()
-
-        # Generate HTML summary report
-        summary_html = self.generate_html_report(summary)
-        with open(self.reports_dir / "index.html", "w") as f:
-            f.write(summary_html)
-
-        # Generate detailed reports for each language
-        for language in self.analysis_data.keys():
-            detailed_report = self.generate_detailed_report(language)
-            detailed_html = self.generate_detailed_html_report(
-                language, detailed_report
-            )
-
-            with open(self.reports_dir / f"details_{language}.html", "w") as f:
-                f.write(detailed_html)
-
-        # Generate visualizations
-        self.generate_visualizations(summary)
-
-        # Save summary data as JSON for further processing
-        with open(self.reports_dir / "summary.json", "w") as f:
-            json.dump(summary, f, indent=2)
-
-        logger.info(f"Reports generated successfully. Available at {self.reports_dir}")
-
-
-def main():
-    """Main entry point"""
-    try:
-        report_generator = ReportGenerator()
-        report_generator.generate_all_reports()
-        return 0
-    except Exception as e:
-        logger.error(f"Error generating reports: {e}")
-        return 1
-
-
-if __name__ == "__main__":
-    exit(main())
diff --git a/.github/scripts/issue_generator.py b/.github/scripts/issue_generator.py
deleted file mode 100755
index 50821c2..0000000
--- a/.github/scripts/issue_generator.py
+++ /dev/null
@@ -1,627 +0,0 @@
-#!/usr/bin/env python3
-"""
-Issue Generator for CrossGL Feature Discovery
-
-This script takes the output from the docs_crawler.py analysis and:
-1. Compares against the implemented features in CrossGL
-2. Creates structured GitHub issues for missing features
-3. Organizes issues into milestones by language
-4. Creates parent issues with subtasks for each category
-"""
-
-import os
-import re
-import json
-import logging
-import time
-from pathlib import Path
-from typing import Dict, List, Set, Any, Optional
-from datetime import datetime
-
-from github import Github
-from github.Issue import Issue
-from github.Repository import Repository
-from github.Milestone import Milestone
-from github.GithubException import GithubException
-
-# Setup logging
-logging.basicConfig(
-    level=logging.INFO,
-    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
-    handlers=[
-        logging.FileHandler(".github/logs/issue_generator.log"),
-        logging.StreamHandler(),
-    ],
-)
-logger = logging.getLogger("issue_generator")
-
-# Ensure directories exist
-os.makedirs(".cache/analysis", exist_ok=True)
-os.makedirs(".cache/issues", exist_ok=True)
-os.makedirs(".github/logs", exist_ok=True)
-
-# Category definitions for organizing issues
-CATEGORIES = {
-    "functions": {
-        "title": "Functions",
-        "description": "Missing function implementations in the CrossGL Translator",
-        "labels": ["enhancement", "function", "good first issue"],
-    },
-    "operators": {
-        "title": "Operators",
-        "description": "Missing operator implementations in the CrossGL Translator",
-        "labels": ["enhancement", "operator", "good first issue"],
-    },
-    "types": {
-        "title": "Types",
-        "description": "Missing type implementations in the CrossGL Translator",
-        "labels": ["enhancement", "type", "good first issue"],
-    },
-}
-
-# Language-specific settings
-LANGUAGE_SETTINGS = {
-    "metal": {
-        "name": "Metal Shading Language",
-        "doc_url": (
-            "https://developer.apple.com/documentation/metal/metal_shading_language"
-        ),
-        "priority": 1,
-    },
-    "directx": {
-        "name": "DirectX HLSL",
-        "doc_url": "https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl",
-        "priority": 2,
-    },
-    "opengl": {
-        "name": "OpenGL GLSL",
-        "doc_url": "https://www.khronos.org/registry/OpenGL-Refpages/gl4/",
-        "priority": 3,
-    },
-    "vulkan": {
-        "name": "Vulkan SPIR-V",
-        "doc_url": (
-            "https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html"
-        ),
-        "priority": 4,
-    },
-    "slang": {
-        "name": "Slang",
-        "doc_url": "https://shader-slang.com/slang/docs/reference/",
-        "priority": 5,
-    },
-    "mojo": {
-        "name": "Mojo",
-        "doc_url": "https://docs.modular.com/mojo/stdlib",
-        "priority": 6,
-    },
-}
-
-# Implementation status
-IMPLEMENTATION_STATUS = {
-    "MISSING": 0,  # Not implemented at all
-    "PARTIAL": 1,  # Partially implemented
-    "COMPLETE": 2,  # Fully implemented
-}
-
-
-class CrossGLAnalyzer:
-    """Analyzes the CrossGL codebase to detect implemented features"""
-
-    def __init__(self):
-        self.crosstl_dir = Path("crosstl")
-        self.backends_dir = self.crosstl_dir / "backend"
-        self.translator_dir = self.crosstl_dir / "translator"
-        self.codegen_dir = self.translator_dir / "codegen"
-
-        self.implemented_features = {
-            "functions": self._get_implemented_functions(),
-            "operators": self._get_implemented_operators(),
-            "types": self._get_implemented_types(),
-        }
-
-    def _get_implemented_functions(self) -> Dict[str, Set[str]]:
-        """Get all implemented functions per backend"""
-        implemented = {lang: set() for lang in LANGUAGE_SETTINGS.keys()}
-
-        # Check codegen files for function implementations
-        for lang in implemented.keys():
-            backend_dir = self.backends_dir / lang.capitalize()
-            codegen_file = self.codegen_dir / f"{lang}_codegen.py"
-
-            if not backend_dir.exists() or not codegen_file.exists():
-                continue
-
-            # Extract functions from codegen files
-            if codegen_file.exists():
-                with open(codegen_file, "r") as f:
-                    content = f.read()
-
-                    # Look for function definitions and visit_* methods
-                    for match in re.finditer(r"def\s+(?:visit_)?(\w+)", content):
-                        function_name = match.group(1)
-                        # Filter out common methods that aren't actual shader functions
-                        if not function_name.startswith(("__", "visit_", "generate")):
-                            implemented[lang].add(function_name)
-
-            # Look through backend directory
-            if backend_dir.exists():
-                for py_file in backend_dir.glob("**/*.py"):
-                    with open(py_file, "r") as f:
-                        content = f.read()
-
-                        # Look for function definitions specific to this language
-                        for match in re.finditer(r"def\s+(\w+)", content):
-                            function_name = match.group(1)
-                            # Filter out common methods that aren't actual shader functions
-                            if not function_name.startswith("__"):
-                                implemented[lang].add(function_name)
-
-        return implemented
-
-    def _get_implemented_operators(self) -> Dict[str, Set[str]]:
-        """Get all implemented operators per backend"""
-        implemented = {lang: set() for lang in LANGUAGE_SETTINGS.keys()}
-
-        # Extract operators from codegen files
-        for lang in implemented.keys():
-            codegen_file = self.codegen_dir / f"{lang}_codegen.py"
-
-            if not codegen_file.exists():
-                continue
-
-            with open(codegen_file, "r") as f:
-                content = f.read()
-
-                # Look for operator handling in visit_BinaryOp, visit_UnaryOp, etc.
-                for match in re.finditer(
-                    r'(?:visit_(?:Binary|Unary)Op).*?operator\s*==\s*[\'"]([+\-*/%<>=!&|^~]+)[\'"]',
-                    content,
-                    re.DOTALL,
-                ):
-                    operator = match.group(1)
-                    implemented[lang].add(operator)
-
-        return implemented
-
-    def _get_implemented_types(self) -> Dict[str, Set[str]]:
-        """Get all implemented types per backend"""
-        implemented = {lang: set() for lang in LANGUAGE_SETTINGS.keys()}
-
-        # Extract types from codegen and backend files
-        for lang in implemented.keys():
-            codegen_file = self.codegen_dir / f"{lang}_codegen.py"
-
-            if not codegen_file.exists():
-                continue
-
-            with open(codegen_file, "r") as f:
-                content = f.read()
-
-                # Look for type processing
-                for match in re.finditer(
-                    r'(?:visit_TypeDecl|process_type)\(.*?[\'"](\w+)[\'"]', content
-                ):
-                    type_name = match.group(1)
-                    implemented[lang].add(type_name)
-
-        return implemented
-
-    def get_implementation_status(
-        self, feature_type: str, feature_name: str, language: str
-    ) -> int:
-        """Check if a feature is implemented for a specific language"""
-        if language not in self.implemented_features[feature_type]:
-            return IMPLEMENTATION_STATUS["MISSING"]
-
-        if feature_name in self.implemented_features[feature_type][language]:
-            return IMPLEMENTATION_STATUS["COMPLETE"]
-
-        # Check for partial implementation (e.g., function exists but with different signature)
-        if feature_type == "functions":
-            # Check if a similar function exists
-            similar_functions = {
-                func
-                for func in self.implemented_features[feature_type][language]
-                if feature_name.lower() in func.lower()
-            }
-            if similar_functions:
-                return IMPLEMENTATION_STATUS["PARTIAL"]
-
-        return IMPLEMENTATION_STATUS["MISSING"]
-
-
-class IssueGenerator:
-    """Generates GitHub issues for missing features"""
-
-    def __init__(self, github_token: str, repo_name: str):
-        self.gh = Github(github_token)
-        self.repo = self.gh.get_repo(repo_name)
-        self.analyzer = CrossGLAnalyzer()
-        self.analysis_dir = Path(".cache/analysis")
-        self.issues_cache_dir = Path(".cache/issues")
-        self.issues_cache_dir.mkdir(parents=True, exist_ok=True)
-
-        # Cache for existing issues to avoid duplicate API calls
-        self.existing_issues = self._load_existing_issues()
-        self.existing_milestones = self._load_existing_milestones()
-
-        # Track created issues for linking
-        self.created_issues = {}
-
-    def _load_existing_issues(self) -> Dict[str, Issue]:
-        """Load existing issues from the repository to avoid duplicates"""
-        logger.info("Loading existing issues...")
-
-        # Try to load from cache first
-        cache_file = self.issues_cache_dir / "existing_issues.json"
-        if cache_file.exists():
-            try:
-                with open(cache_file, "r") as f:
-                    cache_data = json.load(f)
-
-                # Check if cache is recent (less than 1 day old)
-                cache_time = datetime.fromisoformat(
-                    cache_data.get("timestamp", "2000-01-01")
-                )
-                if (datetime.now() - cache_time).days < 1:
-                    logger.info("Using cached issues data")
-                    return {
-                        issue["title"]: issue for issue in cache_data.get("issues", [])
-                    }
-            except Exception as e:
-                logger.warning(f"Error loading issues cache: {e}")
-
-        # Load from GitHub API
-        issues = {}
-        for issue in self.repo.get_issues(state="open"):
-            issues[issue.title] = {
-                "title": issue.title,
-                "number": issue.number,
-                "body": issue.body,
-                "labels": [label.name for label in issue.labels],
-                "milestone": issue.milestone.number if issue.milestone else None,
-            }
-
-        # Save to cache
-        with open(cache_file, "w") as f:
-            json.dump(
-                {
-                    "timestamp": datetime.now().isoformat(),
-                    "issues": list(issues.values()),
-                },
-                f,
-                indent=2,
-            )
-
-        logger.info(f"Loaded {len(issues)} existing issues")
-        return issues
-
-    def _load_existing_milestones(self) -> Dict[str, Milestone]:
-        """Load existing milestones from the repository"""
-        logger.info("Loading existing milestones...")
-        milestones = {}
-
-        for milestone in self.repo.get_milestones():
-            milestones[milestone.title] = milestone
-
-        logger.info(f"Loaded {len(milestones)} existing milestones")
-        return milestones
-
-    def _get_or_create_milestone(self, language: str) -> Milestone:
-        """Get or create a milestone for a language"""
-        milestone_title = f"{LANGUAGE_SETTINGS[language]['name']} Implementation"
-
-        if milestone_title in self.existing_milestones:
-            return self.existing_milestones[milestone_title]
-
-        # Create milestone if it doesn't exist
-        description = f"Implementation of {LANGUAGE_SETTINGS[language]['name']} features in CrossGL Translator"
-        milestone = self.repo.create_milestone(
-            title=milestone_title,
-            state="open",
-            description=description,
-        )
-
-        self.existing_milestones[milestone_title] = milestone
-        logger.info(f"Created milestone: {milestone_title}")
-        return milestone
-
-    def _create_issue(
-        self,
-        title: str,
-        body: str,
-        labels: List[str] = None,
-        milestone: Optional[Milestone] = None,
-    ) -> Issue:
-        """Create a GitHub issue with error handling and rate limit awareness"""
-        if labels is None:
-            labels = []
-
-        # Check if issue already exists
-        if title in self.existing_issues:
-            issue_number = self.existing_issues[title]["number"]
-            logger.info(f"Issue already exists: {title} (#{issue_number})")
-            return self.repo.get_issue(issue_number)
-
-        # Create the issue with retry for rate limits
-        max_retries = 3
-        for attempt in range(max_retries):
-            try:
-                issue = self.repo.create_issue(
-                    title=title, body=body, labels=labels, milestone=milestone
-                )
-
-                # Update cache
-                self.existing_issues[title] = {
-                    "title": title,
-                    "number": issue.number,
-                    "body": body,
-                    "labels": labels,
-                    "milestone": milestone.number if milestone else None,
-                }
-
-                logger.info(f"Created issue: {title} (#{issue.number})")
-                return issue
-
-            except GithubException as e:
-                if e.status == 403 and attempt < max_retries - 1:
-                    # Rate limit hit, wait and retry
-                    logger.warning(
-                        f"Rate limit hit, waiting 60 seconds... ({attempt+1}/{max_retries})"
-                    )
-                    time.sleep(60)
-                else:
-                    logger.error(f"Error creating issue '{title}': {e}")
-                    raise
-
-        raise RuntimeError(
-            f"Failed to create issue after {max_retries} attempts: {title}"
-        )
-
-    def _format_feature_documentation(
-        self, feature: Dict[str, Any], language: str
-    ) -> str:
-        """Format feature documentation for inclusion in issue body"""
-        feature_type = (
-            "function"
-            if "signature" in feature
-            else "operator" if "symbol" in feature else "type"
-        )
-
-        if feature_type == "function":
-            doc = f"### Function: `{feature['name']}`\n\n"
-
-            if feature.get("signature"):
-                doc += f"**Signature:**\n```{language}\n{feature['signature']}\n```\n\n"
-
-            if feature.get("description"):
-                doc += f"**Description:**\n{feature['description']}\n\n"
-
-            if feature.get("parameters"):
-                doc += "**Parameters:**\n"
-                for param in feature["parameters"]:
-                    doc += f"- `{param['name']}`: {param.get('type', '')}\n"
-                doc += "\n"
-
-            if feature.get("return_type"):
-                doc += f"**Returns:** {feature['return_type']}\n\n"
-
-            if feature.get("url"):
-                doc += f"**Documentation:** [Official {LANGUAGE_SETTINGS[language]['name']} Documentation]({feature['url']})\n\n"
-
-        elif feature_type == "operator":
-            doc = f"### Operator: `{feature['symbol']}`\n\n"
-
-            if feature.get("name") and feature["name"] != feature["symbol"]:
-                doc += f"**Name:** {feature['name']}\n\n"
-
-            if feature.get("description"):
-                doc += f"**Description:**\n{feature['description']}\n\n"
-
-            if feature.get("example"):
-                doc += f"**Example:**\n```{language}\n{feature['example']}\n```\n\n"
-
-        else:  # type
-            doc = f"### Type: `{feature['name']}`\n\n"
-
-            if feature.get("description"):
-                doc += f"**Description:**\n{feature['description']}\n\n"
-
-            if feature.get("category"):
-                doc += f"**Category:** {feature['category']}\n\n"
-
-        return doc
-
-    def _generate_task_description(
-        self, feature: Dict[str, Any], language: str, feature_type: str
-    ) -> str:
-        """Generate task description for implementation"""
-        task_desc = f"""## Task: Implement {feature_type} in {LANGUAGE_SETTINGS[language]['name']}
-
-### Description
-Implement the {feature['name']} {feature_type} for the {LANGUAGE_SETTINGS[language]['name']} backend in CrossGL Translator.
-
-### Implementation Details
-You should implement this {feature_type} in the following files:
-
-- `crosstl/translator/codegen/{language}_codegen.py` - Add support for this {feature_type}
-- Add appropriate methods in the {language.capitalize()} backend directory
-
-### Testing Requirements
-- Create test cases in `tests/test_translator/test_codegen/test_{language}_codegen.py`
-- Ensure tests verify correct translation of this {feature_type}
-- Include both positive and negative test cases
-
-### Documentation
-{self._format_feature_documentation(feature, language)}
-"""
-        return task_desc
-
-    def generate_parent_issues(
-        self, language: str, analysis_data: Dict[str, Any]
-    ) -> Dict[str, Issue]:
-        """Generate parent issues for each category of features"""
-        milestone = self._get_or_create_milestone(language)
-        parent_issues = {}
-
-        for category, category_info in CATEGORIES.items():
-            if category not in analysis_data:
-                continue
-
-            missing_count = sum(
-                1
-                for feature in analysis_data[category]
-                if self.analyzer.get_implementation_status(
-                    category, feature["name"], language
-                )
-                == IMPLEMENTATION_STATUS["MISSING"]
-            )
-
-            if missing_count == 0:
-                logger.info(
-                    f"No missing {category} for {language}, skipping parent issue"
-                )
-                continue
-
-            title = f"[{language.upper()}] Implement Missing {category_info['title']}"
-            body = f"""# {LANGUAGE_SETTINGS[language]['name']} {category_info['title']} Implementation
-
-This issue tracks the implementation of missing {category_info['title'].lower()} in the {LANGUAGE_SETTINGS[language]['name']} backend of CrossGL Translator.
-
-## Description
-{category_info['description']} for the {LANGUAGE_SETTINGS[language]['name']} backend.
-
-## Progress
-There are {missing_count} missing {category} to implement.
-
-## Tasks
-The following sub-issues will be created for individual {category}:
-
-"""
-
-            # Create parent issue
-            labels = category_info["labels"].copy()
-            labels.append(language)
-            parent_issue = self._create_issue(title, body, labels, milestone)
-            parent_issues[category] = parent_issue
-
-        return parent_issues
-
-    def generate_feature_issues(
-        self, language: str, parent_issues: Dict[str, Issue]
-    ) -> None:
-        """Generate individual feature issues linked to parent issues"""
-        milestone = self._get_or_create_milestone(language)
-
-        # Load analysis data
-        analysis_file = self.analysis_dir / f"{language}.json"
-        if not analysis_file.exists():
-            logger.warning(f"Analysis data not found for {language}")
-            return
-
-        with open(analysis_file, "r") as f:
-            analysis_data = json.load(f)
-
-        # Create feature issues
-        for category, category_info in CATEGORIES.items():
-            if category not in analysis_data:
-                continue
-
-            # Skip if no parent issue (meaning no missing features)
-            if category not in parent_issues:
-                continue
-
-            parent_issue = parent_issues[category]
-            issue_references = []
-
-            for feature in analysis_data[category]:
-                feature_name = feature["name"]
-
-                # Check if already implemented
-                status = self.analyzer.get_implementation_status(
-                    category, feature_name, language
-                )
-                if status != IMPLEMENTATION_STATUS["MISSING"]:
-                    continue
-
-                # Create issue for missing feature
-                title = (
-                    f"[{language.upper()}] Implement {category[:-1]} '{feature_name}'"
-                )
-                labels = category_info["labels"].copy()
-                labels.append(language)
-
-                # Generate task description
-                body = self._generate_task_description(feature, language, category[:-1])
-
-                # Add reference to parent issue
-                body += f"\n\nParent issue: #{parent_issue.number}"
-
-                try:
-                    issue = self._create_issue(title, body, labels, milestone)
-                    issue_references.append(f"- [ ] [{feature_name}](#{issue.number})")
-                except Exception as e:
-                    logger.error(f"Error creating issue for {feature_name}: {e}")
-                    issue_references.append(
-                        f"- [ ] {feature_name} (issue creation failed)"
-                    )
-
-            # Update parent issue with references to child issues
-            if issue_references:
-                updated_body = parent_issue.body + "\n" + "\n".join(issue_references)
-                parent_issue.edit(body=updated_body)
-                logger.info(
-                    f"Updated parent issue #{parent_issue.number} with {len(issue_references)} child issues"
-                )
-
-    def generate_all_issues(self) -> None:
-        """Generate all issues for all languages"""
-        logger.info("Starting issue generation for all languages...")
-
-        # Process each language
-        for language in LANGUAGE_SETTINGS.keys():
-            analysis_file = self.analysis_dir / f"{language}.json"
-            if not analysis_file.exists():
-                logger.warning(f"Skipping {language}: No analysis data found")
-                continue
-
-            with open(analysis_file, "r") as f:
-                analysis_data = json.load(f)
-
-            logger.info(f"Processing {language}...")
-
-            try:
-                # Create parent issues first
-                parent_issues = self.generate_parent_issues(language, analysis_data)
-
-                # Then create child issues linked to parents
-                self.generate_feature_issues(language, parent_issues)
-
-                logger.info(f"Completed issue generation for {language}")
-            except Exception as e:
-                logger.error(f"Error generating issues for {language}: {e}")
-
-        logger.info("Issue generation complete")
-
-
-def main():
-    """Main entry point"""
-    github_token = os.environ.get("GITHUB_TOKEN")
-    if not github_token:
-        logger.error("GITHUB_TOKEN environment variable is not set")
-        return 1
-
-    repo_name = os.environ.get("CrossGL/Issue-Bot")
-
-    try:
-        issue_generator = IssueGenerator(github_token, repo_name)
-        issue_generator.generate_all_issues()
-        return 0
-    except Exception as e:
-        logger.error(f"Error in issue generation: {e}")
-        return 1
-
-
-if __name__ == "__main__":
-    exit(main())
diff --git a/.github/workflows/feature-discovery.yml b/.github/workflows/feature-discovery.yml
deleted file mode 100644
index c4e8b34..0000000
--- a/.github/workflows/feature-discovery.yml
+++ /dev/null
@@ -1,141 +0,0 @@
-name: Shader Language Feature Discovery
-
-on:
-  schedule:
-    # Run biweekly at midnight UTC on Sunday
-    - cron: "0 0 * * 0"
-  pull_request: # remove before merging
-    branches:
-      - main
-  workflow_dispatch: # Allow manual triggering
-    inputs:
-      languages:
-        description: "Comma-separated list of languages to analyze (leave empty for all)"
-        required: false
-        default: ""
-      force_refresh:
-        description: "Force refresh cached documentation"
-        required: false
-        type: boolean
-        default: false
-
-env:
-  CACHE_VERSION: 1 # Increment to invalidate caches
-
-jobs:
-  prepare:
-    runs-on: ubuntu-latest
-    outputs:
-      matrix: ${{ steps.set-matrix.outputs.matrix }}
-    steps:
-      - name: Checkout repository
-        uses: actions/checkout@v4
-
-      - name: Set up matrix
-        id: set-matrix
-        run: |
-          LANGUAGES="${{ github.event.inputs.languages }}"
-          if [ -z "$LANGUAGES" ]; then
-            LANGUAGES="metal,directx,opengl,vulkan,slang,mojo"
-          fi
-          JSON_ARRAY=$(echo "$LANGUAGES" | tr ',' '\n' | jq -R . | jq -s -c .)
-          echo "matrix={\"language\":$JSON_ARRAY}" >> $GITHUB_OUTPUT
-
-  analyze-documentation:
-    needs: prepare
-    # runs-on: ubuntu-latest-64-cores # Using larger runner for performance
-    runs-on: ubuntu-latest
-    strategy:
-      matrix: ${{fromJson(needs.prepare.outputs.matrix)}}
-      fail-fast: false
-
-    steps:
-      - name: Checkout repository
-        uses: actions/checkout@v4
-
-      - name: Set up Python
-        uses: actions/setup-python@v5
-        with:
-          python-version: "3.11"
-          cache: "pip"
-
-      - name: Install dependencies
-        run: |
-          python -m pip install --upgrade pip
-          pip install -e .
-          pip install -r requirements.txt
-          pip install PyGithub beautifulsoup4 selenium webdriver-manager lxml html5lib markdownify requests aiohttp nltk spacy 
-          python -m spacy download en_core_web_lg
-          python -m nltk.downloader punkt wordnet stopwords
-
-      - name: Cache documentation
-        id: cache-docs
-        uses: actions/cache@v4
-        with:
-          path: ./.cache/docs/${{ matrix.language }}
-          key: docs-${{ matrix.language }}-${{ env.CACHE_VERSION }}-${{ hashFiles('.github/scripts/docs_crawler.py') }}
-          restore-keys: |
-            docs-${{ matrix.language }}-${{ env.CACHE_VERSION }}-
-
-      - name: Download documentation
-        if: steps.cache-docs.outputs.cache-hit != 'true' || github.event.inputs.force_refresh == 'true'
-        run: |
-          python .github/scripts/docs_crawler.py --language ${{ matrix.language }} --download-only
-
-      - name: Analyze documentation
-        run: |
-          python .github/scripts/docs_crawler.py --language ${{ matrix.language }} --analyze-only
-
-      - name: Upload analysis results
-        uses: actions/upload-artifact@v4
-        with:
-          name: ${{ matrix.language }}-analysis
-          path: ./.cache/analysis/${{ matrix.language }}.json
-          retention-days: 1
-
-  generate-issues:
-    needs: analyze-documentation
-    # runs-on: ubuntu-latest-16-cores
-    runs-on: ubuntu-latest
-    permissions:
-      issues: write
-      contents: read
-
-    steps:
-      - name: Checkout repository
-        uses: actions/checkout@v4
-
-      - name: Set up Python
-        uses: actions/setup-python@v5
-        with:
-          python-version: "3.11"
-          cache: "pip"
-
-      - name: Install dependencies
-        run: |
-          python -m pip install --upgrade pip
-          pip install -e .
-          pip install -r requirements.txt
-          pip install PyGithub jinja2 pyyaml rich tqdm
-
-      - name: Download all analysis results
-        uses: actions/download-artifact@v4
-        with:
-          path: ./.cache/analysis/
-
-      - name: Create GitHub Issues
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-        run: |
-          python .github/scripts/issue_generator.py
-
-      - name: Generate Report
-        run: |
-          python .github/scripts/generate_report.py
-
-      - name: Upload Report
-        uses: actions/upload-artifact@v4
-        with:
-          name: implementation-status-report
-          path: ./.cache/reports/
-          retention-days: 30
diff --git a/MANIFEST.in b/MANIFEST.in
index 58f676b..c58e280 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -8,6 +8,7 @@ include backend/CUDA/*.py
 include backend/Mojo/*.py
 include backend/Rust/*.py
 include backend/SPIRV/*.py
+include backend/HIP/*.py
 include translator/*.py
 include translator/codegen/*.py
 include crosstl.py
diff --git a/crosstl/_crosstl.py b/crosstl/_crosstl.py
index 4a7abd8..19f05a0 100644
--- a/crosstl/_crosstl.py
+++ b/crosstl/_crosstl.py
@@ -9,6 +9,7 @@ from .translator.codegen import (
     mojo_codegen,
     rust_codegen,
     cuda_codegen,
+    hip_codegen,
 )
 from .translator.ast import ASTNode
 import argparse
@@ -93,6 +94,11 @@ def translate(
 
         lexer = CudaLexer(shader_code)
         parser = CudaParser(lexer.tokenize())
+    elif file_path.endswith(".hip"):
+        from .backend.HIP import HipLexer, HipParser
+
+        lexer = HipLexer(shader_code)
+        parser = HipParser(lexer.tokenize())
     else:
         raise ValueError(f"Unsupported shader file type: {file_path}")
 
@@ -113,6 +119,8 @@ def translate(
             codegen = rust_codegen.RustCodeGen()
         elif backend == "cuda":
             codegen = cuda_codegen.CudaCodeGen()
+        elif backend == "hip":
+            codegen = hip_codegen.HipCodeGen()
         else:
             raise ValueError(f"Unsupported backend for CrossGL file: {backend}")
     else:
@@ -151,6 +159,10 @@ def translate(
                 from .backend.CUDA.CudaCrossGLCodeGen import CudaToCrossGLConverter
 
                 codegen = CudaToCrossGLConverter()
+            elif file_path.endswith(".hip"):
+                from .backend.HIP.HipCrossGLCodeGen import HipToCrossGLConverter
+
+                codegen = HipToCrossGLConverter()
             else:
                 raise ValueError(f"Reverse translation not supported for: {file_path}")
         else:
@@ -182,7 +194,7 @@ def main():
         "--backend",
         "-b",
         default="cgl",
-        help="Target backend (metal, directx, opengl, vulkan, mojo, rust, cuda, cgl)",
+        help="Target backend (metal, directx, opengl, vulkan, mojo, rust, cuda, hip, cgl)",
     )
     parser.add_argument("--output", "-o", help="Output file path")
     parser.add_argument(
@@ -208,6 +220,7 @@ def main():
                 "mojo": ".mojo",
                 "rust": ".rs",
                 "cuda": ".cu",
+                "hip": ".hip",
                 "cgl": ".cgl",
             }
             output_path = base + ext_map.get(args.backend, ".out")
diff --git a/crosstl/backend/HIP/HipAst.py b/crosstl/backend/HIP/HipAst.py
new file mode 100644
index 0000000..3612238
--- /dev/null
+++ b/crosstl/backend/HIP/HipAst.py
@@ -0,0 +1,397 @@
+"""HIP AST Node definitions"""
+
+
+class ASTNode:
+    """Base class for all AST nodes"""
+
+
+class ShaderNode(ASTNode):
+    """Root node representing a complete HIP program"""
+
+    def __init__(
+        self,
+        includes=None,
+        functions=None,
+        structs=None,
+        global_variables=None,
+        kernels=None,
+    ):
+        self.includes = includes or []
+        self.functions = functions or []
+        self.structs = structs or []
+        self.global_variables = global_variables or []
+        self.kernels = kernels or []
+
+    def __repr__(self):
+        return f"ShaderNode(includes={self.includes}, functions={self.functions}, structs={self.structs}, global_variables={self.global_variables}, kernels={self.kernels})"
+
+
+class FunctionNode(ASTNode):
+    """Node representing a function declaration"""
+
+    def __init__(
+        self, return_type, name, params, body, qualifiers=None, attributes=None
+    ):
+        self.return_type = return_type
+        self.name = name
+        self.params = params
+        self.body = body
+        self.qualifiers = qualifiers or []  # __global__, __device__, __host__
+        self.attributes = attributes or []
+
+    def __repr__(self):
+        return f"FunctionNode(return_type={self.return_type}, name={self.name}, params={self.params}, body={self.body}, qualifiers={self.qualifiers})"
+
+
+class KernelNode(FunctionNode):
+    """Node representing a HIP kernel function (marked with __global__)"""
+
+    def __init__(self, return_type, name, params, body, attributes=None):
+        super().__init__(return_type, name, params, body, ["__global__"], attributes)
+
+    def __repr__(self):
+        return f"KernelNode(name={self.name}, params={self.params}, body={self.body})"
+
+
+class KernelLaunchNode(ASTNode):
+    """Node representing a kernel launch: kernel<<<blocks, threads>>>(args)"""
+
+    def __init__(
+        self, kernel_name, blocks, threads, shared_mem=None, stream=None, args=None
+    ):
+        self.kernel_name = kernel_name
+        self.blocks = blocks
+        self.threads = threads
+        self.shared_mem = shared_mem  # Optional shared memory size
+        self.stream = stream  # Optional stream
+        self.args = args or []
+
+    def __repr__(self):
+        return f"KernelLaunchNode(kernel_name={self.kernel_name}, blocks={self.blocks}, threads={self.threads}, args={self.args})"
+
+
+class StructNode(ASTNode):
+    """Node representing a struct declaration"""
+
+    def __init__(self, name, members, attributes=None):
+        self.name = name
+        self.members = members
+        self.attributes = attributes or []
+
+    def __repr__(self):
+        return f"StructNode(name={self.name}, members={self.members})"
+
+
+class VariableNode(ASTNode):
+    """Node representing a variable declaration"""
+
+    def __init__(self, vtype, name, value=None, qualifiers=None):
+        self.vtype = vtype
+        self.name = name
+        self.value = value
+        self.qualifiers = qualifiers or []  # __shared__, __constant__, etc.
+
+    def __repr__(self):
+        return f"VariableNode(vtype={self.vtype}, name={self.name}, value={self.value}, qualifiers={self.qualifiers})"
+
+
+class AssignmentNode(ASTNode):
+    """Node representing an assignment operation"""
+
+    def __init__(self, left, right, operator="="):
+        self.left = left
+        self.right = right
+        self.operator = operator
+
+    def __repr__(self):
+        return f"AssignmentNode(left={self.left}, operator={self.operator}, right={self.right})"
+
+
+class BinaryOpNode(ASTNode):
+    """Node representing a binary operation"""
+
+    def __init__(self, left, op, right):
+        self.left = left
+        self.op = op
+        self.right = right
+
+    def __repr__(self):
+        return f"BinaryOpNode(left={self.left}, op={self.op}, right={self.right})"
+
+
+class UnaryOpNode(ASTNode):
+    """Node representing a unary operation"""
+
+    def __init__(self, op, operand):
+        self.op = op
+        self.operand = operand
+
+    def __repr__(self):
+        return f"UnaryOpNode(op={self.op}, operand={self.operand})"
+
+
+class FunctionCallNode(ASTNode):
+    """Node representing a function call"""
+
+    def __init__(self, name, args):
+        self.name = name
+        self.args = args
+
+    def __repr__(self):
+        return f"FunctionCallNode(name={self.name}, args={self.args})"
+
+
+class AtomicOperationNode(FunctionCallNode):
+    """Node representing a HIP atomic operation"""
+
+    def __init__(self, operation, args):
+        super().__init__(operation, args)
+        self.operation = operation  # atomicAdd, hipAtomicAdd, etc.
+
+    def __repr__(self):
+        return f"AtomicOperationNode(operation={self.operation}, args={self.args})"
+
+
+class SyncNode(ASTNode):
+    """Node representing synchronization operations"""
+
+    def __init__(self, sync_type, args=None):
+        self.sync_type = sync_type  # __syncthreads, hipDeviceSynchronize
+        self.args = args or []
+
+    def __repr__(self):
+        return f"SyncNode(sync_type={self.sync_type}, args={self.args})"
+
+
+class MemberAccessNode(ASTNode):
+    """Node representing member access (dot or arrow operator)"""
+
+    def __init__(self, object, member, is_pointer=False):
+        self.object = object
+        self.member = member
+        self.is_pointer = is_pointer  # True for ->, False for .
+
+    def __repr__(self):
+        op = "->" if self.is_pointer else "."
+        return f"MemberAccessNode(object={self.object}, member={self.member}, operator={op})"
+
+
+class ArrayAccessNode(ASTNode):
+    """Node representing array access"""
+
+    def __init__(self, array, index):
+        self.array = array
+        self.index = index
+
+    def __repr__(self):
+        return f"ArrayAccessNode(array={self.array}, index={self.index})"
+
+
+class IfNode(ASTNode):
+    """Node representing an if statement"""
+
+    def __init__(self, condition, if_body, else_body=None):
+        self.condition = condition
+        self.if_body = if_body
+        self.else_body = else_body
+
+    def __repr__(self):
+        return f"IfNode(condition={self.condition}, if_body={self.if_body}, else_body={self.else_body})"
+
+
+class ForNode(ASTNode):
+    """Node representing a for loop"""
+
+    def __init__(self, init, condition, update, body):
+        self.init = init
+        self.condition = condition
+        self.update = update
+        self.body = body
+
+    def __repr__(self):
+        return f"ForNode(init={self.init}, condition={self.condition}, update={self.update}, body={self.body})"
+
+
+class WhileNode(ASTNode):
+    """Node representing a while loop"""
+
+    def __init__(self, condition, body):
+        self.condition = condition
+        self.body = body
+
+    def __repr__(self):
+        return f"WhileNode(condition={self.condition}, body={self.body})"
+
+
+class DoWhileNode(ASTNode):
+    """Node representing a do-while loop"""
+
+    def __init__(self, body, condition):
+        self.body = body
+        self.condition = condition
+
+    def __repr__(self):
+        return f"DoWhileNode(body={self.body}, condition={self.condition})"
+
+
+class SwitchNode(ASTNode):
+    """Node representing a switch statement"""
+
+    def __init__(self, expression, cases, default_case=None):
+        self.expression = expression
+        self.cases = cases
+        self.default_case = default_case
+
+    def __repr__(self):
+        return f"SwitchNode(expression={self.expression}, cases={self.cases}, default_case={self.default_case})"
+
+
+class CaseNode(ASTNode):
+    """Node representing a case in a switch statement"""
+
+    def __init__(self, value, body):
+        self.value = value
+        self.body = body
+
+    def __repr__(self):
+        return f"CaseNode(value={self.value}, body={self.body})"
+
+
+class ReturnNode(ASTNode):
+    """Node representing a return statement"""
+
+    def __init__(self, value=None):
+        self.value = value
+
+    def __repr__(self):
+        return f"ReturnNode(value={self.value})"
+
+
+class BreakNode(ASTNode):
+    """Node representing a break statement"""
+
+    def __repr__(self):
+        return "BreakNode()"
+
+
+class ContinueNode(ASTNode):
+    """Node representing a continue statement"""
+
+    def __repr__(self):
+        return "ContinueNode()"
+
+
+class VectorConstructorNode(ASTNode):
+    """Node representing HIP vector constructor (make_float4, etc.)"""
+
+    def __init__(self, vector_type, args):
+        self.vector_type = vector_type
+        self.args = args
+
+    def __repr__(self):
+        return (
+            f"VectorConstructorNode(vector_type={self.vector_type}, args={self.args})"
+        )
+
+
+class TernaryOpNode(ASTNode):
+    """Node representing a ternary conditional operator"""
+
+    def __init__(self, condition, true_expr, false_expr):
+        self.condition = condition
+        self.true_expr = true_expr
+        self.false_expr = false_expr
+
+    def __repr__(self):
+        return f"TernaryOpNode(condition={self.condition}, true_expr={self.true_expr}, false_expr={self.false_expr})"
+
+
+class CastNode(ASTNode):
+    """Node representing a type cast"""
+
+    def __init__(self, target_type, expression):
+        self.target_type = target_type
+        self.expression = expression
+
+    def __repr__(self):
+        return f"CastNode(target_type={self.target_type}, expression={self.expression})"
+
+
+class PreprocessorNode(ASTNode):
+    """Node representing preprocessor directives"""
+
+    def __init__(self, directive, content):
+        self.directive = directive  # include, define, etc.
+        self.content = content
+
+    def __repr__(self):
+        return f"PreprocessorNode(directive={self.directive}, content={self.content})"
+
+
+class HipBuiltinNode(ASTNode):
+    """Node representing HIP built-in variables (threadIdx, hipThreadIdx_x, etc.)"""
+
+    def __init__(self, builtin_name, component=None):
+        self.builtin_name = builtin_name  # threadIdx, hipThreadIdx_x, etc.
+        self.component = component  # x, y, z component (for CUDA-style builtins)
+
+    def __repr__(self):
+        if self.component:
+            return f"HipBuiltinNode(builtin_name={self.builtin_name}, component={self.component})"
+        return f"HipBuiltinNode(builtin_name={self.builtin_name})"
+
+
+class TextureAccessNode(ASTNode):
+    """Node representing texture memory access"""
+
+    def __init__(self, texture_name, coordinates):
+        self.texture_name = texture_name
+        self.coordinates = coordinates
+
+    def __repr__(self):
+        return f"TextureAccessNode(texture_name={self.texture_name}, coordinates={self.coordinates})"
+
+
+class SharedMemoryNode(VariableNode):
+    """Node representing shared memory variable declaration"""
+
+    def __init__(self, vtype, name, size=None):
+        super().__init__(vtype, name, qualifiers=["__shared__"])
+        self.size = size  # For dynamic shared memory
+
+    def __repr__(self):
+        return (
+            f"SharedMemoryNode(vtype={self.vtype}, name={self.name}, size={self.size})"
+        )
+
+
+class ConstantMemoryNode(VariableNode):
+    """Node representing constant memory variable declaration"""
+
+    def __init__(self, vtype, name, value=None):
+        super().__init__(vtype, name, value, qualifiers=["__constant__"])
+
+    def __repr__(self):
+        return f"ConstantMemoryNode(vtype={self.vtype}, name={self.name}, value={self.value})"
+
+
+class HipErrorHandlingNode(ASTNode):
+    """Node representing HIP error handling"""
+
+    def __init__(self, error_var, hip_call):
+        self.error_var = error_var
+        self.hip_call = hip_call
+
+    def __repr__(self):
+        return f"HipErrorHandlingNode(error_var={self.error_var}, hip_call={self.hip_call})"
+
+
+class HipDevicePropertyNode(ASTNode):
+    """Node representing HIP device property access"""
+
+    def __init__(self, property_name, device_id=None):
+        self.property_name = property_name
+        self.device_id = device_id
+
+    def __repr__(self):
+        return f"HipDevicePropertyNode(property_name={self.property_name}, device_id={self.device_id})"
diff --git a/crosstl/backend/HIP/HipCrossGLCodeGen.py b/crosstl/backend/HIP/HipCrossGLCodeGen.py
new file mode 100644
index 0000000..8741585
--- /dev/null
+++ b/crosstl/backend/HIP/HipCrossGLCodeGen.py
@@ -0,0 +1,464 @@
+"""
+HIP to CrossGL Code Generator
+
+This module provides code generation functionality to convert HIP (HIP Is a Portable GPU Runtime)
+AST nodes to CrossGL intermediate representation.
+"""
+
+from typing import Any
+from .HipAst import (
+    ASTNode,
+    ShaderNode,
+    FunctionNode,
+    KernelNode,
+    StructNode,
+    VariableNode,
+    AssignmentNode,
+    BinaryOpNode,
+    UnaryOpNode,
+    FunctionCallNode,
+    AtomicOperationNode,
+    SyncNode,
+    MemberAccessNode,
+    ArrayAccessNode,
+    IfNode,
+    ForNode,
+    WhileNode,
+    ReturnNode,
+    BreakNode,
+    ContinueNode,
+    PreprocessorNode,
+    HipBuiltinNode,
+)
+
+
+class HipToCrossGLConverter:
+    """Converts HIP AST to CrossGL format"""
+
+    def __init__(self):
+        self.indent_level = 0
+        self.output = []
+
+    def generate(self, ast_node):
+        """Generate CrossGL code from HIP AST"""
+        self.output = []
+        self.indent_level = 0
+        self.visit(ast_node)
+        return "\n".join(self.output)
+
+    def visit(self, node):
+        """Visit a node and generate code"""
+        method_name = f"visit_{type(node).__name__}"
+        visitor = getattr(self, method_name, self.generic_visit)
+        return visitor(node)
+
+    def generic_visit(self, node):
+        """Default visitor for unknown nodes"""
+        if isinstance(node, str):
+            return node
+        elif isinstance(node, list):
+            return [self.visit(item) for item in node]
+        else:
+            return str(node)
+
+    def emit(self, code):
+        """Emit code with proper indentation"""
+        if code.strip():
+            self.output.append("    " * self.indent_level + code)
+        else:
+            self.output.append("")
+
+    def visit_HipProgramNode(self, node):
+        """Visit HIP program node (main program)"""
+        # Always emit the comment first
+        self.emit("// HIP to CrossGL conversion")
+
+        # Process all statements
+        for stmt in node.statements:
+            if isinstance(stmt, FunctionNode):
+                if hasattr(stmt, "qualifiers") and "__global__" in getattr(
+                    stmt, "qualifiers", []
+                ):
+                    self.emit(f"// Kernel: {stmt.name}")
+                    self.visit_kernel_as_compute_shader(stmt)
+                else:
+                    self.emit(f"// Function: {stmt.name}")
+                    self.visit(stmt)
+                self.emit("")
+            elif isinstance(stmt, StructNode):
+                self.visit(stmt)
+                self.emit("")
+            elif isinstance(stmt, VariableNode):
+                self.visit(stmt)
+                self.emit("")
+            else:
+                self.visit(stmt)
+
+    def visit_FunctionNode(self, node):
+        """Visit function declaration"""
+        # Skip device functions in CrossGL (they become inline)
+        if hasattr(node, "qualifiers") and "__device__" in getattr(
+            node, "qualifiers", []
+        ):
+            return
+
+        return_type = self.convert_hip_type_to_crossgl(
+            node.return_type if hasattr(node, "return_type") else "void"
+        )
+        params = []
+
+        if hasattr(node, "params") and node.params:
+            for param in node.params:
+                if isinstance(param, dict):
+                    param_type = self.convert_hip_type_to_crossgl(
+                        param.get("type", "int")
+                    )
+                    param_name = param.get("name", "param")
+                    params.append(f"{param_type} {param_name}")
+                else:
+                    param_type = self.convert_hip_type_to_crossgl(
+                        getattr(param, "vtype", "int")
+                    )
+                    param_name = getattr(param, "name", "param")
+                    params.append(f"{param_type} {param_name}")
+
+        param_str = ", ".join(params)
+        self.emit(f"{return_type} {node.name}({param_str}) {{")
+
+        self.indent_level += 1
+        if hasattr(node, "body") and node.body:
+            if isinstance(node.body, list):
+                for stmt in node.body:
+                    self.visit(stmt)
+            else:
+                self.visit(node.body)
+        self.indent_level -= 1
+
+        self.emit("}")
+
+    def visit_kernel_as_compute_shader(self, kernel):
+        """Convert HIP kernel to CrossGL compute shader"""
+        # Generate compute shader layout
+        self.emit("@compute")
+        self.emit("@workgroup_size(1, 1, 1)  // Default workgroup size")
+
+        # Generate function signature
+        params = []
+        if hasattr(kernel, "params") and kernel.params:
+            for param in kernel.params:
+                if isinstance(param, dict):
+                    param_type = self.convert_hip_type_to_crossgl(
+                        param.get("type", "int")
+                    )
+                    param_name = param.get("name", "param")
+                    # Add storage buffer qualifiers for pointer parameters
+                    if "*" in param.get("type", ""):
+                        params.append(
+                            f"@group(0) @binding({len(params)}) var<storage, read_write> {param_name}: array<{param_type.replace('*', '').strip()}>"
+                        )
+                    else:
+                        params.append(f"{param_type} {param_name}")
+                else:
+                    param_type = self.convert_hip_type_to_crossgl(
+                        getattr(param, "vtype", "int")
+                    )
+                    param_name = getattr(param, "name", "param")
+                    if "*" in getattr(param, "vtype", ""):
+                        params.append(
+                            f"@group(0) @binding({len(params)}) var<storage, read_write> {param_name}: array<{param_type.replace('*', '').strip()}>"
+                        )
+                    else:
+                        params.append(f"{param_type} {param_name}")
+
+        self.emit(f"fn {kernel.name}(")
+        self.indent_level += 1
+        for i, param in enumerate(params):
+            if i == len(params) - 1:
+                self.emit(f"{param}")
+            else:
+                self.emit(f"{param},")
+        self.indent_level -= 1
+        self.emit(") {")
+
+        # Add built-in variable declarations
+        self.indent_level += 1
+        self.emit("let thread_id = gl_GlobalInvocationID;")
+        self.emit("let block_id = gl_WorkGroupID;")
+        self.emit("let thread_local_id = gl_LocalInvocationID;")
+        self.emit("let block_dim = gl_WorkGroupSize;")
+        self.emit("")
+
+        # Process kernel body
+        if hasattr(kernel, "body") and kernel.body:
+            if isinstance(kernel.body, list):
+                for stmt in kernel.body:
+                    self.visit(stmt)
+            else:
+                self.visit(kernel.body)
+
+        self.indent_level -= 1
+        self.emit("}")
+
+    def visit_StructNode(self, node):
+        """Visit struct declaration"""
+        self.emit(f"struct {node.name} {{")
+        self.indent_level += 1
+
+        if hasattr(node, "members") and node.members:
+            for member in node.members:
+                if isinstance(member, VariableNode):
+                    member_type = self.convert_hip_type_to_crossgl(
+                        getattr(member, "vtype", "int")
+                    )
+                    self.emit(f"{member_type} {member.name};")
+
+        self.indent_level -= 1
+        self.emit("};")
+
+    def visit_VariableNode(self, node):
+        """Visit variable declaration"""
+        var_type = self.convert_hip_type_to_crossgl(getattr(node, "vtype", "int"))
+
+        if hasattr(node, "value") and node.value:
+            value = self.visit(node.value)
+            self.emit(f"var {node.name}: {var_type} = {value};")
+        else:
+            self.emit(f"var {node.name}: {var_type};")
+
+    def visit_AssignmentNode(self, node):
+        """Visit assignment"""
+        left = self.visit(node.left)
+        right = self.visit(node.right)
+        operator = getattr(node, "operator", "=")
+        self.emit(f"{left} {operator} {right};")
+
+    def visit_BinaryOpNode(self, node):
+        """Visit binary operation"""
+        left = self.visit(node.left)
+        right = self.visit(node.right)
+        return f"({left} {node.op} {right})"
+
+    def visit_UnaryOpNode(self, node):
+        """Visit unary operation"""
+        operand = self.visit(node.operand)
+        if hasattr(node, "postfix") and node.postfix:
+            return f"({operand}{node.op})"
+        else:
+            return f"({node.op}{operand})"
+
+    def visit_FunctionCallNode(self, node):
+        """Visit function call"""
+        args = []
+        if hasattr(node, "args") and node.args:
+            args = [self.visit(arg) for arg in node.args]
+        elif hasattr(node, "arguments") and node.arguments:
+            args = [self.visit(arg) for arg in node.arguments]
+
+        args_str = ", ".join(args)
+
+        # Get function name
+        if hasattr(node, "name"):
+            func_name = node.name
+        else:
+            func_name = str(node.function) if hasattr(node, "function") else "unknown"
+
+        # Convert HIP built-in functions
+        crossgl_func = self.convert_hip_builtin_function(func_name)
+        return f"{crossgl_func}({args_str})"
+
+    def visit_MemberAccessNode(self, node):
+        """Visit member access"""
+        obj = self.visit(node.object)
+        if hasattr(node, "is_pointer") and node.is_pointer:
+            # Convert pointer access to direct access in CrossGL
+            return f"{obj}.{node.member}"
+        else:
+            return f"{obj}.{node.member}"
+
+    def visit_ArrayAccessNode(self, node):
+        """Visit array access"""
+        array = self.visit(node.array)
+        index = self.visit(node.index)
+        return f"{array}[{index}]"
+
+    def visit_HipBuiltinNode(self, node):
+        """Visit HIP built-in variables"""
+        builtin_map = {
+            "threadIdx": "gl_LocalInvocationID",
+            "blockIdx": "gl_WorkGroupID",
+            "gridDim": "gl_NumWorkGroups",
+            "blockDim": "gl_WorkGroupSize",
+        }
+
+        base_name = builtin_map.get(node.builtin_name, node.builtin_name)
+        if hasattr(node, "component") and node.component:
+            return f"{base_name}.{node.component}"
+        else:
+            return base_name
+
+    def visit_ReturnNode(self, node):
+        """Visit return statement"""
+        if hasattr(node, "value") and node.value:
+            value = self.visit(node.value)
+            self.emit(f"return {value};")
+        else:
+            self.emit("return;")
+
+    def visit_IfNode(self, node):
+        """Visit if statement"""
+        condition = self.visit(node.condition)
+        self.emit(f"if ({condition}) {{")
+
+        self.indent_level += 1
+        if hasattr(node, "if_body") and node.if_body:
+            if isinstance(node.if_body, list):
+                for stmt in node.if_body:
+                    self.visit(stmt)
+            else:
+                self.visit(node.if_body)
+        self.indent_level -= 1
+
+        if hasattr(node, "else_body") and node.else_body:
+            self.emit("} else {")
+            self.indent_level += 1
+            if isinstance(node.else_body, list):
+                for stmt in node.else_body:
+                    self.visit(stmt)
+            else:
+                self.visit(node.else_body)
+            self.indent_level -= 1
+
+        self.emit("}")
+
+    def visit_ForNode(self, node):
+        """Visit for loop"""
+        init = self.visit(node.init) if hasattr(node, "init") and node.init else ""
+        condition = (
+            self.visit(node.condition)
+            if hasattr(node, "condition") and node.condition
+            else ""
+        )
+        update = (
+            self.visit(node.update) if hasattr(node, "update") and node.update else ""
+        )
+
+        self.emit(f"for ({init}; {condition}; {update}) {{")
+
+        self.indent_level += 1
+        if hasattr(node, "body") and node.body:
+            if isinstance(node.body, list):
+                for stmt in node.body:
+                    self.visit(stmt)
+            else:
+                self.visit(node.body)
+        self.indent_level -= 1
+
+        self.emit("}")
+
+    def convert_hip_type_to_crossgl(self, hip_type):
+        """Convert HIP types to CrossGL equivalents"""
+        if hip_type is None:
+            return "void"
+
+        if not isinstance(hip_type, str):
+            hip_type = str(hip_type)
+
+        type_mapping = {
+            # Basic types
+            "void": "void",
+            "bool": "bool",
+            "char": "i8",
+            "unsigned char": "u8",
+            "short": "i16",
+            "unsigned short": "u16",
+            "int": "i32",
+            "unsigned int": "u32",
+            "long": "i64",
+            "unsigned long": "u64",
+            "float": "f32",
+            "double": "f64",
+            "size_t": "u32",
+            # HIP vector types
+            "float2": "vec2<f32>",
+            "float3": "vec3<f32>",
+            "float4": "vec4<f32>",
+            "double2": "vec2<f64>",
+            "double3": "vec3<f64>",
+            "double4": "vec4<f64>",
+            "int2": "vec2<i32>",
+            "int3": "vec3<i32>",
+            "int4": "vec4<i32>",
+            "uint2": "vec2<u32>",
+            "uint3": "vec3<u32>",
+            "uint4": "vec4<u32>",
+        }
+
+        # Handle pointers
+        if "*" in hip_type:
+            base_type = hip_type.replace("*", "").strip()
+            mapped_base = type_mapping.get(base_type, base_type)
+            return f"ptr<{mapped_base}>"
+
+        # Handle arrays
+        if "[" in hip_type and "]" in hip_type:
+            parts = hip_type.split("[")
+            base_type = parts[0].strip()
+            size = parts[1].split("]")[0]
+            mapped_base = type_mapping.get(base_type, base_type)
+            return f"array<{mapped_base}, {size}>"
+
+        return type_mapping.get(hip_type, hip_type)
+
+    def convert_hip_builtin_function(self, func_name):
+        """Convert HIP built-in functions to CrossGL equivalents"""
+        function_mapping = {
+            # Math functions
+            "sqrtf": "sqrt",
+            "powf": "pow",
+            "sinf": "sin",
+            "cosf": "cos",
+            "tanf": "tan",
+            "logf": "log",
+            "expf": "exp",
+            "fabsf": "abs",
+            "fminf": "min",
+            "fmaxf": "max",
+            "floorf": "floor",
+            "ceilf": "ceil",
+            # Double precision variants
+            "sqrt": "sqrt",
+            "pow": "pow",
+            "sin": "sin",
+            "cos": "cos",
+            "tan": "tan",
+            "log": "log",
+            "exp": "exp",
+            "fabs": "abs",
+            "fmin": "min",
+            "fmax": "max",
+            "floor": "floor",
+            "ceil": "ceil",
+            # Vector functions
+            "make_float2": "vec2<f32>",
+            "make_float3": "vec3<f32>",
+            "make_float4": "vec4<f32>",
+            "make_int2": "vec2<i32>",
+            "make_int3": "vec3<i32>",
+            "make_int4": "vec4<i32>",
+            # Sync functions
+            "__syncthreads": "workgroupBarrier",
+            "__threadfence": "memoryBarrier",
+        }
+
+        return function_mapping.get(func_name, func_name)
+
+    # Legacy method for backwards compatibility
+    def convert(self, node):
+        """Legacy convert method for compatibility"""
+        return self.generate(node)
+
+
+def hip_to_crossgl(hip_ast: Any) -> str:
+    """Convert HIP AST to CrossGL code string"""
+    converter = HipToCrossGLConverter()
+    return converter.generate(hip_ast)
diff --git a/crosstl/backend/HIP/HipLexer.py b/crosstl/backend/HIP/HipLexer.py
new file mode 100644
index 0000000..d530605
--- /dev/null
+++ b/crosstl/backend/HIP/HipLexer.py
@@ -0,0 +1,304 @@
+import re
+from typing import List
+
+
+# Token class for HIP lexer
+class Token:
+    def __init__(self, token_type: str, value: str, line: int = 1, column: int = 1):
+        self.type = token_type
+        self.value = value
+        self.line = line
+        self.column = column
+
+    def __repr__(self):
+        return f"Token({self.type}, '{self.value}')"
+
+
+# Skip tokens that don't need processing
+SKIP_TOKENS = {"WHITESPACE", "COMMENT_SINGLE", "COMMENT_MULTI"}
+
+# HIP token definitions - order matters for correct tokenization
+TOKENS = tuple(
+    [
+        # Comments
+        ("COMMENT_SINGLE", r"//.*"),
+        ("COMMENT_MULTI", r"/\*[\s\S]*?\*/"),
+        # HIP execution configuration (must come before operators)
+        ("KERNEL_LAUNCH_START", r"<<<"),
+        ("KERNEL_LAUNCH_END", r">>>"),
+        # HIP keywords and qualifiers
+        ("__GLOBAL__", r"\b__global__\b"),
+        ("__DEVICE__", r"\b__device__\b"),
+        ("__HOST__", r"\b__host__\b"),
+        ("__SHARED__", r"\b__shared__\b"),
+        ("__CONSTANT__", r"\b__constant__\b"),
+        ("__RESTRICT__", r"\b__restrict__\b"),
+        ("__MANAGED__", r"\b__managed__\b"),
+        ("__NOINLINE__", r"\b__noinline__\b"),
+        ("__FORCEINLINE__", r"\b__forceinline__\b"),
+        # HIP built-in variables
+        ("THREADIDX", r"\bthreadIdx\b"),
+        ("BLOCKIDX", r"\bblockIdx\b"),
+        ("GRIDDIM", r"\bgridDim\b"),
+        ("BLOCKDIM", r"\bblockDim\b"),
+        ("WARPSIZE", r"\bwarpSize\b"),
+        ("HIPTHREADIDX", r"\bhipThreadIdx_x\b|hipThreadIdx_y\b|hipThreadIdx_z\b"),
+        ("HIPBLOCKIDX", r"\bhipBlockIdx_x\b|hipBlockIdx_y\b|hipBlockIdx_z\b"),
+        ("HIPBLOCKDIM", r"\bhipBlockDim_x\b|hipBlockDim_y\b|hipBlockDim_z\b"),
+        ("HIPGRIDDIM", r"\bhipGridDim_x\b|hipGridDim_y\b|hipGridDim_z\b"),
+        # HIP built-in functions
+        ("SYNCTHREADS", r"\b__syncthreads\b|hipDeviceSynchronize\b"),
+        ("SYNCWARP", r"\b__syncwarp\b"),
+        ("ATOMICADD", r"\batomicAdd\b|hipAtomicAdd\b"),
+        ("ATOMICSUB", r"\batomicSub\b|hipAtomicSub\b"),
+        ("ATOMICMAX", r"\batomicMax\b|hipAtomicMax\b"),
+        ("ATOMICMIN", r"\batomicMin\b|hipAtomicMin\b"),
+        ("ATOMICEXCH", r"\batomicExch\b|hipAtomicExch\b"),
+        ("ATOMICCAS", r"\batomicCAS\b|hipAtomicCAS\b"),
+        # HIP error handling
+        ("HIPERROR", r"\bhipError_t\b"),
+        ("HIPSUCCESS", r"\bhipSuccess\b"),
+        # Standard C/C++ keywords
+        ("TYPEDEF", r"\btypedef\b"),
+        ("STRUCT", r"\bstruct\b"),
+        ("UNION", r"\bunion\b"),
+        ("ENUM", r"\benum\b"),
+        ("CLASS", r"\bclass\b"),
+        ("NAMESPACE", r"\bnamespace\b"),
+        ("TEMPLATE", r"\btemplate\b"),
+        ("TYPENAME", r"\btypename\b"),
+        ("EXTERN", r"\bextern\b"),
+        ("STATIC", r"\bstatic\b"),
+        ("INLINE", r"\binline\b"),
+        ("CONST", r"\bconst\b"),
+        ("VOLATILE", r"\bvolatile\b"),
+        ("MUTABLE", r"\bmutable\b"),
+        ("VIRTUAL", r"\bvirtual\b"),
+        ("PUBLIC", r"\bpublic\b"),
+        ("PRIVATE", r"\bprivate\b"),
+        ("PROTECTED", r"\bprotected\b"),
+        # Control flow
+        ("IF", r"\bif\b"),
+        ("ELSE", r"\belse\b"),
+        ("FOR", r"\bfor\b"),
+        ("WHILE", r"\bwhile\b"),
+        ("DO", r"\bdo\b"),
+        ("SWITCH", r"\bswitch\b"),
+        ("CASE", r"\bcase\b"),
+        ("DEFAULT", r"\bdefault\b"),
+        ("BREAK", r"\bbreak\b"),
+        ("CONTINUE", r"\bcontinue\b"),
+        ("RETURN", r"\breturn\b"),
+        ("GOTO", r"\bgoto\b"),
+        # HIP and C++ types
+        ("VOID", r"\bvoid\b"),
+        ("BOOL", r"\bbool\b"),
+        ("CHAR", r"\bchar\b"),
+        ("SHORT", r"\bshort\b"),
+        ("INT", r"\bint\b"),
+        ("LONG", r"\blong\b"),
+        ("FLOAT", r"\bfloat\b"),
+        ("DOUBLE", r"\bdouble\b"),
+        ("SIGNED", r"\bsigned\b"),
+        ("UNSIGNED", r"\bunsigned\b"),
+        ("SIZE_T", r"\bsize_t\b"),
+        # HIP vector types
+        ("FLOAT2", r"\bfloat2\b"),
+        ("FLOAT3", r"\bfloat3\b"),
+        ("FLOAT4", r"\bfloat4\b"),
+        ("DOUBLE2", r"\bdouble2\b"),
+        ("DOUBLE3", r"\bdouble3\b"),
+        ("DOUBLE4", r"\bdouble4\b"),
+        ("INT2", r"\bint2\b"),
+        ("INT3", r"\bint3\b"),
+        ("INT4", r"\bint4\b"),
+        ("UINT2", r"\buint2\b"),
+        ("UINT3", r"\buint3\b"),
+        ("UINT4", r"\buint4\b"),
+        ("CHAR2", r"\bchar2\b"),
+        ("CHAR3", r"\bchar3\b"),
+        ("CHAR4", r"\bchar4\b"),
+        ("UCHAR2", r"\buchar2\b"),
+        ("UCHAR3", r"\buchar3\b"),
+        ("UCHAR4", r"\buchar4\b"),
+        ("SHORT2", r"\bshort2\b"),
+        ("SHORT3", r"\bshort3\b"),
+        ("SHORT4", r"\bshort4\b"),
+        ("USHORT2", r"\bushort2\b"),
+        ("USHORT3", r"\bushort3\b"),
+        ("USHORT4", r"\bushort4\b"),
+        ("LONG2", r"\blong2\b"),
+        ("LONG3", r"\blong3\b"),
+        ("LONG4", r"\blong4\b"),
+        ("ULONG2", r"\bulong2\b"),
+        ("ULONG3", r"\bulong3\b"),
+        ("ULONG4", r"\bulong4\b"),
+        ("LONGLONG2", r"\blonglong2\b"),
+        ("LONGLONG3", r"\blonglong3\b"),
+        ("LONGLONG4", r"\blonglong4\b"),
+        ("ULONGLONG2", r"\bulonglong2\b"),
+        ("ULONGLONG3", r"\bulonglong3\b"),
+        ("ULONGLONG4", r"\bulonglong4\b"),
+        # HIP texture types
+        ("TEXTURE", r"\btexture\b"),
+        ("SURFACE", r"\bsurface\b"),
+        ("HIPARRAY", r"\bhipArray\b"),
+        ("HIPARRAYT", r"\bhipArray_t\b"),
+        # Boolean literals
+        ("TRUE", r"\btrue\b"),
+        ("FALSE", r"\bfalse\b"),
+        ("NULL", r"\bNULL\b"),
+        ("NULLPTR", r"\bnullptr\b"),
+        # Identifiers and literals (must come after keywords)
+        ("IDENTIFIER", r"[a-zA-Z_][a-zA-Z0-9_]*"),
+        ("INTEGER", r"\d+[lLuU]*"),
+        (
+            "FLOAT",
+            r"\d*\.\d+([fFdDlL]*|[eE][+-]?\d+[fFdDlL]*)?|\d+[eE][+-]?\d+[fFdDlL]*|\d+[fFdDlL]",
+        ),
+        ("STRING", r'"([^"\\]|\\.)*"'),
+        ("CHAR", r"'([^'\\]|\\.)'"),
+        # Preprocessor
+        ("HASH", r"#"),
+        # Operators (multi-character first)
+        ("SCOPE", r"::"),
+        ("LSHIFT", r"<<"),
+        ("RSHIFT", r">>"),
+        ("PLUS_ASSIGN", r"\+="),
+        ("MINUS_ASSIGN", r"-="),
+        ("STAR_ASSIGN", r"\*="),
+        ("SLASH_ASSIGN", r"/="),
+        ("PERCENT_ASSIGN", r"%="),
+        ("AND_ASSIGN", r"&="),
+        ("OR_ASSIGN", r"\|="),
+        ("XOR_ASSIGN", r"\^="),
+        ("LSHIFT_ASSIGN", r"<<="),
+        ("RSHIFT_ASSIGN", r">>="),
+        ("AND", r"&&"),
+        ("OR", r"\|\|"),
+        ("EQ", r"=="),
+        ("NE", r"!="),
+        ("LE", r"<="),
+        ("GE", r">="),
+        ("INCREMENT", r"\+\+"),
+        ("DECREMENT", r"--"),
+        ("ARROW", r"->"),
+        ("DOT", r"\."),
+        # Single character operators
+        ("PLUS", r"\+"),
+        ("MINUS", r"-"),
+        ("STAR", r"\*"),
+        ("SLASH", r"/"),
+        ("PERCENT", r"%"),
+        ("ASSIGN", r"="),
+        ("LT", r"<"),
+        ("GT", r">"),
+        ("NOT", r"!"),
+        ("AMPERSAND", r"&"),
+        ("PIPE", r"\|"),
+        ("XOR", r"\^"),
+        ("TILDE", r"~"),
+        ("QUESTION", r"\?"),
+        ("COLON", r":"),
+        # Delimiters
+        ("LBRACE", r"\{"),
+        ("RBRACE", r"\}"),
+        ("LPAREN", r"\("),
+        ("RPAREN", r"\)"),
+        ("LBRACKET", r"\["),
+        ("RBRACKET", r"\]"),
+        ("SEMICOLON", r";"),
+        ("COMMA", r","),
+        # Whitespace and newlines (must be last)
+        ("NEWLINE", r"\n"),
+        ("WHITESPACE", r"[ \t\r]+"),
+    ]
+)
+
+# Keywords mapping for reserved word detection
+KEYWORDS = {
+    "__global__": "__GLOBAL__",
+    "__device__": "__DEVICE__",
+    "__host__": "__HOST__",
+    "__shared__": "__SHARED__",
+    "__constant__": "__CONSTANT__",
+    "__restrict__": "__RESTRICT__",
+    "__managed__": "__MANAGED__",
+    "__noinline__": "__NOINLINE__",
+    "__forceinline__": "__FORCEINLINE__",
+    "threadIdx": "THREADIDX",
+    "blockIdx": "BLOCKIDX",
+    "gridDim": "GRIDDIM",
+    "blockDim": "BLOCKDIM",
+    "warpSize": "WARPSIZE",
+}
+
+
+class HipLexer:
+    def __init__(self, code: str):
+        self._token_patterns = [(name, re.compile(pattern)) for name, pattern in TOKENS]
+        self.code = code
+        self._length = len(code)
+        self.reserved_keywords = KEYWORDS
+        self.line = 1
+        self.column = 1
+
+    def tokenize(self) -> List[Token]:
+        """Tokenize the input code and return list of tokens"""
+        tokens = []
+        pos = 0
+
+        while pos < self._length:
+            token = self._next_token(pos)
+            if token is None:
+                raise SyntaxError(
+                    f"Illegal character '{self.code[pos]}' at position {pos}"
+                )
+            new_pos, token_type, text = token
+
+            # Check if identifier is a reserved keyword
+            if token_type == "IDENTIFIER" and text in self.reserved_keywords:
+                token_type = self.reserved_keywords[text]
+
+            # Skip whitespace and comments unless needed for debugging
+            if token_type not in SKIP_TOKENS:
+                tokens.append(Token(token_type, text, self.line, self.column))
+
+            # Update line and column tracking
+            if token_type == "NEWLINE":
+                self.line += 1
+                self.column = 1
+            else:
+                self.column += len(text)
+
+            pos = new_pos
+
+        return tokens
+
+    def _next_token(self, pos: int):
+        """Find the next token starting at the given position"""
+        for token_type, pattern in self._token_patterns:
+            match = pattern.match(self.code, pos)
+            if match:
+                text = match.group(0)
+                return match.end(), token_type, text
+        return None
+
+
+# For compatibility with existing test expectations
+def parse_hip_code(code: str):
+    """
+    Parse HIP code and return the AST
+
+    Args:
+        code: HIP source code as string
+
+    Returns:
+        AST representing the parsed HIP code
+    """
+    from .HipParser import HipParser
+
+    lexer = HipLexer(code)
+    tokens = lexer.tokenize()
+    parser = HipParser(tokens)
+    return parser.parse()
diff --git a/crosstl/backend/HIP/HipParser.py b/crosstl/backend/HIP/HipParser.py
new file mode 100644
index 0000000..0f0447a
--- /dev/null
+++ b/crosstl/backend/HIP/HipParser.py
@@ -0,0 +1,797 @@
+"""HIP Parser for converting HIP tokens to AST"""
+
+from typing import List
+from .HipLexer import HipLexer, Token
+from .HipAst import (
+    ASTNode,
+    ShaderNode,
+    FunctionNode,
+    KernelNode,
+    StructNode,
+    VariableNode,
+    AssignmentNode,
+    BinaryOpNode,
+    UnaryOpNode,
+    FunctionCallNode,
+    AtomicOperationNode,
+    SyncNode,
+    MemberAccessNode,
+    ArrayAccessNode,
+    IfNode,
+    ForNode,
+    WhileNode,
+    ReturnNode,
+    BreakNode,
+    ContinueNode,
+    PreprocessorNode,
+    HipBuiltinNode,
+)
+
+
+class HipProgramNode(ASTNode):
+    """Root node representing a complete HIP program"""
+
+    def __init__(self, statements=None):
+        self.statements = statements or []
+
+    def __repr__(self):
+        return f"HipProgramNode(statements={self.statements})"
+
+
+class HipParser:
+    """Parser for HIP language constructs"""
+
+    def __init__(self, tokens: List[Token]):
+        self.tokens = tokens
+        self.pos = 0
+        self.current_token = self.tokens[0] if tokens else None
+
+    def error(self, message: str):
+        """Raise a parsing error with context"""
+        token_info = (
+            f"at token '{self.current_token.value}'"
+            if self.current_token
+            else "at end of input"
+        )
+        raise SyntaxError(f"Parse error {token_info}: {message}")
+
+    def advance(self):
+        """Move to the next token"""
+        if self.pos < len(self.tokens) - 1:
+            self.pos += 1
+            self.current_token = self.tokens[self.pos]
+        else:
+            self.current_token = None
+
+    def peek(self, offset: int = 1):
+        """Look ahead at the next token without advancing"""
+        peek_pos = self.pos + offset
+        if peek_pos < len(self.tokens):
+            return self.tokens[peek_pos]
+        return None
+
+    def consume(self, expected_type: str):
+        """Consume a token of the expected type"""
+        if not self.current_token:
+            self.error(f"Expected {expected_type} but reached end of input")
+
+        if self.current_token.type != expected_type:
+            self.error(f"Expected {expected_type}, got {self.current_token.type}")
+
+        token = self.current_token
+        self.advance()
+        return token
+
+    def match(self, *token_types: str) -> bool:
+        """Check if current token matches any of the given types"""
+        if not self.current_token:
+            return False
+        return self.current_token.type in token_types
+
+    def parse(self):
+        """Parse the entire HIP program"""
+        statements = []
+
+        while self.current_token:
+            if self.match("NEWLINE", "SEMICOLON"):
+                self.advance()
+                continue
+
+            stmt = self.parse_statement()
+            if stmt:
+                statements.append(stmt)
+
+        return HipProgramNode(statements)
+
+    def parse_statement(self):
+        """Parse a single statement"""
+        if not self.current_token:
+            return None
+
+        # Skip newlines and semicolons
+        if self.match("NEWLINE", "SEMICOLON"):
+            self.advance()
+            return None
+
+        # Parse preprocessor directives
+        if self.match("HASH"):
+            return self.parse_preprocessor()
+
+        # Parse device/host/global qualifiers
+        if self.match("__DEVICE__", "__HOST__", "__GLOBAL__"):
+            return self.parse_function_with_qualifier()
+
+        # Parse struct definitions
+        if self.match("STRUCT"):
+            return self.parse_struct()
+
+        # Parse class definitions
+        if self.match("CLASS"):
+            return self.parse_class()
+
+        # Parse return statements
+        if self.match("RETURN"):
+            return self.parse_return_statement()
+
+        # Parse control flow statements
+        if self.match("IF"):
+            return self.parse_if_statement()
+        elif self.match("FOR"):
+            return self.parse_for_statement()
+        elif self.match("WHILE"):
+            return self.parse_while_statement()
+
+        # Try to parse function or variable declaration
+        if self.is_function_declaration():
+            return self.parse_simple_function()
+        elif self.is_variable_declaration():
+            return self.parse_variable_declaration()
+        else:
+            # Parse expression statement
+            return self.parse_expression_statement()
+
+    def parse_preprocessor(self):
+        """Parse preprocessor directives"""
+        self.consume("HASH")
+
+        if not self.current_token:
+            self.error("Expected preprocessor directive after #")
+
+        directive = self.current_token.value
+        self.advance()
+
+        # Parse the rest of the line
+        content = []
+        while self.current_token and not self.match("NEWLINE"):
+            content.append(self.current_token.value)
+            self.advance()
+
+        return PreprocessorNode(directive, " ".join(content))
+
+    def parse_function_with_qualifier(self):
+        """Parse function with device/host qualifiers"""
+        qualifiers = []
+
+        # Parse all qualifiers
+        while self.match(
+            "__DEVICE__", "__HOST__", "__GLOBAL__", "__FORCEINLINE__", "__NOINLINE__"
+        ):
+            qualifiers.append(self.current_token.value)
+            self.advance()
+
+        # Parse return type
+        return_type = self.parse_type()
+
+        # Parse function name
+        name = self.consume("IDENTIFIER").value
+
+        # Parse parameters
+        self.consume("LPAREN")
+        params = self.parse_parameter_list()
+        self.consume("RPAREN")
+
+        # Parse function body or semicolon for declaration
+        body = None
+        if self.match("LBRACE"):
+            body = self.parse_block()
+        elif self.match("SEMICOLON"):
+            self.advance()
+
+        function = FunctionNode(return_type, name, params, body, qualifiers)
+
+        # If it has __global__ qualifier, it's a kernel
+        if "__global__" in qualifiers:
+            return KernelNode(return_type, name, params, body)
+
+        return function
+
+    def parse_simple_function(self):
+        """Parse a simple function without qualifiers"""
+        return_type = self.parse_type()
+        name = self.consume("IDENTIFIER").value
+
+        # Parse parameters
+        self.consume("LPAREN")
+        params = self.parse_parameter_list()
+        self.consume("RPAREN")
+
+        # Parse function body or semicolon for declaration
+        body = None
+        if self.match("LBRACE"):
+            body = self.parse_block()
+        elif self.match("SEMICOLON"):
+            self.advance()
+
+        return FunctionNode(return_type, name, params, body)
+
+    def parse_struct(self):
+        """Parse struct definitions"""
+        self.consume("STRUCT")
+
+        name = None
+        if self.match("IDENTIFIER"):
+            name = self.current_token.value
+            self.advance()
+
+        # Parse struct body
+        members = []
+        if self.match("LBRACE"):
+            self.consume("LBRACE")
+            while self.current_token and not self.match("RBRACE"):
+                if self.match("NEWLINE", "SEMICOLON"):
+                    self.advance()
+                    continue
+
+                # Parse struct member
+                member = self.parse_struct_member()
+                if member:
+                    members.append(member)
+
+            self.consume("RBRACE")
+
+        # Optional semicolon
+        if self.match("SEMICOLON"):
+            self.advance()
+
+        return StructNode(name, members)
+
+    def parse_class(self):
+        """Parse class definitions (treat similar to struct for now)"""
+        self.consume("CLASS")
+
+        name = self.consume("IDENTIFIER").value
+
+        # Parse class body (simplified)
+        members = []
+        if self.match("LBRACE"):
+            self.consume("LBRACE")
+            while self.current_token and not self.match("RBRACE"):
+                if self.match("NEWLINE", "SEMICOLON"):
+                    self.advance()
+                    continue
+
+                # Skip access specifiers
+                if self.match("PUBLIC", "PRIVATE", "PROTECTED"):
+                    self.advance()
+                    if self.match("COLON"):
+                        self.advance()
+                    continue
+
+                # Parse class member
+                member = self.parse_struct_member()
+                if member:
+                    members.append(member)
+
+            self.consume("RBRACE")
+
+        # Optional semicolon
+        if self.match("SEMICOLON"):
+            self.advance()
+
+        return StructNode(name, members)  # Treat class as struct for simplicity
+
+    def parse_struct_member(self):
+        """Parse struct member"""
+        try:
+            # Parse type
+            member_type = self.parse_type()
+
+            # Parse member name
+            name = self.consume("IDENTIFIER").value
+
+            # Handle array declarations
+            if self.match("LBRACKET"):
+                self.consume("LBRACKET")
+                # Skip array size for now
+                while self.current_token and not self.match("RBRACKET"):
+                    self.advance()
+                self.consume("RBRACKET")
+
+            # Consume semicolon
+            if self.match("SEMICOLON"):
+                self.advance()
+
+            return VariableNode(member_type, name)
+        except:
+            # Skip problematic member
+            while self.current_token and not self.match("SEMICOLON", "RBRACE"):
+                self.advance()
+            if self.match("SEMICOLON"):
+                self.advance()
+            return None
+
+    def parse_variable_declaration(self):
+        """Parse variable declarations"""
+        qualifiers = []
+
+        # Parse storage qualifiers
+        while self.match(
+            "__SHARED__", "__CONSTANT__", "__DEVICE__", "STATIC", "EXTERN"
+        ):
+            qualifiers.append(self.current_token.value)
+            self.advance()
+
+        # Parse type
+        var_type = self.parse_type()
+
+        # Parse variable name
+        name = self.consume("IDENTIFIER").value
+
+        # Parse initializer (optional)
+        value = None
+        if self.match("ASSIGN"):
+            self.advance()
+            value = self.parse_expression()
+
+        # Handle array declarations
+        if self.match("LBRACKET"):
+            self.consume("LBRACKET")
+            # Skip array size for now
+            while self.current_token and not self.match("RBRACKET"):
+                self.advance()
+            self.consume("RBRACKET")
+
+        # Consume semicolon
+        if self.match("SEMICOLON"):
+            self.advance()
+
+        return VariableNode(var_type, name, value, qualifiers)
+
+    def parse_type(self):
+        """Parse type specification"""
+        type_name = ""
+
+        # Handle basic types and HIP vector types
+        if self.match(
+            "INT",
+            "FLOAT",
+            "DOUBLE",
+            "BOOL",
+            "VOID",
+            "CHAR",
+            "SHORT",
+            "LONG",
+            "UNSIGNED",
+            "SIGNED",
+        ):
+            type_name = self.current_token.value
+            self.advance()
+        elif self.match(
+            "FLOAT2",
+            "FLOAT3",
+            "FLOAT4",
+            "INT2",
+            "INT3",
+            "INT4",
+            "DOUBLE2",
+            "DOUBLE3",
+            "DOUBLE4",
+        ):
+            type_name = self.current_token.value
+            self.advance()
+        elif self.match("IDENTIFIER"):
+            type_name = self.current_token.value
+            self.advance()
+        else:
+            type_name = "int"  # Default type
+
+        # Handle pointer types
+        while self.match("ASTERISK", "STAR"):
+            type_name += "*"
+            self.advance()
+
+        return type_name
+
+    def parse_parameter_list(self):
+        """Parse function parameter list"""
+        params = []
+
+        if self.match("RPAREN"):
+            return params
+
+        while True:
+            # Parse parameter type
+            param_type = self.parse_type()
+
+            # Parse parameter name (optional)
+            param_name = ""
+            if self.match("IDENTIFIER"):
+                param_name = self.current_token.value
+                self.advance()
+
+            params.append({"type": param_type, "name": param_name})
+
+            if self.match("COMMA"):
+                self.advance()
+            else:
+                break
+
+        return params
+
+    def parse_return_statement(self):
+        """Parse return statement"""
+        self.consume("RETURN")
+
+        value = None
+        if not self.match("SEMICOLON"):
+            value = self.parse_expression()
+
+        if self.match("SEMICOLON"):
+            self.advance()
+
+        return ReturnNode(value)
+
+    def parse_if_statement(self):
+        """Parse if statement"""
+        self.consume("IF")
+        self.consume("LPAREN")
+        condition = self.parse_expression()
+        self.consume("RPAREN")
+
+        # Parse if body - could be a single statement or block
+        if_body = None
+        if self.match("LBRACE"):
+            if_body = self.parse_block()
+        else:
+            if_body = self.parse_statement()
+
+        else_body = None
+        if self.match("ELSE"):
+            self.advance()
+            if self.match("LBRACE"):
+                else_body = self.parse_block()
+            else:
+                else_body = self.parse_statement()
+
+        return IfNode(condition, if_body, else_body)
+
+    def parse_for_statement(self):
+        """Parse for statement"""
+        self.consume("FOR")
+        self.consume("LPAREN")
+
+        init = None
+        if not self.match("SEMICOLON"):
+            init = self.parse_expression()
+        self.consume("SEMICOLON")
+
+        condition = None
+        if not self.match("SEMICOLON"):
+            condition = self.parse_expression()
+        self.consume("SEMICOLON")
+
+        update = None
+        if not self.match("RPAREN"):
+            update = self.parse_expression()
+        self.consume("RPAREN")
+
+        body = self.parse_statement()
+
+        return ForNode(init, condition, update, body)
+
+    def parse_while_statement(self):
+        """Parse while statement"""
+        self.consume("WHILE")
+        self.consume("LPAREN")
+        condition = self.parse_expression()
+        self.consume("RPAREN")
+
+        body = self.parse_statement()
+
+        return WhileNode(condition, body)
+
+    def parse_block(self):
+        """Parse a block of statements"""
+        self.consume("LBRACE")
+        statements = []
+
+        while self.current_token and not self.match("RBRACE"):
+            stmt = self.parse_statement()
+            if stmt:
+                statements.append(stmt)
+
+        self.consume("RBRACE")
+        return statements
+
+    def parse_expression_statement(self):
+        """Parse expression statement"""
+        expr = self.parse_expression()
+
+        if self.match("SEMICOLON"):
+            self.advance()
+
+        return expr
+
+    def parse_expression(self):
+        """Parse expressions (simplified)"""
+        return self.parse_assignment_expression()
+
+    def parse_assignment_expression(self):
+        """Parse assignment expressions"""
+        left = self.parse_logical_or_expression()
+
+        if self.match(
+            "ASSIGN", "PLUS_ASSIGN", "MINUS_ASSIGN", "MULTIPLY_ASSIGN", "DIVIDE_ASSIGN"
+        ):
+            op = self.current_token.value
+            self.advance()
+            right = self.parse_assignment_expression()
+            return AssignmentNode(left, right, op)
+
+        return left
+
+    def parse_logical_or_expression(self):
+        """Parse logical OR expressions"""
+        left = self.parse_logical_and_expression()
+
+        while self.match("LOGICAL_OR"):
+            op = self.current_token.value
+            self.advance()
+            right = self.parse_logical_and_expression()
+            left = BinaryOpNode(left, op, right)
+
+        return left
+
+    def parse_logical_and_expression(self):
+        """Parse logical AND expressions"""
+        left = self.parse_equality_expression()
+
+        while self.match("LOGICAL_AND"):
+            op = self.current_token.value
+            self.advance()
+            right = self.parse_equality_expression()
+            left = BinaryOpNode(left, op, right)
+
+        return left
+
+    def parse_equality_expression(self):
+        """Parse equality expressions"""
+        left = self.parse_relational_expression()
+
+        while self.match("EQ", "NE"):
+            op = self.current_token.value
+            self.advance()
+            right = self.parse_relational_expression()
+            left = BinaryOpNode(left, op, right)
+
+        return left
+
+    def parse_relational_expression(self):
+        """Parse relational expressions"""
+        left = self.parse_additive_expression()
+
+        while self.match("LT", "LE", "GT", "GE"):
+            op = self.current_token.value
+            self.advance()
+            right = self.parse_additive_expression()
+            left = BinaryOpNode(left, op, right)
+
+        return left
+
+    def parse_additive_expression(self):
+        """Parse additive expressions"""
+        left = self.parse_multiplicative_expression()
+
+        while self.match("PLUS", "MINUS"):
+            op = self.current_token.value
+            self.advance()
+            right = self.parse_multiplicative_expression()
+            left = BinaryOpNode(left, op, right)
+
+        return left
+
+    def parse_multiplicative_expression(self):
+        """Parse multiplicative expressions"""
+        left = self.parse_unary_expression()
+
+        while self.match("MULTIPLY", "STAR", "DIVIDE", "SLASH", "MODULO", "PERCENT"):
+            op = self.current_token.value
+            self.advance()
+            right = self.parse_unary_expression()
+            left = BinaryOpNode(left, op, right)
+
+        return left
+
+    def parse_unary_expression(self):
+        """Parse unary expressions"""
+        if self.match(
+            "PLUS", "MINUS", "NOT", "BITWISE_NOT", "INCREMENT", "DECREMENT", "STAR"
+        ):
+            op = self.current_token.value
+            self.advance()
+            operand = self.parse_unary_expression()
+            return UnaryOpNode(op, operand)
+
+        return self.parse_postfix_expression()
+
+    def parse_postfix_expression(self):
+        """Parse postfix expressions"""
+        expr = self.parse_primary_expression()
+
+        while True:
+            if self.match("LBRACKET"):  # Array access
+                self.consume("LBRACKET")
+                index = self.parse_expression()
+                self.consume("RBRACKET")
+                expr = ArrayAccessNode(expr, index)
+            elif self.match("DOT"):  # Member access
+                self.consume("DOT")
+                member = self.consume("IDENTIFIER").value
+                expr = MemberAccessNode(expr, member, False)
+            elif self.match("ARROW"):  # Pointer member access
+                self.consume("ARROW")
+                member = self.consume("IDENTIFIER").value
+                expr = MemberAccessNode(expr, member, True)
+            elif self.match("LPAREN"):  # Function call
+                self.consume("LPAREN")
+                args = self.parse_argument_list()
+                self.consume("RPAREN")
+                expr = FunctionCallNode(expr, args)
+            elif self.match("INCREMENT", "DECREMENT"):  # Postfix increment/decrement
+                op = self.current_token.value
+                self.advance()
+                expr = UnaryOpNode(op + "_POST", expr)
+            else:
+                break
+
+        return expr
+
+    def parse_primary_expression(self):
+        """Parse primary expressions"""
+        if self.match("IDENTIFIER"):
+            name = self.current_token.value
+            self.advance()
+
+            # Check for HIP built-in variables
+            if name in ["threadIdx", "blockIdx", "blockDim", "gridDim"]:
+                component = None
+                if self.match("DOT"):
+                    self.advance()
+                    if self.match("IDENTIFIER"):
+                        component = self.current_token.value
+                        self.advance()
+                return HipBuiltinNode(name, component)
+
+            return name
+
+        elif self.match("THREADIDX", "BLOCKIDX", "BLOCKDIM", "GRIDDIM"):
+            # Handle built-in variables as specific tokens
+            name = self.current_token.value
+            self.advance()
+
+            component = None
+            if self.match("DOT"):
+                self.advance()
+                if self.match("IDENTIFIER"):
+                    component = self.current_token.value
+                    self.advance()
+
+            return HipBuiltinNode(name, component)
+
+        elif self.match("INTEGER", "FLOAT_NUM", "FLOAT", "STRING"):
+            value = self.current_token.value
+            self.advance()
+            return value
+
+        elif self.match("LPAREN"):
+            self.consume("LPAREN")
+            expr = self.parse_expression()
+            self.consume("RPAREN")
+            return expr
+
+        else:
+            self.error(
+                f"Unexpected token in expression: {self.current_token.type if self.current_token else 'EOF'}"
+            )
+
+    def parse_argument_list(self):
+        """Parse function call argument list"""
+        args = []
+
+        if self.match("RPAREN"):
+            return args
+
+        while True:
+            arg = self.parse_expression()
+            args.append(arg)
+
+            if self.match("COMMA"):
+                self.advance()
+            else:
+                break
+
+        return args
+
+    def is_function_declaration(self) -> bool:
+        """Check if current position is a function declaration"""
+        # Simple heuristic: type followed by identifier followed by (
+        saved_pos = self.pos
+        try:
+            # Skip type
+            if self.match(
+                "IDENTIFIER", "INT", "FLOAT", "DOUBLE", "VOID", "BOOL", "CHAR"
+            ):
+                self.advance()
+                if self.match("IDENTIFIER"):
+                    self.advance()
+                    if self.match("LPAREN"):
+                        return True
+        except:
+            pass
+        finally:
+            # Restore position
+            self.pos = saved_pos
+            self.current_token = (
+                self.tokens[self.pos] if self.pos < len(self.tokens) else None
+            )
+
+        return False
+
+    def is_variable_declaration(self) -> bool:
+        """Check if current position is a variable declaration"""
+        # Simple heuristic: type followed by identifier (not followed by ()
+        saved_pos = self.pos
+        try:
+            # Skip qualifiers
+            while self.match(
+                "__SHARED__", "__CONSTANT__", "__DEVICE__", "STATIC", "EXTERN"
+            ):
+                self.advance()
+
+            # Check type
+            if self.match(
+                "IDENTIFIER",
+                "INT",
+                "FLOAT",
+                "DOUBLE",
+                "VOID",
+                "BOOL",
+                "CHAR",
+                "FLOAT2",
+                "FLOAT3",
+                "FLOAT4",
+            ):
+                self.advance()
+                if self.match("IDENTIFIER"):
+                    self.advance()
+                    # Not a function if not followed by (
+                    if not self.match("LPAREN"):
+                        return True
+        except:
+            pass
+        finally:
+            # Restore position
+            self.pos = saved_pos
+            self.current_token = (
+                self.tokens[self.pos] if self.pos < len(self.tokens) else None
+            )
+
+        return False
+
+
+def parse_hip_code(code: str) -> HipProgramNode:
+    """Parse HIP code and return AST"""
+    lexer = HipLexer(code)
+    tokens = lexer.tokenize()
+    parser = HipParser(tokens)
+    return parser.parse()
diff --git a/crosstl/backend/HIP/__init__.py b/crosstl/backend/HIP/__init__.py
new file mode 100644
index 0000000..25faedb
--- /dev/null
+++ b/crosstl/backend/HIP/__init__.py
@@ -0,0 +1,6 @@
+"""HIP Backend for CrossGL Translator"""
+
+from .HipLexer import HipLexer
+from .HipParser import HipParser, HipProgramNode
+from .HipAst import *
+from .HipCrossGLCodeGen import HipToCrossGLConverter
diff --git a/crosstl/formatter.py b/crosstl/formatter.py
index 246d2c4..59e00d6 100644
--- a/crosstl/formatter.py
+++ b/crosstl/formatter.py
@@ -19,6 +19,7 @@ class ShaderLanguage(Enum):
     MOJO = "mojo"
     RUST = "rust"
     CUDA = "cuda"
+    HIP = "hip"
     UNKNOWN = "unknown"
 
 
@@ -67,6 +68,8 @@ class CodeFormatter:
             return ShaderLanguage.RUST
         elif ext in [".cu", ".cuh", ".cuda"]:
             return ShaderLanguage.CUDA
+        elif ext in [".hip"]:
+            return ShaderLanguage.HIP
         else:
             return ShaderLanguage.UNKNOWN
 
@@ -99,6 +102,7 @@ class CodeFormatter:
             ShaderLanguage.METAL,
             ShaderLanguage.RUST,
             ShaderLanguage.CUDA,
+            ShaderLanguage.HIP,
         ]:
             return self._format_with_clang(code, language)
         elif language == ShaderLanguage.SPIRV:
@@ -120,6 +124,7 @@ class CodeFormatter:
             ShaderLanguage.METAL: "LLVM",
             ShaderLanguage.RUST: "LLVM",
             ShaderLanguage.CUDA: "Google",
+            ShaderLanguage.HIP: "Google",
         }
         style = style_map.get(language, "LLVM")
 
@@ -131,6 +136,7 @@ class CodeFormatter:
                 ShaderLanguage.METAL: ".metal",
                 ShaderLanguage.RUST: ".rs",
                 ShaderLanguage.CUDA: ".cu",
+                ShaderLanguage.HIP: ".hip",
             }
             ext = ext_map.get(language, ".txt")
 
@@ -330,6 +336,7 @@ def format_shader_code(code, backend, output_path=None):
         "mojo": ShaderLanguage.MOJO,
         "rust": ShaderLanguage.RUST,
         "cuda": ShaderLanguage.CUDA,
+        "hip": ShaderLanguage.HIP,
     }
 
     language = language_map.get(backend.lower())
diff --git a/crosstl/translator/codegen/hip_codegen.py b/crosstl/translator/codegen/hip_codegen.py
new file mode 100644
index 0000000..f56acff
--- /dev/null
+++ b/crosstl/translator/codegen/hip_codegen.py
@@ -0,0 +1,519 @@
+"""
+CrossGL to HIP Code Generator
+
+This module provides code generation functionality to convert CrossGL AST to HIP source code.
+HIP (Heterogeneous-Compute Interface for Portability) is AMD's CUDA-compatible runtime API
+for GPU programming.
+"""
+
+from ..ast import (
+    ASTNode,
+    CbufferNode,
+    FunctionNode,
+    ShaderNode,
+    StructNode,
+    VariableNode,
+)
+
+
+class HipCodeGen:
+    """Generates HIP code from CrossGL AST"""
+
+    def __init__(self):
+        self.indent_level = 0
+        self.code_lines = []
+        self.current_function = None
+        self.variable_counter = 0
+
+        # CrossGL to HIP type mapping
+        self.type_map = {
+            # Basic types
+            "int": "int",
+            "float": "float",
+            "double": "double",
+            "bool": "bool",
+            "void": "void",
+            "uint": "unsigned int",
+            # Vector types
+            "vec2": "float2",
+            "vec3": "float3",
+            "vec4": "float4",
+            "ivec2": "int2",
+            "ivec3": "int3",
+            "ivec4": "int4",
+            "uvec2": "uint2",
+            "uvec3": "uint3",
+            "uvec4": "uint4",
+            "dvec2": "double2",
+            "dvec3": "double3",
+            "dvec4": "double4",
+            # Matrix types
+            "mat2": "float2x2",
+            "mat3": "float3x3",
+            "mat4": "float4x4",
+            "dmat2": "double2x2",
+            "dmat3": "double3x3",
+            "dmat4": "double4x4",
+            # Texture types
+            "sampler2D": "texture<float4, 2>",
+            "sampler3D": "texture<float4, 3>",
+            "samplerCube": "textureCube<float4>",
+            "image2D": "surface<void, 2>",
+            "buffer": "hipDeviceptr_t",
+        }
+
+        # CrossGL to HIP function mapping
+        self.function_map = {
+            # Math functions
+            "sin": "sinf",
+            "cos": "cosf",
+            "tan": "tanf",
+            "asin": "asinf",
+            "acos": "acosf",
+            "atan": "atanf",
+            "atan2": "atan2f",
+            "sinh": "sinhf",
+            "cosh": "coshf",
+            "tanh": "tanhf",
+            "exp": "expf",
+            "exp2": "exp2f",
+            "log": "logf",
+            "log2": "log2f",
+            "sqrt": "sqrtf",
+            "inversesqrt": "rsqrtf",
+            "pow": "powf",
+            "abs": "fabsf",
+            "floor": "floorf",
+            "ceil": "ceilf",
+            "round": "roundf",
+            "trunc": "truncf",
+            "fract": "fracf",
+            "mod": "fmodf",
+            "min": "fminf",
+            "max": "fmaxf",
+            "clamp": "fmaxf(fminf",  # Special handling needed
+            "mix": "lerp",
+            "step": "step",
+            "smoothstep": "smoothstep",
+            # Vector functions
+            "length": "length",
+            "distance": "distance",
+            "dot": "dot",
+            "cross": "cross",
+            "normalize": "normalize",
+            "reflect": "reflect",
+            "refract": "refract",
+            # Geometric functions
+            "faceforward": "faceforward",
+            # Vector constructors
+            "vec2": "make_float2",
+            "vec3": "make_float3",
+            "vec4": "make_float4",
+            "ivec2": "make_int2",
+            "ivec3": "make_int3",
+            "ivec4": "make_int4",
+            "uvec2": "make_uint2",
+            "uvec3": "make_uint3",
+            "uvec4": "make_uint4",
+            # Texture functions
+            "texture": "tex2D",
+            "textureLod": "tex2DLod",
+            "textureGrad": "tex2DGrad",
+        }
+
+        # Built-in variable mappings
+        self.builtin_map = {
+            "gl_LocalInvocationID.x": "threadIdx.x",
+            "gl_LocalInvocationID.y": "threadIdx.y",
+            "gl_LocalInvocationID.z": "threadIdx.z",
+            "gl_WorkGroupID.x": "blockIdx.x",
+            "gl_WorkGroupID.y": "blockIdx.y",
+            "gl_WorkGroupID.z": "blockIdx.z",
+            "gl_WorkGroupSize.x": "blockDim.x",
+            "gl_WorkGroupSize.y": "blockDim.y",
+            "gl_WorkGroupSize.z": "blockDim.z",
+            "gl_NumWorkGroups.x": "gridDim.x",
+            "gl_NumWorkGroups.y": "gridDim.y",
+            "gl_NumWorkGroups.z": "gridDim.z",
+            "gl_GlobalInvocationID.x": "(blockIdx.x * blockDim.x + threadIdx.x)",
+            "gl_GlobalInvocationID.y": "(blockIdx.y * blockDim.y + threadIdx.y)",
+            "gl_GlobalInvocationID.z": "(blockIdx.z * blockDim.z + threadIdx.z)",
+        }
+
+    def generate(self, node: ASTNode) -> str:
+        """Generate HIP code from CrossGL AST"""
+        self.code_lines = []
+        self.indent_level = 0
+
+        # Add necessary includes
+        self.add_includes()
+
+        # Generate code
+        self.visit(node)
+
+        return "\n".join(self.code_lines)
+
+    def add_includes(self):
+        """Add necessary HIP includes"""
+        self.code_lines.extend(
+            [
+                "#include <hip/hip_runtime.h>",
+                "#include <hip/hip_runtime_api.h>",
+                "#include <hip/math_functions.h>",
+                "#include <hip/device_functions.h>",
+                "",
+            ]
+        )
+
+    def indent(self) -> str:
+        """Return current indentation string"""
+        return "    " * self.indent_level
+
+    def add_line(self, line: str = ""):
+        """Add a line with current indentation"""
+        if line:
+            self.code_lines.append(self.indent() + line)
+        else:
+            self.code_lines.append("")
+
+    def visit(self, node: ASTNode) -> str:
+        """Visit a node and generate code"""
+        method_name = f"visit_{type(node).__name__}"
+        visitor = getattr(self, method_name, self.generic_visit)
+        return visitor(node)
+
+    def generic_visit(self, node: ASTNode) -> str:
+        """Generic visitor for unsupported nodes"""
+        raise NotImplementedError(
+            f"Code generation not implemented for {type(node).__name__}"
+        )
+
+    def visit_ShaderNode(self, node: ShaderNode) -> str:
+        """Visit shader node"""
+        # Generate structs
+        for struct in node.structs:
+            self.visit(struct)
+
+        # Generate global variables
+        for var in node.global_variables:
+            self.visit(var)
+
+        # Generate cbuffers
+        for cbuffer in node.cbuffers:
+            self.visit(cbuffer)
+
+        # Generate functions
+        for func in node.functions:
+            self.visit(func)
+
+        return ""
+
+    def visit_FunctionNode(self, node: FunctionNode) -> str:
+        """Visit function node"""
+        self.current_function = node.name
+
+        # Determine function qualifiers
+        qualifiers = []
+        if hasattr(node, "qualifier") and node.qualifier:
+            if "kernel" in node.qualifier or "compute" in node.qualifier:
+                qualifiers.append("__global__")
+            elif "device" in node.qualifier:
+                qualifiers.append("__device__")
+            else:
+                qualifiers.append("__device__")  # Default for HIP
+        else:
+            qualifiers.append("__device__")  # Default for HIP
+
+        # Function signature
+        return_type = self.map_type(node.return_type)
+        params = ", ".join(self.visit_parameter(param) for param in node.params)
+
+        qualifier_str = " ".join(qualifiers)
+        signature = f"{qualifier_str} {return_type} {node.name}({params})"
+
+        self.add_line(signature)
+
+        if node.body:
+            self.add_line("{")
+            self.indent_level += 1
+            if isinstance(node.body, list):
+                for stmt in node.body:
+                    self.visit(stmt)
+            else:
+                self.visit(node.body)
+            self.indent_level -= 1
+            self.add_line("}")
+        else:
+            self.add_line(";")
+
+        self.add_line()
+        self.current_function = None
+        return ""
+
+    def visit_parameter(self, param) -> str:
+        """Visit parameter node"""
+        if isinstance(param, dict):
+            param_type = self.map_type(param.get("type", "int"))
+            param_name = param.get("name", "param")
+        else:
+            param_type = self.map_type(getattr(param, "vtype", "int"))
+            param_name = getattr(param, "name", "param")
+        return f"{param_type} {param_name}"
+
+    def visit_StructNode(self, node: StructNode) -> str:
+        """Visit struct node"""
+        self.add_line(f"struct {node.name}")
+        self.add_line("{")
+        self.indent_level += 1
+
+        for member in node.members:
+            if isinstance(member, VariableNode):
+                member_type = self.map_type(
+                    getattr(member, "vtype", getattr(member, "var_type", "int"))
+                )
+                self.add_line(f"{member_type} {member.name};")
+
+        self.indent_level -= 1
+        self.add_line("};")
+        self.add_line()
+        return ""
+
+    def visit_VariableNode(self, node: VariableNode) -> str:
+        """Visit variable node"""
+        var_type = self.map_type(node.vtype)
+
+        if hasattr(node, "value") and node.value:
+            value = self.visit(node.value)
+            self.add_line(f"{var_type} {node.name} = {value};")
+        else:
+            self.add_line(f"{var_type} {node.name};")
+
+        return ""
+
+    def visit_CbufferNode(self, node: CbufferNode) -> str:
+        """Visit cbuffer node - convert to struct"""
+        self.add_line(f"struct {node.name}")
+        self.add_line("{")
+        self.indent_level += 1
+
+        for member in node.members:
+            if isinstance(member, VariableNode):
+                member_type = self.map_type(
+                    getattr(member, "vtype", getattr(member, "var_type", "int"))
+                )
+                self.add_line(f"{member_type} {member.name};")
+
+        self.indent_level -= 1
+        self.add_line("};")
+        self.add_line()
+        return ""
+
+    def visit_list(self, node_list) -> str:
+        """Visit list of nodes"""
+        for node in node_list:
+            self.visit(node)
+        return ""
+
+    def visit_IfNode(self, node) -> str:
+        """Visit if node"""
+        condition = self.visit(node.if_condition)
+        self.add_line(f"if ({condition})")
+        self.add_line("{")
+        self.indent_level += 1
+        if isinstance(node.if_body, list):
+            for stmt in node.if_body:
+                self.visit(stmt)
+        else:
+            self.visit(node.if_body)
+        self.indent_level -= 1
+        self.add_line("}")
+
+        if hasattr(node, "else_body") and node.else_body:
+            self.add_line("else")
+            self.add_line("{")
+            self.indent_level += 1
+            if isinstance(node.else_body, list):
+                for stmt in node.else_body:
+                    self.visit(stmt)
+            else:
+                self.visit(node.else_body)
+            self.indent_level -= 1
+            self.add_line("}")
+
+        return ""
+
+    def visit_ForNode(self, node) -> str:
+        """Visit for loop node"""
+        init = self.visit(node.init) if node.init else ""
+        condition = self.visit(node.condition) if node.condition else ""
+        update = self.visit(node.update) if node.update else ""
+
+        self.add_line(f"for ({init}; {condition}; {update})")
+        self.add_line("{")
+        self.indent_level += 1
+        if isinstance(node.body, list):
+            for stmt in node.body:
+                self.visit(stmt)
+        else:
+            self.visit(node.body)
+        self.indent_level -= 1
+        self.add_line("}")
+
+        return ""
+
+    def visit_ReturnNode(self, node) -> str:
+        """Visit return node"""
+        if node.value:
+            value = self.visit(node.value)
+            self.add_line(f"return {value};")
+        else:
+            self.add_line("return;")
+        return ""
+
+    def visit_AssignmentNode(self, node) -> str:
+        """Visit assignment node"""
+        left = self.visit(node.left)
+        right = self.visit(node.right)
+        return f"{left} = {right}"
+
+    def visit_BinaryOpNode(self, node) -> str:
+        """Visit binary operation node"""
+        left = self.visit(node.left)
+        right = self.visit(node.right)
+
+        # Handle special operators
+        if node.op == "and":
+            return f"({left} && {right})"
+        elif node.op == "or":
+            return f"({left} || {right})"
+        else:
+            return f"({left} {node.op} {right})"
+
+    def visit_UnaryOpNode(self, node) -> str:
+        """Visit unary operation node"""
+        operand = self.visit(node.operand)
+
+        if node.op == "not":
+            return f"!{operand}"
+        elif node.op in ["++", "--"]:
+            if hasattr(node, "postfix") and node.postfix:
+                return f"{operand}{node.op}"
+            else:
+                return f"{node.op}{operand}"
+        else:
+            return f"{node.op}{operand}"
+
+    def visit_FunctionCallNode(self, node) -> str:
+        """Visit function call node"""
+        func_name = node.name
+        args = [self.visit(arg) for arg in node.args]
+
+        # Map function name
+        mapped_name = self.function_map.get(func_name, func_name)
+
+        # Handle special functions
+        if func_name == "clamp":
+            if len(args) == 3:
+                return f"fmaxf({args[1]}, fminf({args[2]}, {args[0]}))"
+        elif func_name in ["texture", "tex2D"]:
+            # Handle texture sampling
+            if len(args) >= 2:
+                return f"tex2D({args[0]}, {args[1]})"
+        elif func_name == "barrier":
+            return "__syncthreads()"
+        elif func_name == "memoryBarrier":
+            return "__threadfence()"
+
+        args_str = ", ".join(args)
+        return f"{mapped_name}({args_str})"
+
+    def visit_str(self, node) -> str:
+        """Visit string node"""
+        return str(node)
+
+    def visit_int(self, node) -> str:
+        """Visit integer node"""
+        return str(node)
+
+    def visit_float(self, node) -> str:
+        """Visit float node"""
+        return str(node)
+
+    def visit_ArrayAccessNode(self, node) -> str:
+        """Visit array access node"""
+        array = self.visit(node.array)
+        index = self.visit(node.index)
+        return f"{array}[{index}]"
+
+    def visit_MemberAccessNode(self, node) -> str:
+        """Visit member access node"""
+        object_expr = self.visit(node.object)
+
+        # Handle vector swizzling
+        if node.member in ["x", "y", "z", "w", "r", "g", "b", "a"]:
+            return f"{object_expr}.{node.member}"
+        elif len(node.member) > 1 and all(c in "xyzw" for c in node.member):
+            # Multi-component swizzle - might need special handling
+            return f"{object_expr}.{node.member}"
+        else:
+            return f"{object_expr}.{node.member}"
+
+    def visit_TernaryOpNode(self, node) -> str:
+        """Visit ternary operation node"""
+        condition = self.visit(node.condition)
+        true_expr = self.visit(node.true_expr)
+        false_expr = self.visit(node.false_expr)
+        return f"({condition} ? {true_expr} : {false_expr})"
+
+    def map_type(self, type_name: str) -> str:
+        """Map CrossGL type to HIP type"""
+        # Handle array types
+        if "[" in type_name and "]" in type_name:
+            base_type = type_name.split("[")[0]
+            array_part = type_name[type_name.find("[") :]
+            mapped_base = self.type_map.get(base_type, base_type)
+            return f"{mapped_base}{array_part}"
+
+        return self.type_map.get(type_name, type_name)
+
+    def generate_kernel_wrapper(self, kernel_node: FunctionNode) -> str:
+        """Generate host-side kernel launch wrapper"""
+        wrapper_lines = []
+
+        # Generate wrapper function
+        wrapper_name = f"launch_{kernel_node.name}"
+        params = []
+        args = []
+
+        for param in kernel_node.parameters:
+            param_type = self.map_type(param.param_type)
+            params.append(f"{param_type} {param.name}")
+            args.append(param.name)
+
+        # Add grid and block size parameters
+        params.extend(["dim3 gridSize", "dim3 blockSize", "hipStream_t stream = 0"])
+
+        wrapper_lines.extend(
+            [
+                f"void {wrapper_name}({', '.join(params)})",
+                "{",
+                f"    hipLaunchKernelGGL({kernel_node.name}, gridSize, blockSize, 0, stream, {', '.join(args)});",
+                "}",
+            ]
+        )
+
+        return "\n".join(wrapper_lines)
+
+
+def generate_hip_code(ast: ShaderNode) -> str:
+    """
+    Generate HIP code from CrossGL AST
+
+    Args:
+        ast: CrossGL shader AST
+
+    Returns:
+        Generated HIP source code
+    """
+    generator = HipCodeGen()
+    return generator.generate(ast)
diff --git a/examples/output/ComplexShader.hip b/examples/output/ComplexShader.hip
new file mode 100644
index 0000000..6668991
--- /dev/null
+++ b/examples/output/ComplexShader.hip
@@ -0,0 +1,146 @@
+#include <hip/device_functions.h>
+#include <hip/hip_runtime.h>
+#include <hip/hip_runtime_api.h>
+#include <hip/math_functions.h>
+
+struct Material {
+  float3 albedo;
+  float roughness;
+  float metallic;
+  float3 emissive;
+  float opacity;
+  bool hasNormalMap;
+  texture<float4, 2> albedoMap;
+  texture<float4, 2> normalMap;
+  texture<float4, 2> metallicRoughnessMap;
+};
+
+struct Light {
+  float3 position;
+  float3 color;
+  float intensity;
+  float radius;
+  bool castShadows;
+  float4x4 viewProjection;
+};
+
+struct Scene {
+  float3 ambientLight;
+  float time;
+  float elapsedTime;
+  int activeLightCount;
+  float4x4 viewMatrix;
+  float4x4 projectionMatrix;
+};
+
+struct VertexInput {
+  float3 position;
+  float3 normal;
+  float3 tangent;
+  float3 bitangent;
+  float2 texCoord0;
+  float2 texCoord1;
+  float4 color;
+  int materialIndex;
+};
+
+struct VertexOutput {
+  float3 worldPosition;
+  float3 worldNormal;
+  float3 worldTangent;
+  float3 worldBitangent;
+  float2 texCoord0;
+  float2 texCoord1;
+  float4 color;
+  float3x3 TBN;
+  int materialIndex;
+  float4 clipPosition;
+};
+
+struct FragmentOutput {
+  float4 color;
+  float4 normalBuffer;
+  float4 positionBuffer;
+  float depth;
+};
+
+struct GlobalUniforms {
+  Scene scene;
+  float3 cameraPosition;
+  float globalRoughness;
+  float2 screenSize;
+  float nearPlane;
+  float farPlane;
+  int frameCount;
+};
+
+float PI;
+float EPSILON;
+int MAX_ITERATIONS;
+float a2;
+float num;
+float denom;
+__device__ float geometrySchlickGGX(float NdotV, float roughness) {
+  float r;
+  float k;
+  float num;
+  float denom;
+  return;
+}
+
+__device__ float geometrySmith(float3 N, float3 V, float3 L, float roughness) {
+  float NdotV;
+  float ggx2;
+  return;
+}
+
+__device__ float3 fresnelSchlick(float cosTheta, float3 F0) { return; }
+
+__device__ float noise3D(float3 p) {
+  float3 i;
+  float3 u;
+  float n000;
+  float n010;
+  float n100;
+  float n110;
+  float n00;
+  float n10;
+  float n0;
+  return;
+}
+
+__device__ float fbm(float3 p, int octaves, float lacunarity, float gain) {
+  float sum;
+  float amplitude;
+  float frequency;
+  int i;
+  i;
+  i++;
+  for ((= 0); (< octaves);) {
+    if ((i >= MAX_ITERATIONS)) {
+      break;
+    }
+    sum;
+    frequency;
+  }
+  return;
+}
+
+__device__ float4 samplePlanarProjection(texture<float4, 2> tex,
+                                         float3 worldPos, float3 normal) {
+  float3 absNormal;
+  bool useY;
+  float2 uv;
+  if (useX) {
+    uv;
+    if ((normal.x < 0.0)) {
+      MemberAccessNode(object = uv, member = x);
+    }
+  } else {
+    uv;
+    if ((normal.z < 0.0)) {
+      MemberAccessNode(object = uv, member = x);
+    }
+  }
+  return;
+}
diff --git a/examples/output/PerlinNoise.hip b/examples/output/PerlinNoise.hip
new file mode 100644
index 0000000..1645a8a
--- /dev/null
+++ b/examples/output/PerlinNoise.hip
@@ -0,0 +1,35 @@
+#include <hip/device_functions.h>
+#include <hip/hip_runtime.h>
+#include <hip/hip_runtime_api.h>
+#include <hip/math_functions.h>
+
+struct VertexInput {
+  float3 position;
+};
+
+struct VertexOutput {
+  float2 uv;
+  float4 position;
+};
+
+struct FragmentInput {
+  float2 uv;
+};
+
+struct FragmentOutput {
+  float4 color;
+};
+
+__device__ VertexOutput main(VertexInput input) {
+  VertexOutput output;
+  MemberAccessNode(object = output, member = uv);
+  MemberAccessNode(object = output, member = position);
+  return;
+}
+
+__device__ FragmentOutput main(FragmentInput input) {
+  FragmentOutput output;
+  float noise;
+  float3 color;
+  return;
+}
diff --git a/examples/output/SimpleShader.hip b/examples/output/SimpleShader.hip
new file mode 100644
index 0000000..eb54310
--- /dev/null
+++ b/examples/output/SimpleShader.hip
@@ -0,0 +1,38 @@
+#include <hip/device_functions.h>
+#include <hip/hip_runtime.h>
+#include <hip/hip_runtime_api.h>
+#include <hip/math_functions.h>
+
+struct VertexInput {
+  float3 position;
+  float2 texCoord;
+};
+
+struct VertexOutput {
+  float2 uv;
+  float4 position;
+};
+
+struct FragmentInput {
+  float2 uv;
+};
+
+struct FragmentOutput {
+  float4 color;
+};
+
+__device__ VertexOutput main(VertexInput input) {
+  VertexOutput output;
+  MemberAccessNode(object = output, member = uv);
+  MemberAccessNode(object = output, member = position);
+  return;
+}
+
+__device__ FragmentOutput main(FragmentInput input) {
+  FragmentOutput output;
+  float r;
+  float g;
+  float b;
+  MemberAccessNode(object = output, member = color);
+  return;
+}
diff --git a/setup.py b/setup.py
index 419f1e1..6698fbb 100644
--- a/setup.py
+++ b/setup.py
@@ -14,6 +14,7 @@ setup(
         "crosstl/backend/Mojo",
         "crosstl/backend/Rust",
         "crosstl/backend/CUDA",
+        "crosstl/backend/HIP",
     ],
     version="0.0.1.3",
     author="CrossGL team",


Test patch:
diff --git a/.github/workflows/backend-tests.yml b/.github/workflows/backend-tests.yml
index 281c889..b1b615b 100644
--- a/.github/workflows/backend-tests.yml
+++ b/.github/workflows/backend-tests.yml
@@ -14,7 +14,17 @@ jobs:
     strategy:
       matrix:
         backend:
-          [directx, metal, GLSL, "slang", "SPIRV", "mojo", "rust", "CUDA"]
+          [
+            directx,
+            metal,
+            GLSL,
+            "slang",
+            "SPIRV",
+            "mojo",
+            "rust",
+            "CUDA",
+            "HIP",
+          ]
         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/examples-test.yml b/.github/workflows/examples-test.yml
index db8ebec..9cc48da 100644
--- a/.github/workflows/examples-test.yml
+++ b/.github/workflows/examples-test.yml
@@ -47,6 +47,7 @@ jobs:
           python -c "import crosstl; crosstl.translate('ArrayTest.cgl', backend='mojo', save_shader='output/ArrayTest.mojo')"
           python -c "import crosstl; crosstl.translate('ArrayTest.cgl', backend='rust', save_shader='output/ArrayTest.rs')"
           python -c "import crosstl; crosstl.translate('ArrayTest.cgl', backend='cuda', save_shader='output/ArrayTest.cu')"
+          python -c "import crosstl; crosstl.translate('ArrayTest.cgl', backend='hip', save_shader='output/ArrayTest.hip')"
 
           # Simple Shader
           python -c "import crosstl; crosstl.translate('SimpleShader.cgl', backend='metal', save_shader='output/SimpleShader.metal')"
@@ -56,6 +57,7 @@ jobs:
           python -c "import crosstl; crosstl.translate('SimpleShader.cgl', backend='mojo', save_shader='output/SimpleShader.mojo')"
           python -c "import crosstl; crosstl.translate('SimpleShader.cgl', backend='rust', save_shader='output/SimpleShader.rs')"
           python -c "import crosstl; crosstl.translate('SimpleShader.cgl', backend='cuda', save_shader='output/SimpleShader.cu')"
+          python -c "import crosstl; crosstl.translate('SimpleShader.cgl', backend='hip', save_shader='output/SimpleShader.hip')"
 
           # Perlin Noise
           python -c "import crosstl; crosstl.translate('PerlinNoise.cgl', backend='metal', save_shader='output/PerlinNoise.metal')"
@@ -65,6 +67,7 @@ jobs:
           python -c "import crosstl; crosstl.translate('PerlinNoise.cgl', backend='mojo', save_shader='output/PerlinNoise.mojo')"
           python -c "import crosstl; crosstl.translate('PerlinNoise.cgl', backend='rust', save_shader='output/PerlinNoise.rs')"
           python -c "import crosstl; crosstl.translate('PerlinNoise.cgl', backend='cuda', save_shader='output/PerlinNoise.cu')"
+          python -c "import crosstl; crosstl.translate('PerlinNoise.cgl', backend='hip', save_shader='output/PerlinNoise.hip')"
 
           # Complex Shader
           python -c "import crosstl; crosstl.translate('ComplexShader.cgl', backend='metal', save_shader='output/ComplexShader.metal')"
@@ -74,6 +77,7 @@ jobs:
           python -c "import crosstl; crosstl.translate('ComplexShader.cgl', backend='mojo', save_shader='output/ComplexShader.mojo')"
           python -c "import crosstl; crosstl.translate('ComplexShader.cgl', backend='rust', save_shader='output/ComplexShader.rs')"
           python -c "import crosstl; crosstl.translate('ComplexShader.cgl', backend='cuda', save_shader='output/ComplexShader.cu')"
+          python -c "import crosstl; crosstl.translate('ComplexShader.cgl', backend='hip', save_shader='output/ComplexShader.hip')"
         shell: bash
         continue-on-error: true
 
@@ -127,6 +131,12 @@ jobs:
           - { backend: "cuda", example: "PerlinNoise", extension: ".cu" }
           - { backend: "cuda", example: "ComplexShader", extension: ".cu" }
 
+          # HIP backend
+          - { backend: "hip", example: "ArrayTest", extension: ".hip" }
+          - { backend: "hip", example: "SimpleShader", extension: ".hip" }
+          - { backend: "hip", example: "PerlinNoise", extension: ".hip" }
+          - { backend: "hip", example: "ComplexShader", extension: ".hip" }
+
           # Slang backend is excluded as it's still experimental
           # and not fully implemented
 
diff --git a/.github/workflows/translator-tests.yml b/.github/workflows/translator-tests.yml
index d310647..71b4b4a 100644
--- a/.github/workflows/translator-tests.yml
+++ b/.github/workflows/translator-tests.yml
@@ -23,6 +23,7 @@ jobs:
             "mojo",
             "rust",
             "CUDA",
+            "hip",
             "general",
           ]
         python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
diff --git a/examples/output/ArrayTest.hip b/examples/output/ArrayTest.hip
new file mode 100644
index 0000000..9415caa
--- /dev/null
+++ b/examples/output/ArrayTest.hip
@@ -0,0 +1,43 @@
+#include <hip/device_functions.h>
+#include <hip/hip_runtime.h>
+#include <hip/hip_runtime_api.h>
+#include <hip/math_functions.h>
+
+struct VertexInput {
+  float3 position;
+  float2 texCoord;
+};
+
+struct VertexOutput {
+  float2 uv;
+  float4 position;
+};
+
+struct FragmentInput {
+  float2 uv;
+};
+
+struct FragmentOutput {
+  float4 color;
+};
+
+struct TestBuffer {};
+
+__device__ VertexOutput main(VertexInput input) {
+  VertexOutput output;
+  MemberAccessNode(object = output, member = uv);
+  float scale;
+  float3 position;
+  MemberAccessNode(object = output, member = position);
+  return;
+}
+
+__device__ FragmentOutput main(FragmentInput input) {
+  FragmentOutput output;
+  float3 color;
+  if ((input.uv.x > 0.5)) {
+    color;
+  }
+  MemberAccessNode(object = output, member = color);
+  return;
+}
diff --git a/examples/test.py b/examples/test.py
index b77b721..535c210 100644
--- a/examples/test.py
+++ b/examples/test.py
@@ -40,6 +40,12 @@ def main():
                 save_shader="output/ComplexShader.cu",
             )
 
+            hip_code = crosstl.translate(
+                "ComplexShader.cgl",
+                backend="hip",
+                save_shader="output/ComplexShader.hip",
+            )
+
             print("Complex shader translation successful!")
         except Exception as e:
             print(f"Warning: Complex shader translation failed: {e}")
@@ -76,6 +82,12 @@ def main():
                 save_shader="output/PerlinNoise.cu",
             )
 
+            hip_code = crosstl.translate(
+                "PerlinNoise.cgl",
+                backend="hip",
+                save_shader="output/PerlinNoise.hip",
+            )
+
             print("Perlin noise shader translation successful!")
         except Exception as e:
             print(f"Warning: Perlin noise shader translation failed: {e}")
@@ -106,6 +118,10 @@ def main():
                 "ArrayTest.cgl", backend="cuda", save_shader="output/ArrayTest.cu"
             )
 
+            hip_code = crosstl.translate(
+                "ArrayTest.cgl", backend="hip", save_shader="output/ArrayTest.hip"
+            )
+
             print("Array test shader translation successful!")
         except Exception as e:
             print(f"Warning: Array test shader translation failed: {e}")
@@ -137,6 +153,12 @@ def main():
             save_shader="output/SimpleShader.cu",
         )
 
+        hip_code = crosstl.translate(
+            "SimpleShader.cgl",
+            backend="hip",
+            save_shader="output/SimpleShader.hip",
+        )
+
         print("Simple shader translation successful!")
         return 0
     except Exception as e:
diff --git a/tests/test_backend/test_HIP/__init__.py b/tests/test_backend/test_HIP/__init__.py
new file mode 100644
index 0000000..72f25ac
--- /dev/null
+++ b/tests/test_backend/test_HIP/__init__.py
@@ -0,0 +1,1 @@
+# HIP Backend Tests
diff --git a/tests/test_backend/test_HIP/test_codegen.py b/tests/test_backend/test_HIP/test_codegen.py
new file mode 100644
index 0000000..620e257
--- /dev/null
+++ b/tests/test_backend/test_HIP/test_codegen.py
@@ -0,0 +1,133 @@
+"""Test HIP Code Generation"""
+
+import pytest
+from crosstl.backend.HIP.HipLexer import HipLexer
+from crosstl.backend.HIP.HipParser import HipParser
+from crosstl.backend.HIP.HipCrossGLCodeGen import HipToCrossGLConverter
+
+
+class TestHipCodeGen:
+    def test_basic_kernel_conversion(self):
+        """Test basic kernel to CrossGL conversion"""
+        code = """
+        __global__ void simple_kernel() {
+            int idx = 0;
+        }
+        """
+        lexer = HipLexer(code)
+        tokens = lexer.tokenize()
+        parser = HipParser(tokens)
+        ast = parser.parse()
+
+        codegen = HipToCrossGLConverter()
+        result = codegen.generate(ast)
+
+        assert "// HIP to CrossGL conversion" in result
+        assert "// Kernel: simple_kernel" in result
+
+    def test_device_function_conversion(self):
+        """Test device function conversion"""
+        code = """
+        __device__ float add() {
+            return 1.0;
+        }
+        """
+        lexer = HipLexer(code)
+        tokens = lexer.tokenize()
+        parser = HipParser(tokens)
+        ast = parser.parse()
+
+        codegen = HipToCrossGLConverter()
+        result = codegen.generate(ast)
+
+        assert "// HIP to CrossGL conversion" in result
+        assert "// Function: add" in result
+
+    def test_multiple_kernels_conversion(self):
+        """Test multiple kernels conversion"""
+        code = """
+        __global__ void kernel1() {
+            int x = 1;
+        }
+        
+        __global__ void kernel2() {
+            int x = 2;
+        }
+        """
+        lexer = HipLexer(code)
+        tokens = lexer.tokenize()
+        parser = HipParser(tokens)
+        ast = parser.parse()
+
+        codegen = HipToCrossGLConverter()
+        result = codegen.generate(ast)
+
+        assert "// Kernel: kernel1" in result
+        assert "// Kernel: kernel2" in result
+
+    def test_type_conversion(self):
+        """Test HIP type to CrossGL type conversion"""
+        codegen = HipToCrossGLConverter()
+
+        # Test basic types
+        assert codegen.convert_hip_type_to_crossgl("int") == "i32"
+        assert codegen.convert_hip_type_to_crossgl("float") == "f32"
+        assert codegen.convert_hip_type_to_crossgl("double") == "f64"
+        assert codegen.convert_hip_type_to_crossgl("bool") == "bool"
+        assert codegen.convert_hip_type_to_crossgl("void") == "void"
+
+    def test_function_conversion(self):
+        """Test HIP function to CrossGL function conversion"""
+        codegen = HipToCrossGLConverter()
+
+        # Test math functions
+        assert codegen.convert_hip_builtin_function("sqrtf") == "sqrt"
+        assert codegen.convert_hip_builtin_function("sinf") == "sin"
+        assert codegen.convert_hip_builtin_function("cosf") == "cos"
+        assert (
+            codegen.convert_hip_builtin_function("__syncthreads") == "workgroupBarrier"
+        )
+
+    def test_struct_conversion(self):
+        """Test struct conversion"""
+        code = """
+        struct Point {
+            float x;
+            float y;
+        };
+        """
+        lexer = HipLexer(code)
+        tokens = lexer.tokenize()
+        parser = HipParser(tokens)
+        ast = parser.parse()
+
+        codegen = HipToCrossGLConverter()
+        result = codegen.generate(ast)
+
+        assert "// HIP to CrossGL conversion" in result
+        assert "struct Point" in result
+
+    def test_empty_program(self):
+        """Test empty program conversion"""
+        code = ""
+        lexer = HipLexer(code)
+        tokens = lexer.tokenize()
+        parser = HipParser(tokens)
+        ast = parser.parse()
+
+        codegen = HipToCrossGLConverter()
+        result = codegen.generate(ast)
+
+        assert "// HIP to CrossGL conversion" in result
+
+    def test_vector_type_conversion(self):
+        """Test HIP vector type conversion"""
+        codegen = HipToCrossGLConverter()
+
+        # Test vector type mappings
+        assert codegen.convert_hip_type_to_crossgl("float2") == "vec2<f32>"
+        assert codegen.convert_hip_type_to_crossgl("float3") == "vec3<f32>"
+        assert codegen.convert_hip_type_to_crossgl("float4") == "vec4<f32>"
+        assert codegen.convert_hip_type_to_crossgl("int2") == "vec2<i32>"
+        assert codegen.convert_hip_type_to_crossgl("int3") == "vec3<i32>"
+        assert codegen.convert_hip_type_to_crossgl("int4") == "vec4<i32>"
diff --git a/tests/test_backend/test_HIP/test_lexer.py b/tests/test_backend/test_HIP/test_lexer.py
new file mode 100644
index 0000000..e384965
--- /dev/null
+++ b/tests/test_backend/test_HIP/test_lexer.py
@@ -0,0 +1,422 @@
+"""
+Tests for HIP Lexer
+
+This module contains tests for the HIP lexer functionality,
+ensuring proper tokenization of HIP code constructs.
+"""
+
+import pytest
+from crosstl.backend.HIP.HipLexer import HipLexer
+
+
+class TestHipLexer:
+    """Test cases for HIP lexer"""
+
+    def test_keywords_tokenization(self):
+        """Test HIP keyword tokenization"""
+        code = """
+        __global__ __device__ __host__ __shared__ __constant__
+        __forceinline__ __noinline__ template typename class
+        struct union enum namespace using extern static const
+        """
+        lexer = HipLexer(code)
+        tokens = lexer.tokenize()
+
+        # Extract token types
+        token_types = [token.type for token in tokens]
+
+        # Check for HIP-specific keywords
+        assert "__GLOBAL__" in token_types
+        assert "__DEVICE__" in token_types
+        assert "__HOST__" in token_types
+        assert "__SHARED__" in token_types
+        assert "__CONSTANT__" in token_types
+        assert "__FORCEINLINE__" in token_types
+        assert "__NOINLINE__" in token_types
+        assert "TEMPLATE" in token_types
+        assert "TYPENAME" in token_types
+        assert "CLASS" in token_types
+        assert "STRUCT" in token_types
+
+    def test_hip_vector_types(self):
+        """Test HIP vector type tokenization"""
+        code = """
+        int2 int3 int4 float2 float3 float4
+        double2 double3 double4 uint2 uint3 uint4
+        """
+        lexer = HipLexer(code)
+        tokens = lexer.tokenize()
+
+        # Vector types should be tokenized as specific token types
+        token_pairs = [
+            (token.type, token.value) for token in tokens if token.type != "NEWLINE"
+        ]
+
+        expected_tokens = [
+            ("INT2", "int2"),
+            ("INT3", "int3"),
+            ("INT4", "int4"),
+            ("FLOAT2", "float2"),
+            ("FLOAT3", "float3"),
+            ("FLOAT4", "float4"),
+            ("DOUBLE2", "double2"),
+            ("DOUBLE3", "double3"),
+            ("DOUBLE4", "double4"),
+            ("UINT2", "uint2"),
+            ("UINT3", "uint3"),
+            ("UINT4", "uint4"),
+        ]
+
+        for expected_token in expected_tokens:
+            assert (
+                expected_token in token_pairs
+            ), f"Expected token {expected_token} not found in {token_pairs}"
+
+    def test_hip_builtin_variables(self):
+        """Test HIP built-in variable tokenization"""
+        code = """
+        threadIdx.x blockIdx.y blockDim.z gridDim.x
+        """
+        lexer = HipLexer(code)
+        tokens = lexer.tokenize()
+
+        token_values = [token.value for token in tokens]
+
+        assert "threadIdx" in token_values
+        assert "blockIdx" in token_values
+        assert "blockDim" in token_values
+        assert "gridDim" in token_values
+
+    def test_hip_memory_functions(self):
+        """Test HIP memory function tokenization"""
+        code = """
+        hipMalloc hipFree hipMemcpy hipMemset
+        __syncthreads __threadfence __threadfence_block
+        """
+        lexer = HipLexer(code)
+        tokens = lexer.tokenize()
+
+        # Check specific token types
+        token_pairs = [
+            (token.type, token.value) for token in tokens if token.type != "NEWLINE"
+        ]
+        token_values = [token.value for token in tokens if token.type == "IDENTIFIER"]
+
+        # These should be IDENTIFIER tokens
+        assert "hipMalloc" in token_values
+        assert "__threadfence" in token_values
+        assert "__threadfence_block" in token_values
+
+        # __syncthreads should be a specific token type
+        assert ("SYNCTHREADS", "__syncthreads") in token_pairs
+
+    def test_operators_tokenization(self):
+        """Test operator tokenization"""
+        code = """
+        + - * / % == != < > <= >= && || ! & | ^ << >> ++ --
+        += -= *= /= %= &= |= ^= <<= >>= = ? : . -> ::
+        """
+        lexer = HipLexer(code)
+        tokens = lexer.tokenize()
+
+        token_types = [token.type for token in tokens]
+
+        assert "PLUS" in token_types
+        assert "MINUS" in token_types
+        assert "STAR" in token_types
+        assert "SLASH" in token_types
+        assert "EQ" in token_types
+        assert "NE" in token_types
+        assert "AND" in token_types
+        assert "OR" in token_types
+        assert "ARROW" in token_types
+        assert "SCOPE" in token_types
+
+    def test_numeric_literals(self):
+        """Test numeric literal tokenization"""
+        code = """
+        42 3.14f 2.71828 0xFF 0777 1e5 2.5e-3f
+        """
+        lexer = HipLexer(code)
+        tokens = lexer.tokenize()
+
+        # Check for different numeric types
+        integers = [token for token in tokens if token.type == "INTEGER"]
+        floats = [token for token in tokens if token.type == "FLOAT"]
+
+        assert len(integers) >= 2  # At least decimal and hex
+        assert len(floats) >= 2  # At least regular float and scientific notation
+
+    def test_string_literals(self):
+        """Test string literal tokenization"""
+        code = """
+        "hello world" 'c' "escaped \\"string\\"" "path/to/file"
+        """
+        lexer = HipLexer(code)
+        tokens = lexer.tokenize()
+
+        strings = [token for token in tokens if token.type == "STRING"]
+        chars = [token for token in tokens if token.type == "CHAR"]
+
+        assert len(strings) >= 3
+        assert len(chars) >= 1
+
+    def test_preprocessor_directives(self):
+        """Test preprocessor directive tokenization"""
+        code = """
+        #include <hip/hip_runtime.h>
+        #define MAX_SIZE 1024
+        #ifdef DEBUG
+        #endif
+        """
+        lexer = HipLexer(code)
+        tokens = lexer.tokenize()
+
+        token_types = [token.type for token in tokens]
+
+        assert "HASH" in token_types
+        assert "IDENTIFIER" in token_types  # include, define, etc.
+
+    def test_delimiters_tokenization(self):
+        """Test delimiter tokenization"""
+        code = """
+        ( ) [ ] { } , ; : ::
+        """
+        lexer = HipLexer(code)
+        tokens = lexer.tokenize()
+
+        token_types = [token.type for token in tokens]
+
+        assert "LPAREN" in token_types
+        assert "RPAREN" in token_types
+        assert "LBRACKET" in token_types
+        assert "RBRACKET" in token_types
+        assert "LBRACE" in token_types
+        assert "RBRACE" in token_types
+        assert "COMMA" in token_types
+        assert "SEMICOLON" in token_types
+        assert "COLON" in token_types
+        assert "SCOPE" in token_types
+
+    def test_template_syntax(self):
+        """Test template syntax tokenization"""
+        code = """
+        template<typename T> class Vector<T, int N>
+        """
+        lexer = HipLexer(code)
+        tokens = lexer.tokenize()
+
+        token_types = [token.type for token in tokens]
+        [token.value for token in tokens]
+
+        assert "TEMPLATE" in token_types
+        assert "LT" in token_types
+        assert "GT" in token_types
+        assert "TYPENAME" in token_types
+
+    def test_function_declaration(self):
+        """Test function declaration tokenization"""
+        code = """
+        __global__ void kernel(float* data, int size) {
+            int idx = threadIdx.x + blockIdx.x * blockDim.x;
+        }
+        """
+        lexer = HipLexer(code)
+        tokens = lexer.tokenize()
+
+        token_types = [token.type for token in tokens]
+
+        assert "__GLOBAL__" in token_types
+        assert "VOID" in token_types
+        assert "LPAREN" in token_types
+        assert "RPAREN" in token_types
+        assert "LBRACE" in token_types
+        assert "RBRACE" in token_types
+
+    def test_struct_declaration(self):
+        """Test struct declaration tokenization"""
+        code = """
+        struct Point {
+            float x, y, z;
+        };
+        """
+        lexer = HipLexer(code)
+        tokens = lexer.tokenize()
+
+        token_types = [token.type for token in tokens]
+
+        assert "STRUCT" in token_types
+        assert "LBRACE" in token_types
+        assert "RBRACE" in token_types
+        assert "SEMICOLON" in token_types
+
+    def test_control_flow_keywords(self):
+        """Test control flow keyword tokenization"""
+        code = """
+        if else for while do switch case default break continue return
+        """
+        lexer = HipLexer(code)
+        tokens = lexer.tokenize()
+
+        token_types = [token.type for token in tokens]
+
+        assert "IF" in token_types
+        assert "ELSE" in token_types
+        assert "FOR" in token_types
+        assert "WHILE" in token_types
+        assert "SWITCH" in token_types
+        assert "CASE" in token_types
+        assert "DEFAULT" in token_types
+        assert "BREAK" in token_types
+        assert "CONTINUE" in token_types
+        assert "RETURN" in token_types
+
+    def test_access_specifiers(self):
+        """Test access specifier tokenization"""
+        code = """
+        public: private: protected:
+        """
+        lexer = HipLexer(code)
+        tokens = lexer.tokenize()
+
+        token_types = [token.type for token in tokens]
+
+        assert "PUBLIC" in token_types
+        assert "PRIVATE" in token_types
+        assert "PROTECTED" in token_types
+
+    def test_memory_qualifiers(self):
+        """Test memory qualifier tokenization"""
+        code = """
+        __shared__ float shared_data[256];
+        __constant__ int constant_value = 42;
+        """
+        lexer = HipLexer(code)
+        tokens = lexer.tokenize()
+
+        token_types = [token.type for token in tokens]
+
+        assert "__SHARED__" in token_types
+        assert "__CONSTANT__" in token_types
+
+    def test_math_functions(self):
+        """Test math function tokenization"""
+        code = """
+        sinf cosf tanf sqrtf powf fabsf floorf ceilf
+        """
+        lexer = HipLexer(code)
+        tokens = lexer.tokenize()
+
+        token_values = [token.value for token in tokens if token.type == "IDENTIFIER"]
+
+        assert "sinf" in token_values
+        assert "sqrtf" in token_values
+        assert "powf" in token_values
+
+    def test_vector_constructors(self):
+        """Test vector constructor tokenization"""
+        code = """
+        make_float2(1.0f, 2.0f) make_int3(1, 2, 3) make_float4(0.0f)
+        """
+        lexer = HipLexer(code)
+        tokens = lexer.tokenize()
+
+        token_values = [token.value for token in tokens if token.type == "IDENTIFIER"]
+
+        assert "make_float2" in token_values
+        assert "make_int3" in token_values
+        assert "make_float4" in token_values
+
+    def test_comments(self):
+        """Test comment tokenization"""
+        code = """
+        // Single line comment
+        /* Multi-line
+           comment */
+        int x = 5; // End of line comment
+        """
+        lexer = HipLexer(code)
+        tokens = lexer.tokenize()
+
+        # Comments should be filtered out, but code should still tokenize
+        token_values = [token.value for token in tokens if token.type == "IDENTIFIER"]
+        assert "x" in token_values
+
+    def test_whitespace_handling(self):
+        """Test whitespace and newline handling"""
+        code = """
+        
+        int    x   =   5   ;
+        
+        float y = 3.14f;
+        
+        """
+        lexer = HipLexer(code)
+        tokens = lexer.tokenize()
+
+        # Should have proper tokens despite irregular whitespace
+        token_types = [token.type for token in tokens if token.type != "NEWLINE"]
+
+        assert "INT" in token_types
+        assert "IDENTIFIER" in token_types
+        assert "ASSIGN" in token_types
+        assert "INTEGER" in token_types
+
+    def test_complex_expression(self):
+        """Test complex expression tokenization"""
+        code = """
+        result = (a.x * b.y) + sqrt(c[i] - d->member) / 2.0f;
+        """
+        lexer = HipLexer(code)
+        tokens = lexer.tokenize()
+
+        token_types = [token.type for token in tokens]
+
+        assert "IDENTIFIER" in token_types
+        assert "ASSIGN" in token_types
+        assert "LPAREN" in token_types
+        assert "DOT" in token_types
+        assert "STAR" in token_types
+        assert "PLUS" in token_types
+        assert "LBRACKET" in token_types
+        assert "ARROW" in token_types
+        assert "SLASH" in token_types
+
+    def test_hip_api_calls(self):
+        """Test HIP API call tokenization"""
+        code = """
+        hipError_t err = hipMalloc(&ptr, size);
+        hipLaunchKernelGGL(kernel, gridSize, blockSize, 0, 0, args);
+        """
+        lexer = HipLexer(code)
+        tokens = lexer.tokenize()
+
+        token_pairs = [
+            (token.type, token.value) for token in tokens if token.type != "NEWLINE"
+        ]
+        token_values = [token.value for token in tokens if token.type == "IDENTIFIER"]
+
+        # hipError_t should be a specific token type
+        assert ("HIPERROR", "hipError_t") in token_pairs
+
+        # These should be IDENTIFIER tokens
+        assert "hipMalloc" in token_values
+        assert "hipLaunchKernelGGL" in token_values
+
+    def test_empty_input(self):
+        """Test empty input handling"""
+        code = ""
+        lexer = HipLexer(code)
+        tokens = lexer.tokenize()
+
+        assert len(tokens) == 0
+
+    def test_only_whitespace(self):
+        """Test whitespace-only input"""
+        code = "   \n  \t  \n  "
+        lexer = HipLexer(code)
+        tokens = lexer.tokenize()
+
+        # Should only contain newlines
+        non_newline_tokens = [token for token in tokens if token.type != "NEWLINE"]
+        assert len(non_newline_tokens) == 0
diff --git a/tests/test_backend/test_HIP/test_parser.py b/tests/test_backend/test_HIP/test_parser.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/test_translator/test_codegen/test_hip_codegen.py b/tests/test_translator/test_codegen/test_hip_codegen.py
new file mode 100644
index 0000000..b354c40
--- /dev/null
+++ b/tests/test_translator/test_codegen/test_hip_codegen.py
@@ -0,0 +1,365 @@
+"""Test HIP Code Generation from CrossGL"""
+
+import pytest
+from crosstl.translator.lexer import Lexer
+from crosstl.translator.parser import Parser
+from crosstl.translator.codegen.hip_codegen import HipCodeGen
+
+
+class TestHipCodeGen:
+    def test_simple_function_generation(self):
+        """Test generating a simple HIP function from CrossGL"""
+        source_code = """
+        shader TestShader {
+            vertex {
+                void main() {
+                    int x;
+                }
+            }
+        }
+        """
+
+        lexer = Lexer(source_code)
+        parser = Parser(lexer.tokens)
+        ast = parser.parse()
+
+        codegen = HipCodeGen()
+        hip_code = codegen.generate(ast)
+
+        assert "#include <hip/hip_runtime.h>" in hip_code
+        assert "#include <hip/hip_runtime_api.h>" in hip_code
+        assert "__device__ void main()" in hip_code
+
+    def test_compute_shader_to_kernel(self):
+        """Test converting a compute shader to HIP kernel"""
+        source_code = """
+        shader TestShader {
+            compute {
+                void main() {
+                    int id;
+                }
+            }
+        }
+        """
+
+        lexer = Lexer(source_code)
+        parser = Parser(lexer.tokens)
+        ast = parser.parse()
+
+        codegen = HipCodeGen()
+        hip_code = codegen.generate(ast)
+
+        assert "__global__ void main()" in hip_code
+
+    def test_type_conversion(self):
+        """Test CrossGL to HIP type conversion"""
+        codegen = HipCodeGen()
+
+        # Test basic types
+        assert codegen.map_type("int") == "int"
+        assert codegen.map_type("float") == "float"
+        assert codegen.map_type("double") == "double"
+        assert codegen.map_type("bool") == "bool"
+        assert codegen.map_type("void") == "void"
+
+        # Test vector types
+        assert codegen.map_type("vec2") == "float2"
+        assert codegen.map_type("vec3") == "float3"
+        assert codegen.map_type("vec4") == "float4"
+        assert codegen.map_type("ivec2") == "int2"
+        assert codegen.map_type("ivec3") == "int3"
+        assert codegen.map_type("ivec4") == "int4"
+
+    def test_function_conversion(self):
+        """Test CrossGL to HIP function conversion"""
+        codegen = HipCodeGen()
+
+        # Test math functions
+        assert codegen.function_map.get("sqrt") == "sqrtf"
+        assert codegen.function_map.get("pow") == "powf"
+        assert codegen.function_map.get("sin") == "sinf"
+        assert codegen.function_map.get("cos") == "cosf"
+
+        # Test vector constructors
+        assert codegen.function_map.get("vec2") == "make_float2"
+        assert codegen.function_map.get("vec3") == "make_float3"
+        assert codegen.function_map.get("vec4") == "make_float4"
+
+    def test_builtin_variable_conversion(self):
+        """Test built-in variable conversion"""
+        codegen = HipCodeGen()
+
+        # Test thread index mapping
+        assert codegen.builtin_map.get("gl_LocalInvocationID.x") == "threadIdx.x"
+        assert codegen.builtin_map.get("gl_LocalInvocationID.y") == "threadIdx.y"
+        assert codegen.builtin_map.get("gl_LocalInvocationID.z") == "threadIdx.z"
+
+        # Test workgroup index mapping
+        assert codegen.builtin_map.get("gl_WorkGroupID.x") == "blockIdx.x"
+        assert codegen.builtin_map.get("gl_WorkGroupID.y") == "blockIdx.y"
+        assert codegen.builtin_map.get("gl_WorkGroupID.z") == "blockIdx.z"
+
+        # Test workgroup size mapping
+        assert codegen.builtin_map.get("gl_WorkGroupSize.x") == "blockDim.x"
+        assert codegen.builtin_map.get("gl_WorkGroupSize.y") == "blockDim.y"
+        assert codegen.builtin_map.get("gl_WorkGroupSize.z") == "blockDim.z"
+
+    def test_struct_generation(self):
+        """Test struct generation"""
+        source_code = """
+        shader TestShader {
+            struct Vertex {
+                vec3 position;
+                vec3 normal;
+            }
+        }
+        """
+
+        lexer = Lexer(source_code)
+        parser = Parser(lexer.tokens)
+        ast = parser.parse()
+
+        codegen = HipCodeGen()
+        hip_code = codegen.generate(ast)
+
+        assert "struct Vertex" in hip_code
+        assert "float3 position;" in hip_code
+        assert "float3 normal;" in hip_code
+
+    def test_variable_with_qualifiers(self):
+        """Test variable generation with memory qualifiers"""
+        source_code = """
+        shader TestShader {
+            compute {
+                void main() {
+                    float shared_data;
+                    float constants;
+                }
+            }
+        }
+        """
+
+        lexer = Lexer(source_code)
+        parser = Parser(lexer.tokens)
+        ast = parser.parse()
+
+        codegen = HipCodeGen()
+        hip_code = codegen.generate(ast)
+
+        # For now, just check that basic variables are generated
+        assert "float shared_data;" in hip_code
+        assert "float constants;" in hip_code
+
+    def test_atomic_operations(self):
+        """Test atomic operations code generation"""
+        source_code = """
+        shader TestShader {
+            compute {
+                void main() {
+                    int counter;
+                    atomicAdd(counter, 1);
+                }
+            }
+        }
+        """
+
+        lexer = Lexer(source_code)
+        parser = Parser(lexer.tokens)
+        ast = parser.parse()
+
+        codegen = HipCodeGen()
+        hip_code = codegen.generate(ast)
+
+        # Check for basic structure
+        assert "__global__" in hip_code or "__device__" in hip_code
+
+    def test_synchronization_functions(self):
+        """Test synchronization function generation"""
+        source_code = """
+        shader TestShader {
+            compute {
+                void main() {
+                    barrier();
+                    memoryBarrier();
+                }
+            }
+        }
+        """
+
+        lexer = Lexer(source_code)
+        parser = Parser(lexer.tokens)
+        ast = parser.parse()
+
+        codegen = HipCodeGen()
+        hip_code = codegen.generate(ast)
+
+        # Check for basic structure
+        assert "__global__" in hip_code or "__device__" in hip_code
+
+    def test_vector_operations(self):
+        """Test vector operations generation"""
+        source_code = """
+        shader TestShader {
+            compute {
+                void main() {
+                    vec3 a = vec3(1.0, 2.0, 3.0);
+                    vec3 b = vec3(4.0, 5.0, 6.0);
+                    vec3 result = a + b;
+                }
+            }
+        }
+        """
+
+        lexer = Lexer(source_code)
+        parser = Parser(lexer.tokens)
+        ast = parser.parse()
+
+        codegen = HipCodeGen()
+        hip_code = codegen.generate(ast)
+
+        # Check for basic structure with HIP includes
+        assert "#include <hip/hip_runtime.h>" in hip_code
+
+    def test_math_functions(self):
+        """Test math function generation"""
+        source_code = """
+        shader TestShader {
+            compute {
+                void main() {
+                    float x = 1.0;
+                    float result = sqrt(sin(x) + cos(x));
+                }
+            }
+        }
+        """
+
+        lexer = Lexer(source_code)
+        parser = Parser(lexer.tokens)
+        ast = parser.parse()
+
+        codegen = HipCodeGen()
+        hip_code = codegen.generate(ast)
+
+        # Check for basic structure with HIP includes
+        assert "#include <hip/hip_runtime.h>" in hip_code
+
+    def test_texture_operations(self):
+        """Test texture operation generation"""
+        source_code = """
+        shader TestShader {
+            fragment {
+                void main() {
+                    sampler2D tex;
+                    vec2 uv = vec2(0.5, 0.5);
+                    vec4 color = texture(tex, uv);
+                }
+            }
+        }
+        """
+
+        lexer = Lexer(source_code)
+        parser = Parser(lexer.tokens)
+        ast = parser.parse()
+
+        codegen = HipCodeGen()
+        hip_code = codegen.generate(ast)
+
+        # Check for basic structure
+        assert "#include <hip/hip_runtime.h>" in hip_code
+
+    def test_control_flow(self):
+        """Test control flow generation"""
+        source_code = """
+        shader TestShader {
+            compute {
+                void main() {
+                    int i;
+                    if (i > 0) {
+                        i = i + 1;
+                    } else {
+                        i = i - 1;
+                    }
+                    
+                    for (int j = 0; j < 10; j++) {
+                        i = i * 2;
+                    }
+                }
+            }
+        }
+        """
+
+        lexer = Lexer(source_code)
+        parser = Parser(lexer.tokens)
+        ast = parser.parse()
+
+        codegen = HipCodeGen()
+        hip_code = codegen.generate(ast)
+
+        # Check for basic structure
+        assert "#include <hip/hip_runtime.h>" in hip_code
+
+    def test_array_operations(self):
+        """Test array operation generation"""
+        source_code = """
+        shader TestShader {
+            compute {
+                void main() {
+                    float data[256];
+                    int index = 0;
+                    data[index] = 1.0;
+                }
+            }
+        }
+        """
+
+        lexer = Lexer(source_code)
+        parser = Parser(lexer.tokens)
+        ast = parser.parse()
+
+        codegen = HipCodeGen()
+        hip_code = codegen.generate(ast)
+
+        # Check for basic structure
+        assert "#include <hip/hip_runtime.h>" in hip_code
+
+    def test_empty_shader(self):
+        """Test empty shader generation"""
+        source_code = ""
+
+        lexer = Lexer(source_code)
+        parser = Parser(lexer.tokens)
+        ast = parser.parse()
+
+        codegen = HipCodeGen()
+        hip_code = codegen.generate(ast)
+
+        assert "#include <hip/hip_runtime.h>" in hip_code
+        assert "#include <hip/hip_runtime_api.h>" in hip_code
+
+    def test_multiple_functions(self):
+        """Test multiple function generation"""
+        source_code = """
+        shader TestShader {
+            vertex {
+                void vertex_main() {
+                    int x;
+                }
+            }
+            fragment {
+                void fragment_main() {
+                    float y;
+                }
+            }
+        }
+        """
+
+        lexer = Lexer(source_code)
+        parser = Parser(lexer.tokens)
+        ast = parser.parse()
+
+        codegen = HipCodeGen()
+        hip_code = codegen.generate(ast)
+
+        # Check for HIP includes
+        assert "#include <hip/hip_runtime.h>" in hip_code
+        assert "#include <hip/hip_runtime_api.h>" in hip_code