Skip to content

Commit

Permalink
Allow source file to be passed to repl (#396)
Browse files Browse the repository at this point in the history
  • Loading branch information
openorclose committed Feb 19, 2020
1 parent c756088 commit 30543cb
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 17 deletions.
7 changes: 7 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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::
Expand Down
53 changes: 36 additions & 17 deletions src/repl/repl.ts
Original file line number Diff line number Diff line change
@@ -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<IOptions> = { 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()

0 comments on commit 30543cb

Please sign in to comment.