//--------------------------------------------------------------------------------------- // ParsePostfixExpression // // PostfixExpression: // LeftHandSideExpression | // LeftHandSideExpression '++' | // LeftHandSideExpression '--' // //--------------------------------------------------------------------------------------- private AstNode ParsePostfixExpression(AstNode ast, out bool isLeftHandSideExpr) { isLeftHandSideExpr = true; Context exprCtx = null; if (null != ast) { if (!m_scanner.GotEndOfLine) { if (JSToken.Increment == m_currentToken.Token) { isLeftHandSideExpr = false; exprCtx = ast.Context.Clone(); exprCtx.UpdateWith(m_currentToken); ast = new PostOrPrefixOperator(exprCtx, this, ast, m_currentToken.Token, PostOrPrefix.PostfixIncrement); GetNextToken(); } else if (JSToken.Decrement == m_currentToken.Token) { isLeftHandSideExpr = false; exprCtx = ast.Context.Clone(); exprCtx.UpdateWith(m_currentToken); ast = new PostOrPrefixOperator(exprCtx, this, ast, m_currentToken.Token, PostOrPrefix.PostfixDecrement); GetNextToken(); } } } return ast; }
//--------------------------------------------------------------------------------------- // ParseUnaryExpression // // UnaryExpression : // PostfixExpression | // 'delete' UnaryExpression | // 'void' UnaryExpression | // 'typeof' UnaryExpression | // '++' UnaryExpression | // '--' UnaryExpression | // '+' UnaryExpression | // '-' UnaryExpression | // '~' UnaryExpression | // '!' UnaryExpression // //--------------------------------------------------------------------------------------- private AstNode ParseUnaryExpression(out bool isLeftHandSideExpr, bool isMinus) { AstNode ast = null; isLeftHandSideExpr = false; bool dummy = false; Context exprCtx = null; AstNode expr = null; switch (m_currentToken.Token) { case JSToken.Void: exprCtx = m_currentToken.Clone(); GetNextToken(); expr = ParseUnaryExpression(out dummy, false); exprCtx.UpdateWith(expr.Context); ast = new VoidNode(exprCtx, this, expr); break; case JSToken.TypeOf: exprCtx = m_currentToken.Clone(); GetNextToken(); expr = ParseUnaryExpression(out dummy, false); exprCtx.UpdateWith(expr.Context); ast = new TypeOfNode(exprCtx, this, expr); break; case JSToken.Plus: exprCtx = m_currentToken.Clone(); GetNextToken(); expr = ParseUnaryExpression(out dummy, false); exprCtx.UpdateWith(expr.Context); ast = new NumericUnary(exprCtx, this, expr, JSToken.Plus); break; case JSToken.Minus: exprCtx = m_currentToken.Clone(); GetNextToken(); expr = ParseUnaryExpression(out dummy, true); exprCtx.UpdateWith(expr.Context); ast = new NumericUnary(exprCtx, this, expr, JSToken.Minus); break; case JSToken.BitwiseNot: exprCtx = m_currentToken.Clone(); GetNextToken(); expr = ParseUnaryExpression(out dummy, false); exprCtx.UpdateWith(expr.Context); ast = new NumericUnary(exprCtx, this, expr, JSToken.BitwiseNot); break; case JSToken.LogicalNot: exprCtx = m_currentToken.Clone(); GetNextToken(); expr = ParseUnaryExpression(out dummy, false); exprCtx.UpdateWith(expr.Context); ast = new NumericUnary(exprCtx, this, expr, JSToken.LogicalNot); break; case JSToken.Delete: exprCtx = m_currentToken.Clone(); GetNextToken(); expr = ParseUnaryExpression(out dummy, false); exprCtx.UpdateWith(expr.Context); ast = new Delete(exprCtx, this, expr); break; case JSToken.Increment: exprCtx = m_currentToken.Clone(); GetNextToken(); expr = ParseUnaryExpression(out dummy, false); exprCtx.UpdateWith(expr.Context); ast = new PostOrPrefixOperator(exprCtx, this, expr, m_currentToken.Token, PostOrPrefix.PrefixIncrement); break; case JSToken.Decrement: exprCtx = m_currentToken.Clone(); GetNextToken(); expr = ParseUnaryExpression(out dummy, false); exprCtx.UpdateWith(expr.Context); ast = new PostOrPrefixOperator(exprCtx, this, expr, m_currentToken.Token, PostOrPrefix.PrefixDecrement); break; default: m_noSkipTokenSet.Add(NoSkipTokenSet.s_PostfixExpressionNoSkipTokenSet); try { ast = ParseLeftHandSideExpression(isMinus); } catch (RecoveryTokenException exc) { if (IndexOfToken(NoSkipTokenSet.s_PostfixExpressionNoSkipTokenSet, exc) == -1) { throw; } else { if (exc._partiallyComputedNode == null) SkipTokensAndThrow(); else ast = exc._partiallyComputedNode; } } finally { m_noSkipTokenSet.Remove(NoSkipTokenSet.s_PostfixExpressionNoSkipTokenSet); } ast = ParsePostfixExpression(ast, out isLeftHandSideExpr); break; } return ast; }
public virtual void Visit(PostOrPrefixOperator node) { if (node != null) { AcceptChildren(node); } }
public override void Visit(PostOrPrefixOperator node) { if (node != null) { base.Visit(node); // strict mode has some restrictions we want to check now if (ScopeStack.Peek().UseStrict) { // the operator cannot be the eval function or arguments object. // that means the operator is a lookup, and the field for that lookup // is the arguments object or the predefined "eval" object. // could probably just check the names, since we can't create local variables // with those names anyways. var lookup = node.Operand as Lookup; if (lookup != null && (lookup.VariableField is JSArgumentsField || (lookup.VariableField is JSPredefinedField && string.CompareOrdinal(lookup.Name, "eval") == 0))) { node.Operand.Context.HandleError(JSError.StrictModeInvalidPreOrPost, true); } } } }
internal xpostorprefixoperator(PostOrPrefixOperator popo) : base(popo) { operatorTok = popo.operatorTok; }
public override void Visit(PostOrPrefixOperator node) { // same logic for most nodes TypicalHandler(node); }