brainrotscript
Version:
š§ A brainrot programming language that compiles to JavaScript - because why write normal code when you can write code that's absolutely sending you? š
149 lines (125 loc) ⢠5.45 kB
JavaScript
const fs = require('fs');
const path = require('path');
class BrainrotCompiler {
constructor() {
// Load the brainrot keyword mappings
const mapPath = path.join(__dirname, '..', 'brainrot-map.json');
this.keywordMap = JSON.parse(fs.readFileSync(mapPath, 'utf8'));
// Create reverse mapping for efficient lookup (brainrot -> js)
this.brainrotToJs = {};
for (const [jsKeyword, brainrotKeyword] of Object.entries(this.keywordMap)) {
this.brainrotToJs[brainrotKeyword] = jsKeyword;
}
}
/**
* Compiles a .brainrot file to JavaScript
* @param {string} inputPath - Path to the .brainrot file
* @param {string} outputPath - Path where the compiled .js file should be saved
*/
compile(inputPath, outputPath) {
try {
// Read the brainrot source code
const brainrotCode = fs.readFileSync(inputPath, 'utf8');
// Translate to JavaScript
const jsCode = this.translateToJavaScript(brainrotCode);
// Write the compiled JavaScript
fs.writeFileSync(outputPath, jsCode);
console.log(`ā
Successfully compiled ${inputPath} ā ${outputPath}`);
return jsCode;
} catch (error) {
console.error(`ā Compilation failed: ${error.message}`);
throw error;
}
}
/**
* Translates brainrot code to JavaScript
* @param {string} brainrotCode - The source code in brainrot language
* @returns {string} - The equivalent JavaScript code
*/
translateToJavaScript(brainrotCode) {
let jsCode = brainrotCode;
// Replace brainrot keywords with JavaScript keywords
// We need to be careful about word boundaries to avoid partial replacements
for (const [brainrotKeyword, jsKeyword] of Object.entries(this.brainrotToJs)) {
// Use regex with word boundaries to ensure complete word replacement
const regex = new RegExp(`\\b${this.escapeRegex(brainrotKeyword)}\\b`, 'g');
jsCode = jsCode.replace(regex, jsKeyword);
}
// Fix class method definitions - remove 'function' keyword from class methods
// This handles cases like "function constructor(" -> "constructor("
jsCode = this.fixClassMethods(jsCode);
return jsCode;
}
/**
* Fixes class method definitions by removing 'function' keyword
* @param {string} jsCode - JavaScript code that may have incorrect class methods
* @returns {string} - Fixed JavaScript code
*/
fixClassMethods(jsCode) {
const lines = jsCode.split('\n');
let inClass = false;
let braceDepth = 0;
let classStartDepth = 0;
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
// Track brace depth
const openBraces = (line.match(/\{/g) || []).length;
const closeBraces = (line.match(/\}/g) || []).length;
braceDepth += openBraces - closeBraces;
// Check if we're entering a class
if (/^\s*class\s+\w+/.test(line)) {
inClass = true;
classStartDepth = braceDepth - openBraces; // Depth before the class opening brace
}
// Check if we're exiting the class
if (inClass && braceDepth <= classStartDepth) {
inClass = false;
}
// If we're inside a class, fix method definitions
if (inClass) {
// Remove 'function' keyword from method definitions
// Handle: " function methodName(" -> " methodName("
// Handle: " async function methodName(" -> " async methodName("
lines[i] = line.replace(/^(\s+)(async\s+)?function\s+(\w+)\s*\(/g, '$1$2$3(');
}
}
return lines.join('\n');
}
/**
* Escapes special regex characters in a string
* @param {string} string - String to escape
* @returns {string} - Escaped string
*/
escapeRegex(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
/**
* Compiles and executes a .brainrot file
* @param {string} inputPath - Path to the .brainrot file
*/
run(inputPath) {
const tempJsPath = inputPath.replace('.brainrot', '.temp.js');
try {
// Compile to temporary JavaScript file
this.compile(inputPath, tempJsPath);
// Execute the compiled JavaScript
console.log('\nš Running compiled code:\n');
require(path.resolve(tempJsPath));
} catch (error) {
console.error(`ā Execution failed: ${error.message}`);
} finally {
// Clean up temporary file
if (fs.existsSync(tempJsPath)) {
fs.unlinkSync(tempJsPath);
}
}
}
/**
* Gets available brainrot keywords
* @returns {Object} - The keyword mapping
*/
getKeywords() {
return this.keywordMap;
}
}
module.exports = BrainrotCompiler;