Overview
RubyLisp is a relatively simple Lisp dialect based on Scheme implimented using Ruby.
RubyLisp is a lexically scoped Lisp-1:
Lexically scoped:
The scope of definitions are determined by where they are made in the
lexical structure of the code. Each lambda
, let
, and do
creates
a new lexical scope. From [2]:
Here references to the established entity can occur only within certain program portions that are lexically (that is, textually) contained within the establishing construct. Typically the construct will have a part designated the body, and the scope of all entities established will be (or include) the body.
Lisp-1:
A Lisp where functions and variables share a single namespace. This
differs from a Lisp-2 in which functions and variables have separate
namespaces.
Installation
Add this line to your application's Gemfile:
gem 'rubylisp'
And then execute:
$ bundle
Or install it yourself as:
$ gem install rubylisp
Contributing
- Fork it
- Create your feature branch (git checkout -b my-new-feature)
- Commit your changes (git commit -am 'Add some feature')
- Push to the branch (git push origin my-new-feature)
- Create new Pull Request
The rubylisp command
Installing the rubylisp gem installs the rubylisp
command
>:rubylisp help
NAME:
rubylisp
DESCRIPTION:
A large sub/super-set of MIT/GNU-Scheme implemented in pure Ruby.
COMMANDS:
help Display global or [command] help documentation
repl Rubylisp REPL
test Runs tests
GLOBAL OPTIONS:
-h, --help
Display help documentation
-v, --version
Display version information
-t, --trace
Display backtrace when an error occurs
>:
REPL
RubyLisp includes a very basic REPL that, as expected, lets you type in snippets (it does not support multiline snippets) of Lisp code, evaluates them, and prints the result.
>:rubylisp help repl
NAME:
repl
SYNOPSIS:
rubylisp repl [options]
DESCRIPTION:
Rubylisp REPL
EXAMPLES:
# Simply run the REPL
rubylisp repl
# Run the REPL, loading a file first
rubylisp repl --file code.lsp
OPTIONS:
-f, --file LISPFILE
The name of the lisp file to load
>: rubylisp repl
RubyLisp REPL
> 4
4
> (+ 2 3)
5
> (define (fib x) (if (eq? x 0) 1 (* x (fib (- x 1)))))
<function: fib>
> (fib 4)
24
The repl uses readline for editing and history. History is saved in ~/.rubylisp_history. Evaling (quit)
will exit the repl.
Test runner
The rubylisp
command also contains a test runner.
>:ruby -Ilib bin/rubylisp help test
NAME:
test
SYNOPSIS:
rubylisp test [options]
DESCRIPTION:
Runs tests
EXAMPLES:
# Run the tests in tests/list_tests.lsp with verbose output
rubylisp test -v -f tests/list_tests.lsp
# Quietly run all tests in the directory tests
rubylisp test -q -d tests
OPTIONS:
-f, --file TESTFILE
The name of the test file to run
-d, --dir TESTDIR
The name of a directory of test files, all of which will be run
--verbose
Verbose test output: all context & it labels, and each assertion and it's result.
--terse
terse test output (the default): + for passes, - for failures, and ! for errors
--quiet
Only output a summary
>:rubylisp test -d lisptest --terse
Running lisp tests
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++
Ran 928 lisp tests in 7.0789 seconds
928 passes, 0 failures, 0 errors
Integrating
The simplist way to integrate RubyLisp is to have it parse and evaluate strings of lisp code.
>: irb
2.0.0-p247 :001 > require 'rubylisp'
=> true
2.0.0-p247 :002 > Lisp::Initializer.register_builtins
=> ...
2.0.0-p247 :003 > Lisp::Parser.new.parse_and_eval('(+ 1 2)').to_s
=> "3"
2.0.0-p247 :004 >
But lets say you are using rubylisp to do something more embedded such as provide an extension language to your application. It's easy to provide the Lisp runtime with functions written in Ruby that can be called from Lisp code.
to be continued...