private Node CreateWith(Node obj, Node body, int lineno) { SetRequiresActivation(); Node result = new Node(Token.BLOCK, lineno); result.AddChildToBack(new Node(Token.ENTERWITH, obj)); Node bodyNode = new Node(Token.WITH, body, lineno); result.AddChildrenToBack(bodyNode); result.AddChildToBack(new Node(Token.LEAVEWITH)); return result; }
private Node CreateIf(Node cond, Node ifTrue, Node ifFalse, int lineno) { int condStatus = IsAlwaysDefinedBoolean(cond); if (condStatus == ALWAYS_TRUE_BOOLEAN) { return ifTrue; } else { if (condStatus == ALWAYS_FALSE_BOOLEAN) { if (ifFalse != null) { return ifFalse; } // Replace if (false) xxx by empty block return new Node(Token.BLOCK, lineno); } } Node result = new Node(Token.BLOCK, lineno); Node ifNotTarget = Node.NewTarget(); Jump IFNE = new Jump(Token.IFNE, cond); IFNE.target = ifNotTarget; result.AddChildToBack(IFNE); result.AddChildrenToBack(ifTrue); if (ifFalse != null) { Node endTarget = Node.NewTarget(); result.AddChildToBack(MakeJump(Token.GOTO, endTarget)); result.AddChildToBack(ifNotTarget); result.AddChildrenToBack(ifFalse); result.AddChildToBack(endTarget); } else { result.AddChildToBack(ifNotTarget); } return result; }
protected internal virtual Node VisitLet(bool createWith, Node parent, Node previous, Node scopeNode) { Node vars = scopeNode.GetFirstChild(); Node body = vars.GetNext(); scopeNode.RemoveChild(vars); scopeNode.RemoveChild(body); bool isExpression = scopeNode.GetType() == Token.LETEXPR; Node result; Node newVars; if (createWith) { result = new Node(isExpression ? Token.WITHEXPR : Token.BLOCK); result = ReplaceCurrent(parent, previous, scopeNode, result); List<object> list = new List<object>(); Node objectLiteral = new Node(Token.OBJECTLIT); for (Node v = vars.GetFirstChild(); v != null; v = v.GetNext()) { Node current = v; if (current.GetType() == Token.LETEXPR) { // destructuring in let expr, e.g. let ([x, y] = [3, 4]) {} IList<object> destructuringNames = (IList<object>)current.GetProp(Node.DESTRUCTURING_NAMES); Node c = current.GetFirstChild(); if (c.GetType() != Token.LET) { throw Kit.CodeBug(); } // Add initialization code to front of body if (isExpression) { body = new Node(Token.COMMA, c.GetNext(), body); } else { body = new Node(Token.BLOCK, new Node(Token.EXPR_VOID, c.GetNext()), body); } // Update "list" and "objectLiteral" for the variables // defined in the destructuring assignment if (destructuringNames != null) { Sharpen.Collections.AddAll(list, destructuringNames); for (int i = 0; i < destructuringNames.Count; i++) { objectLiteral.AddChildToBack(new Node(Token.VOID, Node.NewNumber(0.0))); } } current = c.GetFirstChild(); } // should be a NAME, checked below if (current.GetType() != Token.NAME) { throw Kit.CodeBug(); } list.Add(ScriptRuntime.GetIndexObject(current.GetString())); Node init = current.GetFirstChild(); if (init == null) { init = new Node(Token.VOID, Node.NewNumber(0.0)); } objectLiteral.AddChildToBack(init); } objectLiteral.PutProp(Node.OBJECT_IDS_PROP, Sharpen.Collections.ToArray(list)); newVars = new Node(Token.ENTERWITH, objectLiteral); result.AddChildToBack(newVars); result.AddChildToBack(new Node(Token.WITH, body)); result.AddChildToBack(new Node(Token.LEAVEWITH)); } else { result = new Node(isExpression ? Token.COMMA : Token.BLOCK); result = ReplaceCurrent(parent, previous, scopeNode, result); newVars = new Node(Token.COMMA); for (Node v = vars.GetFirstChild(); v != null; v = v.GetNext()) { Node current = v; if (current.GetType() == Token.LETEXPR) { // destructuring in let expr, e.g. let ([x, y] = [3, 4]) {} Node c = current.GetFirstChild(); if (c.GetType() != Token.LET) { throw Kit.CodeBug(); } // Add initialization code to front of body if (isExpression) { body = new Node(Token.COMMA, c.GetNext(), body); } else { body = new Node(Token.BLOCK, new Node(Token.EXPR_VOID, c.GetNext()), body); } // We're removing the LETEXPR, so move the symbols Scope.JoinScopes((Scope)current, (Scope)scopeNode); current = c.GetFirstChild(); } // should be a NAME, checked below if (current.GetType() != Token.NAME) { throw Kit.CodeBug(); } Node stringNode = Node.NewString(current.GetString()); stringNode.SetScope((Scope)scopeNode); Node init = current.GetFirstChild(); if (init == null) { init = new Node(Token.VOID, Node.NewNumber(0.0)); } newVars.AddChildToBack(new Node(Token.SETVAR, stringNode, init)); } if (isExpression) { result.AddChildToBack(newVars); scopeNode.SetType(Token.COMMA); result.AddChildToBack(scopeNode); scopeNode.AddChildToBack(body); if (body is Scope) { Scope scopeParent = ((Scope)body).GetParentScope(); ((Scope)body).SetParentScope((Scope)scopeNode); ((Scope)scopeNode).SetParentScope(scopeParent); } } else { result.AddChildToBack(new Node(Token.EXPR_VOID, newVars)); scopeNode.SetType(Token.BLOCK); result.AddChildToBack(scopeNode); scopeNode.AddChildrenToBack(body); if (body is Scope) { Scope scopeParent = ((Scope)body).GetParentScope(); ((Scope)body).SetParentScope((Scope)scopeNode); ((Scope)scopeNode).SetParentScope(scopeParent); } } } return result; }