let's add a parent selector here:

import fs from 'fs';

class XCSS {
    static compile(code: string) {
        // Stores function definitions
        const functions: Record<string, { params: string[], body: string[] }> = {};

        // Split the code into lines for processing
        const lines = code.split(/\r?\n/);

        // Will hold the final output CSS lines
        const outputLines: string[] = [];

        // Flags and accumulators for parsing function definitions
        let inFunction = false;
        let currentFunctionName = '';
        let currentFunctionParams: string[] = [];
        let currentFunctionBody: string[] = [];

        for (let line of lines) {
            line = line.trim();

            if (line.startsWith('@import')) {
                // Handle @import directives
                outputLines.push(line + ';');

            } else if (line.startsWith('@function')) {
                // Start of a function definition
                const funcMatch = line.match(/@function\s+([^(]+)\(([^)]*)\)\s*{/);
                if (funcMatch) {
                    inFunction = true;
                    currentFunctionName = funcMatch[1].trim();
                    currentFunctionParams = funcMatch[2].split(',').map(p => p.trim());
                    currentFunctionBody = [];
                }

            } else if (inFunction) {
                if (line === '}') {
                    // End of function definition, store it
                    functions[currentFunctionName] = {
                        params: currentFunctionParams,
                        body: currentFunctionBody,
                    };
                    inFunction = false;
                    currentFunctionName = '';
                    currentFunctionParams = [];
                    currentFunctionBody = [];
                } else {
                    // Accumulate function body lines
                    currentFunctionBody.push(line);
                }

            } else if (line.startsWith('@include')) {
                // Handle @include directives
                const includeMatch = line.match(/@include\s+([^(]+)\(([^)]*)\);?/);
                if (includeMatch) {
                    const includeName = includeMatch[1].trim();
                    const includeArgs = includeMatch[2].split(',').map(a => a.trim().replace(/['"]/g, ''));

                    const func = functions[includeName];
                    if (func) {
                        const paramValues: Record<string, string> = {};
                        func.params.forEach((param, index) => {
                            paramValues[param] = includeArgs[index] || '';
                        });

                        // Replace variables in the function body and add to output
                        for (let funcLine of func.body) {
                            let processedLine = funcLine;
                            for (const [param, value] of Object.entries(paramValues)) {
                                const regex = new RegExp('\\' + param + '\\b', 'g');
                                processedLine = processedLine.replace(regex, value);
                            }
                            outputLines.push(processedLine);
                        }
                    } else {
                        console.error(`Function ${includeName} not defined.`);
                    }
                }

            } else {
                // Regular CSS lines or selectors
                outputLines.push(line);
            }
        }

        // Combine the output lines into a single string
        return outputLines.join('\n');
    }
}

// Example usage:

const xcssCode = `
@import url('https://fonts.googleapis.com/css2?family=Ubuntu:wght@400;700&display=swap');

@function dark-mode($font) {
  background-color: #000;
  color: #fff;
  font-family: $font, sans-serif;
}

body {
  @include dark-mode('Ubuntu');
}
`;

const cssOutput = XCSS.compile(xcssCode);
console.log(cssOutput);

---

Here's how we should use the parent selector:

div<p {
  // ...
}