This document explains how to use the Umu interpreter.

First Step

To start the interpreter in an interactive environment called REPL (Read-Evaluate-Print Loop) , run the umu command with the -i option.

$ umu/exe/umu -i
umu:1> print "Hello world\n"
Hello world

val it : Unit = ()
umu:2>                  # Enter [Ctrl]+[d]
$

If you specify a file containing a script after the -i option, the REPL will read that file and then start the REPL.

$ umu/exe/umu -i umu/example/factorial.umu
umu:1> factorial 3
val it : Int = 6
umu:2>

REPL’s Subcommand

The following subcommands can be used in REPL:

:class

Display information about classes.

:env and :envall

Display information about environment.

:dump and :nodump

Controls dump display at runtime.

:trace and :notrace

Controls trace display at runtime.

:class

Summary

If only the subcommand :class is specified, inheritance relationships between classes will be displayed hierarchically.

umu:1> :class
Top/
    Class
    Object/
        Atom/
            Bool
            Number/
                Float
                Int
            String
            Symbol
    :
    :
    :
umu:2>

Detail

The subcommand :class followed by a class name displays information about the specified class and a list of messages to which it can respond.

umu:1> :class Bool
ABSTRACT CLASS?: No, this is a concrete class
SUPERCLASS: Atom
ANCESTORS: Atom, Object, Top
CLASS MESSAGES:
    &Bool.true : Bool
    &Bool.false : Bool
INHERITED INSTANCE MESSAGES:
  INHERIT FROM: Object
    Object#show : String
    Object#to-s : String
    Object#contents : Top
    Object#== : Object -> Bool
    Object#force : Top
INSTANCE MESSAGES:
    Bool#< : Bool -> Bool
    Bool#not : Bool
umu:2>

:env and :envall

Names such as variable names, function names, and module names are registered in a dictionary called the environment.

The subcommand :env extracts user-declared names from the environment and displays them.

$ umu/exe/umu -i
umu:1> val x = 3    # Declare variable 'x'
val x : Int = 3
umu:2> :env         # Check the environment ==> x
structure Umu
val x : Int
umu:3> val y = 4    # Declare variable 'x'
val y : Int = 4
umu:4> :env         # Check the environment ==> x, y
structure Umu
val x : Int
val y : Int
umu:5> x + y        # Evaluate expression
val it : Int = 7
umu:6> :env         # Check the environment ==> x, y, it
structure Umu
val x : Int
val y : Int
val it : Int
umu:7>

If a script is specified as a command argument, the name declared within the script will also be displayed.

$ umu/exe/umu -i umu/example/factorial.umu
umu:1> :env
structure Umu
fun factorial
umu:2>

The subcommand :envall displays all names registered in the current environment.

umu:1> :envall
fun !!
fun *
fun +
fun :=
  :
  :
  :
fun zero
fun zero?
fun zip
fun |
umu:2>

:dump and :nodump

The interpreter processes the input script as follows.

/Source(Script)/ ->
    <Lexical analysis> -> [Tokens] ->
    <Parse>    -> [Concrete Syntax Tree] ->
    <Desugar>  -> [Abstract Syntax Tree] ->
    <Evaluate> ->
/Result(environment and value)/

The dump function displays the following intermediate objects that are generated during this process.

  • Tokens

  • Concrete syntax tree

  • Abstract syntax tree

Use the subcommand :dump to enable the dump function, and use :nodump to disable it.

umu:1> :dump
umu:2> 3 + 4
________ Source: '<stdin>' ________
0002: 3 + 4

________ Tokens: '<stdin>' ________
0002: INT(3) SP '+' SP INT(4) NL("\n")

________ Concrete Syntax: #2 in "<stdin>" ________
(3 + 4)

________ Abstract Syntax: #2 in "<stdin>" ________
(+ 3 4)

val it : Int = 7
umu:3> :nodump
umu:4>

:trace and :notrace

The trace function displays the desugaring process and evaluation processes inside the interpreter in a hierarchical manner.

Use the subcommand :trace to enable the trace function, and use :notrace to disable it.

umu:1> :trace
umu:2> 3 + 4
________ Source: '<stdin>' ________
0002: 3 + 4

________ Desugar Trace ________
[Desu] Redefinable (CSCEB::Infix): (3 + 4)
| [Desu] Int (CSCEUA::Number): 3 --> Int (ASCEUA::Number): 3
| [Desu] Int (CSCEUA::Number): 4 --> Int (ASCEUA::Number): 4
--> Apply (ASCEB): (+ 3 4)

________ Evaluator Trace ________
[Eval(Expr)] Apply (ASCEB): (+ 3 4)
| [Eval(Expr)] Short (ASCEU::Identifier): +
| --> Fun (VC): #<+: {x : Number y : Number -> (x).(+ y)}>
| [Eval(Expr)] Int (ASCEUA::Number): 3 --> Int (VCAN): 3
| [Eval(Expr)] Int (ASCEUA::Number): 4 --> Int (VCAN): 4
| [Apply] Fun (VC): (#<+: {x : Number y : Number -> (x).(+ y)}> 3 4)
| | [Eval(Expr)] Entry (ASCEB::Send): (x).(+ y)
| | | [Eval(Expr)] Short (ASCEU::Identifier): x
| | | --> Int (VCAN): 3
| | | [Eval(Expr)] Short (ASCEU::Identifier): y
| | | --> Int (VCAN): 4
| | | [Invoke] Int (VCAN): (3).meth_add(4 : Int) -> Int
| | | --> Int (VCAN): 7
| | --> Int (VCAN): 7
| --> Int (VCAN): 7
--> Int (VCAN): 7

val it : Int = 7
umu:3> :notrace
umu:4>