Amigo v0.91. Range types and arrays


A range type can be created in Amigo by the following way:

class MyRange : IRange
{
    const Low = 3;
    const High = 15;

    static fn GetEnumerator(): RangeEnumerator
    {
        new RangeEnumerator(Low, High);
    }
}

or using the syntax sugar:

3..15

The interface IRange is defined in system.am

interface IRange: IEnumerable {}

Class RangeEnumerator is:

class RangeEnumerator
{
    var FLow, FHigh;
    var FCurrent;

    fn Reset()
    {
        FCurrent = FLow - 1;
    }

    fn MoveNext(): bool
    {
        FCurrent = FCurrent + 1;
        FCurrent <= FHigh;
    }

    fn GetCurrent()
    {
        FCurrent;
    }

    fn constructor (Low, High)
    {
        FLow = Low;
        FHigh = High;
        Reset();
    }
}

Class ArrayList already exists in the module system.am. It partially duplicates the functionality of the corresponding .Net class and simulates dynamic tuple.

Amigo language introduces dynamic arrays as typed ranged tuples:

class DynArray<T>: ArrayList
{
    fn constructor(N)
    {
    	base();
     	for (var I = 0; I < N; I++)
            Add(null);
    };

    property this[I: int]: T
    {
    	get => FItems[I];
        set => FItems[I] = value;
    }
}

Keyword this denotes default property. It introduces restriction for the type of array elements.

Instances of DynArray<T> can be created with using C# - like syntax:

var a: int[] = new int[5];

a[2] = 4;

for (var x in a)
  println(x);

or more simple:

var a = new int[5];

In implementation, access to the array elements is done with the inline functions.

Let's consider ranged arrays (Pascal-like arrays) in Amigo. First of all, we are introducing the ranged tuples:

class RangedTuple<R>: IEnumerable
{
    var FItems: Tuple;
    var FLow: R;
    var FHigh: R;

    bunch constructor
    {
        fn (Low: R, High: R)
        {
            FLow = Low;
            FHigh = High;
            FItems = new Tuple((FHigh as int) - (FLow as int) + 1);
        }
        ,
        fn (AType)
        {
            FLow = low(AType) as R;
            FHigh = high(AType) as R;
            FItems = new Tuple((FHigh as int) - (FLow as int) + 1);
        }
        ,
        fn ()
        {
            FLow = low(R) as R;
            FHigh = high(R) as R;
            FItems = new Tuple((FHigh as int) - (FLow as int) + 1);
        }
   }

    fn GetEnumerator(): RangedTupleEnumerator
    {
    	new RangedTupleEnumerator(FItems, FLow as int, FHigh as int);
    }

    property this[I: R]
    {
    	get => FItems[(I as int) - (FLow as int)];
        set => FItems[(I as int) - (FLow as int)] = value;
    }

    property Low => FLow;
    property High => FHigh;
    property Length => FItems.Length;
}

Generic parameter R denotes a range type. Two overloaded constructors are joined in a bunch. Class RangedTupleEnumerator is:

class RangedTupleEnumerator
{
    var A, I, L, H, FCurrent;

    fn Reset()
    {
        I = L - 1;
    }

    fn MoveNext(): bool
    {
        I++;
        I <= H;
    }

    fn GetCurrent()
    {
        A[I - L];
    }

    fn constructor (A, L, H)
    {
        this.A = A;
        this.L = L;
        this.H = H;
        Reset();
    }
}

Now, we can introduce the ranged array (Pascal-like) array:

class RangedArray<R, T>: RangedTuple<R>
{
    bunch constructor
    {
        fn (Low: R, High: R)
        {
            base(Low, High);
        }
        ,
        fn (AType)
        {
            base(AType);
        }
        fn ()
        {
            base();
        }
   }

    property this[I: R]: T
    {
    	get => FItems[(I as int) - (FLow as int)];
        set => FItems[(I as int) - (FLow as int)] = value;
    }
}

Class RangedArray<R, T> inherits class RangedTuple<R> and restricts access to the array elements.

It will be used in the implementation of the AmigoPascal. As Amigo engine provides cross-language compilation, the module system.am will be used in AmigoPascal programs without changes.

In the Amigo language, the syntax sugar is available for the ranged arrays:

var A = new int[3..15];
for (var x in A)
  println(x);

or use RangedArray<R, T> explicitly

type R = 3..5;
var A = new RangedArray<R, int>();
As RangedArray<R, T> is a class, we can inherit it and provide custom methods and properties.


Copyright © 2024-2005 Alexander Baranovsky