Templates (Classes) - markpwns1/Dormez GitHub Wiki

Classes in Dormez are called Templates. This is because a Template is just an instantiatable table, a template for a table, if you will. Also because I don't know if I'm confident enough to call them classes just yet. See the following example Template:

declare template Vector2 {
    with x;
    with y;
    
    // Let Z be an alias for Y, in case you're working on
    // an XZ plane and not an XY plane
    get z       { return this.y; }
    set z : z   { this.y = z; }
    
    constructor : x, y {
        this.x = x;
        this.y = y;
    }
    
    function toString {
        return this.x.toString() + ", " + this.y.toString();
    }
}

The template can then be instantiated like this:

declare v = Vector(3, 4);

Any of the template's members can then be accessed:

console.print(v.x); // prints "3"

As you can see, Templates follow the exact same syntax and rules as tables. That's because they are tables. The template above is actually just a shortcut for the following code:

function Vector2 : x, y {
    return table {
        with x = x;
        with y = y;
    
        // Let Z be an alias for Y, in case you're working on
        // an XZ plane and not an XY plane
        get z       { return this.y; }
        set z : z   { this.y = z; }
    
        function toString {
            return this.x.toString() + ", " + this.y.toString();
        }
    }
}

The internal code for templates is literally just a call to the table declaration function. And yes, this does mean that tables are technically capable of constructors, getters, and setters. That means calling Vector2(1, 2).getType() will return DTable. This is by design.

There are no public and private fields in Templates (yet), but all fields are public by default. Like in some other languages, fields that are meant to be private should have a prefix of _ .

Constructors are just fancy functions. They can be called like any other function, even after instantiation, like this: instance["constructor"](1, 2, 3);

Inheritance

Templates support inheritance, too. See the following example:

declare template Vector3 extending Vector2 {

    with z;
    
    constructor : x, y, z {
        base(x, y);
        this.z = z;
    }
    
    function toString {
        return base.toString() + ", " + this.z;
    }
}

declare v = Vector3(1, 2, 3);

console.print(v.toString()); // prints "1, 2, 3"

As you can see, the child's z overrides the parent's z . Any members in a child that conflict with a parent's member always take precedence over the parent. Furthermore, if you try to read any members that do not exist in a child, the Dormez interpreter will automatically search for it in the parent.

Operator overloading

Templates support overloading any operator except indexers. Refer to the following example:

declare Vector = template {
    x, y,
    
    constructor = function of x, y {
        this.x = x;
        this.y = y;
    },
    
    add = function of other {
        return Vector(this.x + other.x, this.y + other.y);
    },
    
    sub = function of other {
        return Vector(this.x - other.x, this.y - other.y);
    }
    
    // ...
}

The full list of operators that can be overloaded are the following:

  • add(other)
  • sub(other)
  • multiply(other)
  • divide(other)
  • negate() -- unary negative operator -
  • mod(other) -- modulus operator %
  • exponent(other) -- exponent operator ^
  • equals(other)
  • notEquals(other)
  • lessThan(other)
  • greaterThan(other)

Furthermore, toString() and getType() can also be overridden, though the latter is not recommended.