Syntax¶
The syntax of Oasis is very simple.
Variable Definitons¶
To define a variable, use the let
keyword.
let foo = 1
To make a constant, use the const
keyword.
let const foo = 1
To assign a new value to a defined variable, no keyword is needed.
let foo = 1
foo = 2
You can also modify a variable’s value by using the different forms of the =
operator.
let foo = 1
foo = 2
foo += 1
foo -= 1
Relative Expressions A relative expression is an expression that is evaluated whenever it’s used. It’s titled so because it’s an expression relative to another.
let foo = 12
rel bar = foo * 2
io:print(bar) // 24
foo = 13
io:print(bar) // 26
A relative expression cannot share a name with a variable. Relative expressions are
Indexing¶
To get a property of something, use :
.
For example:
// JavaScript:
foo.bar // property bar of foo
// oasis:
foo:bar // property bar of foo
To get the index of an array, use :(index)
.
For example:
// JavaScript:
foo[12] // element at index 12 of foo
// oasis:
foo:(12) // element at index 12 of foo
Block Statements¶
For most block statements, a marker for the beginning of a block is not necessary. All blocks must end with the end
keyword.
if 1 == 1
io:print("woah! 1 is equal to 1!!")
end
if 2 == 2
io:print("woah! 2 is equal to 2!!")
else
io:print("woah! 2 is not equal to 2!!")
end
// block passed to a function
5:times do
io:print("hello") // prints "hello" 5 times
end
Literals¶
Oasis has string literals, number literals, boolean literals, list literals, dictionary literals, and char literals.
let foo = "hello"
let bar = 1
let baz = true
let qux = [1, 2, 3]
let quux = {"foo" | "hello", "bar" | 1}
let corge = 'a'
Functions¶
Functions only exist in the form of function literals. These are practically lambdas.
let foo = fn(x)
return x * x
end
// Function with no parameters
let fooBar = fn
// does something or other
end
foo(2) // 4
// You can also pass functions to functions!
let bar = fn(x, y)
return x(y)
end
bar(fn(n) return 1 / n end, 5) // 1/5
// alternatively
bar(fn(n) => 1 / n, 5)
// There is a function shorthand, for single-expression functions.
let square = fn(x) => x * x
Prototypes¶
Prototypes also only exist in literal form.
let foo = proto
x = 2
y = fn(n) => this:x * n
end
io:print(foo:x) // 2
io:print(foo:n(4)) // 8
// Prototypes can also inherit
let bar = proto : foo
z = 5
end
io:print(bar:x) // 2
io:print(bar:y(3)) // 6
io:print(bar:z) // 5
You can clone a prototype with the clone
keyword.
let foo = proto
x = 1
end
let bar = foo
foo:x = 3
io:print(bar:x) // 3
let baz = clone foo
foo:x = 5
io:print(foo:x) // 5
io:print(bar:x) // 5
io:print(baz:x) // 3
Exceptions¶
To run a block of code and catch any exceptions, use the test
keyword.
The catch code goes in the error
block.
test
let foo = 1 / 0
error(e) // you can use '_' to ignore the exception
io:print("woah! I caught an exception!")
end
Loops¶
For loops have two different forms. The first one is the traditional for loop.
for let i = 0 | i < 10 | i += 1
io:print(i)
end
The second one is the iterator for loop. This is a more modern form of for loop.
for i in range(0, 10)
io:print(i)
end
There is also the while loop.
while true
io:print("woah! I'm in a loop!")
end
You can also use the break
keyword to break out of a loop.
while true
io:print("woah! I'm in a loop!")
break
end
You can also use the continue
keyword to skip the rest of the loop.
while true
if true
continue
end
io:print("woah! I'm in a loop!") // this will never print
end
List Comprehensions¶
List comprehensions are syntatic sugar for mapping a function over a list.
let foo = [1, 2, 3, 4, 5]
let bar = {fn(i) => i * 2 of foo} // [2, 4, 6, 8, 10]
Operators¶
Here’s a rundown of all of Oasis’s operators.
Arithmetic
1 + 2 // addition: 3
1 - 2 // subtraction: -1
1 * 2 // multiplication: 2
1 / 2 // division: 0.5
1 % 2 // modulus: 1
Directional evaluation
These are the directional evaluation operators. They are used to evaluate expressions in a specific direction. They are always evaluated left-to-right, but depending on the direction of the arrow, it will return the first or last expression. These are identical to the comma operator in C, but with direction.
1 |> 2 |> 3 // right evaluation: 3
1 <| 2 <| 3 // left evaluation: 1
Comparison
1 == 2 // equality: false
1 != 2 // inequality: true
1 < 2 // less than: true
1 > 2 // greater than: false
1 <= 2 // less than or equal to: true
1 >= 2 // greater than or equal to: false
true and true // logical and: true
true or false // logical or: true
not true // logical not: false
null ? 1 // null coalescing: 1