- WindLang, A simple programming language built with golang π
- What is wind?
- Playground
- Cool but why?
- Why Golang, not Rust?
- How to use it?
- So what can it do?
- Hello world?
- Variables
- Data types
- Arrays
- Array.push(element) -> any[]
- Array.pop() -> any
- Array.removeAt(index) -> any
- Array.len() -> int
- Array.join(separator) -> string
- Array.map(function) -> any[]
- Array.filter(function) -> any[]
- Array.reduce(fn(accumulator, element), initialValue) -> any
- Array.contains(function) -> boolean
- Array.count(function) -> int
- Array.clone() -> any[]
- Strings
- String.len(separator) -> int
- String.charAt(index) -> string
- String.contains(substr) -> boolean
- String.containsAny(substr) -> boolean
- String.count(substr) -> string
- String.replace(old, new) -> string
- String.replaceAll(old, new) -> string
- String.replaceN(old, new, n) -> string
- String.changeAt(index, new) -> string
- String.indexOf(substr) -> int
- String.lastIndexOf(substr) -> int
- String.split(separator) -> string[]
- String.trim() -> string
- String.toLowerCase() -> string
- String.toUpperCase() -> string
- Functions
- Closures
- If expressions
- Include statement
- For loops
- While loops
- HashMaps
- Todos
Wind is an interpreted language written in golang.
The easiest way to play with WindLang is to use the playground
I'm working on this as a side project and it's the 5th attempt at writing my own programming language, And it got me my first job too! it's awesome π
I already tried to build this with Rust, but I battled a lot with the Rust compiler and felt like golang is a better middle ground I got so much faster with golang, and it was surprising that the golang implementation was actually faster! Not because golang is faster than rust, it's my lack of knowledge, and the way I code is not "Rusty"
Head up to the releases page and download Wind for your operating system
And execute windlang executable
WindLang, A simple programming language written in golang
Usage:
windlang [command]
Available Commands:
completion Generate the autocompletion script for the specified shell
help Help about any command
run Run a Wind script
Flags:
-h, --help help for windlang
-t, --toggle Help message for toggle
Use "windlang [command] --help" for more information about a command.
This is the Wind cli you can use the run command to run a Wind script file Install the vscode extension here!
Let me demonstrate the features implemented as of now
println("Hello world");Yes, Wind can print Hello world, Surprising huh?
let x = 1;
println(x); // 1
x = "Hello world";
println(x); // Hello WorldYou can declare variables in Wind with the let keyword, Variables in wind are dynamically typed and you can reassign them to any type.
1 // int
3.14 // float
true, false // boolean
nil // null
"Hello World" // String
[1, "2", true] // Arrays
{
"name": "Youssef",
"age": 18
} // HashMapslet arr = [1, "2", true];
println(arr[0]); // 1
println(arr[1]); // 2
println(arr[2]); // true
arr.push("3") // [1, "2", true, "3"]
println(arr[3]); // 3
arr.pop() // [1, "2", true]Arrays in Wind can take any type of data, and can be of any size
You can append to an array by using the append function
You can remove an element by index using the remove function.
let x = [1, 2, 3];
x.push(4) // [1, 2, 3, 4]Array push function adds an element to the end of the array
let x = [1, 2, 3, 4];
x.push(4); // [1, 2, 3, 4]
let y = x.pop(); // [1, 2, 3]
println(y); // 4Array pop function removes the last element of the array and returns it
let x = [1, 2, 3, 4];
x.push(4); // [1, 2, 3, 4]
let y = x.removeAt(3); // [1, 2, 3]
println(y); // 4Array removeAt function removes an element at the index of the array and returns it
let x = [1, "hi", true];
println(x.len()); // 3Array len function returns the length of the array
let x = [1, "hi", 3, 4];
println(x.join("-")); // 1-hi-3-4Array join function returns a string with all the elements of the array separated by the separator
let x = [1, 2, 3];
println(x.map(fn(x) {x * 2})); // [2, 4, 6]Array map function applies the function to each element of the array and returns a new array with the results
let x = [1, 2, 3, 4];
let even = x.filter(fn(x) { x % 2 == 0});
println(even); // [2, 4]]Array filter function applies the function to each element of the array and if the function returns true, the element is added to the new array
let x = [1, 2, 3, 4, 5];
let sum = x.reduce(fn(acc, x) { acc + x}, 0);
println(sum); // 15Array reduce function applies the function to each element of the array and returns a single value
let arr = [1, 3, 5];
println(arr.contains(fn(x) { x % 2 == 0})); // false
arr = [1, 2, 3, 4, 5];
println(arr.contains(fn(x) { x % 2 == 0})); // trueArray contains function applies the function to each element of the array and returns true if the function returns true for any element
let arr = [1, 3, 5];
println(arr.count(fn(x) { x % 2 == 0})); // 0
arr = [1, 2, 3, 4, 5];
println(arr.count(fn(x) { x % 2 == 0})); // 2Array count function applies the function to each element of the array and returns the number of times the function returns true
let x = [1, 2, 3];
let notCloned = x;
let cloned = x.clone();
x[0] = "changed";
println(notCloned[0]); // Changed
println(cloned[0]); // 1Array clone function returns a copy of the array
Strings in Wind start and end with a double quote " and can contain any character and can be multi-line
let x = "Hello";
println(x.len()); // 5String len function returns the length of the string
let name = "youssef";
println(name.charAt(0)); // yString charAt function returns the character at the specified index
let name = "youssef";
println(name.contains("ss")); // trueString contains function returns true if the string contains the exact substring
let vowels = "aeiou";
let name = "youssef";
println(name.containsAny(vowels)); // trueString contains function returns true if the string contains any character of the substring
let name = "youssef";
println(name.count("s")); // 2String count function returns the number of times the substring appears in the string
let name = "John Doe";
println(name.replace("o", "x")); // Jxhn DoeString replace function returns a new string after replacing one old substring with a new substring
let name = "John Doe";
println(name.replaceAll("o", "x")); // Jxhn DxeString replace function returns a new string after replacing all old substring with a new substring
let name = "Youssef";
println(name.replaceN("s", "x", 1)); // Youxsef
println(name.replaceN("s", "x", 2)); // YouxxefString replace function returns a new string after replacing n of old substring with a new substring
let name = "Ahmed";
println(name.changeAt(0, "a")); // ahmedString changeAt function returns a new string after changing the character at the specified index
let name = "John Doe";
println(name.indexOf("o")); // 1String indexOf function returns the index of the first occurrence of the substring
let name = "John Doe";
println(name.lastIndexOf("o")); // 6String indexOf function returns the index of the last occurrence of the substring
let name = "Youssef Ahmed";
let names = name.split(" "); // ["Youssef", "Ahmed"]
let firstName = names[0];
let lastName = names[1];
println("First name is: " + firstName); // First name is: Youssef
println("Last name is: " + lastName); // Last name is: AhmedString join function returns an array of strings by splitting the string by the separator
let name = " John Doe ";
println(name.trim()); // "John Doe"String trim function removes whitespace from the start/end of the string and returns a new string
let name = "JoHn dOe";
println(name.toLowerCase()); // john doeString toLowerCase function returns a new string with all the characters in lower case
let name = "JoHn dOe";
println(name.toUpperCase()); // JOHN DOEString toLowerCase function returns a new string with all the characters in upper case
let add = fn(x, y) { x + y; };
// This is the same as
let add = fn(x, y) {
return x + y;
};
println(add(1, 2)); // 3Yes, this looks like Rust functions. The last expression in a function is implicitly returned
let addConstructor = fn(x) {
fn(y) {
x + y;
};
};
// This is the same as
let addConstructor = fn(x) {
return fn(y) {
return x + y;
};
};
let addTwo = addConstructor(2); // This will return a function
println(addTwo(3)); // 5This is one of the coolest things implemented in Wind. As I said functions in Wind are expressions, so you can return a function or pass a function to another function.
let welcome = fn(name, greeter) {
greeter() + " " + name
};
let greeter = fn() { "Hello π"};
println(welcome("Wind π", greeter)); // Hello π Wind π// Use if as an expression
let grade = 85;
let msg = if (grade > 50) { "You passed" } else { "You didn't pass" };
println(msg); // You passed
// Or use if as a statement
if (grade > 50) {
println("You passed");
} else {
println("You didn't pass");
}As you can see here we can use it as an expression or as a statement
Note that after any expression the semicolon is optional. We can type "You passed"; or "You passed" and it will implicitly return it
// test.wind
let msg = "Hello π";
let greeter = fn() {
println(msg);
};// main.wind
include "./test.wind";
greeter(); // Hello π
// You can also alias includes
include "./test.wind" as test;
test.greeter(); // Hello πInclude statements allow you to include other Wind scripts, It initializes them once and can be used by multiple files at the same time while preserving state.
let names = ["Youssef", "Ahmed", "Soren", "Morten", "Mads", "Jakob"];
for (let i = 0; i < len(names); i++) {
println("Hello " + names[i]);
}
// Hello Youssef
// Hello Ahmed
// Hello Soren
// Hello Morten
// Hello Mads
// Hello Jakoblet x = 0;
while (x < 5) {
println(x);
x++;
}
// 0
// 1
// 2
// 3
// 4let person = {
"name": "Youssef",
"age": 18,
"incrementAge": fn() {
person.age++;
}
};
println(person["name"]); // Youssef
println(person.age); // 18
person.incrementAge();
println(person.age); // 19Hashmaps are like js object and can store key value pairs, Keys can be integers, strings and booleans. Values can be any type.
-
Named include statements -
HashMaps (Javascript objects -
A bytecode interpreter maybe
