UNPKG

@five-vm/cli

Version:

High-performance CLI for Five VM development with WebAssembly integration

225 lines 8.23 kB
/** * Five Bytecode Compiler * * Handles compilation of Five script source (.v files) to bytecode (.bin files) * using the existing WASM compilation infrastructure. * * This maintains the real compilation capabilities while providing a clean SDK interface. */ import { readFile } from 'fs/promises'; import { CompilationSDKError } from '../types.js'; /** * Bytecode compiler for Five scripts */ export class BytecodeCompiler { debug; wasmCompiler; constructor(config = {}) { this.debug = config.debug || false; if (this.debug) { console.log('[BytecodeCompiler] Initialized'); } } /** * Compile Five script source to bytecode */ async compile(source, options = {}) { const startTime = Date.now(); // Compile source (debug info available in this.debug mode) try { // Lazy load WASM compiler if (!this.wasmCompiler) { await this.loadWasmCompiler(); } // Prepare compilation options const compilerOptions = { optimize: options.optimize || false, target: options.target || 'vm', debug: options.debug || false, maxSize: options.maxSize || 1048576, // 1MB default optimizationLevel: options.optimizationLevel || 'v2' // Default to V2 }; // Perform compilation const result = await this.wasmCompiler.compile(source, compilerOptions); const compilationTime = Date.now() - startTime; if (result.success && result.bytecode) { if (this.debug) { console.log(`[BytecodeCompiler] Compilation successful in ${compilationTime}ms`); console.log(`[BytecodeCompiler] Bytecode size: ${result.bytecode.length} bytes`); } return { success: true, bytecode: result.bytecode, abi: result.abi, disassembly: result.disassembly || [], metadata: { sourceSize: source.length, bytecodeSize: result.bytecode.length, functions: this.extractFunctions(result.abi), compilationTime } }; } else { const errors = this.transformErrors(result.errors || []); if (this.debug) { console.log(`[BytecodeCompiler] Compilation failed with ${errors.length} errors`); errors.forEach(error => { console.log(` - ${error.severity}: ${error.message} (${error.line}:${error.column})`); }); } return { success: false, errors }; } } catch (error) { throw new CompilationSDKError(`Compilation error: ${error instanceof Error ? error.message : 'Unknown error'}`, { source: source.substring(0, 200), options }); } } /** * Compile script from file path */ async compileFile(filePath, options = {}) { if (this.debug) { console.log(`[BytecodeCompiler] Reading file: ${filePath}`); } try { const source = await readFile(filePath, 'utf-8'); return this.compile(source, options); } catch (error) { throw new CompilationSDKError(`Failed to read file ${filePath}: ${error instanceof Error ? error.message : 'Unknown error'}`, { filePath, options }); } } /** * Validate Five script source without compiling */ async validateSource(source) { if (this.debug) { console.log(`[BytecodeCompiler] Validating source (${source.length} chars)...`); } try { if (!this.wasmCompiler) { await this.loadWasmCompiler(); } const result = await this.wasmCompiler.validateSource(source); return { valid: result.valid, errors: result.errors ? this.transformErrors(result.errors) : undefined }; } catch (error) { if (this.debug) { console.log(`[BytecodeCompiler] Validation error: ${error}`); } return { valid: false, errors: [{ message: error instanceof Error ? error.message : 'Unknown validation error', severity: 'error' }] }; } } /** * Get compiler version and information */ async getCompilerInfo() { try { if (!this.wasmCompiler) { await this.loadWasmCompiler(); } return { version: '1.0.0', // TODO: Get from WASM module wasmLoaded: !!this.wasmCompiler, debug: this.debug }; } catch (error) { return { version: 'unknown', wasmLoaded: false, debug: this.debug, error: error instanceof Error ? error.message : 'Unknown error' }; } } // ==================== Private Methods ==================== /** * Load WASM compiler (reuse existing infrastructure) */ async loadWasmCompiler() { try { // Load WASM compiler silently unless debug // Import existing WASM compiler from the CLI // This path points to the existing working compiler const { FiveCompilerWasm } = await import('../../wasm/compiler.js'); const wasmInstance = new FiveCompilerWasm(console); // Use console as logger // CRITICAL: Initialize the compiler - this step was missing! await wasmInstance.initialize(); this.wasmCompiler = wasmInstance; if (this.debug) { console.log('[BytecodeCompiler] WASM compiler loaded and initialized successfully'); } } catch (error) { throw new CompilationSDKError(`Failed to load WASM compiler: ${error instanceof Error ? error.message : 'Unknown error'}`, { debug: this.debug }); } } /** * Transform compiler errors to SDK format */ transformErrors(errors) { return errors.map(error => ({ message: error.message || error.toString(), line: error.line, column: error.column, severity: error.severity || 'error' })); } /** * Extract function definitions from ABI */ extractFunctions(abi) { if (!abi || !abi.functions) { return []; } return abi.functions.map((func, index) => ({ name: func.name, index, parameters: func.parameters?.map((param) => ({ name: param.name, type: param.type, optional: param.optional || false })) || [], returnType: func.returnType })); } /** * Generate ABI from Five script source code */ async generateABI(source) { if (this.debug) { console.log(`[BytecodeCompiler] Generating ABI for source (${source.length} chars)...`); } try { if (!this.wasmCompiler) { await this.loadWasmCompiler(); } const abi = await this.wasmCompiler.generateABI(source); if (this.debug) { console.log(`[BytecodeCompiler] ABI generated:`, JSON.stringify(abi, null, 2)); } return abi; } catch (error) { if (this.debug) { console.log(`[BytecodeCompiler] ABI generation error: ${error}`); } throw new CompilationSDKError(`ABI generation failed: ${error instanceof Error ? error.message : 'Unknown error'}`, { source }); } } } //# sourceMappingURL=BytecodeCompiler.js.map