Fixed structure a bit

This commit is contained in:
sebastian 2023-04-02 13:46:46 +02:00
parent 03a486410f
commit 6a2ebf4ecd

View file

@ -1,6 +1,7 @@
# Build # Build
First generate the parser using [BNFC](https://bnfc.digitalgrammars.com/), First generate the parser using [BNFC](https://bnfc.digitalgrammars.com/),
this is done using the command `bnfc -o src -d Grammar.cf` this is done using the command `bnfc -o src -d Grammar.cf`
Churf can then be built using `cabal install` Churf can then be built using `cabal install`
Using the tool [make](https://www.gnu.org/software/make/) the entire thing can be built by running `make` Using the tool [make](https://www.gnu.org/software/make/) the entire thing can be built by running `make`
@ -9,6 +10,7 @@ If [just](https://github.com/casey/just) is preferred then run `just build`
# Compiling a program # Compiling a program
Using the Hindley-Milner type checker: `./language -t hm example.crf` Using the Hindley-Milner type checker: `./language -t hm example.crf`
Using the bidirectional type checker: `./language -t bi example.crf` Using the bidirectional type checker: `./language -t bi example.crf`
# Syntax and quirks # Syntax and quirks
@ -42,7 +44,8 @@ test = 0 ;
A bind is a name followed by a white space separated list of arguments, then an equal sign followed by an expression. A bind is a name followed by a white space separated list of arguments, then an equal sign followed by an expression.
Both name and arguments have to start with lower case letters Both name and arguments have to start with lower case letters
`Bind ::= LIdent [LIdent] "=" Exp
`Bind ::= LIdent [LIdent] "=" Exp`
```hs ```hs
example x y = x + y ; example x y = x + y ;
@ -51,6 +54,7 @@ example x y = x + y ;
## Signature ## Signature
A signature is a name followed by a colon and then the type A signature is a name followed by a colon and then the type
The name has to start with a lowe case letter The name has to start with a lowe case letter
`Sig ::= LIdent ":" Type` `Sig ::= LIdent ":" Type`
```hs ```hs
@ -65,7 +69,7 @@ A data type is declared as follows
The words in quotes are necessary keywords The words in quotes are necessary keywords
The type can be any type for parsing, but only `TData` will type check. The type can be any type for parsing, but only `TData` will type check.
The list of inj is separated by white space. Using new lines is recommended for ones own sanity. The list of Inj is separated by white space. Using new lines is recommended for ones own sanity.
```hs ```hs
@ -93,9 +97,13 @@ data types have to start with an upper case letter, a function type is two types
and foralls take one type variable followed by a type. and foralls take one type variable followed by a type.
`TLit ::= UIdent` `TLit ::= UIdent`
`TVar ::= LIdent` `TVar ::= LIdent`
`TData ::= UIdent "(" [Type] ")"` `TData ::= UIdent "(" [Type] ")"`
`TFun ::= Type "->" Type` `TFun ::= Type "->" Type`
`TAll ::= "forall" LIdent "." Type` `TAll ::= "forall" LIdent "." Type`
```hs ```hs
@ -111,57 +119,68 @@ exampleAll : forall a. forall b. a -> b ;
There are a couple different expressions, probably best explained by their rules There are a couple different expressions, probably best explained by their rules
Type annotated expression Type annotated expression
`EAnn ::= "(" Exp ":" Type ")"` `EAnn ::= "(" Exp ":" Type ")"`
Variable Variable
`EVar ::= LIdent` `EVar ::= LIdent`
```hs ```hs
x x
``` ```
constructor Constructor
`EInj ::= UIdent` `EInj ::= UIdent`
```hs ```hs
Just Just
``` ```
Literal Literal
`ELit ::= Lit` `ELit ::= Lit`
```hs ```hs
0 0
``` ```
Function application Function application
`EApp ::= Exp2 Exp3` `EApp ::= Exp2 Exp3`
```hs ```hs
f 0 f 0
``` ```
Addition Addition
`EAdd ::= Exp1 "+" Exp2` `EAdd ::= Exp1 "+" Exp2`
```hs ```hs
3 + 5 3 + 5
``` ```
Let expression Let expression
`ELet ::= "let" Bind "in" Exp ` `ELet ::= "let" Bind "in" Exp `
```hs ```hs
let f x = x in f 0 let f x = x in f 0
``` ```
Abstraction, known as lambda or closure Abstraction, known as lambda or closure
`EAbs ::= "\\" LIdent "." Exp` `EAbs ::= "\\" LIdent "." Exp`
```hs ```hs
\x. x \x. x
``` ```
Case expression consist of a list semicolon separated list of Branches Case expression consist of a list semicolon separated list of Branches
`ECase ::= "case" Exp "of" "{" [Branch] "}"` `ECase ::= "case" Exp "of" "{" [Branch] "}"`
```hs ```hs
case xs of { case xs of {
Cons x xs => 1; Cons x xs => 1;
Nil => 0; Nil => 0;
}; };
```
### Branch ### Branch
A branch is a pattern followed by the fat arrow and then an expression A branch is a pattern followed by the fat arrow and then an expression
@ -173,31 +192,41 @@ A pattern can be either a variable, literal, a wildcard represented by `_`, an e
, or a constructor followed by a recursive list of patterns. , or a constructor followed by a recursive list of patterns.
Variable match Variable match
`PVar ::= LIdent` `PVar ::= LIdent`
The x in the following example The x in the following example
```hs ```hs
x => 0 x => 0
``` ```
Literal match Literal match
`PLit ::= Lit` `PLit ::= Lit`
The 1 in the following example The 1 in the following example
```hs ```hs
1 => 0 1 => 0
``` ```
A wildcard match A wildcard match
`PCatch ::= "_"` `PCatch ::= "_"`
The underscore in the following example The underscore in the following example
```hs ```hs
_ => 0 _ => 0
``` ```
A constructor without arguments A constructor without arguments
`PEnum ::= UIdent` `PEnum ::= UIdent`
The Nothing in the following example The Nothing in the following example
```hs ```hs
Nothing => 0 Nothing => 0
``` ```
The recursive match on a constructor The recursive match on a constructor
`PInj ::= UIdent [Pattern1]` `PInj ::= UIdent [Pattern1]`
The outer Just represents the UIdent and the rest is the recursive match The outer Just represents the UIdent and the rest is the recursive match
```hs ```hs
Just (Just 0) => 1 Just (Just 0) => 1