An S-Expression parser library, written in Swift.
Lisp and its innovative constructs, continue to inspire me. The philosophy of combination and abstraction, as formulated in SICP left me wanting to write my own Lisp environment. This repository is the first step in that direction.
I hope you may find use in this.
There are two important functions, decode and encode.
public func Decode(_ input: String) -> Sexp
Decode takes in a string and outputs an S-Expression object.
If any error occurs, it returns an S-Expression containing the :error
atom.
public func Encode(_ exp: Sexp) -> String
Encode takes an S-Expression object and returns a string that contains the S-Expression representation of the object.
An S-Expression can be one of several types.
List types:
- List
()
,(+ 1 2 3)
Value types:
- Quote
"Cited string"
,'Quoted string'
- Number
42
,-69
- Float
4.20
- Atom (based on Elixir atoms)
:err
,:foobar
- Boolean
:true
or:false
- Symbol
+
,foobar
,write-file
The order in which there are listed, is the order in which they are parsed. Thus there is a hierarchy of types, which determines the output of the decode function.
Atoms are different from symbols, in that atoms won't evaluate to anything.
The symbol foo
may evaluate to a procedure, a number, or even an atom.
The atom :foo
will always resolve to :foo
.
There are also two special atoms: :ok
and :err
.
These atoms perform the same function as the result type in Rust.
Besided the S-Expression code found in libsexp, there is also libcadr.
This library contains the Cons
type, and the Car()
, and Cdr()
functions.
/// Get the first element of a list
public func Car(_ lexp: libsexp.List) -> libsexp.Sexp
/// Get the other elements of a list
public func Cdr(_ lexp: libsexp.List) -> libsexp.List
/// Construct cell
public typealias Cons = (car: libsexp.Sexp, cdr: libsexp.List)
/// Construct a cell
public func Construct(_ exp: libsexp.Sexp) -> libcadr.Cons
With Construct()
you can create an Cons cell from any S-Expression.