Stack based array language (Uiua)
Timon Gehr
timon.gehr at gmx.ch
Wed Oct 4 08:36:39 UTC 2023
On 9/30/23 18:55, monkyyy wrote:
> How could you make a small project in d that hacks together a stack meta
> layer on top of ranges?
Generates a lot of template bloat, but you can do this:
```d
import std;
auto dupZeroes(R,T...)(Tuple!(R,T) stack){
return stack
.dup
.dup
.push(0)
.equals
.push(1)
.add
.keep
.flip
.len
.take
;
}
void main(){
tuple()
.push([1,0,2,3,0,4,5,0])
.dupZeroes
.push([1,2,3])
.dupZeroes
.push([0,3,0,4,5])
.dupZeroes
.writeln;
}
alias equals=binary!((a,b)=>a==b);
alias add=binary!((a,b)=>a+b);
alias keep=binary!((a,b)=>zip(a,b).mapArgs!((x,y)=>repeat(x,y)).joiner);
alias len=unary!(x=>x.length);
alias take=std.range.take;
alias take=binary!((a,b)=>a.take(b));
template mapArgs(alias f){ auto mapArgs(R)(R r)=>r.map!(x=>f(x.expand)); }
struct Tuple(T...){
T expand;
alias expand this;
string toString(){
string r;
foreach(i,ref x;expand){
if(i) r~="\n";
r~=text(x);
}
return r;
}
}
auto tuple(T...)(T args)=>Tuple!T(forward!args);
auto dup(S,T...)(Tuple!(S,T) stack)=>tuple(stack.expand,stack[$-1]);
auto push(S,T...)(Tuple!T stack,S head)=>tuple(stack.expand,head);
auto flip(R,S,T...)(Tuple!(R,S,T)
stack)=>tuple(stack[0..$-2],stack[$-1],stack[$-2]);
template apply(alias f,int nargs=-1){
auto apply(S,T...)(Tuple!(S,T) stack){
static if(nargs==-1){
static if(__traits(compiles,f(stack.expand).expand)) return
tuple(f(stack.expand).expand);
else static if(__traits(compiles,f(stack.expand))) return
tuple(f(stack.expand));
else return tuple(stack[0],apply(tuple(stack[1..$])).expand);
}else{
static if(__traits(compiles,f(stack[$-nargs..$]).expand))
return tuple(stack[0..$-nargs],f(stack[$-nargs..$]).expand);
else return tuple(stack[0..$-nargs],f(stack[$-nargs..$]));
}
}
}
alias broadcast1(alias f)=(x){
static if(__traits(compiles,f(x))) return f(x);
else static if(__traits(compiles,x.map!broadcast1)) return
x.map!broadcast1;
else static assert(0,f(x));
};
alias unary(alias f)=apply!(broadcast1!f,1);
alias broadcast2(alias f)=(x,y){
static if(__traits(compiles,f(x,y))) return f(x,y);
else static if(__traits(compiles,x.map!(a=>broadcast2(a,y))))
return x.map!(a=>broadcast2(a,y));
else static if(__traits(compiles,y.map!(b=>broadcast2(x,b))))
return y.map!(b=>broadcast2(x,b));
else static
if(__traits(compiles,zip(x,y).mapArgs!((a,b)=>broadcast2(a,b)))) return
zip(x,y).mapArgs!((a,b)=>broadcast2(a,b));
else static assert(0,f(x,y));
};
alias binary(alias f)=apply!(broadcast2!f,2);
```
More information about the Digitalmars-d
mailing list