From 30543cb07db375106bc2b1e7fe1b04b5d1bb4513 Mon Sep 17 00:00:00 2001 From: Daryl Tan <3646725+openorclose@users.noreply.github.com> Date: Wed, 19 Feb 2020 11:03:01 +0800 Subject: [PATCH] Allow source file to be passed to repl (#396) --- README.rst | 7 +++++++ src/repl/repl.ts | 53 ++++++++++++++++++++++++++++++++---------------- 2 files changed, 43 insertions(+), 17 deletions(-) diff --git a/README.rst b/README.rst index 9a3fe39f0..d55af58e7 100644 --- a/README.rst +++ b/README.rst @@ -30,6 +30,13 @@ To try out *Source* in a REPL, run $ node dist/repl/repl.js [chapter] # default: 1 +If you wish, you can pass in a file path instead, to evaluate some *Source* before initialising the REPL +It will be run in *Source* chapter 4. + +.. code-block:: + + $ node dist/repl/repl.js [path/to/file] + or alternatively, install js-slang and run .. code-block:: diff --git a/src/repl/repl.ts b/src/repl/repl.ts index 956a88da1..367fabdbe 100644 --- a/src/repl/repl.ts +++ b/src/repl/repl.ts @@ -1,29 +1,48 @@ +import fs = require('fs') import repl = require('repl') // 'repl' here refers to the module named 'repl' in index.d.ts -import { createContext, parseError, runInContext } from '../index' +import { createContext, IOptions, parseError, runInContext } from '../index' -function startRepl(chapter = 1, useSubst: boolean) { +function startRepl(chapter = 1, useSubst: boolean, prelude = '') { // use defaults for everything const context = createContext(chapter) - repl.start( - // the object being passed as argument fits the interface ReplOptions in the repl module. - { - eval: (cmd, unusedContext, unusedFilename, callback) => { - runInContext(cmd, context, { scheduler: 'preemptive', useSubst }).then(obj => { - if (obj.status === 'finished') { - callback(null, obj.value) - } else { - callback(new Error(parseError(context.errors)), undefined) + const options: Partial = { scheduler: 'preemptive', useSubst } + runInContext(prelude, context, options).then(preludeResult => { + if (preludeResult.status === 'finished') { + console.log(preludeResult.value) + repl.start( + // the object being passed as argument fits the interface ReplOptions in the repl module. + { + eval: (cmd, unusedContext, unusedFilename, callback) => { + runInContext(cmd, context, options).then(obj => { + if (obj.status === 'finished') { + callback(null, obj.value) + } else { + callback(new Error(parseError(context.errors)), undefined) + } + }) } - }) - } + } + ) + } else { + throw new Error(parseError(context.errors)) } - ) + }) } function main() { - const chapter = process.argv.length > 2 ? parseInt(process.argv[2], 10) : 1 - const useSubst = process.argv.length > 3 ? process.argv[3] === 'subst' : false - startRepl(chapter, useSubst) + const firstArg = process.argv[2] + if (process.argv.length === 3 && String(Number(firstArg)) !== firstArg.trim()) { + fs.readFile(firstArg, 'utf8', (err, data) => { + if (err) { + throw err + } + startRepl(4, false, data) + }) + } else { + const chapter = process.argv.length > 2 ? parseInt(firstArg, 10) : 1 + const useSubst = process.argv.length > 3 ? process.argv[3] === 'subst' : false + startRepl(chapter, useSubst) + } } main()