atto-lisp-0.1: Efficient parsing and serialisation of S-Expressions.

Data.AttoLisp

Contents

Description

Efficient parsing and serialisation of S-Expressions (as used by Lisp).

This module is intended to be imported qualified, e.g.:

 import qualified Data.AttoLisp as L

Synopsis

Core Lisp Types

data Lisp Source

A Lisp expression (S-expression).

Symbols are case-sensitive.

Constructors

Symbol Text

A symbol (including keyword)

String Text

A string.

Number Number

A number

List [Lisp]

A proper list: (foo x 42)

DotList [Lisp] Lisp

A list with a non-nil tail: (foo x . 42). The list argument must be non-empty and the tail must be non-nil.

nil :: LispSource

The empty list.

isNull :: Lisp -> BoolSource

Returns True if the expression is nil or the empty list.

Type Conversion

class FromLisp a whereSource

A type that can be converted from an S-expression, with the possibility of failure.

When writing an instance, use mzero or fail to make a conversion fail, e.g. the value is of the wrong type.

An example type and instance:

data Coord { x :: Double, y :: Double }

instance FromLisp Coord where
   parseLisp (DotList [x] y) = pure (Coord x y) 
   -- A non-DotList value is of the wrong shape, so use mzero to fail.
   parseLisp _          = mzero

The above instance expects that Coord 4 5 is encoded as (4 . 5). This makes sense for a few special types, but most of the time the standard encoding should be used: (coord 4 5). The struct combinator provides special support for this use case:

instance FromLisp Coord where
   parseLisp = struct "coord" Coord

It uses some special type class magic to figure out the arity of its second argument.

Methods

parseLisp :: Lisp -> Parser aSource

data Result a Source

The result of running a Parser.

Constructors

Error String 
Success a 

type Failure f r = String -> f rSource

Failure continuation.

type Success a f r = a -> f rSource

Success continuation.

data Parser a Source

A continuation-based parser type.

parse :: (a -> Parser b) -> a -> Result bSource

Run a Parser.

parseMaybe :: (a -> Parser b) -> a -> Maybe bSource

Run a Parser with a Maybe result type.

parseEither :: (a -> Parser b) -> a -> Either String bSource

Run a Parser with an Either result type.

typeMismatchSource

Arguments

:: String

The name of the type you are trying to parse.

-> Lisp

The actual value encountered.

-> Parser a 

Fail parsing due to a type mismatch, with a descriptive message.

class ToLisp a whereSource

A type that can be converted to an S-expression.

An example type and instance:

data Coord { x :: Double, y :: Double }

instance ToLisp Coord where
   toLisp (Coord x y) = struct "coord" [toLisp x, toLisp y]

Methods

toLisp :: a -> LispSource

Constructors and destructors

mkStruct :: Text -> [Lisp] -> LispSource

Create a Lisp struct in a standardised format.

Fields in a struct are accessed by position.

struct :: ParseList f a => Text -> f -> Lisp -> Parser aSource

Decode structure serialised with mkStruct.

The second argument should be a function, usually a constructor. The resulting parser automatically figures out the arity of the function. For example:

data Foo = Foo Int deriving (Eq, Show)

parseFoo :: Lisp -> Parser Foo
parseFoo = struct "foo" Foo

test = parseMaybe parseFoo val == Just (Foo 23)
  where val = List [Symbol "foo", Number 23]

Encoding and parsing

lisp :: Parser LispSource

Parse an arbitrary lisp expression.

atom :: Parser LispSource

Parse a symbol or a number. Symbols are expected to be utf8.

TODO: support escapes in symbols