UNPKG

goiasscript

Version:

🇧🇷 Linguagem de programação goiana com métodos nativos - GoiásScript v2.0

390 lines (333 loc) 11.7 kB
/** * GoiásScript JIT Compiler MVP * Just-In-Time compilation for performance optimization * Fase 5: Performance & Otimização */ const GoianoASTParser = require('../parser/ASTParser'); class GoianoJITCompiler { constructor() { this.hotSpots = new Map(); // Código executado frequentemente this.compiledCache = new Map(); // Cache de código otimizado this.executionCounts = new Map(); // Contador de execuções this.threshold = 5; // Limite para ativar JIT this.astParser = new GoianoASTParser(); this.optimizations = { inlineExpressions: true, loopUnrolling: true, constantFolding: true, deadCodeElimination: true, astOptimization: true }; } /** * Analisa código e decide se deve aplicar JIT * @param {string} code - Código GoiásScript * @param {string} identifier - Identificador único (função/bloco) * @returns {boolean} Se deve aplicar JIT */ shouldApplyJIT(code, identifier) { const count = this.executionCounts.get(identifier) || 0; this.executionCounts.set(identifier, count + 1); // Aplica JIT apenas após múltiplas execuções return count >= this.threshold; } /** * Compila código com otimizações JIT * @param {string} code - Código GoiásScript original * @param {string} identifier - Identificador único * @returns {string} Código JavaScript otimizado */ compile(code, identifier) { // Verificar cache primeiro if (this.compiledCache.has(identifier)) { return this.compiledCache.get(identifier); } console.log(`🔥 JIT: Otimizando hot spot "${identifier}"`); let optimizedCode = code; // Aplicar otimizações sequencialmente if (this.optimizations.constantFolding) { optimizedCode = this._applyConstantFolding(optimizedCode); } if (this.optimizations.inlineExpressions) { optimizedCode = this._applyInlining(optimizedCode); } if (this.optimizations.loopUnrolling) { optimizedCode = this._applyLoopUnrolling(optimizedCode); } if (this.optimizations.deadCodeElimination) { optimizedCode = this._eliminateDeadCode(optimizedCode); } // AST-based optimizations if (this.optimizations.astOptimization) { optimizedCode = this._applyASTOptimizations(optimizedCode, identifier); } // Adicionar profiling hooks optimizedCode = this._addProfilingHooks(optimizedCode, identifier); // Cache do código otimizado this.compiledCache.set(identifier, optimizedCode); this.hotSpots.set(identifier, { originalCode: code, optimizedCode: optimizedCode, compiledAt: Date.now(), executions: this.executionCounts.get(identifier) }); return optimizedCode; } /** * Constant Folding - Avalia expressões constantes em tempo de compilação * @private */ _applyConstantFolding(code) { // Otimizar operações matemáticas simples code = code.replace(/(\d+)\s*\+\s*(\d+)/g, (match, a, b) => { return (parseInt(a) + parseInt(b)).toString(); }); code = code.replace(/(\d+)\s*\*\s*(\d+)/g, (match, a, b) => { return (parseInt(a) * parseInt(b)).toString(); }); // Otimizar concatenação de strings code = code.replace(/"([^"]*?)"\s*\+\s*"([^"]*?)"/g, '"$1$2"'); return code; } /** * Inline Expressions - Substitui chamadas de função por código inline * @private */ _applyInlining(code) { // Inline de operações matemáticas simples do GoianoMath code = code.replace(/GoianoMath\.maior\((\d+),\s*(\d+)\)/g, (match, a, b) => { return `(${a} > ${b} ? ${a} : ${b})`; }); code = code.replace(/GoianoMath\.arredondar\(([^)]+)\)/g, 'Math.round($1)'); // Inline de métodos de string simples code = code.replace(/\.pra_maiusculo\(\)/g, '.toUpperCase()'); code = code.replace(/\.pra_minusculo\(\)/g, '.toLowerCase()'); return code; } /** * Loop Unrolling - Desenrola loops pequenos para melhor performance * @private */ _applyLoopUnrolling(code) { // Desenrolar loops 'pra' pequenos (até 4 iterações) const loopRegex = /pra\s*\(\s*uai\s+(\w+)\s+é\s+(\d+);\s*\1\s*<\s*(\d+);\s*\1\+\+\s*\)\s*\{([^}]*)\}/g; code = code.replace(loopRegex, (match, varName, start, end, body) => { const startNum = parseInt(start); const endNum = parseInt(end); const iterations = endNum - startNum; // Só desenrolar loops pequenos if (iterations <= 4 && iterations > 0) { let unrolled = ''; for (let i = startNum; i < endNum; i++) { const iterationBody = body.replace(new RegExp(`\\b${varName}\\b`, 'g'), i.toString()); unrolled += `{ ${iterationBody.trim()} }\n`; } return unrolled; } return match; // Manter loop original se muito grande }); return code; } /** * Dead Code Elimination - Remove código não alcançável * @private */ _eliminateDeadCode(code) { // Remove código após return code = code.replace(/faz_favor\s+[^;]+;[\s\S]*?(})/g, 'faz_favor $1; $2'); // Remove variáveis não utilizadas (aproximação simples) const lines = code.split('\n'); const usedVars = new Set(); const declaredVars = new Set(); // Primeira passada: encontrar variáveis usadas lines.forEach(line => { const varUsage = line.match(/\b(\w+)\b/g); if (varUsage) { varUsage.forEach(v => usedVars.add(v)); } }); // Segunda passada: encontrar declarações lines.forEach(line => { const varDecl = line.match(/uai\s+(\w+)\s+é/); if (varDecl) { declaredVars.add(varDecl[1]); } }); // Remover declarações não usadas const filteredLines = lines.filter(line => { const varDecl = line.match(/uai\s+(\w+)\s+é/); if (varDecl) { const varName = varDecl[1]; // Manter se usado mais de uma vez (declaração + uso) const usageCount = [...lines.join(' ').matchAll(new RegExp(`\\b${varName}\\b`, 'g'))].length; return usageCount > 1; } return true; }); return filteredLines.join('\n'); } /** * Aplica otimizações baseadas em AST * @private */ _applyASTOptimizations(code, identifier) { try { // Parse código para AST const ast = this.astParser.parse(code); const analysis = this.astParser.analyzeForOptimizations(ast); let optimized = code; // Otimização baseada na análise if (analysis.complexityScore > 10) { // Código complexo - aplicar otimizações agressivas console.log(`🔥 JIT [${identifier}]: Código complexo detectado (score: ${analysis.complexityScore})`); optimized = this._applyAggressiveOptimizations(optimized, analysis); } // Otimizar loops identificados if (analysis.loops.length > 0) { console.log(`🔥 JIT [${identifier}]: ${analysis.loops.length} loops detectados`); optimized = this._optimizeLoops(optimized, analysis.loops); } // Otimizar funções pequenas if (analysis.functions.length > 0) { optimized = this._optimizeSmallFunctions(optimized, analysis.functions); } return optimized; } catch (error) { console.warn(`⚠️ JIT [${identifier}]: Falha na otimização AST:`, error.message); return code; } } /** * Aplica otimizações agressivas para código complexo * @private */ _applyAggressiveOptimizations(code, analysis) { // Memoização para funções puras code = code.replace( /faz_trem (\w+)\(([^)]*)\)\s*\{([^}]*faz_favor[^}]*)\}/g, (match, funcName, params, body) => { if (!body.includes('uai ') && !body.includes('prosa(')) { // Função possivelmente pura - adicionar memoização return ` const __memo_${funcName} = new Map(); faz_trem ${funcName}(${params}) { const __key = JSON.stringify(arguments); if (__memo_${funcName}.has(__key)) { return __memo_${funcName}.get(__key); } ${body} const __result = ${body.match(/faz_favor\s+([^;]+)/)?.[1] || 'undefined'}; __memo_${funcName}.set(__key, __result); return __result; }`; } return match; } ); return code; } /** * Otimiza loops identificados no AST * @private */ _optimizeLoops(code, loops) { // Vectorização de loops simples code = code.replace( /pra\s*\(\s*uai\s+(\w+)\s+=\s+0;\s*\1\s+<\s+(\w+)\.tamanho\(\);\s*\1\+\+\s*\)\s*\{\s*(\w+)\[(\1)\]\s*([+\-*/]?=)\s*([^;]+);\s*\}/g, (match, i, arr, targetArr, indexVar, op, value) => { // Tentar vectorizar operações em array return `${targetArr}.forEach((item, ${i}) => { ${targetArr}[${i}] ${op} ${value}; });`; } ); return code; } /** * Otimiza funções pequenas * @private */ _optimizeSmallFunctions(code, functions) { // Inline de funções muito pequenas (menos de 3 linhas) functions.forEach(func => { if (func.paramCount <= 2) { const funcRegex = new RegExp(`faz_trem\\s+${func.name}\\s*\\([^)]*\\)\\s*\\{([^}]{1,100})\\}`, 'g'); code = code.replace(funcRegex, (match, body) => { if ((body.match(/;/g) || []).length <= 2) { // Função pequena - marcar para possível inlining return `/* INLINE_CANDIDATE */ ${match}`; } return match; }); } }); return code; } /** * Adiciona hooks de profiling para coleta de métricas * @private */ _addProfilingHooks(code, identifier) { const profilingCode = ` // JIT Profiling Start const __jit_start_${identifier.replace(/\W/g, '_')} = performance.now(); ${code} // JIT Profiling End const __jit_end_${identifier.replace(/\W/g, '_')} = performance.now(); console.log('🔥 JIT [${identifier}]: ' + (__jit_end_${identifier.replace(/\W/g, '_')} - __jit_start_${identifier.replace(/\W/g, '_')}) + 'ms'); `; return profilingCode; } /** * Gera relatório de performance */ generatePerformanceReport() { const report = { totalHotSpots: this.hotSpots.size, totalExecutions: Array.from(this.executionCounts.values()).reduce((a, b) => a + b, 0), cacheHitRatio: this.compiledCache.size / Math.max(this.hotSpots.size, 1), optimizations: this.optimizations, hotSpots: [] }; this.hotSpots.forEach((info, identifier) => { report.hotSpots.push({ identifier, executions: info.executions, compiledAt: new Date(info.compiledAt).toISOString(), originalSize: info.originalCode.length, optimizedSize: info.optimizedCode.length, compressionRatio: (info.originalCode.length - info.optimizedCode.length) / info.originalCode.length }); }); return report; } /** * Limpa cache de código compilado */ clearCache() { this.compiledCache.clear(); this.hotSpots.clear(); console.log('🔥 JIT: Cache limpo'); } /** * Configura otimizações ativas */ setOptimizations(optimizations) { this.optimizations = { ...this.optimizations, ...optimizations }; } /** * Define threshold para ativação do JIT */ setThreshold(threshold) { this.threshold = threshold; } /** * Obtém estatísticas de hot spots */ getHotSpots() { return Array.from(this.hotSpots.entries()).map(([identifier, info]) => ({ identifier, executions: this.executionCounts.get(identifier), ...info })); } } module.exports = GoianoJITCompiler;