Skip to content

MarioAriasC/monkey.kt

Repository files navigation

monkey.kt

Kotlin's implementation of the Monkey Language

Articles

https://medium.com/@mario.arias.c/comparing-kotlin-and-golang-implementations-of-the-monkey-language-3a41122ea732

https://medium.com/@mario.arias.c/comparing-kotlin-and-go-implementations-of-the-monkey-language-ii-raiders-of-the-lost-performance-b9aa09945281

Status

The two books (Writing An Interpreter In Go and Writing A Compiler in Go) are implemented.

Hello, this is the monkey.kt programming language
Feel free to type any command
>>> let add = fn(a, b) { a + b; }
fn(a, b) {
    (a + b)
}
>>> let x = add(1, 2)
3
>>> add(x, 5)
8

For an implementation of the interpreter with macros (but not a compiler) check the branch eval-macros

Execution

There are four different executable environments, JVM, GraalVM Native Image, Native and JavaScript Each executable has 3 different shell scripts, build, repl, benchmarks

Executable environment Build REPL Benchmarks
JVM build-jvm.sh repl-jvm.sh benchmarks-jvm.sh
Graal build-graal.sh repl-graal.sh benchmarks-graal.sh
Native build-native.sh repl-native.sh benchmarks-native.sh
JavaScript build-js.sh NA benchmarks-node.sh or benchmarks-bun.sh

You must run the build-[ENV].sh before running repl-[ENV].sh or benchmarks-[ENV].sh

JVM

For *nix systems, run the following command:

$ ./build-jvm.sh

And then:

$ ./repl-jvm.sh

GraalVM Native Image

To run the application with GraalVM Native Image, you need to follow certain steps:

  • Install GraalVM, I recommend using SDKMAN (Not just for GraalVM but for any JVM tool in general)
  • Install the native-image executable
  • Create a GRAALVM_HOME environment variable. On *nix systems export GRAALVM_HOME="$HOME/.sdkman/candidates/java/21.2.0.r11-grl/ or your equivalent GraalVM location
  • Run the command
$ ./build-graal.sh

And then:

$ ./repl-graal.sh

Kotlin Native

For *nix systems, run the following command:

$ ./build-native.sh

And then:

$ ./repl-native.sh

Kotlin JS

For *nix systems, run the following command:

$ ./build-js.sh

The JS REPL is not working at the moment. But you can still run the benchmarks using Node or Bun (Must be installed before hand)

Benchmarks

To run the standard Monkey language benchmarks (fibonacci(35);) add a parameter vm, vm-fast, eval or eval-fast to the benchmark script.

Example

$ ./benchmarks-jvm.sh vm
engine=vm, result=9227465, duration=7.516433414s
$ ./benchmarks-graal.sh eval  
engine=eval, result=9227465, duration=22.173455585s

All the benchmarks tested on a MBP 15-inch 2019. Intel Core i9 2.3Ghz 8-Core, 32 GB 2400 MHZ DDR4

If you want to run proper benchmarks, I recommend hyperfine

$ hyperfine --warmup 3 './benchmarks-jvm.sh vm' './benchmarks-jvm.sh vm-fast' './benchmarks-jvm.sh eval' './benchmarks-jvm.sh eval-fast'
Benchmark 1: ./benchmarks-jvm.sh vm
  Time (mean ± σ):      9.505 s ±  0.788 s    [User: 9.759 s, System: 0.262 s]
  Range (min … max):    8.639 s … 10.745 s    10 runs

Benchmark 2: ./benchmarks-jvm.sh vm-fast
  Time (mean ± σ):      6.633 s ±  0.196 s    [User: 6.837 s, System: 0.206 s]
  Range (min … max):    6.317 s …  6.908 s    10 runs

Benchmark 3: ./benchmarks-jvm.sh eval
  Time (mean ± σ):     13.368 s ±  0.943 s    [User: 13.643 s, System: 0.261 s]
  Range (min … max):   11.970 s … 14.961 s    10 runs

Benchmark 4: ./benchmarks-jvm.sh eval-fast
  Time (mean ± σ):     10.321 s ±  0.760 s    [User: 10.713 s, System: 0.256 s]
  Range (min … max):    9.551 s … 11.455 s    10 runs

Summary
  './benchmarks-jvm.sh vm-fast' ran
    1.43 ± 0.13 times faster than './benchmarks-jvm.sh vm'
    1.56 ± 0.12 times faster than './benchmarks-jvm.sh eval-fast'
    2.02 ± 0.15 times faster than './benchmarks-jvm.sh eval'
$ hyperfine --warmup 3 './benchmarks-graal.sh vm' './benchmarks-graal.sh vm-fast' './benchmarks-graal.sh eval' './benchmarks-graal.sh eval-fast'
Benchmark 1: ./benchmarks-graal.sh vm
  Time (mean ± σ):     21.364 s ±  0.627 s    [User: 21.057 s, System: 0.165 s]
  Range (min … max):   20.759 s … 22.628 s    10 runs

Benchmark 2: ./benchmarks-graal.sh vm-fast
  Time (mean ± σ):     16.955 s ±  0.534 s    [User: 16.740 s, System: 0.136 s]
  Range (min … max):   16.158 s … 18.018 s    10 runs

Benchmark 3: ./benchmarks-graal.sh eval
  Time (mean ± σ):     20.561 s ±  0.270 s    [User: 20.321 s, System: 0.150 s]
  Range (min … max):   20.119 s … 20.910 s    10 runs

Benchmark 4: ./benchmarks-graal.sh eval-fast
  Time (mean ± σ):     16.934 s ±  0.258 s    [User: 16.730 s, System: 0.135 s]
  Range (min … max):   16.327 s … 17.206 s    10 runs

Summary
  './benchmarks-graal.sh eval-fast' ran
    1.00 ± 0.04 times faster than './benchmarks-graal.sh vm-fast'
    1.21 ± 0.02 times faster than './benchmarks-graal.sh eval'
    1.26 ± 0.04 times faster than './benchmarks-graal.sh vm'

Test

For *nix systems, run the following command:

$ ./tests.sh

About

Kotlin implementation of the Monkey Language

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published