import {log} from './log.js' import {Lifecycle} from './util/lifecycle.js' import {Input} from './vm/input.js' import {Lexer} from "./vm/lexer.js"; import {Parser} from "./vm/parser.js"; import {commands} from "./vm/commands/index.js"; import {Executor} from "./vm/vm.js"; import {ConsoleDisplay, OutputManager, WlClipboard} from "./vm/output.js"; import {processPath} from "./vm/commands/command.js"; import * as fs from "node:fs"; ;(async () => { const lifecycle = new Lifecycle() const input = new Input() input.adoptLifecycle(lifecycle) input.subscribe(line => log.verbose('input', { line })) const lexer = new Lexer(input) lexer.subscribe(token => log.verbose('token', token)) const parser = new Parser(commands, lexer) parser.subscribe(exec => log.verbose('exec', exec)) const output: OutputManager = { display: new ConsoleDisplay, clipboard: new WlClipboard, } const exec = new Executor(output, parser, input) exec.adoptLifecycle(lifecycle) console.log('`str` : An interactive string manipulation environment') console.log('Copyright (C) 2026 Garrett Mills ') console.log('') const rcFile = processPath('~/.str.rc') if ( fs.existsSync(rcFile) ) { log.verbose('rc', { rcFile }) const rcFileContent = fs.readFileSync(rcFile).toString() await input.pushLines('\n' + rcFileContent) console.log('Successfully loaded ~/.str.rc\n') } exec.subscribe(state => state.outputSubject()) input.setupPrompt() process.on('SIGINT', () => lifecycle.close()) })()