public static ASTNode writeFunction(boolean isSuper, FunctionCall lhs, ASTNode rhs) { if (lhs.args.size() > 0) { ASTNode first = lhs.args.first().getValue(); if (!(first instanceof SimpleAccessVariable)) { return new UpdateExpression(isSuper, lhs, rhs); } else { lhs.args.add("value", rhs); } } lhs.name = RSymbol.getSymbol(lhs.name.pretty() + "<-"); lhs.isAssignment(true); lhs.isSuper(isSuper); return lhs; }
public static ASTNode create(boolean isSuper, ASTNode lhs, ASTNode rhs) { if (lhs instanceof SimpleAccessVariable) { return writeVariable(isSuper, ((SimpleAccessVariable) lhs).symbol, rhs); } else if (lhs instanceof AccessVector) { return writeVector(isSuper, (AccessVector) lhs, rhs); } else if (lhs instanceof FieldAccess) { return writeField(isSuper, (FieldAccess) lhs, rhs); } else if (lhs instanceof FunctionCall) { return writeFunction(isSuper, (FunctionCall) lhs, rhs); } else if (lhs instanceof Constant) { // TODO: move this to the parser? RAny value = ((Constant) lhs).getValue(); if (value instanceof RString) { RString svalue = (RString) value; if (svalue.size() == 1) { String name = svalue.getString(0); return writeVariable(isSuper, RSymbol.getSymbol(name), rhs); } } throw RError.getUnknownObject(rhs); // TODO it's own exception } Utils.nyi(); return null; }
@Override public Object execute(Frame frame) { RAny lhsVal = (RAny) lhs.execute(frame); Object rowFromVal = rowFromExpr.execute(frame); Object rowToVal = rowToExpr.execute(frame); Object colFromVal = colFromExpr.execute(frame); Object colToVal = colToExpr.execute(frame); boolean dropVal = dropExpr.executeLogical(frame) != RLogical.FALSE; // FIXME: what is the correct execution order of these args? int exactVal = exactExpr.executeLogical(frame); if (!(lhsVal instanceof RArray)) { throw RError.getObjectNotSubsettable(ast, lhsVal.typeOf()); } RArray array = (RArray) lhsVal; try { int rowFrom = extractLimit(rowFromVal); // zero-based int rowTo = extractLimit(rowToVal); int colFrom = extractLimit(colFromVal); int colTo = extractLimit(colToVal); int[] dim = array.dimensions(); if (dim == null || dim.length != 2) { throw RError.getIncorrectDimensions(getAST()); } int m = dim[0]; int n = dim[1]; int rowStep; int rowSize; if (rowFrom <= rowTo) { rowStep = 1; if (rowTo > m) { throw new UnexpectedResultException(null); } rowSize = rowTo - rowFrom + 1; } else { rowStep = -1; if (rowFrom > m) { throw new UnexpectedResultException(null); } rowSize = rowFrom - rowTo + 1; } int colStep; int colSize; if (colFrom <= colTo) { colStep = 1; if (colTo > n) { throw new UnexpectedResultException(null); } colSize = colTo - colFrom + 1; } else { colStep = -1; if (colFrom > n) { throw new UnexpectedResultException(null); } colSize = colFrom - colTo + 1; } int[] ndim; if (!dropVal || (rowSize > 1 && colSize > 1)) { ndim = new int[] {rowSize, colSize}; } else { ndim = null; } int size = rowSize * colSize; RArray res = Utils.createArray(array, size, ndim, null, null); // drop attributes if (colStep == 1 && rowStep == 1) { int j = colFrom * m + rowFrom; // j - index to source matrix int jmax = j + rowSize; int jadvance = m - rowSize; for (int i = 0; i < size; i++) { res.set(i, array.getRef(j++)); // i - index to target matrix if (j == jmax) { j += jadvance; jmax += m; } } } else { int i = 0; // NOTE: here we know that colFrom != colTo and rowFrom != rowTo for (int col = colFrom; col != colTo + colStep; col += colStep) { for (int row = rowFrom; row != rowTo + rowStep; row += rowStep) { res.set(i++, array.getRef(col * m + row)); } } } return res; } catch (UnexpectedResultException e) { // FIXME: clean this up; does Colon need to be package-private? ASTNode rowAST = rowFromExpr.getAST().getParent(); Builtin rowColon = (Builtin) Primitives.getCallFactory(RSymbol.getSymbol(":"), null) .create(rowAST, rowFromExpr, rowToExpr); SelectorNode selIExpr = Selector.createSelectorNode(rowAST, true, rowColon); ASTNode colAST = colFromExpr.getAST().getParent(); Builtin colColon = (Builtin) Primitives.getCallFactory(RSymbol.getSymbol(":"), null) .create(colAST, colFromExpr, colToExpr); SelectorNode selJExpr = Selector.createSelectorNode(ast, true, colColon); MatrixRead nn = new MatrixRead(ast, true, lhs, selIExpr, selJExpr, dropExpr, exactExpr); replace(nn, "install MatrixRead from MatrixSequenceSubset"); Selector selI = selIExpr.executeSelector( rowColon.doBuiltIn(frame, new RAny[] {(RAny) rowFromVal, (RAny) rowToVal})); Selector selJ = selJExpr.executeSelector( colColon.doBuiltIn(frame, new RAny[] {(RAny) colFromVal, (RAny) colToVal})); return nn.executeLoop(array, selI, selJ, dropVal, exactVal); } }
/** * Compares two symbols to see if src is a partial match with tgt. Return false if either of * them has a null name(). * * <pre> * FIXME: Is it possible for name() to be null? * </pre> */ static boolean partialNameMatch(RSymbol src, RSymbol tgt) { if (src.name() == null || tgt.name() == null) { return false; } return (tgt.name().startsWith(src.name())); }