A Functional Language Interpreter.
- flex[lex] tool
- bison[yacc] tool
- g++ compiler[latest version will be good]
- Linux OS.
- Download zip file from github.
- Unzip it into any directory.
- Go to YAIL-[master]/lib folder
- execute make command. This will create bnK-lang executable in the lib directory.
- Then go to samples folder which contains some simple programs.
- Then execute the following command: ../lib/bnK-lang < file.yail [present in the samples directory.]
- To learn compiler design.
- To understand how computer languages are designed and what it takes to build them.
- To have experience with writing large code base and learn how to maintain it.
- And finally to have fun. It`s really a humbling experience to see writing a simple program in your own language and see it executing on your own machine.
- It is typed.
- Supports basic arithmatic operations.
- Supports basic types like Integers, Float, String, Function and Arrays[only for Integers and Double]
- Supports the creation of functions and nested functions.
- Supports Closure and Currying.
- Supports creation of Threads.
Creating variables in yail language is similar to C or Java. First you need to specify the type and then the name of the variable. Since it is a functional language, all variables that you define must be initialized.
Int num = 12; # statements must end with semicoln.
# or
Double d = 12.34; # To make value double, you need to write "." followed by some number.
# or
String str = "Hello world";
# or
Int[] num = [1, 2, 3, 4];
# or
Double[] num = [1.3, 2.3];
# or
Bool flag = false;
There is no restriction on creation of variables, you can create them where ever you want and whenever you want.
Multiple assignments are not allowed. So following code snippet will through an error and is in accordance with Functional language.
Int a = 12;
a = 34; # error
You can control the flow of your program using good old if, else or elif structure. As in Java the coditional expression must result in boolean value otherwise error will be thrown.
Int a = 12, b = 10;
if(a > b){
print("a is grater\n");
}
else{
print("b is greater\n");
}
else block is compulsory whenever you write if or elif.
Int a = 10, b = 23, c = 25;
if(a > b){
if(a > c){
print("a is greater\n");
}
else{
print("c is greater\n");
}
}
elif(b > c){
print("b is greater\n");
}
else{
print("c is greater\n");
}
yail has only one container object, Arrays. In this language arrays are fixed length and homogeneous, meaning they contain values of the specified type.
Arrays support following operations:
- Indexing
- Concatenation
- Slicing
# array creation
Int[] a = [1, 2, 3, 4, 5];
# concatenation
Int[] b = a + [123, 34];
# slicing
Int[] c = b[1:4];
In yail functions are basic way of creating abstractions. Function block are created using function keyword, followed by name of the function, then optional arguments and the return type followed by statements which you want to execute once the function is called.
function funct_name([Type var,[Type var...]): ReturnType{
# list of statements.
}
# finding square.
function square(Int n):Int{
return n * n;
}
# finding factorial
function fact(Int n):Int{
if(n == 0)
return 1;
else
return n * fact(n - 1);
}
# iterating through an array.
function printArray(Int[] arr):Nothing{
if(arr.length > 0){
print(arr[0], " ");
printArray(arr[1:]);
}
else{
print("\n");
}
}
# simple map implementation.
function map(Int[] arr, Int index, Function f):Int[]{
if(index < arr.length){
return [f(arr[index])] + map(arr, index + 1, f);
}
else{
return [];
}
}
funct_name([arg,[arg..]]);
yail supports nesting functions within function and supports closure to
function outer():Nothing{
function inner():Nothing{
print("Hello world\n");
}
inner();
}
outer();
function nC(Int n):Function{
Int factN = fact(n);
function Cr(Int r):Int{
return factN/(fact(n - r) * fact(r));
}
return Cr;
}
Function _5c = nC(5);
print("5C2: ", _5c(2));
Currying is a technique in which a function is called with few parameters then it officially takes. After this partial application, a new Function object is returned which you can use it to pass left over arguments so that the function finally gets called.
function addThreeNumbers(Int a, Int b, Int c):Int{
return a + b + c;
}
Function add1 = addThreeNumbers(1); # new function object gets returned which is ready to take 'b' and 'c'.
Function add5 = add1(5);
Int result = add5(10); # result = 16
print("Result: ", result);
The samples directory contains a quicksort example, which uses currying concept.
Lots of things needs to be implemented in this project but i believe following are really important which i want to concentrate on.
- Implementing error module.[right now, if you get any error, interpreter just exits or a segmentation fault is thrown]
- Thread scheduling.
- Testing.
I am still working on this project. Comments are really appreciated.
Following People helped me a lot during my project.
-
Ajey Bharadwaj A
-
Gourav H Dhelaria
-
Prof. N S Kumar [our Project Guide]