I have been working with my team, 2Pablos Games. We are currently working on a Scratch game with its game engine, and we are also working on a Roblox framework on the side. In order to introduce various new ideas, I have been working on designing a scripting language called EngineScript, a high-level table-oriented (every object is a table) multi-paradigm language.
The language is still in development, and there's no interpreter yet. Please tell me what you think, and I can respond to questions. To see more examples, check the website, as I will eventually update it to further explain the syntax and semantics.
-- Hello, world!
console.print("Hello, world!")
-- Factorial
local fact = [n]{
-- not(order(n, 0)); not n > 0; n <= 0
-- *(number, fact(-(number, 1)))) == n * fact(n - 1)
check(not(order(n, 0)), 1, *(n, fact(-(n, 1))))
}; console.print(fact(5))
-- Fibonacci
local fib = [n]{
-- +(fib(-(n, 1)), fib(-(n, 2))) == fib(n - 1) + fib(n - 2)
check(order(2, n), n, +(fib(-(n, 1)), fib(-(n, 2))))
}; fib(10)
-- FizzBuzz
local loop = [num, out]{
local fizz = equal(%(num, 3), 0) -- n % 3 == 0
local buzz = equal(%(num, 5), 0) -- n % 5 == 0
out.insert(check(fizz, check(buzz, "FizzBuzz", "Fizz"), check(buzz, "Buzz", num)))
check(order(100, num), loop(+(num, 1)), out)
}; console.print:loop(1)
What do table-oriented mean?
A table-oriented language uses tables to represent data. To explain this, let's define then use a function (variable as a lambda object).
local foo = {}
foo()
When this program runs, it sets foo.self
to the lambda object, which is used when we use it as a function. But, because foo is a table, we can define items with the variable.
foo.bar = 42
foo(), foo.bar -- both legal
This is because foo is ["self" = {}, "bar" = [self = 42], ...]
. This can be useful because instead of defining two items in a table like items = [main = {}, sub = {}]
to main = [self = {}, sub = {}]
.