Skip to content

Instantly share code, notes, and snippets.

@hodzanassredin
Created November 23, 2023 12:48
Show Gist options
  • Save hodzanassredin/fc83a360706d06dcc1b9ce0a287e2110 to your computer and use it in GitHub Desktop.
Save hodzanassredin/fc83a360706d06dcc1b9ce0a287e2110 to your computer and use it in GitHub Desktop.
Interfaces in Component Pascal
MODULE Interfaces;
IMPORT StdLog;
TYPE
MultiRec* = POINTER TO ABSTRACT RECORD END;
InterfacePrototype* = POINTER TO ABSTRACT RECORD END;
Iterator* = POINTER TO ABSTRACT RECORD(MultiRec) END;
IteratorPrototype = POINTER TO RECORD(InterfacePrototype) END;
Collection* = POINTER TO ABSTRACT RECORD(MultiRec) END;
CollectionPrototype = POINTER TO RECORD(InterfacePrototype) END;
T = ANYPTR;
MyArrayIterator = POINTER TO RECORD(Iterator)
coll : MyArray;
END;
MyArrayCollection = POINTER TO RECORD(Collection)
coll : MyArray;
END;
MyArray = POINTER TO RECORD(MultiRec)
arr : ARRAY 10 OF T
END;
VAR IteratorInterface- : IteratorPrototype; CollectionInterface- : CollectionPrototype;
PROCEDURE (it : MultiRec) GetOriginalObj*() : ANYPTR, NEW, ABSTRACT;
PROCEDURE (it : MultiRec) CastToInterface*(prototype : InterfacePrototype) : ANYPTR, NEW, ABSTRACT;
PROCEDURE (it : MyArrayIterator) GetOriginalObj*() : ANYPTR;
BEGIN
RETURN it.coll;
END GetOriginalObj;
PROCEDURE (it : MyArrayIterator) CastToInterface*(prototype : InterfacePrototype) : ANYPTR;
BEGIN
RETURN it.coll.CastToInterface(prototype);
END CastToInterface;
PROCEDURE (it : MyArrayCollection) GetOriginalObj*() : ANYPTR;
BEGIN
RETURN it;
END GetOriginalObj;
PROCEDURE (it : MyArrayCollection) CastToInterface*(prototype : InterfacePrototype) : ANYPTR;
BEGIN
RETURN it.coll.CastToInterface(prototype);
END CastToInterface;
PROCEDURE (it : Iterator) ForEach*(fn : PROCEDURE(item : T)), NEW, ABSTRACT;
PROCEDURE (it : Collection) Get*(idx : INTEGER) : T, NEW, ABSTRACT;
PROCEDURE (it : MyArrayIterator) ForEach(fn : PROCEDURE(item : T));
VAR i : INTEGER;
BEGIN
FOR i := 0 TO LEN(it.coll.arr) - 1 DO
fn(it.coll.arr[i])
END;
END ForEach;
PROCEDURE (it : MyArray) GetIterator() : Iterator, NEW;
VAR i : MyArrayIterator;
BEGIN
NEW(i);
i.coll := it;
RETURN i;
END GetIterator;
PROCEDURE (it : MyArray) GetCollection() : Collection, NEW;
VAR i : MyArrayCollection;
BEGIN
NEW(i);
i.coll := it;
RETURN i;
END GetCollection;
PROCEDURE (it : MyArray) CastToInterface*(prototype : InterfacePrototype) : ANYPTR;
BEGIN
WITH
| prototype : IteratorPrototype DO RETURN it.GetIterator()
| prototype : CollectionPrototype DO RETURN it.GetCollection()
ELSE RETURN NIL END;
END CastToInterface;
PROCEDURE (it : MyArray) GetOriginalObj*() : ANYPTR;
BEGIN
RETURN it;
END GetOriginalObj;
PROCEDURE (it : MyArrayCollection) Get(idx : INTEGER) : T;
BEGIN
RETURN it.coll.arr[idx]
END Get;
PROCEDURE Test*;
VAR iter : ARRAY 10 OF Iterator; colls : ARRAY 10 OF Collection;myArr : MyArray; someIter : Iterator; someCollection : Collection;
BEGIN
NEW(myArr);
iter[0] := myArr.GetIterator();
colls[0] := myArr.GetCollection();
someIter := colls[0].CastToInterface(IteratorInterface)(Iterator);
someCollection := iter[0].CastToInterface(CollectionInterface)(Collection);
ASSERT(someIter # NIL);
ASSERT(someCollection # NIL);
END Test;
BEGIN
NEW(IteratorInterface);NEW(CollectionInterface)
END Interfaces.
Interfaces.Test;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment