private static Node addBeforeCurrent(Node parent, Node previous, Node current, Node toAdd) { if (previous == null) { if (!(current == parent.FirstChild)) Context.CodeBug (); parent.addChildToFront (toAdd); } else { if (!(current == previous.Next)) Context.CodeBug (); parent.addChildAfter (toAdd, previous); } return toAdd; }
private static Node addBeforeCurrent(Node parent, Node previous, Node current, Node toAdd) { if (previous == null) { if (!(current == parent.FirstChild)) { Context.CodeBug(); } parent.addChildToFront(toAdd); } else { if (!(current == previous.Next)) { Context.CodeBug(); } parent.addChildAfter(toAdd, previous); } return(toAdd); }
/// <summary> For .. In /// /// </summary> internal Node CreateForIn(Node loop, Node lhs, Node obj, Node body, bool isForEach) { int type = lhs.Type; Node lvalue; if (type == Token.VAR) { /* * check that there was only one variable given. * we can't do this in the parser, because then the * parser would have to know something about the * 'init' node of the for-in loop. */ Node lastChild = lhs.LastChild; if (lhs.FirstChild != lastChild) { parser.ReportError ("msg.mult.index"); } lvalue = Node.newString (Token.NAME, lastChild.String); } else { lvalue = makeReference (lhs); if (lvalue == null) { parser.ReportError ("msg.bad.for.in.lhs"); return obj; } } Node localBlock = new Node (Token.LOCAL_BLOCK); int initType = (isForEach) ? Token.ENUM_INIT_VALUES : Token.ENUM_INIT_KEYS; Node init = new Node (initType, obj); init.putProp (Node.LOCAL_BLOCK_PROP, localBlock); Node cond = new Node (Token.ENUM_NEXT); cond.putProp (Node.LOCAL_BLOCK_PROP, localBlock); Node id = new Node (Token.ENUM_ID); id.putProp (Node.LOCAL_BLOCK_PROP, localBlock); Node newBody = new Node (Token.BLOCK); Node assign = simpleAssignment (lvalue, id); newBody.addChildToBack (new Node (Token.EXPR_VOID, assign)); newBody.addChildToBack (body); loop = CreateWhile (loop, cond, newBody); loop.addChildToFront (init); if (type == Token.VAR) loop.addChildToFront (lhs); localBlock.addChildToBack (loop); return localBlock; }
private Node CreateLoop(Node.Jump loop, int loopType, Node body, Node cond, Node init, Node incr) { Node bodyTarget = Node.newTarget (); Node condTarget = Node.newTarget (); if (loopType == LOOP_FOR && cond.Type == Token.EMPTY) { cond = new Node (Token.TRUE); } Node.Jump IFEQ = new Node.Jump (Token.IFEQ, cond); IFEQ.target = bodyTarget; Node breakTarget = Node.newTarget (); loop.addChildToBack (bodyTarget); loop.addChildrenToBack (body); if (loopType == LOOP_WHILE || loopType == LOOP_FOR) { // propagate lineno to condition loop.addChildrenToBack (new Node (Token.EMPTY, loop.Lineno)); } loop.addChildToBack (condTarget); loop.addChildToBack (IFEQ); loop.addChildToBack (breakTarget); loop.target = breakTarget; Node continueTarget = condTarget; if (loopType == LOOP_WHILE || loopType == LOOP_FOR) { // Just add a GOTO to the condition in the do..while loop.addChildToFront (makeJump (Token.GOTO, condTarget)); if (loopType == LOOP_FOR) { if (init.Type != Token.EMPTY) { if (init.Type != Token.VAR) { init = new Node (Token.EXPR_VOID, init); } loop.addChildToFront (init); } Node incrTarget = Node.newTarget (); loop.addChildAfter (incrTarget, body); if (incr.Type != Token.EMPTY) { incr = new Node (Token.EXPR_VOID, incr); loop.addChildAfter (incr, incrTarget); } continueTarget = incrTarget; } } loop.Continue = continueTarget; return loop; }