use of suite.node.Tree in project suite by stupidsing.
the class PrettyPrinter method prettyPrint_.
// op0 for avoiding unnecessary indenting; prec0 for parenthesizing
private void prettyPrint_(Node node, Operator op0, int prec0) {
int x = getX(), y = getY();
int length = lengthEstimator.getEstimatedLength(node);
// line too long?
if (node instanceof Tree) {
Tree tree = (Tree) node;
Operator op = tree.getOperator();
int prec = op.getPrecedence();
boolean isNeedPars = prec <= prec0;
int parsIndent = 0, parsIndent0 = 0;
if (isNeedPars) {
parsIndent = currentLineIndent;
parsIndent0 = incrementIndent();
append("(");
}
if (lineLength < x + length)
if (isLookingLikeList(op, node))
prettyPrintList(op, node);
else {
Node left = tree.getLeft();
Node right = tree.getRight();
Assoc assoc = op.getAssoc();
int leftPrec = prec - (assoc == Assoc.LEFT ? 1 : 0);
int rightPrec = prec - (assoc == Assoc.RIGHT ? 1 : 0);
if (op == TermOp.BRACES)
leftPrec = rightPrec = 0;
Tree tree1 = Tree.decompose(right, op);
Node r0 = tree1 != null ? tree1.getLeft() : null;
int es0 = lengthEstimator.getEstimatedLength(left);
int es1 = r0 != null ? lengthEstimator.getEstimatedLength(r0) : lineLength;
int opLength = op.getName().length();
// breaks "a + b + xxx" in the second operator
if (//
assoc == Assoc.RIGHT && //
x + es0 + es1 + opLength < lineLength && r0 != preferLineBreakBeforeKeyword) {
prettyPrint_(left, op, leftPrec);
OperatorPosition opPos = appendOperator(op);
prettyPrint_(right, op, rightPrec);
closeBraces(op, opPos);
} else {
// breaks after the operator
boolean isIncRightIndent = op != op0;
int indent0 = 0;
prettyPrint_(left, op, leftPrec);
if (isIncRightIndent)
indent0 = incrementIndent();
OperatorPosition opPos;
if (getLineSize() + lengthEstimator.getEstimatedLength(right) < squeezeLineLength)
opPos = appendOperator(op);
else
opPos = appendOperatorLineFeed(op);
prettyPrint_(right, op, rightPrec);
closeBraces(op, opPos);
if (isIncRightIndent)
revertIndent(indent0);
}
}
else
append(Formatter.dump(node));
if (isNeedPars) {
if (y != getY())
nl(parsIndent);
append(")");
revertIndent(parsIndent0);
}
} else {
if (node == lineBreakBeforeKeyword && !isLineBegin())
nl();
// space sufficient
append(Formatter.dump(node));
}
}
use of suite.node.Tree in project suite by stupidsing.
the class PrettyPrinter method prettyPrintList.
private void prettyPrintList(Operator op, Node node) {
int prec = op.getPrecedence(), prec1 = prec - 1;
if (node instanceof Tree) {
Tree tree = (Tree) node;
if (tree.getOperator() == op) {
boolean isLeftAssoc = op.getAssoc() == Assoc.LEFT;
OperatorPosition opPos;
if (isLeftAssoc) {
prettyPrintList(op, tree.getLeft());
opPos = appendOperatorLineFeed(op);
prettyPrintIndented(tree.getRight(), prec1);
} else {
prettyPrintIndented(tree.getLeft(), prec1);
opPos = appendOperatorLineFeed(op);
prettyPrintList(op, tree.getRight());
}
closeBraces(op, opPos);
return;
}
}
// if (node != Atom.nil) // suppress list termination
prettyPrint_(node, op, prec);
}
use of suite.node.Tree in project suite by stupidsing.
the class Comparer method compare.
@Override
public int compare(Node n0, Node n1) {
n0 = n0.finalNode();
n1 = n1.finalNode();
Class<? extends Node> clazz0 = n0.getClass();
Class<? extends Node> clazz1 = n1.getClass();
int c = Integer.compare(order.get(clazz0), order.get(clazz1));
if (c == 0)
if (clazz0 == Atom.class)
return ((Atom) n0).name.compareTo(((Atom) n1).name);
else if (clazz0 == Dict.class) {
Map<Node, Reference> m0 = ((Dict) n0).map;
Map<Node, Reference> m1 = ((Dict) n1).map;
Set<Node> keys = new HashSet<>();
keys.addAll(m0.keySet());
keys.addAll(m1.keySet());
for (Node key : Read.from(keys).sort(this::compare)) c = c != 0 ? c : Object_.compare(m0.get(key), m1.get(key));
return c;
} else if (clazz0 == Int.class)
return Integer.compare(((Int) n0).number, ((Int) n1).number);
else if (clazz0 == Reference.class)
return Integer.compare(((Reference) n0).getId(), ((Reference) n1).getId());
else if (clazz0 == Str.class)
return ((Str) n0).value.compareTo(((Str) n1).value);
else if (Tree.class.isAssignableFrom(clazz0)) {
Tree t0 = (Tree) n0;
Tree t1 = (Tree) n1;
c = t0.getOperator().getPrecedence() - t1.getOperator().getPrecedence();
c = c != 0 ? c : compare(t0.getLeft(), t1.getLeft());
c = c != 0 ? c : compare(t0.getRight(), t1.getRight());
return c;
} else if (clazz0 == Tuple.class) {
Node[] nodes0 = ((Tuple) n0).nodes;
Node[] nodes1 = ((Tuple) n1).nodes;
int i = 0, l = min(nodes0.length, nodes1.length);
while (c == 0 && i < l) c = compare(nodes0[i], nodes1[i]);
if (c == 0)
c = Integer.compare(nodes0.length, nodes1.length);
return c;
} else
return Integer.compare(n0.hashCode(), n1.hashCode());
else
return c;
}
use of suite.node.Tree in project suite by stupidsing.
the class Nodify method newNodifier.
@SuppressWarnings("unchecked")
private Nodifier newNodifier(Type type) {
Nodifier nodifier;
if (type instanceof Class) {
Class<?> clazz = (Class<?>) type;
if (clazz == boolean.class)
nodifier = new Nodifier(object -> Atom.of(object.toString()), node -> node == Atom.TRUE);
else if (clazz == int.class)
nodifier = new Nodifier(object -> Int.of((Integer) object), node -> ((Int) node).number);
else if (clazz == Chars.class)
nodifier = new Nodifier(object -> new Str(object.toString()), node -> To.chars(((Str) node).value));
else if (clazz == String.class)
nodifier = new Nodifier(object -> new Str(object.toString()), node -> ((Str) node).value);
else if (clazz.isEnum())
nodifier = new Nodifier(object -> Atom.of(object.toString()), Read.from(clazz.getEnumConstants()).toMap(e -> Atom.of(e.toString()))::get);
else if (clazz.isArray()) {
Class<?> componentType = clazz.getComponentType();
Nodifier nodifier1 = getNodifier(componentType);
Fun<Object, Node> forward = object -> {
Node node = Atom.NIL;
for (int i = Array.getLength(object) - 1; 0 <= i; i--) node = Tree.of(TermOp.OR____, apply_(nodifier1, Array.get(object, i)), node);
return node;
};
nodifier = new Nodifier(forward, node -> {
List<Object> list = //
Read.from(//
Tree.iter(node, TermOp.OR____)).map(//
n -> apply_(nodifier1, n)).toList();
int size = list.size();
Object objects = Array.newInstance(componentType, size);
for (int i = 0; i < size; i++) Array.set(objects, i, list.get(i));
return objects;
});
} else if (// polymorphism
clazz.isInterface())
nodifier = new Nodifier(object -> {
Class<?> clazz1 = object.getClass();
Node n = apply_(getNodifier(clazz1), object);
return Tree.of(TermOp.COLON_, Atom.of(clazz1.getName()), n);
}, node -> {
Tree tree = Tree.decompose(node, TermOp.COLON_);
if (tree != null) {
Class<?> clazz1;
try {
clazz1 = Class.forName(((Atom) tree.getLeft()).name);
} catch (ClassNotFoundException ex) {
clazz1 = Fail.t(ex);
}
return apply_(getNodifier(clazz1), tree.getRight());
} else
// happens when an enum implements an interface
return Fail.t("cannot instantiate enum from interfaces");
});
else {
List<FieldInfo> fieldInfos = //
Read.from(//
inspect.fields(clazz)).map(field -> {
Type type1 = field.getGenericType();
return new FieldInfo(field, field.getName(), getNodifier(type1));
}).toList();
List<Pair<Atom, FieldInfo>> pairs = Read.from(fieldInfos).map(f -> Pair.of(Atom.of(f.name), f)).toList();
nodifier = new Nodifier(object -> Rethrow.ex(() -> {
Dict dict = new Dict();
for (Pair<Atom, FieldInfo> pair : pairs) {
FieldInfo fieldInfo = pair.t1;
Node value = apply_(fieldInfo.nodifier, fieldInfo.field.get(object));
dict.map.put(pair.t0, Reference.of(value));
}
return dict;
}), node -> Rethrow.ex(() -> {
Map<Node, Reference> map = ((Dict) node).map;
Object object1 = Object_.new_(clazz);
for (Pair<Atom, FieldInfo> pair : pairs) {
FieldInfo fieldInfo = pair.t1;
Node value = map.get(pair.t0).finalNode();
fieldInfo.field.set(object1, apply_(fieldInfo.nodifier, value));
}
return object1;
}));
}
} else if (type instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) type;
Type rawType = pt.getRawType();
Type[] typeArgs = pt.getActualTypeArguments();
Class<?> clazz = rawType instanceof Class ? (Class<?>) rawType : null;
if (collectionClasses.contains(clazz)) {
Nodifier nodifier1 = getNodifier(typeArgs[0]);
nodifier = new Nodifier(object -> {
Tree start = Tree.of(null, null, null), tree = start;
for (Object o : (Collection<?>) object) {
Tree tree0 = tree;
Tree.forceSetRight(tree0, tree = Tree.of(TermOp.OR____, apply_(nodifier1, o), null));
}
Tree.forceSetRight(tree, Atom.NIL);
return start.getRight();
}, node -> {
List<Object> list = Read.from(Tree.iter(node, TermOp.OR____)).map(n -> apply_(nodifier1, n)).toList();
Collection<Object> object1 = (Collection<Object>) instantiate(clazz);
object1.addAll(list);
return object1;
});
} else if (mapClasses.contains(clazz)) {
Nodifier kn = getNodifier(typeArgs[0]);
Nodifier vn = getNodifier(typeArgs[1]);
nodifier = new Nodifier(object -> {
Dict dict = new Dict();
for (Entry<?, ?> e : ((Map<?, ?>) object).entrySet()) dict.map.put(apply_(kn, e.getKey()), Reference.of(apply_(vn, e.getValue())));
return dict;
}, node -> {
Map<Node, Reference> map = ((Dict) node).map;
Map<Object, Object> object1 = (Map<Object, Object>) instantiate(clazz);
for (Entry<Node, Reference> e : map.entrySet()) object1.put(apply_(kn, e.getKey()), apply_(vn, e.getValue().finalNode()));
return object1;
});
} else
nodifier = getNodifier(rawType);
} else
nodifier = Fail.t("unrecognized type " + type);
return nodifier;
}
use of suite.node.Tree in project suite by stupidsing.
the class Chr method addRule.
public void addRule(Node node) {
Rule rule = new Rule();
while (node != Atom.of("end")) {
Tree t0 = Tree.decompose(node, TermOp.TUPLE_);
Tree t1 = t0 != null ? Tree.decompose(t0.getRight(), TermOp.TUPLE_) : null;
if (t1 != null) {
Node key = t0.getLeft();
Node value = t1.getLeft();
node = t1.getRight();
if (key == Atom.of("given"))
rule.givens = To.list(Tree.iter(value));
else if (key == Atom.of("if"))
rule.ifs = To.list(Tree.iter(value));
else if (key == Atom.of("then"))
rule.thens = To.list(Tree.iter(value));
else if (key == Atom.of("when"))
rule.when = value;
else
Fail.t("invalid key " + key);
} else
Fail.t("invalid rule " + node);
}
rules.add(rule);
}
Aggregations