CHAPTER 24

Interactive Console

Like most other languages, Julian provides an interactive console that bring REPL (Read-Evaluate-Print) experiences to users. Since Julian is still in its early days, you will find the console particularly useful in your development routine as it can help you quickly validate the correctness of the code.

Start Julian in interactive mode

~> julian -i

This will override -s or -f options.

Now the user can input code after the prompt:

>>> _

Read input

(1) The interpreter executes per line. When the user completes one line (by EOL char) it will trigger execution. To ease the use, a ';' is automatically complemented if absent. But there are exceptions to this rule.

(2) If the first line ends with { and it's determined to be a type declaration (class/interface/etc.), the interpreter enters into type definition mode. In this mode, it will keep receiving input until a matching } is hit, ignoring EOLs in between. An example of this:

>>> class A {
...   void fun(){ }
...   int fun2(){
...     return 5;
...   }
... }  // This is the matching '}', signaling the end of type declaration. 
>>> _

If a matching '}' is found in a line with other characters following, it incurs an error and the type def mode bails out.

(3) Similarly, if the first line ends with { and it's determined to be a function declaration, the interpreter enters into function definition mode. This mode is very similar to type definition mode.

>>> void fun(){
...     return 5;
... }  // This is the matching '}', signaling the end of function declaration. 
>>> _

(4) The user may conclude a line with an independent '' to explicitly ask for continuation. But once in the explict continuation mode, further '' is not needed. The input must be finished by an explicit ';'.

>>> Console.println \
... ("some text" \ // This \ is not really needed.
... };
some text
>>> _

(5) The user may use arrow key (up/down) to browse command history and rerun a command.

Evaluate input

(1) The input will be evaluated in a single and continuously existing context.

(2) If a type is defined, it's loaded into the context immediately. This is different from the behavior of Julian in script mode, where it always defers loading to the point when the type is actually needed.

(3) Any exception will be captured and printed out.

Print output

If the input contains one or more expressions, the result of last expression will be printed out, unless it is a void.

>>> 3
3
>>> 2 + 3
5 
>>> fun() // fun() returns a string "something returned by fun()"
something returned by fun()
>>> fun2() // fun2() returns void
>>> _

Meta commands

(1) Meta commands are input in the format of ".comm args"

>>> .help

(2) List of meta-commands (commands greyed out are not available yet as of 0.1.34)

  • .helpprint a meta-command list. This command also supports showing detailed help for a particular meta-command if the command name is appended.
  • .exitexit the interpreter.
  • .clearclear the screen.
  • .historyshow history of commands in compact mode (multi-line input will show the 1st line only). This command also supports options such as "-full"(prints history of full commands in pages and allows forward/exit), "{keyword}"(show history of commands that contains {keyword}).
  • .resetclear all the loaded modules/types/vars from the context.
  • .load {file-path}load and run a script file.
  • .modulesshow a list of imported modules.
  • .localsshow a list of declared variables which are still visible in the global context.
  • .functionsshow a list of declared functions.
  • .typesshow a list of declared types. This command also supports options such as "-all"(show all types including those from system), "{keyword}"(show only types whose name contains the keyword).
  • .module {name}show meta-info of the named module (typed contained within, source file, etc.).
  • .function {name}show definition of the named function.
  • .type {name}show definition of the named type.
  • .!{shell command}run a command on the parent shell. This command is OS-dependent. For example, you say .!dir on Windows, but .!ls on Linux.
  • .set {option}={value}configure interpreter settings. Options available are "quiet", "prompt", "module-path", etc. If "={value}" is not provided, show the current setting for that option instead.