Skip to content

Commit

Permalink
[1 2⋄3 4], ⎕AV,
Browse files Browse the repository at this point in the history
  • Loading branch information
dzaima committed May 5, 2020
1 parent bafc10d commit dfebe5d
Show file tree
Hide file tree
Showing 9 changed files with 106 additions and 129 deletions.
4 changes: 2 additions & 2 deletions docs/chars.txt
Expand Up @@ -14,8 +14,8 @@ fns:
∨ gcd; gcd (aka some; contains truthy)
⍲ nand; not all / contains falsy
⍱ nor; none / all falsy
⊥ from; 2⊥⍵
⊤ to; 2⊤⍵
⊥ from; 2⊥⍵; aka decode, pack
⊤ to; 2⊤⍵; aka encode, unpack
○ trig; pi×⍵
! nCk; factorial

Expand Down
2 changes: 1 addition & 1 deletion src/APL/Exec.java
Expand Up @@ -759,7 +759,7 @@ private Obj valueOfRaw(Token t) {
}
}
if (t instanceof DfnTok) return UserDefined.of((DfnTok) t, sc);
if (t instanceof BracketTok) return new Brackets((BracketTok) t, sc);
if (t instanceof BracketTok) return Brackets.of((BracketTok) t, sc);
if (t instanceof BacktickTok) return new ArrFun((BacktickTok) t, sc);
if (t instanceof BigTok) return ((BigTok) t).val;
if (t instanceof ScopeTok) return new StrMap(sc);
Expand Down
4 changes: 2 additions & 2 deletions src/APL/Main.java
Expand Up @@ -301,11 +301,11 @@ public static Obj oexec(LineTok s, Scope sc) {
return val;
}

public static Obj vexec(LineTok s, Scope sc) {
public static Value vexec(LineTok s, Scope sc) {
Obj val = Main.exec(s, sc);
if (val instanceof VarArr) val = ((VarArr) val).get();
if (val instanceof Settable) val = ((Settable) val).get();
if (val instanceof Value) return val;
if (val instanceof Value) return (Value) val;
throw new SyntaxError("expected array, got " + val.humanType(true), s);
}

Expand Down
1 change: 1 addition & 0 deletions src/APL/Scope.java
Expand Up @@ -85,6 +85,7 @@ public Obj get (String name) {
case "⎕SH": return new Shell();
case "⎕NC": return new NC();
case "⎕A": return Main.alphabet;
case "⎕AV": return Main.toAPL(Main.CODEPAGE);
case "⎕D": return Main.digits;
case "⎕L":
case "⎕LA": return Main.lowercaseAlphabet;
Expand Down
14 changes: 7 additions & 7 deletions src/APL/types/Obj.java
Expand Up @@ -20,14 +20,14 @@ public boolean equals (Obj o) {

public String humanType(boolean article) {

if (this instanceof Arr) return article? "an array" : "array";
if (this instanceof Char) return article? "a character" : "character";
if (this instanceof Num) return article? "a number" : "number";
if (this instanceof APLMap) return article? "a map" : "map";
if (this instanceof Fun) return article? "a function" : "function";
if (this instanceof Null) return article? "javanull" : "javanull";
if (this instanceof Arr )return article? "an array" : "array";
if (this instanceof Char )return article? "a character" : "character";
if (this instanceof Num )return article? "a number" : "number";
if (this instanceof APLMap )return article? "a map" : "map";
if (this instanceof Fun )return article? "a function" : "function";
if (this instanceof Null )return article? "javanull" : "javanull";
if (this instanceof Brackets)return article? "brackets" : "brackets";
if (this instanceof VarArr) return article? "a vararr" : "vararr";
if (this instanceof VarArr )return article? "a vararr" : "vararr";
if (this instanceof Variable)return article? "a variable" : "variable";
if (this instanceof Pick )return article? "an array item": "array item";
if (this instanceof Mop )return article? "monadic operator" : "a monadic operator";
Expand Down
48 changes: 35 additions & 13 deletions src/APL/types/dimensions/Brackets.java
@@ -1,24 +1,17 @@
package APL.types.dimensions;

import APL.*;
import APL.errors.SyntaxError;
import APL.tokenizer.types.BracketTok;
import APL.tokenizer.Token;
import APL.tokenizer.types.*;
import APL.types.*;
import APL.types.functions.VarArr;
import APL.types.functions.builtins.fns.UpArrowBuiltin;

public class Brackets extends Obj {

public Value val;
public final Value val;

public Brackets(BracketTok t, Scope sc) {
if (t.tokens.size() != 0) {
if (t.tokens.size() != 1) throw new SyntaxError("multiple statements in bracket indexing");
Obj res = Main.exec(t.tokens.get(0), sc);
if (res instanceof VarArr) res = ((VarArr) res).get();
if (res instanceof Variable) res = ((Variable) res).get();
if (!(res instanceof Value)) throw new SyntaxError("brackets contained " + res.humanType(true));
val = (Value) res;
}
public Brackets(Value val) {
this.val = val;
}

public Integer toInt() {
Expand All @@ -37,4 +30,33 @@ public Type type() {
public String toString() {
return "["+val+"]";
}

public static Obj of(BracketTok t, Scope sc) {
if (t.tokens.size() == 0) return new Brackets(null);
if (t.tokens.size() == 1) {
Value res = Main.vexec(t.tokens.get(0), sc);
return new Brackets(res);
}
Value[] lns = new Value[t.tokens.size()];
for (int i = 0; i < t.tokens.size(); i++) {
LineTok tk = t.tokens.get(i);
lns[i] = Main.vexec(tk, sc);
}
return UpArrowBuiltin.merge(lns, new int[]{lns.length}, new BracketFn(t));
}

private static class BracketFn extends Callable {
protected BracketFn(Token t) {
super(null);
token = t;
}

public String toString() {
return "[⋄]";
}

public Type type() {
return Type.var;
}
}
}
6 changes: 3 additions & 3 deletions src/APL/types/functions/builtins/fns/LShoeBuiltin.java
Expand Up @@ -21,9 +21,9 @@ public Value call(Value w) {
}

@Override public Value call(Value a, Value w) {
if (w.rank != 1) throw new DomainError("⊂: ⍵ should be of rank 1", this);
if (a.rank != 1) throw new DomainError("⊂: ⍺ should be of rank 1", this);
if (a.ia+1 != w.ia) throw new LengthError("⊂: (1+≢⍺) ≡ ≢⍵ is required", this);
if (w.rank != 1) throw new DomainError("⊂: ⍵ should be of rank 1 ("+Main.formatAPL(w.shape)+" ≡ ⍴⍵)", this);
if (a.rank != 1) throw new DomainError("⊂: ⍺ should be of rank 1 ("+Main.formatAPL(a.shape)+" ≡ ⍴⍺)", this);
if (a.ia+1 != w.ia) throw new LengthError("⊂: (1+≢⍺) ≡ ≢⍵ is required ("+Main.formatAPL(a.shape)+" ≡ ⍴⍺; "+Main.formatAPL(w.shape)+" ≡ ⍴⍵)", this);
int[] aa = a.asIntVec();
ArrayList<Value> parts = new ArrayList<>();

Expand Down
154 changes: 54 additions & 100 deletions src/APL/types/functions/builtins/fns/UpArrowBuiltin.java
Expand Up @@ -16,132 +16,86 @@ public Value call(Value w) {
if (w instanceof Arr) {
if (w instanceof DoubleArr || w instanceof ChrArr || w instanceof BitArr) return w;
Value[] subs = w.values();
if (subs.length == 0) return w;

Value first = subs[0];
int[] def = new int[first.rank];
System.arraycopy(first.shape, 0, def, 0, def.length);
boolean allNums = true;
boolean eqShapes = true;
for (Value v : subs) {
if (v.rank != def.length) throw new RankError("↑: expected equal ranks of items", this, v);
for (int i = 0; i < def.length; i++) {
if (v.shape[i] > def[i]) {
def[i] = v.shape[i];
eqShapes = false;
}
}
if (!v.quickDoubleArr()) {
allNums = false;
return merge(subs, w.shape, this);
} else return w;
}

public static Value merge(Value[] vals, int[] sh, Callable blame) {
if (vals.length == 0) return EmptyArr.SHAPE0N;

Value first = vals[0];
int[] def = new int[first.rank];
System.arraycopy(first.shape, 0, def, 0, def.length);
boolean allNums = true;
boolean eqShapes = true;
for (Value v : vals) {
if (v.rank != def.length) throw new RankError(blame+": expected equal ranks of items (shapes "+Main.toAPL(first.shape)+" vs "+Main.toAPL(v.shape)+")", blame, v);
for (int i = 0; i < def.length; i++) {
if (v.shape[i] > def[i]) {
def[i] = v.shape[i];
eqShapes = false;
}
}
int subIA = Arr.prod(def);
int totalIA = subIA * Arr.prod(w.shape);
int[] resShape = new int[def.length + w.rank];
System.arraycopy(w.shape, 0, resShape, 0, w.rank);
System.arraycopy(def, 0, resShape, w.rank, def.length);

if (eqShapes) {
if (allNums) {
double[] res = new double[totalIA];

int i = 0;
for (Value v : subs) {
double[] da = v.asDoubleArr();
System.arraycopy(da, 0, res, i, da.length);
i+= subIA;
}
return new DoubleArr(res, resShape);
}
Value[] res = new Value[totalIA];

int i = 0;
for (Value v : subs) {
Value[] va = v.values();
System.arraycopy(va, 0, res, i, va.length);
i+= subIA;
}
return Arr.create(res, resShape);
if (!v.quickDoubleArr()) {
allNums = false;
}

}
int subIA = Arr.prod(def);
int totalIA = subIA * Arr.prod(sh);
int[] resShape = new int[def.length + sh.length];
System.arraycopy(sh, 0, resShape, 0, sh.length);
System.arraycopy(def, 0, resShape, sh.length, def.length);

if (eqShapes) {
if (allNums) {
double[] res = new double[totalIA];

int i = 0;
for (Value v : subs) {
double[] c = v.asDoubleArr();
int k = 0;
for (int j : new SimpleIndexer(def, v.shape)) {
res[i+j] = c[k++];
}
// automatic zero padding
for (Value v : vals) {
double[] da = v.asDoubleArr();
System.arraycopy(da, 0, res, i, da.length);
i+= subIA;
}

return new DoubleArr(res, resShape);
}


Value[] res = new Value[totalIA];

int i = 0;
for (Value v : subs) {
Value proto = v.prototype();
for (int[] sh : new Indexer(def, 0)) {
res[i++] = v.at(sh, proto);
}
for (Value v : vals) {
Value[] va = v.values();
System.arraycopy(va, 0, res, i, va.length);
i+= subIA;
}
return Arr.create(res, resShape);
} else return w;
}

public static Value merge(Value[] w, Callable blame) {
int[] def = new int[w[0].rank];
System.arraycopy(w[0].shape, 0, def, 0, def.length);
for (Value v : w) {
if (v.rank != def.length) throw new RankError("↑: expected equal ranks of items", blame, v);
for (int i = 0; i < def.length; i++) def[i] = Math.max(v.shape[i], def[i]);
}
int subIA = Arr.prod(def);
int totalIA = subIA * w.length;
int[] totalShape = new int[def.length + 1];
totalShape[0] = w.length;
System.arraycopy(def, 0, totalShape, 1, def.length);

boolean allNums = true;
for (Value v : w) {
if (!v.quickDoubleArr()) {
allNums = false;
break;
}
}

if (allNums) {
double[] allVals = new double[totalIA];
double[] res = new double[totalIA];

int i = 0;
for (Value v : w) {
for (Value v : vals) {
double[] c = v.asDoubleArr();
int k = 0;
for (int j : new SimpleIndexer(def, v.shape)) {
allVals[i+j] = c[k++];
res[i+j] = c[k++];
}
// automatic zero padding
i+= subIA;
}

return new DoubleArr(allVals, totalShape);
} else {
Value[] allVals = new Value[totalIA];

int i = 0;
for (Value v : w) {
Value proto = v.prototype();
for (int[] sh : new Indexer(def, 0)) {
// System.out.println(v +" "+ Arrays.toString(sh) +" "+ v.at(sh, v.prototype) +" "+ Arrays.toString(v.shape));
allVals[i++] = v.at(sh, proto);
}

return new DoubleArr(res, resShape);
}


Value[] res = new Value[totalIA];
int i = 0;
for (Value v : vals) {
Value proto = v.prototype();
for (int[] c : new Indexer(def, 0)) {
res[i++] = v.at(c, proto);
}
return Arr.create(allVals, totalShape);
}
return Arr.create(res, resShape);
}


Expand Down
2 changes: 1 addition & 1 deletion src/APL/types/functions/builtins/mops/ObliqueBuiltin.java
Expand Up @@ -72,6 +72,6 @@ public Value call(Obj f, Value w, DerivedMop derv) {
}
}

return UpArrowBuiltin.merge(res, this);
return UpArrowBuiltin.merge(res, new int[]{res.length}, this);
}
}

0 comments on commit dfebe5d

Please sign in to comment.