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>