All Projects → deciduously → Blispr

deciduously / Blispr

Licence: mit
Lisp-in-progress

Programming Languages

rust
11053 projects

Projects that are alternatives of or similar to Blispr

Yoctolisp
Tiny Scheme-like Lisp interpreter written in a weekend
Stars: ✭ 117 (+333.33%)
Mutual labels:  lisp-interpreter
CoCoC
C development system for (Nitr)OS9/6x09, with source
Stars: ✭ 22 (-18.52%)
Mutual labels:  lisp-interpreter
liyad
Liyad (Lisp yet another DSL interpreter) is very small Lisp interpreter written in JavaScript.
Stars: ✭ 27 (+0%)
Mutual labels:  lisp-interpreter
Lice
A multi-paradigm programming language running on JVM
Stars: ✭ 120 (+344.44%)
Mutual labels:  lisp-interpreter
G Fu
Lisp 2 Go
Stars: ✭ 243 (+800%)
Mutual labels:  lisp-interpreter
genyris
Genyris presents a new programming paradigm. Objects can belong to multiple classes independent from construction allowing data to be classified into types after creation.
Stars: ✭ 14 (-48.15%)
Mutual labels:  lisp-interpreter
Mumbler
My experimental programming language using Truffle
Stars: ✭ 100 (+270.37%)
Mutual labels:  lisp-interpreter
Glisp
A Lisp-based Design Tool Bridging Graphic Design and Computational Arts
Stars: ✭ 519 (+1822.22%)
Mutual labels:  lisp-interpreter
lispkit
FUNCTIONAL PROGRAMMING: Application and Implementation, Peter Henderson, ISBN 0-13-331579-7
Stars: ✭ 33 (+22.22%)
Mutual labels:  lisp-interpreter
parens
Parens is a highly flexible and embeddable LISP toolkit. 💻
Stars: ✭ 32 (+18.52%)
Mutual labels:  lisp-interpreter
Lips
Scheme based powerful lisp interpreter written in JavaScript
Stars: ✭ 120 (+344.44%)
Mutual labels:  lisp-interpreter
Esp Lisp
Beta: A small fast lisp interpeter for a ESP8266 as alternative to lua on the nodemcu.
Stars: ✭ 236 (+774.07%)
Mutual labels:  lisp-interpreter
PureLISP.sh
A Pure LISP interpreter written in shell script conformed to POSIX shell
Stars: ✭ 30 (+11.11%)
Mutual labels:  lisp-interpreter
Cisp
A Common Lisp Interpreter Built in COBOL
Stars: ✭ 120 (+344.44%)
Mutual labels:  lisp-interpreter
Pampy
Pampy: The Pattern Matching for Python you always dreamed of.
Stars: ✭ 3,419 (+12562.96%)
Mutual labels:  lisp-interpreter
Golisp
Lisp Interpreter
Stars: ✭ 107 (+296.3%)
Mutual labels:  lisp-interpreter
abap scheme
ABAP Scheme
Stars: ✭ 13 (-51.85%)
Mutual labels:  lisp-interpreter
Pampy.js
Pampy.js: Pattern Matching for JavaScript
Stars: ✭ 544 (+1914.81%)
Mutual labels:  lisp-interpreter
Arpilisp
A Lisp interpreter for Raspberry Pi implemented in a single ARM assembly file
Stars: ✭ 470 (+1640.74%)
Mutual labels:  lisp-interpreter
jisp
Small Lisp expression interpreter made in Java
Stars: ✭ 19 (-29.63%)
Mutual labels:  lisp-interpreter

blispr

Build Status

It's blisp, but in Rust! Blispr.

This is a rewrite of the Lisp built in the book Build Your Own Lisp in Rust. The end product is superficially similar, but there are some places where I have either by choice or necessity implemented something differently - different enough that I can't accurately call this a port of that tutorial. It's just the world's latest unnecessary-est lisp!

Requirements

  • Rust (stable)

Usage

$ git clone https://github.com/deciduously/blispr
$ cd blispr
$ cargo run
   Compiling blispr v0.0.1 (/home/yourstruly/code/blispr)
    Finished dev [unoptimized + debuginfo] target(s) in 0.92s
     Running `target/debug/blispr`
Blispr v0.0.1
Use exit(), Ctrl-C, or Ctrl-D to exit prompt
blispr> (def {x} 100)
()
blispr> (def {y} 200)
()
blispr> (def {a /* comments look like this */ b} 5 6)
()
blispr> (eval (cons (head {+ - * /}) (list a b x y)))
311

Newlines are whitespace as well. The surrounding parens are required - a valid blispr program is one or more forms. Omitting them will result in only the final form getting returned:

blispr> + 4 5
5
blispr> (+ 4 5)
9

The first attempt was evaluated as follows:

blispr> +
<builtin: +>
blispr> 4
4
blispr> 5
5

It uses rustyline as a readline alternative which will save history to ./.blispr-history.txt. See that repo for all supported options.

Run with no arguments for the repl, or pass an input file with -i or --input:

test.blispr:

(def {x} 100)
(def {y} 200)
(def {a b} 5 6)
(eval (cons (head {+ - * /}) (list a b x y)))
$ cargo run -- -i test.blispr 
    Finished dev [unoptimized + debuginfo] target(s) in 0.04s
     Running `target/debug/blispr -i test.blispr`
311

You can pass -d or --debug at runtime (cargo run -- -d or blispr -d) to enable overly verbose debug output:

$ cargo run -- -d
    Finished dev [unoptimized + debuginfo] target(s) in 0.04s
     Running `target/debug/blispr -d`
Blispr v0.0.1
Use exit(), Ctrl-C, or Ctrl-D to exit prompt
 DEBUG blispr::parse > Debug mode enabled
blispr> (eval (list + 1 2))
 DEBUG blispr::parse > blispr(0, 19, [expr(0, 19, [sexpr(0, 19, [expr(1, 5, [symbol(1, 5)]), expr(6, 18, [sexpr(6, 18, [expr(7, 11, [symbol(7, 11)]), expr(12, 13, [symbol(12, 13)]), expr(14, 15, [num(14, 15)]), expr(16, 17, [num(16, 17)])])])])]), EOI(19, 19)])
 DEBUG blispr::parse > Parsed: Blispr([Sexpr([Sym("eval"), Sexpr([Sym("list"), Sym("+"), Num(1), Num(2)])])])
 DEBUG blispr::eval  > lval_eval: Sexpr, evaluating children
 DEBUG blispr::eval  > lval_eval: Symbol lookup - retrieved Fun(Builtin(eval)) from key "eval"
 DEBUG blispr::eval  > lval_eval: Sexpr, evaluating children
 DEBUG blispr::eval  > lval_eval: Symbol lookup - retrieved Fun(Builtin(list)) from key "list"
 DEBUG blispr::eval  > lval_eval: Symbol lookup - retrieved Fun(Builtin(+)) from key "+"
 DEBUG blispr::eval  > lval_eval: Non-sexpr: Num(1)
 DEBUG blispr::eval  > lval_eval: Non-sexpr: Num(2)
 DEBUG blispr::eval  > Calling function Fun(Builtin(list)) on Sexpr([Sym("list"), Sym("+"), Num(1), Num(2)])
 DEBUG blispr::eval  > builtin_list: Building qexpr from [Fun(Builtin(+)), Num(1), Num(2)]
 DEBUG blispr::eval  > Calling function Fun(Builtin(eval)) on Sexpr([Sym("eval"), Sexpr([Sym("list"), Sym("+"), Num(1), Num(2)])])
 DEBUG blispr::eval  > builtin_eval: Sexpr([Fun(Builtin(+)), Num(1), Num(2)])
 DEBUG blispr::eval  > lval_eval: Sexpr, evaluating children
 DEBUG blispr::eval  > lval_eval: Non-sexpr: Fun(Builtin(+))
 DEBUG blispr::eval  > lval_eval: Non-sexpr: Num(1)
 DEBUG blispr::eval  > lval_eval: Non-sexpr: Num(2)
 DEBUG blispr::eval  > Calling function Fun(Builtin(+)) on Sexpr([Fun(Builtin(+)), Num(1), Num(2)])
 DEBUG blispr::eval  > builtin_op: Add 1 and 2
3

Currently implemented

  • Operators: + | add, - | sub, * | mul, / | div, % | rem, ^ | pow, max, min. Aliases point to the same function.

  • Utilties: printenv(), exit() (must be passed with an argument - an empty S-Expression works):

blispr> _def {a b c d e f g h i j k l m n o p q r s t u v w x y z} 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26)
()
blispr> (def {func} (\ {a b} {+ a b}))
()
blispr> (printenv())
{g:7 m:13 o:15 head:<builtin: head> *:<builtin: *> f:6 list:<builtin: list> p:16 printenv:<builtin: printenv> d:4 tail:<builtin: tail> ^:<builtin: ^> cons:<builtin: cons> j:10 sub:<builtin: sub> q:17 init:<builtin: init> s:19 +:<builtin: +> %:<builtin: %> t:20 /:<builtin: /> v:22 w:23 y:25 z:26 func:(\ {a b} {+ a b}) mul:<builtin: mul> join:<builtin: join> exit:<builtin: exit> rem:<builtin: rem> add:<builtin: add> def:<builtin: def> pow:<builtin: pow> h:8 div:<builtin: div> \:<builtin: \> max:<builtin: max> b:2 l:12 n:14 r:18 x:24 k:11 e:5 u:21 eval:<builtin: eval> -:<builtin: -> min:<builtin: min> c:3 i:9 len:<builtin: len> a:1}
blispr> exit()
Goodbye!

$
  • List operations:
blispr> (list 1 2 3)
{1 2 3}
blispr> (eval {+ 1 2})
3
blispr> (join {1 2} {3 4})
{1 2 3 4}
blispr> (len {1 2 3 4 5})
5
blispr> (head {1 2 3})
1
blispr> (tail {1 2 3})
{2 3}
blispr> (cons 3 {4 5})
{3 4 5}
blispr> (init {1 2 3 4})
{1 2 3}
  • Variable defintions - new assignments to the same binding will overwrite old ones:
blispr> (def {x} 100)
()
blispr> (def {y} 200)
()
blispr> (def {a b} 5 6)
()
blispr> (def {arglist} {a b x y})
()
blispr> arglist
{a b x y}
blispr> (+ a b x y)
311
blispr> (def arglist 1 2 3 4)
()
blispr> (list a b x y)
{1 2 3 4}
  • User-defined lambdas

Now with partial application!

blispr> (def {embiggen} (\ {x y} {^ (* x y) (+ x y)}))
()
blispr> (embiggen 2 3)
7776
blispr> (def {real-big} (embiggen 4))
()
blispr> (real-big 2)
262144
blispr> 

...that's it!

Only accepts integers for now, decimal points in numbers are a syntax error.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].