]> git.rmz.io Git - my-scheme.git/log
my-scheme.git
7 years agoHandle boolean constants
Samir Benmendil [Sun, 14 Jan 2018 00:24:21 +0000 (00:24 +0000)]
Handle boolean constants

Turns out that Scheme defines `#t` and `#f` to be `true` and `false`.

`let` is used to devife a new symbol `atom` which is a String.
`case...of` matches the literals and constructs a `LispVal` of the
appropriate type and value. `_` is a match all token.

7 years agoParse Atoms which start with a letter or symbol
Samir Benmendil [Sun, 14 Jan 2018 00:19:18 +0000 (00:19 +0000)]
Parse Atoms which start with a letter or symbol

`<|>` is a Parser combinator, the choice operator. It will try the first
parser, if it doesn't match anything, try the second parser, and so on.

`a:b` creates a list from `a` and `b`. Another possibility would be to
use `[a] ++ b`, where a new list with a single element is created `[a]`
and concatenated with `++`

7 years agoParse Strings surrounded by `"`
Samir Benmendil [Sun, 14 Jan 2018 00:03:01 +0000 (00:03 +0000)]
Parse Strings surrounded by `"`

We need to use a `do-block` because we would like to keep the return
value of a parse in the middle. So we parse a single `char '"'`, parse
`many (noneOf "\"")` and assign the return value to `x` and parse
another `"`.

We apply the `String` constructor to the value of `x` to turn it into a
`LispVal` with `String x`.

Finally we inject the `LispVal` into the `Parser` monad. We need to do
this because each line of a `do-block` needs to be of the same type but
the result of `String x` is a `LispVal`, not a `Parser`. `return` wraps
the `LispVal` up in a `Parser` action that consumes no input.

Consider `a $ b c` as syntactic sugar for `a (b c)`.

7 years agoAdd LispVal data type which can hold any Lisp value
Samir Benmendil [Sat, 13 Jan 2018 23:40:49 +0000 (23:40 +0000)]
Add LispVal data type which can hold any Lisp value

LispVal is an algebraic type which is able to hold any of the types
given.

Not sure what the type of `DottedList` is meant to be.

7 years agoIgnore spaces
Samir Benmendil [Sat, 13 Jan 2018 23:24:30 +0000 (23:24 +0000)]
Ignore spaces

We add the spaces `Parser` which returns nothing `()` and skips any
spaces.

`spaces` is already defined in Parsec, but does not do exactly what we
want, we can hide it from the import.

`skipMany a` matches 0 or more `a` and skips them.

`>>` is the **bind** operator. It may have completely different meanings
depending on the monad you use. In the Parser monad in means "try the
first parameter, then try the second with anything that is left", i.e.
"first skip all the spaces, then match the symbol".

7 years agoreadExpr function to check whether the input matches symbol
Samir Benmendil [Sat, 13 Jan 2018 23:05:55 +0000 (23:05 +0000)]
readExpr function to check whether the input matches symbol

`readExpr :: String -> String` defines `readExpr` to be a function
(`->`) from String to a String.

`readExpr input = ...` will assign anything on the rhs to the `readExpr`
function where `input` is mapped to the first parameter of that
function.

`case ... of` is a *filter*.

`parse a b c` is a function from Parsec where `a` is the parser it should
use, `b` is the name of the input which is used for error messages and
`c` is the String to parse.

`parse` returns an `Either` type whose `Left` constructor indicates an
error. If we get a `Right` value, we bind it to `val`, ignore it and
return the String "Found Value".

7 years agoDefine a parser for various symbols in Scheme
Samir Benmendil [Sat, 13 Jan 2018 22:41:38 +0000 (22:41 +0000)]
Define a parser for various symbols in Scheme

`symbol :: Parser Char` is probably not needed (?)

I don't understand where the `Parser` type comes from, I cannot see it
in the doc of `Text.ParserCombinators.Parsec`. It may be that
`ParserCombinators` is a compatibility layer and that `Parser` is
defined somewhere else.

`oneOf` is provided by Parsec.

7 years agoImport the Parsec library
Samir Benmendil [Sat, 13 Jan 2018 22:24:47 +0000 (22:24 +0000)]
Import the Parsec library

If we want to use the new library, it needs to be imported.

More info for the library can be found on GitHub.
https://github.com/haskell/parsec

7 years agoAdd Parsec dependencie
Samir Benmendil [Sat, 13 Jan 2018 22:22:28 +0000 (22:22 +0000)]
Add Parsec dependencie

This is a Parser module that will be used in the project.

`stack` makes it quite easy to add dependencies. Simply change the
`dependencies` list in `package.yaml` and run `stack build` again. Any
missing modules will be installed.

7 years agoReading input from stdin
Samir Benmendil [Sat, 13 Jan 2018 22:07:28 +0000 (22:07 +0000)]
Reading input from stdin

Introducing `getLine` which reads the next line from stdin.

7 years agoPrint the sum of two arguments
Samir Benmendil [Sat, 13 Jan 2018 22:06:26 +0000 (22:06 +0000)]
Print the sum of two arguments

`read`'s type is defined as `read :: (Read a) => String -> a`, i.e.
`read` takes as `String` and returns an `a` (number?). I don't know what
`=>` means. (`(Read a)` is an instance of class Read ?)

`show`'s type is a bit more complicated it seems as it has multiple
instances for various types of input. But in essence it takes a type and
returns a `String`.

7 years agoRead two arguments from commandline
Samir Benmendil [Sat, 13 Jan 2018 21:59:14 +0000 (21:59 +0000)]
Read two arguments from commandline

`!!` is the "list indexing" operator. It returns the value in the list
on the lhs at the index on the rhs.

`++` concatenates two lists.

A string is a list of chars.

7 years agoHello World with argument
Samir Benmendil [Sat, 13 Jan 2018 21:56:06 +0000 (21:56 +0000)]
Hello World with argument

This will simply print "Hello, " followed by the first argument from the
commandline.

Every Haskell program needs to have a main "action" in the Main module.
This is the entry point.

Files starting with `module <Foo>` will be part of the `Foo` module.

By convention modules are capitalized and definitions aren't.

`import System.Environment` provides `getArgs` to access cli arguments.

Haskell is strongly typed and types may be assigned with `::`. In this case
`main` is of type `IO ()` which is an IO action holding no information.
(more on that later hopefully, as I don't fully understand that.)

7 years agoNew project
Samir Benmendil [Sat, 13 Jan 2018 21:28:41 +0000 (21:28 +0000)]
New project

This project was generated by `stack new`. Some files are obviously not
in use yet, or simply wrong.

7 years agoRoot Commit
Samir Benmendil [Sat, 13 Jan 2018 20:45:07 +0000 (20:45 +0000)]
Root Commit