View the Project on GitHub alicelambda/HEGE

Implementation- Parser

Language Features

- Overview

- Installation and Usage

- Primitive Functions

- Program Flow

- Defining Functions and Variables

- Input Output functions

Hege is a strongly typed scheme-esque language written in Haskell. Hege is designed to be hackable.

Hege is designed to be a hackable base language for exploration in the world of programming language design.

I used this book as guide for developing my own language.

In Hege you need to explicitly convert between types. Trying to add a float to an int would throw a type error.

I mean you can … but please don’t.

- Hackable
- Extensible
- Generic
- Endofunctor

- git
- stack

Clone the repo then build using stack.

```
git clone https://github.com/alicelambda/HEGE.git
cd HEGE/
stack build
```

```
> stack exec hege
λ>
```

Evaluation of expression

```
λ> (+ 4 4)
8
λ> (define (add x) (+ 1 x))
(function ( params"x") ...)
```

To find the type of a parsed expression prefix it with :t.

```
λ> :t 33
33 :: Number
λ> :t 3.4
3.4 :: Float
λ> :t "hello"
"hello" :: String
λ> :t (+ 3 3)
(+ ∷ Atom, 3 :: Number, 3 :: Number) ∷ List
```

file first.hg

```
-- this is a comment
-- isBig function checks if a number is bigger than 301
(define (isBig x)
(if (> (+ x 1) 300) 'big 'small))
```

using the load function

```
stack exec hege
λ> (load "first.hg")
(function ( params"x") ...)
λ> (isBig 3000)
big
```

Primitive functions in Hege are functions that don’t affect things outside of t heir scope. Primitive functions don’t do any IO so they can’t change things in the outside world. They also don’t change global variables. Calling a primitive function with the same input will always return the same output.

Hege supports the following data types

- Ints
- Floats
- Booleans
- Strings
- Characters
- Lists

```
λ> (- 0 5) //creates negative number
-5
```

Numbers in Hege are whole numbers. The Hege parser doesn’t recognize negative number but you can create them through subtraction. Hege supports the following operations on Numbers.

Function | Affect | Src |
---|---|---|

+ | Additions with any number of terms | # |

- | Subtraction with any number of terms | # |

* | integer multiplication | # |

div | integer division | # |

mod | integer modulus | # |

quotient | returns the quotient from division is negative if divisor is negative | # |

remainder | returns the remainder of division but is positive when divides | # |

Below are some example operations.

```
λ> (+ 2 2)
4
λ> (* 8 8)
64
λ> (- 60 (- 40 20))
40
```

Base | Result | Src |
---|---|---|

#h | parses number as hex and converts into decimal | # |

#o | parses number as octal and converts into decimal | # |

```
λ> #hff
255
λ> #o32
26
```

Floating point numbers are represented as doubles in Hege.

Function | Affect | Src |
---|---|---|

+ | Additions with any number of terms | # |

- | Subtraction with any number of terms | # |

* | floating point multiplication | # |

/ | floating point division | # |

```
λ> (* 9.2 4.5)
41.4
λ> (+ 4.5 5.5)
10.0
λ> (- 40.2 3.4)
36.800000000000004
```

Booleans are represented by #t and #f.

Function | Affect | Src | ||
---|---|---|---|---|

= | Binary equality of two LispVals | # | ||

&& | Binary and of two Boolean values | # | ||

Binary or of two Boolean values | # |

```
λ> (= 3 3)
#t
λ> (= 3.3 3.3)
#t
λ> (= 3.3 2.3)
#f
λ> (= "d" "d")
#t
λ> (|| #t #f)
#t
λ> (&& #t #f)
#f
```

Equality operators act on either Float or Num types they return a Boolean value. Arguments must be either all Floats or all Num.

Function | Affect | Src |
---|---|---|

< | Checks if the first arg is less than the second | # |

> | Checks if the first arg is greater than the second | # |

/= | Checks if the first arg doesn’t equal the second | # |

<= | Checks if the first arg is less than or equal to the second | # |

>= | Checks if the first arg is greater than or equal to the second | # |

```
λ> (> 4 4)
#f
λ> (< 3 3)
#f
λ> (< 3.3 3.3)
#f
λ> (/= 3 4)
#t
λ> (<= 33.3 3.0)
#f
```

Function | Affect | Src |
---|---|---|

head | returns first element of list | # |

tail | returns the remaining elements of list | # |

length | return lengths of a string | # |

```
λ> (head '(1 2 3))
1
λ> (tail '(1 2 3))
(2 3)
λ> (length "hello world")
11
```

Function | Affect | Src |
---|---|---|

if | If statements evaluate their first expression, if the result is true it returns the first expression if not it | # |

returns the second expression. | ||

cond | cond statements takes pairs of conditions and results, if the condition evaluates to true then it | # |

returns the result. If it is false it goes to the next condition value pair. If no conditions match it throws | ||

an error. | ||

case | Case statements evaluate their first argument and then searches through pairs of list of expressions | # |

and results. If a value in an expression matches the first argument it returns the result. If the | ||

argument doesn’t match any expression it goes on to the next expression and result pair. | ||

```
λ> (if (= 3 3) #t #f)
#t
λ> (if (= 4 5) #t #f)
#f
λ> (cond (> 3 3) #f (= 3 3) (* 6 6))
36
λ> (cond (= 3 3) (- 3.0 4.0) (< 3 3) (* 3 6))
-1.0
λ> (cond (= 4 5) #f)
expected 2 args found values "no values"
λ> (case 1 ((1 2 3 4) 'small) ((5 6 7 8) 'big))
(quote small)
λ> (case 8 ((1 2 3 4) 'small) ((5 6 7 8) 'big))
(quote big)
```

Hege allows for use defined functions the keyword define is used followed by a list of containing the function name and parameters. Followed by the function definition.

Function | Parameters | Vars | Src |
---|---|---|---|

define | variable name, form | creates a variable with passed value or sets variable to value | # |

define | function name, parameters, body form | creates a function that takes set parameters and runs it’s body form | # |

set! | variable name, form | sets a predefined variable to a value throws error if variable isn’t defined | # |

```
λ> (define (plusOne x) (+ 1 x))
(lambda ("x"
λ> (plusOne 10)
11
λ> (define x 10)
10
λ> x
10
λ> (define x (+ x 20))
30
λ> x
30
10
λ> (set! x 10)
10
λ> (set! dog 2)
unbound variable: dog
```

IO functions in Hege can read from and write to files.

Function | Definitions | Src |
---|---|---|

open-input-file | returns a file handle that is read only | # |

open-output-file | returns a file handle that is write only | # |

close-input-port | closes a read only file handle | # |

close-output-port | closes a write only file handle | # |

read | reads from a file handle returning a string | # |

write | writes a string to a file | # |

```
λ> (define file (open-output-file "file"))
<IO port>
λ> (write "hello" file)
#t
λ>
```