From ad1d7266b811452a5492556a7a1e9d75496bf18f Mon Sep 17 00:00:00 2001 From: Chris Wanstrath Date: Sat, 25 Oct 2025 10:42:49 -0700 Subject: [PATCH] /save --- bin/repl | 51 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/bin/repl b/bin/repl index 6954db7..85a32fb 100755 --- a/bin/repl +++ b/bin/repl @@ -2,7 +2,8 @@ import { Compiler } from '../src/compiler/compiler' import { VM, type Value, Scope, bytecodeToString } from 'reefvm' -import * as readline from 'node:readline' +import * as readline from 'readline' +import * as fs from 'fs' const colors = { reset: '\x1b[0m', @@ -18,7 +19,7 @@ const colors = { } async function repl() { - const commands = ['/clear', '/reset', '/vars', '/funcs', '/history', '/bytecode', '/exit', '/quit'] + const commands = ['/clear', '/reset', '/vars', '/funcs', '/history', '/bytecode', '/exit', '/save', '/quit'] function completer(line: string): [string[], string] { if (line.startsWith('/')) { @@ -115,6 +116,37 @@ async function repl() { return } + if (trimmed.startsWith('/save')) { + const parts = trimmed.split(/\s+/) + const filename = parts[1] + + if (!filename) { + console.log(`\n${colors.red}Usage:${colors.reset} /save `) + rl.prompt() + return + } + + if (codeHistory.length === 0) { + console.log(`\n${colors.dim}No history to save${colors.reset}`) + rl.prompt() + return + } + + // Add .shrimp extension if no extension provided + const finalFilename = filename.includes('.') ? filename : `${filename}.shrimp` + const content = codeHistory.join('\n') + '\n' + + try { + fs.writeFileSync(finalFilename, content, 'utf-8') + console.log(`\n${colors.green}✓${colors.reset} Saved ${codeHistory.length} line${codeHistory.length === 1 ? '' : 's'} to ${colors.bright}${finalFilename}${colors.reset}`) + } catch (error: any) { + console.log(`\n${colors.red}Error:${colors.reset} Failed to save file: ${error.message}`) + } + + rl.prompt() + return + } + codeHistory.push(trimmed) try { @@ -219,13 +251,14 @@ function showWelcome() { ) console.log(`\nType Shrimp expressions. Press ${colors.bright}Ctrl+D${colors.reset} to exit.`) console.log(`\nCommands:`) - console.log(` ${colors.bright}/clear${colors.reset} - Clear screen and reset state`) - console.log(` ${colors.bright}/reset${colors.reset} - Reset state (keep history visible)`) - console.log(` ${colors.bright}/vars${colors.reset} - Show all variables`) - console.log(` ${colors.bright}/funcs${colors.reset} - Show all functions`) - console.log(` ${colors.bright}/history${colors.reset} - Show code history`) - console.log(` ${colors.bright}/bytecode${colors.reset} - Show compiled bytecode`) - console.log(` ${colors.bright}/exit${colors.reset} - Quit REPL`) + console.log(` ${colors.bright}/clear${colors.reset} - Clear screen and reset state`) + console.log(` ${colors.bright}/reset${colors.reset} - Reset state (keep history visible)`) + console.log(` ${colors.bright}/vars${colors.reset} - Show all variables`) + console.log(` ${colors.bright}/funcs${colors.reset} - Show all functions`) + console.log(` ${colors.bright}/history${colors.reset} - Show code history`) + console.log(` ${colors.bright}/bytecode${colors.reset} - Show compiled bytecode`) + console.log(` ${colors.bright}/save ${colors.reset} - Save history to file`) + console.log(` ${colors.bright}/exit${colors.reset} - Quit REPL`) console.log(`\nExamples:`) console.log(` ${colors.cyan}5 + 10${colors.reset}`) console.log(` ${colors.cyan}x = 42${colors.reset}`)