Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/nshafer/elispir
Lisp-like run-time in Elixir
https://github.com/nshafer/elispir
Last synced: about 2 months ago
JSON representation
Lisp-like run-time in Elixir
- Host: GitHub
- URL: https://github.com/nshafer/elispir
- Owner: nshafer
- Created: 2015-09-25T17:57:09.000Z (over 9 years ago)
- Default Branch: master
- Last Pushed: 2015-09-25T19:20:53.000Z (over 9 years ago)
- Last Synced: 2024-10-12T07:25:35.266Z (3 months ago)
- Language: Elixir
- Size: 137 KB
- Stars: 2
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
Elispir
=======Lisp-like parser/evaluator in Elixir. Supports variables, conditionals, functions, closures, recursion.
Inspired by [this blog post](http://itsbarakyo.com/projects/2015/09/17/elisper-lisp-in-elixir.html) by barakyo
### Anonymous functions
iex> sum = fn (a, b) -> a + b end
#Function<12.54118792/2 in :erl_eval.expr/5>
iex> Elispir.eval([sum, 1, 2])
3### Function capture
Use any function available with Elixir's capture operator `&`
iex> Elispir.eval([&+/2, 1, 1])
2iex> Elispir.eval([&+/2, [&+/2, 2, 2], [&+/2, 2, 3]])
9## Do clauses
Evaluate multiple expressions with a `:do` clause. The value of the last expression is returned
iex> Elispir.eval([:do, [&IO.puts/1, "Hello"], [&IO.puts/1, "World"]])
Hello
World
:ok### If statements
iex> Elispir.eval([:if, [&==/2, 1, 1], [&+/2, 1, 1], [&+/2, 2, 2]])
2### Define variables inside a `:do` block
iex> Elispir.eval([:do, [:def, :a, 5]])
5iex> Elispir.eval([:do,
...> [:def, :a, 5],
...> [&+/2, :a, :a]
...> ])
10### Define a named function
iex> Elispir.eval(
...> [:do,
...> [:def, :square,
...> [:fn, [:x],
...> [&*/2, :x, :x]
...> ]
...> ]
...> ]
...> )
"&:square/1"### Call the function (within the same `:do` block)
iex> Elispir.eval(
...> [:do,
...> [:def, :square,
...> [:fn, [:x], [&*/2, :x, :x]]
...> ],
...> [:square, 5],
...> ]
...> )
25### The value of variables is captured at the time that the function is defined (closures)
iex> Elispir.eval(
...> [:do,
...> [:def, :outside, 2],
...> [:def, :square,
...> [:fn, [], [&*/2, :outside, :outside]]
...> ],
...> [:def, :outside, 3],
...> [:square]
...> ]
...> )
4### Call a function recursively
iex> Elispir.eval(
...> [:do,
...> [:def, :factorial,
...> [:fn, [:n],
...> [:if, [&==/2, :n, 0],
...> 1,
...> [&*/2, :n, [:factorial, [&-/2, :n, 1]]]
...> ]
...> ]
...> ],
...> [:factorial, 4]
...> ]
...> )
24See [tests](test/elispir_test.exs) for more examples.