-
Notifications
You must be signed in to change notification settings - Fork 0
Home
An (once) game scripting programming language.
I did this mostly for fun and to learn about implementations of real programming languages, and also to use in my games. It contains a mish-mash of features of other languages that I find cool and useful, like static typing, type inferring and closures. I don't intend on this becoming in the future a replacement game/general scripting language in any way, this is mostly a personal hobby project.
I'm also really not proud nor do I know exactly why I re-implemented a (very dysfunctional and incomplete) type system when .NET offers a tested and working one, pretty much for free. Other than that, most of the stuff I did was solely so I could learn about the ins and outs of writing an interpreted language that is run via a VM. Apart from the syntax tree parser library I used for this project (ANTLR v4.5), most of the features I ended up implementing where not really researched prior to execution, so some things are a bit janky when it comes to stability. The language is not completely implemented yet, and a full list of features with implementation and stability information are found in the next sessions of this file.
ZScript is a static (albeit weakly) typed, imperative, object-oriented programming language inspired by other imperative "C-style" languages like .NET C#, Apple's Swift and JavaScript. In ZScript you can define functions, variables, objects and sequences (more about what sequences are later), and have the code executed by calling one of the defined functions through the runtime's CallFunction(string functionName, object[] arguments) method in C# code.
Supposedly, a few snippets of code talk louder than paragraphs of text to programmers, so here are examples of recursive and iterative implementations of fibonacci in ZScript:
Recursive:
func fib(n:int) : int
{
if(n <= 0)
return 0;
if(n == 1)
return 1;
return fib(n - 1) + fib(n - 2);
}And iterative, showing local variables and for loops:
func fib(n:int) : int
{
if(n == 0) return 0;
if(n == 1) return 1;
var prevPrev = 0;
var prev = 1;
var result = 0;
for (var i = 2; i <= n; i++)
{
result = prev + prevPrev;
prevPrev = prev;
prev = result;
}
return result;
}These short examples showcase a few of the features of the language:
-
Functions
Statements to be executed in ZScript must be contained within functions that can be called either by other functions in the code, or directly by calling the ZRuntime.CallFunction() at C# code level. -
Type inferring
Variables and constants in ZScript are typed, and a type must be provided at time of creation of the value holders, but if the type is omitted, it is inferred from the value it was assigned at time of creation:prevPrev,prev,resultandihave their value inferred as integer because that's the value that was provided when they where created.
Some of the features proposed by the language are not fully implemented, and some are still somewhat unstable, as specified by the table bellow.
| Feature | Status | Author's thoughs |
|---|---|---|
| Variables & constants | Implemented | Still missing things like analysis of initialization before usages. |
| Type System | Partially Implemented | A static type system is in place, but some functionalities are not yet implemented, like binding to native types, for example. I'm also not fully sure about the ability of the type system to infer a common type between two types, it currently allows things like inferring that a list that contains integers and floats as of '[float]' type, when it really contains integers, too. |
| Expression Evaluation | Partially Implemented | Still missing emision of implicit and explicit type cast instructions, making the type system not fully safe. All other aspects are fully implemented, though. |
| Statements | Implemented | Modifications for the switch statement are planned, though. |
| Functions | Implemented | Working completely. |
| Export Functions | Partially Implemented | Same implications to function parameters, see above. |
| Closures | Partially Implemented | Fully working, can capture the variables of the function they are being executed in, including capturing of other closures. Same implications to function parameters, see above. |
| Objects (i.e. classes) | Not Implemented | |
| Sequences | Not Implemented | |
| Type Alias | Not Implemented | Still evaluating the necessity of type aliases, but syntax is already drafted. |