Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/joakimthun/elsa
The Elsa Programming Language
https://github.com/joakimthun/elsa
bytecode compiler elsa-programming-language interpreter language pratt-parser programming-language virtual-machine
Last synced: about 1 month ago
JSON representation
The Elsa Programming Language
- Host: GitHub
- URL: https://github.com/joakimthun/elsa
- Owner: joakimthun
- License: mit
- Created: 2015-09-08T16:37:40.000Z (over 9 years ago)
- Default Branch: master
- Last Pushed: 2017-04-02T19:26:20.000Z (almost 8 years ago)
- Last Synced: 2023-08-11T15:34:52.716Z (over 1 year ago)
- Topics: bytecode, compiler, elsa-programming-language, interpreter, language, pratt-parser, programming-language, virtual-machine
- Language: C++
- Homepage:
- Size: 682 KB
- Stars: 17
- Watchers: 3
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: license
Awesome Lists containing this project
README
## The Elsa Programming Language
A statically typed, garbage collected language that runs on a custom stack based vm.
Elsa is written just for fun(and educational purposes) and is not really intended for actual use.#### Examples:
[Bouncy](../master/src/examples/bouncy): A Breakout clone written in Elsa
![alt tag](https://raw.githubusercontent.com/joakimthun/Elsa/master/src/examples/bouncy.png)#### Running Bouncy
Download the latest release from [here](https://github.com/joakimthun/Elsa/releases).
Then just run "elsa bouncy/main.elsa" from the command line#### Language features:
###### Basic functions
```
// The main function is the entry point of all Elsa programs and is always required
fn main() {
}
// A function that takes no arguments and returns void
fn hello() {
PrintLn("Hello world!");
}
// A function that takes an integer argument and returns an integer
fn returnInt(int x) : int {
return x;
}
```When passing arguments to functions all built-in types are passed by value while structs and arrays are passed by reference(pointers)
###### Closures
```
// All types of functions(including member functions) in Elsa are treated as any other
// "object" and can be passed around and assigned to variables.
// If a functions uses any variables or fields from the context in which it was declared
// the function will keep a reference to that variable or field
var x = 10;
// A function that takes no arguments and returns the integer captured from the outer scope
var ret = fn : int => { return x; };
// A function that takes no arguments, returns void and increments the captured variable by 1
var inc = fn => { x = x + 1; };
inc(); // x is now 11
PrintLn(ret()); // Prints 11
// A function that takes another function(taking no arguments and returns void) as an argument
// and invokes the passed function twice
fn callTwice(fn f) {
f();
f();
}
callTwice(inc); // callTwice will call our inc function twice
PrintLn(ret()); // Prints 13
PrintLn(x); // Prints 13
```###### Variables and built-in types
```
int i = 0;
int h = 0xffff;
float f = 0.0;
char c = '0';
bool t = true;
byte b = byte(0);
byte b2 = byte(0xff);
// Variables can also be declared by using the var keyword
// and letting the compiler infer the type
var x = 15; // int
// All built-in types in Elsa have default values
int: 0
float: 0.0
char: '\0'
byte: 0
// Array and struct instances will be null pointers if not instantiated
// with the new keyword (see the struct section)
```###### Strings
```
// The String struct in Elsa is very incomplete but has some basic functionality// Creating new string instances
var str = "Hello World!";
var first = "123";
var second = "123";// Retrives a char at the specified index
str.CharAt(1) // e
// Returns the length of the string as an integer
str.Length() // 12// Comparing strings, the String struct define its own Equals-function
// see the Structs section for more info
first.Equals(second)); // true
first == second; // true
first != second; // false
// Concatenating strings
var third = first.Concat(second); // third == "123123"
// Substring, substring takes 2 integer arguments
// the start index and the number of chars to grab
third.Substring(0, 3); // "123"
```The source code for the String struct can be found [here](../master/src/std/string.elsa)
###### Type conversions
```
var floatToInt = int(10.0);
var intToFloat = float(10);
var intToChar = char(33);
var charToInt = int('!');
var intToByte = byte(10);
```###### Operators and precedence
```
var x1 = (3 + 5) * 6; // 48
var x2 = (3 + 5) * (6 + 8); // 112
var x3 = (3 + 5 * 6) * 6; // 198
var x4 = (3 + 5 / (1 * 6)) * (6 + 8 * (2 - 1)); // 42
var x5 = true || (true && false); // true
var x6 = (true && false) || (false || false); // false
var x7 = (1 == 1 && 2 == 2) && (7 == 8 || 0 != 8); // true
var x8 = 10 % 3; // 1
// Binary operators
x << 1;
x >> 1;
x | y;
x & y;
byte x1 = 0xFF;
byte y1 = 0xFF;
var r = (int(x1) << 8) | int(y1); // 65535
```###### Arrays
```
var arr = new int[10]; // An array of integers with an intial capacity of 10
var arr2 = new [1, 2, 3, 4, 5, 6]; // Arrays can also be defined by using array literals
// Array member functions
arr.Push(1); // Adds the integer 1 to the back of the array
arr.Pop(); // Pops the last element in the array, pop returns the popped element
arr.Length(); // Returns the array length
// Array operators
arr[2]; // Access the element at index 2 in the array
```###### Branching
```
if(x == 10) {
PrintLn("x == 10");
}
else {
// The else block can be omitted
PrintLn("x == 10");
}
```###### Loops
```
for(var i = 0; i < arr.Length(); i++)
{
PrintLn(arr[i]);
}
while(y || x) {
PrintLn("Loopy loop");
}
```###### Structs
```
struct Bitmap {
// Fields are declared like this
byte[] data;
int width;
int height;// Member functions are declared like any other function but inside a struct declaration
fn GetPixel(int x, int y) : Color {
var stride = 4;
var base = stride * x * width + y * stride;
return new Color { R: data[base], G: data[base + 1], B: data[base + 2], A: data[base + 3] };
}
// The Equals-function is special. If two struct instances(of the same type) are compared with the
// == operator the Equals-function is automatically called.
// If no Equals-function is declared, a check for reference equality is done
fn Equals(Bitmap other) : bool {
return true;
}
};
struct Color {
byte R;
byte G;
byte B;
byte A;
};
// Struct instances are created by using the new keyword
var red = new Color;
// Elsa also supports initializer lists
var red = new Color { R: 0xFF, G: o, B: o, A: 0xFF };
```###### Enums
```
// Enums in Elsa are just integers converted by the compiler at compile time
enum Enum {
Zero, // 0
Three = 3, // 3
Four, // 4
Seven = 7 // 7
};
```###### Working with multiple source files
```
// Including stuff from other .elsa source files is done with the use keyword
use "std/io";fn main() {
PrintLn(z);
}
```###### Standard library
Elsa has a very small standard library with basic functions for printing stuff to the console,
opening a window(and drawing basic shapes), reading files etc.All standard library functions and structs can be found [here](../master/src/std)
#### Building and OS support
Elsa only runs on Windows(at least right now) and has only been tested with the Visual C++ Compiler###### Example VM-program:
```
// factorial (10)
iconst, 1,
l_arg, 0,
br_ineq, 9,
iconst, 1,
ret,
l_arg, 0,
l_arg, 0,
iconst, 1,
isub,
call, 0,
imul,
ret,// main
iconst, 10,
call, 0,
halt
```