use of suite.node.io.Operator in project suite by stupidsing.
the class SewingClonerImpl method cloner.
@Override
public Clone_ cloner(Node node) {
List<Clone_> funs = new ArrayList<>();
Clone_ fun;
while (true) {
Node node0 = node;
Tree tree;
if (node0 instanceof Dict) {
Clone_[][] array = //
Read.from2(//
((Dict) node0).map).map(//
(key, value) -> new Clone_[] { cloner(key), cloner(value) }).toArray(Clone_[].class);
int length = array.length;
return env -> {
@SuppressWarnings("unchecked") Pair<Node, Reference>[] pairs = new Pair[length];
for (int i = 0; i < length; i++) pairs[i] = Pair.of(array[i][0].apply(env), Reference.of(array[i][1].apply(env)));
return Dict.of(pairs);
};
} else if ((tree = Tree.decompose(node0)) != null) {
Operator operator = tree.getOperator();
if (operator != TermOp.OR____) {
Clone_ f = cloner(tree.getLeft());
funs.add(env -> Tree.of(operator, f.apply(env), null));
node = tree.getRight();
continue;
} else {
// delay generalizing for performance
Clone_ lf = cloner(tree.getLeft());
Clone_ rf = cloner(tree.getRight());
fun = env -> Tree.of(operator, lf.apply(env), new Suspend(() -> rf.apply(env)));
}
} else if (node0 instanceof Reference) {
int index = vm.computeIndex((Reference) node0);
fun = env -> env.get(index);
} else if (node0 instanceof Tuple) {
Clone_[] ps = Read.from(((Tuple) node0).nodes).map(this::cloner).toArray(Clone_.class);
int size = ps.length;
fun = env -> {
Node[] nodes = new Node[size];
for (int i = 0; i < size; i++) nodes[i] = ps[i].apply(env);
return Tuple.of(nodes);
};
} else
fun = env -> node0;
funs.add(fun);
break;
}
if (1 < funs.size())
return env -> {
Tree t = Tree.of(null, null, null);
Node node_ = t;
for (Clone_ fun_ : funs) {
Tree t_ = Tree.decompose(node_);
Tree.forceSetRight(t_, fun_.apply(env));
node_ = t_.getRight();
}
return t.getRight();
};
else
return funs.get(0);
}
use of suite.node.io.Operator in project suite by stupidsing.
the class Lexer method detect.
private Token detect() {
LexType type;
Operator operator = Pair.first_(commandUtil.recognize(in, pos));
if (pos < in.length()) {
char ch = in.charAt(pos);
if (operator != null)
type = LexType.OPER_;
else if (ch == '+' && pos + 4 <= in.length() && in.charAt(pos + 1) == '\'')
type = LexType.CHAR__;
else if (ch == '+' && pos + 2 <= in.length() && in.charAt(pos + 1) == 'x')
type = LexType.HEX__;
else if (ch == ' ')
type = LexType.SPACE;
else if (ch == '\'' || ch == '"')
type = LexType.STR__;
else if (//
ch == '(' || ch == '[' || ch == '{' || ch == ')' || ch == ']' || //
ch == '}' || ch == '`')
type = LexType.SYM__;
else
type = LexType.ID___;
} else
type = null;
return new Token(type, operator);
}
use of suite.node.io.Operator in project suite by stupidsing.
the class RecursiveFactorizer method parse_.
private FactorizeResult parse_(Chars chars, int fromOp) {
Chars chars1 = chars.trim();
if (0 < chars1.size()) {
char first = chars1.get(0);
char last = chars1.get(-1);
for (int i = fromOp; i < operators.length; i++) {
Operator operator = operators[i];
Chars range = operator != TermOp.TUPLE_ ? chars : chars1;
Segment ops = ParseUtil.searchPosition(chars.cs, Segment.of(range.start, range.end), operator);
if (ops == null)
continue;
Chars left = Chars.of(chars.cs, chars.start, ops.start);
Chars middle = Chars.of(chars.cs, ops.start, ops.end);
Chars right = Chars.of(chars.cs, ops.end, chars.end);
Chars post = null;
int li, ri;
if (operator == TermOp.BRACES) {
if (chars1.end < ops.start || last != '}')
continue;
right = Chars.of(chars.cs, ops.end, chars1.end - 1);
post = Chars.of(chars.cs, chars1.end - 1, chars.end);
li = 0;
ri = 0;
} else {
if (operator == TermOp.TUPLE_)
if (left.isWhitespaces() || right.isWhitespaces())
continue;
boolean isLeftAssoc = operator.getAssoc() == Assoc.LEFT;
li = fromOp + (isLeftAssoc ? 0 : 1);
ri = fromOp + (isLeftAssoc ? 1 : 0);
}
List<FactorizeResult> list = new ArrayList<>(4);
list.add(parse_(left, li));
list.add(term(middle));
list.add(parse_(right, ri));
if (post != null)
list.add(term(post));
return FactorizeResult.merge(operator.toString(), list);
}
if (//
first == '(' && last == ')' || //
first == '[' && last == ']' || first == '`' && last == '`') {
Chars left = Chars.of(chars.cs, chars.start, chars1.start + 1);
Chars middle = Chars.of(chars.cs, chars1.start + 1, chars1.end - 1);
Chars right = Chars.of(chars.cs, chars1.end - 1, chars.end);
return FactorizeResult.merge("" + first, List.of(term(left), parse_(middle, 0), term(right)));
}
}
return term(chars);
}
use of suite.node.io.Operator in project suite by stupidsing.
the class LengthEstimator method estimateLengths.
public int estimateLengths(Node node) {
int key = getKey(node);
Integer length = lengthByIds.get(key);
if (length == null) {
int len;
if (node instanceof Tree) {
Tree tree = (Tree) node;
Operator op = tree.getOperator();
int len0 = estimateLengths(tree.getLeft());
int len1 = estimateLengths(tree.getRight());
int opLength = op.getName().length();
// rough estimation
len = len0 + len1 + opLength + 2;
} else
len = Formatter.dump(node).length();
length = len;
lengthByIds.put(key, length);
}
return length;
}
use of suite.node.io.Operator in project suite by stupidsing.
the class NewPrettyPrinter method format_.
private void format_(Node node, int parentPrec, String indent, String prefix) {
Tree tree;
if ((tree = Tree.decompose(node)) != null) {
Operator operator = tree.getOperator();
int prec = operator.getPrecedence();
boolean isParenthesesRequired = operator != null ? prec <= parentPrec : false;
String indent1 = indent + ind;
Node[] m;
if (isParenthesesRequired) {
format_(node, 0, indent, concatWithSpace(prefix, "("));
sb.append(indent + ")");
} else if (operator == TermOp.NEXT__) {
format_(tree.getLeft(), TermOp.getLeftPrec(operator), indent, prefix);
sb.append(indent + "#\n");
format_(tree.getRight(), TermOp.getRightPrec(operator), indent, "");
} else if (operator == TermOp.IS____) {
format_(tree.getLeft(), TermOp.getLeftPrec(operator), indent, prefix);
format_(tree.getRight(), TermOp.getRightPrec(operator), indent1, operator.getName());
} else if (operator == TermOp.BIGAND || operator == TermOp.BIGOR_) {
format_(tree.getLeft(), TermOp.getLeftPrec(operator), indent, prefix);
format_(tree.getRight(), TermOp.getRightPrec(operator), indent, operator.getName());
} else if (operator == TermOp.AND___ || operator == TermOp.OR____) {
format_(tree.getLeft(), prec, indent, prefix);
node = tree.getRight();
while ((tree = Tree.decompose(node)) != null && tree.getOperator() == operator) {
format_(tree.getLeft(), prec, indent1, operator.getName());
node = tree.getRight();
}
format_(node, prec, indent1, operator.getName());
} else if (//
(m = Suite.pattern("if .0 then .1 else .2").match(node)) != null && lineLength < lengthEstimator.getEstimatedLength(node)) {
format_(m[0], prec, indent, concatWithSpace(prefix, "if"));
format_(m[1], prec, indent, "then");
format_(m[2], prec, indent, "else");
} else if (//
(m = Suite.pattern("not .0").match(node)) != null && lineLength < lengthEstimator.getEstimatedLength(node))
format_(m[0], prec, indent, concatWithSpace(prefix, "not"));
else if (//
(m = Suite.pattern("once .0").match(node)) != null && lineLength < lengthEstimator.getEstimatedLength(node))
format_(m[0], prec, indent, concatWithSpace(prefix, "once"));
else
format_(node, indent, prefix);
} else
format_(node, indent, prefix);
}
Aggregations