// Operator overloading to make a 1-based array class Arr { protected var value; public proc create() { if (oadl::arg(0).isarray()) { // If an array is passed as the first arg, make // it the initializer if ((oadl::nargs() < 2) || !oadl::arg(1)) { // By-reference unless "false" is the second arg value = oadl::arg(0); } else { // By-value otherwise value = @oadl::arg(0); } } else if (oadl::nargs()) { // Otherwise, assume it is as if it were an iterator value = new Array(oadl::argvec().pack()); forall (value#[i]) value#[i] = i+1; } else { value = nil; } } operator [] () { // a[i,j,k,...] => [](i,j,k,...) var i, n = oadl::nargs(), res = value; for (i = 0; i < n; i++) { res = res[oadl::arg(i)-1]; } return res; } operator [=] () { // a[i,j,k,...] = b => [=](b,i,j,k,...) var n = oadl::nargs(); var val = oadl::arg(n-1); var idx = oadl::argvec()[:n-2] - 1; var hash = (idx*value.stride()).reduce(`+); value#[hash] = val; } operator #[] (idx) { return value#[idx-1]; } operator #[=] (idx,val) { value#[idx-1] = val; } operator + (rhs) { if (rhs ?= Arr) rhs = rhs.value; return new Arr(value + rhs); } operator \+ (lhs) { return new Arr(lhs + value); } operator - (rhs) { if (rhs ?= Arr) rhs = rhs.value; return new Arr(value - rhs); } operator \- (lhs) { return new Arr(lhs + value); } operator !- (lhs) { return new Arr(-value); } operator * (rhs) { if (rhs ?= Arr) rhs = rhs.value; return new Arr(value * rhs); } operator \* (lhs) { return new Arr(lhs * value); } operator / (rhs) { if (rhs ?= Arr) rhs = rhs.value; return new Arr(value / rhs); } operator \/ (lhs) { return new Arr(lhs / value); } public proc print() { "", value, '\n'; } public proc sizeof() { return value.sizeof(); } public proc shape() { return value.shape(); } public proc rank() { return value.rank(); } public proc length() { return value.length(); } public proc isarray() { return true; } public proc concat(b) { return new Arr(value ## b); } public proc subr() { var a = oadl::argvec(); forall (a[i]) if (a[i] != nil) a[i]--; a = value.subr#(a); return new Arr(a, false); } } proc main() { var a = new Arr(2,3,4); "a[1,1,1] = ", a[1,1,1], '\n'; forall (a[i,j,k]) a[i+1,j+1,k+1] *= 100; forall (a#[i]) a#[i+1] -= 1; a.print(); a += 1; a /= 100; a.print(); var b = a[1:2,1:2,1:2]; b[1,1,1] = 1000; b.print(); a.print(); b = foreach (a[i,j,k]) { "a[" ## String(i+1) ## "," ## String(j+1) ## "," ## String(k+1) ## "] = " ## String(a[i+1,j+1,k+1]) }; "", b, '\n'; }