Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/burz/cfl
a Compileable statically typed Functional programming Language
https://github.com/burz/cfl
compiler functional-programming interpreter llvm
Last synced: 3 months ago
JSON representation
a Compileable statically typed Functional programming Language
- Host: GitHub
- URL: https://github.com/burz/cfl
- Owner: burz
- License: mit
- Created: 2014-12-31T09:56:27.000Z (almost 10 years ago)
- Default Branch: master
- Last Pushed: 2015-06-11T18:41:30.000Z (over 9 years ago)
- Last Synced: 2024-07-19T17:42:25.840Z (4 months ago)
- Topics: compiler, functional-programming, interpreter, llvm
- Language: C
- Homepage:
- Size: 1.16 MB
- Stars: 10
- Watchers: 3
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- AwesomeInterpreter - cfl
README
cfl
===================================Author: Anthony Burzillo
******
cfl (standing for C-based Functional Language) is a statically typed
functional programming language.## Usage
To see the usage simply run `./cfl`. If LLVM is already installed (can be installed by running
`brew install llvm` or `apt-get install llvm`, etc.) then the usage will be
```
$ ./cfl
USAGE: cfl filename :: compile the program
-ast filename :: print the AST of the program
-type filename :: print the high level types of the program
-deep filename :: print all the types of the program
-eval filename :: evaluate the program
-ll filename :: print out the llvm code for the program
-asm filename :: print out native assembly code for the program
-jit filename :: evaluate the program using Just-In-Time compiling
```
Note that you can still run cfl without LLVM but you will not have LLVM related options like
-jit or compilation.## Example
Obligatory hello world:
```
main = "hello world!"
```
Note that every cfl program must end with a `main` and global definitions are followed by
a semicolon.The quicksort algorithm can be written in cfl as
```
split x xs l r = case xs of
[] -> (l, r)
| (y : ys) -> let (l', r') = split x ys l r in if y <= x
then (y : l', r')
else (l', y : r');quicksort x = case x of
[] -> []
| (y : ys) -> let (l, r) = split y ys [] []
in quicksort l ++ y : quicksort r;// random x is a globally defined function returning a random integer
// between 0 and x inclusive
random_list x l = if x == 0 then [] else random l : random_list (x - 1) l;main = quicksort $ random_list 100 500
```Running `./cfl -ast` will output
```
split ::= function ~F0 -> (let rec split x = (function xs -> (function l -> (function r -> (case (xs) of [] -> ((l, r)) | (y : ys) -> ((function (l', r') -> (if (((y) < (x)) || ((y) == (x))) then (((y) : (l'), r')) else ((l', (y) : (r'))))) (((((split) (x)) (ys)) (l)) (r))))))) in ((split) (~F0)))
quicksort ::= function ~F1 -> (let rec quicksort x = (case (x) of [] -> ([]) | (y : ys) -> ((function (l, r) -> (((quicksort) (l)) ++ ((y) : ((quicksort) (r))))) (((((split) (y)) (ys)) ([])) ([])))) in ((quicksort) (~F1)))
random_list ::= function ~F2 -> (let rec random_list x = (function l -> (if ((x) == (0)) then ([]) else (((random) (l)) : (((random_list) ((x) + ((-1) * (1)))) (l))))) in ((random_list) (~F2)))
main ::= (quicksort) (((random_list) (100)) (500))
```Running `./cfl -type` will output
```
split => (Integer -> ([Integer] -> ([Integer] -> ([Integer] -> ([Integer], [Integer])))))
quicksort => ([Integer] -> [Integer])
random_list => (Integer -> (Integer -> [Integer]))
main => [Integer]
```Running `./cfl -deep` will output
```
split ~>> function (~F0 :: Integer) -> (let rec (split :: (Integer -> ([Integer] -> ([Integer] -> ([Integer] -> ([Integer], [Integer])))))) (x :: Integer) = (function (xs :: [Integer]) -> (function (l :: [Integer]) -> (function (r :: [Integer]) -> (case (xs :: [Integer]) of [] -> ((l :: [Integer], r :: [Integer]) :: ([Integer], [Integer])) | ((y :: Integer) : (ys :: [Integer])) -> ((function ((l' :: [Integer], r' :: [Integer]) :: ([Integer], [Integer])) -> (if (((y :: Integer) < (x :: Integer) :: Bool) || ((y :: Integer) == (x :: Integer) :: Bool) :: Bool) then (((y :: Integer) : (l' :: [Integer]) :: [Integer], r' :: [Integer]) :: ([Integer], [Integer])) else ((l' :: [Integer], (y :: Integer) : (r' :: [Integer]) :: [Integer]) :: ([Integer], [Integer])) :: ([Integer], [Integer])) :: (([Integer], [Integer]) -> ([Integer], [Integer]))) (((((split :: (Integer -> ([Integer] -> ([Integer] -> ([Integer] -> ([Integer], [Integer])))))) (x :: Integer) :: ([Integer] -> ([Integer] -> ([Integer] -> ([Integer], [Integer]))))) (ys :: [Integer]) :: ([Integer] -> ([Integer] -> ([Integer], [Integer])))) (l :: [Integer]) :: ([Integer] -> ([Integer], [Integer]))) (r :: [Integer]) :: ([Integer], [Integer])) :: ([Integer], [Integer])) :: ([Integer], [Integer])) :: ([Integer] -> ([Integer], [Integer]))) :: ([Integer] -> ([Integer] -> ([Integer], [Integer])))) :: ([Integer] -> ([Integer] -> ([Integer] -> ([Integer], [Integer]))))) in ((split :: (Integer -> ([Integer] -> ([Integer] -> ([Integer] -> ([Integer], [Integer])))))) (~F0 :: Integer) :: ([Integer] -> ([Integer] -> ([Integer] -> ([Integer], [Integer]))))) :: ([Integer] -> ([Integer] -> ([Integer] -> ([Integer], [Integer]))))) :: (Integer -> ([Integer] -> ([Integer] -> ([Integer] -> ([Integer], [Integer])))))
quicksort ~>> function (~F1 :: [Integer]) -> (let rec (quicksort :: ([Integer] -> [Integer])) (x :: [Integer]) = (case (x :: [Integer]) of [] -> ([] :: [Integer]) | ((y :: Integer) : (ys :: [Integer])) -> ((function ((l :: [Integer], r :: [Integer]) :: ([Integer], [Integer])) -> (((quicksort :: ([Integer] -> [Integer])) (l :: [Integer]) :: [Integer]) ++ ((y :: Integer) : ((quicksort :: ([Integer] -> [Integer])) (r :: [Integer]) :: [Integer]) :: [Integer]) :: [Integer]) :: (([Integer], [Integer]) -> [Integer])) (((((split :: (Integer -> ([Integer] -> ([Integer] -> ([Integer] -> ([Integer], [Integer])))))) (y :: Integer) :: ([Integer] -> ([Integer] -> ([Integer] -> ([Integer], [Integer]))))) (ys :: [Integer]) :: ([Integer] -> ([Integer] -> ([Integer], [Integer])))) ([] :: [Integer]) :: ([Integer] -> ([Integer], [Integer]))) ([] :: [Integer]) :: ([Integer], [Integer])) :: [Integer]) :: [Integer]) in ((quicksort :: ([Integer] -> [Integer])) (~F1 :: [Integer]) :: [Integer]) :: [Integer]) :: ([Integer] -> [Integer])
random_list ~>> function (~F2 :: Integer) -> (let rec (random_list :: (Integer -> (Integer -> [Integer]))) (x :: Integer) = (function (l :: Integer) -> (if ((x :: Integer) == (0 :: Integer) :: Bool) then ([] :: [Integer]) else (((random :: (Integer -> Integer)) (l :: Integer) :: Integer) : (((random_list :: (Integer -> (Integer -> [Integer]))) ((x :: Integer) + ((-1 :: Integer) * (1 :: Integer) :: Integer) :: Integer) :: (Integer -> [Integer])) (l :: Integer) :: [Integer]) :: [Integer]) :: [Integer]) :: (Integer -> [Integer])) in ((random_list :: (Integer -> (Integer -> [Integer]))) (~F2 :: Integer) :: (Integer -> [Integer])) :: (Integer -> [Integer])) :: (Integer -> (Integer -> [Integer]))
main ~>> (quicksort :: ([Integer] -> [Integer])) (((random_list :: (Integer -> (Integer -> [Integer]))) (100 :: Integer) :: (Integer -> [Integer])) (500 :: Integer) :: [Integer]) :: [Integer]
```Running `./cfl -eval` or `./cfl -jit`, or running `./cfl program.cfl` and then `./program` will output something like
```
[0, 1, 3, 8, 14, 15, 16, 17, 25, 32, 37, 38, 40, 46, 61, 61, 64, 77, 80, 106, 108, 110, 111, 113, 121, 127, 134, 134, 137, 144, 149, 151, 158, 160, 165, 177, 179, 180, 188, 192, 196, 200, 201, 202, 212, 216, 218, 220, 223, 230, 236, 239, 239, 244, 251, 253, 265, 269, 281, 294, 301, 304, 308, 315, 323, 332, 334, 356, 359, 372, 373, 374, 375, 375, 383, 385, 387, 392, 393, 397, 398, 399, 402, 412, 420, 425, 431, 433, 438, 440, 441, 445, 452, 454, 459, 474, 482, 488, 489, 495]
```## Expressions
### Basic types
The basic types of cfl are bools (`true` or `false`), integers (`0, 1, -1, ...`), and
characters (`'q'`).### Boolean Operations
cfl allows conjunction (`&&`), disjunction (`||`), and negation (`!`) expressions.
### Integer Operations
The operations of addition (`+`), subtraction (`-`), multiplication (`*`), division
(`/`), and modulus (`%`) evaluate to integer values. On the other hand, the comparison
operators of equality (`==`), inequality (`!=`), less-than (`<`), less-than-or-equal
(`<=`), greater-than (`>`), and greater-than-or-equal (`>=`) all evaluate to boolean
values.### Functional Operations
cfl allows the creation of anonymous functions via `function x -> e` where `e` is some
expression, and `x` is the argument to the function. We can create multiple argument
anonymous functions via `function x -> function y -> e` where `x` is
the first argument and `y` is the second, etc.To apply a function `f` simply use `f e` where `e` is the expression for the first
argument, or `f e1 e2` for the first argument `e1` and second argument `e2`. Similary
one can use `f $ x` to apply the entire right side of the `$` to `f`.Finally, one can compose two functions `f . g`.
```
g a = if a then 5 else 4;
f b = b == 5;
main = f . g $ true
```### If Expressions
Use `if e1 then e2 else e3`.
### Let Expressions
cfl allows let expressions to define constants and functions (possibly recursive) via
```
let x = 4 in x + 54
```
and
```
let f x y = if x = 0 then 0 else y + f (x - 1) y in f 3 4
```### Tuple Expressions
Tuples of arbitrary size can be created via `(true, false, [0], 1, [false])`.
Anything but a function name can be matched to a tuple in `let` statements, for instance
```
let (x, y) = (1, 2) in x + y
let f (x, y) = x + y in f 0 1
```
are both valid.### List Expressions
You can create empty lists `[]` or lists with values `[1, 2, 3, 4]`. You can push
values onto a list via
```
5 : [4, 5, 6]
```
You can also concatenate lists
```
[1, 2] ++ [3, 4]
```
Finally, we can match on lists via a case expression via
```
case e1 of [] -> e2 | (x : xs) -> e3
```### String Expressions
Strings are implemented as lists of characters, therefore characters can be pushed onto
strings and two strings can be concatenated. To create a string one can simply write the
quotation enclosed string, i.e. `"hello world!"`.