Skip to content
bizzehdee edited this page Jun 26, 2026 · 4 revisions

REPL

The dscript repl command starts an interactive read-eval-print loop backed by a persistent ScriptEngine. Variables, functions, and classes you declare in one line are available in all subsequent lines.

Running

dscript repl

Or via dotnet run:

dotnet run --project DScript.Cli -- repl

Session example

DScript 0.1.0 REPL  (type .exit to quit, .help for commands)

> var x = 10
> x + 5
15
> function square(n) { return n * n; }
> square(7)
49
> var nums = [1, 2, 3, 4, 5]
> nums.map(n => n * 2)
[ 2, 4, 6, 8, 10 ]
> .exit
bye.

How input is handled

The REPL distinguishes between statements and expressions:

  • Lines that begin with var, let, const, function, or class, or that end with ;, are treated as statements and executed with engine.Execute(). No value is printed.
  • Everything else is treated as an expression, evaluated with engine.EvalComplex(), and its result printed (unless the result is undefined).

This means you can omit the trailing semicolon when typing expressions you want to see the value of.

Built-in commands

Command Description
.help Show the list of REPL commands
.options Show the current REPL options
.options jit <value> Select the JIT back-end: on/reflection, closure, or off
.options optimisation <value> Toggle the compiler's bytecode optimiser: on or off
.exit or .quit End the session
Ctrl-C or Ctrl-D End the session (EOF)

Compilation options

The REPL exposes two tunables via .options:

  • jit — which JIT compiler (if any) compiles hot functions. Unlike a plain embedded ScriptEngine (where the JIT is opt-in and off by default), the REPL enables the reflection-emit back-end by default so hot functions tier up as you iterate. Switch to the portable closure-threaded back-end with .options jit closure, or turn it off entirely with .options jit off.
  • optimisation — the bytecode optimiser (constant folding, dead-code elimination, super-instruction fusion, narrow encoding), on by default. Turn it off with .options optimisation off to compile straight, unoptimised bytecode (useful for inspecting or debugging codegen). Results are identical either way; only the emitted bytecode differs.
> .options
  jit          = on (reflection-emit back-end)
  optimisation = on
> .options jit closure
jit: on (closure-threaded back-end) — hot functions will tier up
> .options optimisation off
optimisation: off

Standard library

The REPL loads DScript.Extras automatically, so console.log, Math, JSON, and all other standard-library globals are available immediately.

Persistent state

All globals survive across inputs within a single session. You can build up a script incrementally:

> function fib(n) { return n <= 1 ? n : fib(n-1) + fib(n-2); }
> fib(10)
55
> var result = fib(15)
> result
610

Async / await and Promises

The REPL drains the microtask queue after every input, so Promise callbacks and async function continuations fire immediately:

> Promise.resolve(42).then(v => console.log('got', v))
got 42
[object Object]
> async function delay(ms) { await new Promise(r => setTimeout(r, ms)); return 'done' }
> delay(0).then(console.log)
done
[object Object]

The [object Object] on the second line is the return value of the .then() call (a new Promise) being echoed by the expression evaluator. It does not indicate an error.

Error handling

Errors are caught and printed to stderr without ending the session:

> undeclaredVariable
Error: 'undeclaredVariable' is not defined
> 1 / 0
Infinity

Clone this wiki locally