[Oberon] Dynamic array allocation?
joerg.straube at iaeth.ch
Tue Apr 9 09:26:42 CEST 2019
Oberon-07 does not offer a language construct to allocate arrays on the heap.
This said, there are ways around it, if you need it.
Put the ARRAY in a RECORD. Eg.
TYPE A = RECORD a: ARRAY 100 OF INTEGER END;
P = POINTER TO A;
VAR p: P;
Workaround 1 only allows a fixed length but no dynamic length. If you only want - lets say three variations of lengths - use inheritence:
TYPE A1 = RECORD a: ARRAY 1000 OF INTEGER END;
A2 = RECORD (A1) a: ARRAY 1000 OF INTEGER END;
A3 = RECORD (A2) a: ARRAY 1000 OF INTEGER END;
P1 = POINTER TO A1; P2 = POINTER TO A2;
P3 = POINTER TO A3;
VAR p1: P1; p2: P2; p3: P3;
The good thing is that all pointer variables p1, p2, and p3 are assignment compatible to P1. So if a PROCEDURE has a parameter of type P1, all three variables can be handed over.
If you need more dynamic variations, you could use ARRAY OF pointers.
LenDesc = RECORD len: ARRAY 256 OF INTEGER END;
Lengths = POINTER TO LenDesc;
File = RECORD line: ARRAY 16 OF Lengths END;
If you want to store the lengths of all lines in a file, you can use above data structure to do it up to a text file with 4096 lines with a granularity of 256 lines. While parsing the text file, you allocate a new Lengths block every 256 lines. The line length of line „x“ can be found via line[x DIV 256].len[x MOD 256]
The heap allocation is basically a procedure in Kernel. If you use the language construct NEW(), the compiler generates a call to Kernel.New. If you are very savvy in low level programming and know the mechanisms the garbage collector uses, you might add a new procedure to Kernel to allocate a memory block of variable length.
Instead of NEW(p, 200) you would then call Kernel.DynaNew(p, 200).
But as I said you have to fully understand the current mechanisms of Kernel.New() and Oberon.GC to do so.
Take Andreas system and compiler. He implemented wirkaround 5 and extended Oberon-07 with a new language construct.
> Am 09.04.2019 um 08:18 schrieb Till Oliver Knoll <till.oliver.knoll at gmail.com>:
> Dear all,
> I suspect that this question has been asked a couple of times already,
> but I found multiple answers which kind of contradict each other.
> Can I dynamically allocate memory (on the heap) for arrays, at least for
> arrays of "built in types" such as INTEGER, BYTE and the like?
> I stumbled via
> Chapter 19. Dynamic Arrays:
> "Dynamic arrays are here introduced as an addition to Oberon. An array
> is called dynamic, if its length is determined “dynamically”, i.e. at
> execution time. This is done by a call to the intrinsic procedure NEW
> with a second parameter indicating the desired length. Example:
> VAR a: ARRAY OF INTEGER;
> BEGIN ... NEW(a, len) ...
> However when I try this in my "Oberon Core" (as found in the Mac App
> Store, based on Project Oberon 2013) I get an "expression expected"
> syntax error at the location of "ARRAY OF INTEGER": the compiler in use
> still seems to expect a constant size declaration here.
> So is this a feature specific to (some version of) the ARM compiler, as
> used by Professor Wirth for his FPGA Oberon?
> Then I also found
> "This procedure can be used, if the user has not adopted the enhanced
> Oberon runtime system and Oberon-07 compiler provided in
> which implements a predefined procedure NEW(p, len) for dynamic open
> arrays (in Experimental Oberon, it is implemented by default)."
> This also seems to support the theory that the "plain vanilla compiler"
> does not support dynamic allocation with NEW(pointer, size)?
> In other words: I need to "upgrade" my Oberon compiler (somehow) such
> that I can dynamically allocate (simple) arrays?
> Thanks, Oliver
> Oberon at lists.inf.ethz.ch mailing list for ETH Oberon and related systems
More information about the Oberon