Hege

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

Blog Home

Hege Programming Language

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

FAQ

What’s the point?

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

What’s this based off of?

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

What’s the deal with types?

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

Can I run this in production?

I mean you can … but please don’t.

What does Hege stand for?

Setting up Hege

Requires

Clone the repo then build using stack.

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

Usage

Launching the REPL

> stack exec hege
λ> 

Usage of REPL

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

Loading and executing Hege file in REPL

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

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.

Data types

Hege supports the following data types

Number operations

λ> (- 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

Parsing Numbers of different bases

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

Float operations

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

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

Numeric comparisons

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

Lists

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

Program flow

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)

Functions and variables

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

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
λ>