snail-0.1.0.0: README.md
# Snail
A no-semantics programming language for gastropods.
## Why?
My colleagues and I are going to start working through [Types and Progamming
Languages][tapl]. In the book you implement languages of varying feature sets.
The book implements these languages in OCaml, however I had this Lisp parser
essentially ready for awhile. There are a handful of "Write you a Scheme
Interpreters"-like tutorials and they all use a parser relatively similar to
this one. However, there are some pretty subtle issues with most of the ones I
have seen. For example, the two examples below parse as two lexemes in a lot of
examples. Even Haskell's parser has [this issue][haskell-parse-issue]!
```
(1a)
(1 a)
```
## Is this really a programming language?
From the ["Programming language" wikipedia page][pl-wikipedia],
> A programming language is a system of notation for writing computer programs.
> The description of a programming language is usually split into the two components of syntax (form) and semantics (meaning)
Snail is used for writing interpreters or compilers. However, it doesn't define
**any** semantics. So, maybe?
## Syntax (form)
Snail describes valid lexemes, text literals, and s-expressions. The valid
lexemes are approximately from R5RS Scheme but this may change in the future.
We also use Haskell's line and block comments. Here is a valid snail program,
```
-- Prints `hello "world"` to the console
(print "hello \"world\"")
-- Prints 3 to the console
(print (+ 1 2))
{-
Defines a function to add two numbers
Applies the function to generate 3
Prints 3 to the console
-}
(let
(f (lambda (x y) (+ x y)))
(print (f 2 1)))
(quote hello)
(nil)
(print true)
(print false)
-- end comment
```
Reminder, this program has no semantics. It is your job to take Snail's
Abstract Syntax Tree (AST) and define the semantics of an interpreter or
compiler.
## Getting the AST
You can see some examples in `test/Snail/IOSpec.hs`, but you can put your snail
program into some file, let's say `hello.snail`. The following Haskell will print
the AST or print a failure,
```haskell
module Main where
import Snail
main :: IO ()
main = do
eResults <- readSnailFile "./hello.snail"
case eResults of
Right ast -> print ast
Left failureString -> print failureString
```
[tapl]: https://www.cis.upenn.edu/~bcpierce/tapl
[haskell-parse-issue]: https://twitter.com/chiroptical/status/1471568781906518018
[pl-wikipedia]: https://en.wikipedia.org/wiki/Programming_language