/OCamLisp

Lisp interpreter implemented in OCaml

Primary LanguageOCamlBSD 3-Clause "New" or "Revised" LicenseBSD-3-Clause

ocamlisp-lipcrepl

Summary

This is a Lisp interpreter implemented in OCaml. It most closely resembles elisp. Currently, it supports:

  • print function (with varargs, unlike many lisps…)
  • basic arithmetic operators (+-*/)
  • concat function
  • read lisp from a single file (regardless of extension as of now)
  • REPL
  • lisp can be complex and nested
  • Variables

Variables

  • This is a work in progress, a variable at least once and then use it. That is to say, you can have
(setq x 55)
(print x)
(print (+ x 5))
(setq y 99)
(print y)
  • This now works as expected (scoped) and no longer breaks when you do for example
(setq y 0)
(setq y 1)

Prerequisites

Assuming one has OCaml installed and properly setup, the non standard packages currently are menhir and Batteries.

Bash instructions:

opam install menhir
opam install Batteries

Build

The build can be handled entirely by the Makefile.

Bash instructions:

make

If any errors occur, check the generated output.log file.

Clean

Note: cleaning the compiled files and anything else generated from the build makes merlin in editors wonky, so it’s advised to keep _build/ while editing or viewing code in an editor using merlin, but this will completely clean.

Bash instructions:

make clean

Run

The binary created after build instructions is main.native. There are two ways to run this project:

Using a file

./main.native filename

For simplicity’s sake, I’ve included a couple of files in the sample/ directory. You can do for example

./main.native sample/add.el

And if you want to check if the output is proper, you can view the file and evaluate yourself. Or since this lisp is very closely based on elisp, if have emacs installed, you can do

emacs --script sample/add.el

REPL (read eval print loop)

./main.native
(your lisp instructions here)

For example:

./main.native
(print (+ 5 7))

Currently, to end instructions, enter enter. To quit gracefully enter CTR-D. If you enter an invalid expression (sexp) such as (print 8)), it fails. When you start the expression on the line, it should end on the line as well.

You can use rlwrap ./main.native for a slightly better repl experience (up, down, left, right arrows become available).