package org.yinwang.pysonar.ast; import org.jetbrains.annotations.NotNull; import org.yinwang.pysonar.Indexer; import org.yinwang.pysonar.Scope; import org.yinwang.pysonar.types.Type; import org.yinwang.pysonar.types.UnionType; public class BinOp extends Node { public Node left; public Node right; public Node op; public BinOp(Node left, Node right, Node op, int start, int end) { super(start, end); this.left = left; this.right = right; this.op = op; addChildren(left, right); } @NotNull @Override public Type resolve(Scope s, int tag) { Type ltype = null, rtype = null; if (left != null) { ltype = resolveExpr(left, s, tag); } if (right != null) { rtype = resolveExpr(right, s, tag); } // If either non-null operand is a string, assume the result is a string. if (ltype == Indexer.idx.builtins.BaseStr || rtype == Indexer.idx.builtins.BaseStr) { return Indexer.idx.builtins.BaseStr; } // If either non-null operand is a number, assume the result is a number. if (ltype == Indexer.idx.builtins.BaseNum || rtype == Indexer.idx.builtins.BaseNum) { return Indexer.idx.builtins.BaseNum; } if (ltype == null) { return (rtype == null ? Indexer.idx.builtins.unknown : rtype); } if (rtype == null) { return (ltype == null ? Indexer.idx.builtins.unknown : ltype); } return UnionType.union(ltype, rtype); } @NotNull @Override public String toString() { return "<BinOp:" + left + " " + op + " " + right + ">"; } @Override public void visit(@NotNull NodeVisitor v) { if (v.visit(this)) { visitNode(left, v); visitNode(right, v); } } }