package water.rapids.ast.prims.assign; import water.DKV; import water.Key; import water.Value; import water.fvec.Frame; import water.rapids.Env; import water.rapids.Val; import water.rapids.ast.AstPrimitive; import water.rapids.ast.AstRoot; import water.rapids.vals.ValFrame; /** * Assign a temp. All such assignments are final (cannot change), but the temp can be deleted. Temp is returned for * immediate use, and also set in the DKV. Must be globally unique in the DKV. */ public class AstTmpAssign extends AstPrimitive { @Override public String[] args() { return new String[]{"id", "frame"}; } @Override public int nargs() { return 1 + 2; } // (tmp= id frame) @Override public String str() { return "tmp="; } @Override public ValFrame apply(Env env, Env.StackHelp stk, AstRoot[] asts) { // Note: non-standard evaluation of the first argument! Instead of being // executed, it is stringified. This, for example, allows us to write an // expression as // (tmp= newid (* frame 3)) // instead of // (tmp= "newid" (* frame 3)) // On the other hand, this makes us unable to create dynamic identifiers // in Rapids, for example this is invalid: // (tmp= (+ "id" 3) (* frame 3)) // Right now there is no need for dynamically generated identifiers, since // we don't even have proper variables or loops or control structures yet. // Key<Frame> id = Key.make(env.expand(asts[1].str())); Val srcVal = stk.track(asts[2].exec(env)); Frame srcFrame = srcVal.getFrame(); Value v = DKV.get(id); if (v != null) { if (v.get().equals(srcFrame)) return (ValFrame) srcVal; else throw new IllegalArgumentException("Temp ID " + id + " already exists"); } Frame dst = new Frame(id, srcFrame._names, srcFrame.vecs()); return new ValFrame(env._ses.track_tmp(dst)); // Track new session-wide ID } }