Made a snap type libary for extensions

js libary working
its just a regular Snap! object, but with a separate class

class source
/*
    you can have properly supported custom js types in Snap!
*/
if (!window.ADT) {
    function parseLisp(str) {
        let proc = new Process(null, world.childThatIsA(IDE_Morph).stage);
        proc.pushContext();
        return proc.assemble(proc.parseCode(str));
    }
    class ADT extends List {
        constructor() {
            super([]);
            this.add(new List(["...", this.constructor.proto]));
        }
        toString(){
            return "<"+this.lookup("_type")+">"
        }
        static
        __do(self, action, args) {
            if (!(self instanceof ADT))
                throw new Error("expecting a js defined adt but got a " + Process.prototype.reportTypeOf(self));
            if (self[action] == List.prototype[action])
                throw new Error("cannot call list methods directly");
            return self[action](...args.itemsArray()) ?? '';
        }
        static
        proto = new List([
                new List(["_type", "adt"]),
                new List(["__do", ADT.__do]),
                new List(["_morph", parseLisp(`(call (get __do) (this [object]) "toString" (list))`)])
            ]);
        static
        init(cls) {
            if (!cls.prototype instanceof this) {
                throw new Error("expecting a js defined adt type but got " + cls.name);
            }
            if (Object.hasOwn(cls,"proto")) return;
            if (cls.prototype.__proto__.constructor !== this)
                this.init(cls.prototype.__proto__.constructor);
            let proto = new List([new List(["...", cls.prototype.__proto__.constructor.proto])])
            for (let k of Object.getOwnPropertyNames(cls.prototype)) {
                proto.bind(k, parseLisp(`(call (get __do) (this [object]) ${k} (this [inputs]))`));
            }
            proto.bind("_type", cls.adtType || cls.name);
            cls.proto = proto;
        }
    }
    window.ADT = ADT;
}
how to use
  1. extend ADT

    class CustomType extends ADT{
        constructor(){
            super();
        }
        _morph(){
            return new TextMorph("hello from custom type");
        }
        static
        adtType="foobar"
    }
    
  2. initialize the class

    ADT.init(CustomType);
    

sorry about deleting it, I was unsure if it should go on the forum