(* Copyright 2016 Anton Krotov This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . *) MODULE Vector; IMPORT sys := SYSTEM, K := KOSAPI; TYPE DESC_VECTOR = RECORD data : INTEGER; count : INTEGER; size : INTEGER END; VECTOR* = POINTER TO DESC_VECTOR; ANYREC* = RECORD END; ANYPTR* = POINTER TO ANYREC; DESTRUCTOR* = PROCEDURE (VAR ptr: ANYPTR); PROCEDURE count* (vector: VECTOR): INTEGER; BEGIN ASSERT(vector # NIL) RETURN vector.count END count; PROCEDURE push* (vector: VECTOR; value: ANYPTR); BEGIN ASSERT(vector # NIL); IF vector.count = vector.size THEN vector.data := K.realloc(vector.data, (vector.size + 1024) * 4); ASSERT(vector.data # 0); vector.size := vector.size + 1024 END; sys.PUT(vector.data + vector.count * 4, value); INC(vector.count) END push; PROCEDURE get* (vector: VECTOR; idx: INTEGER): ANYPTR; VAR res: ANYPTR; BEGIN ASSERT(vector # NIL); ASSERT( (0 <= idx) & (idx < vector.count) ); sys.GET(vector.data + idx * 4, res) RETURN res END get; PROCEDURE put* (vector: VECTOR; idx: INTEGER; value: ANYPTR); BEGIN ASSERT(vector # NIL); ASSERT( (0 <= idx) & (idx < vector.count) ); sys.PUT(vector.data + idx * 4, value) END put; PROCEDURE create* (size: INTEGER): VECTOR; VAR vector: VECTOR; BEGIN NEW(vector); IF vector # NIL THEN vector.data := K.malloc(4 * size); IF vector.data # 0 THEN vector.size := size; vector.count := 0 ELSE DISPOSE(vector) END END RETURN vector END create; PROCEDURE def_destructor (VAR any: ANYPTR); BEGIN DISPOSE(any) END def_destructor; PROCEDURE destroy* (VAR vector: VECTOR; destructor: DESTRUCTOR); VAR i: INTEGER; any: ANYPTR; BEGIN ASSERT(vector # NIL); IF destructor = NIL THEN destructor := def_destructor END; FOR i := 0 TO vector.count - 1 DO any := get(vector, i); destructor(any) END; vector.data := K.free(vector.data); DISPOSE(vector) END destroy; END Vector.