Esempio n. 1
0
        /// <summary>
        /// Called when the item is a unary operation item.
        /// </summary>
        /// <param name="target">The object that was passed to IParseItem.Visit.</param>
        /// <returns>The passed target or a modification of it.</returns>
        /// <exception cref="System.ArgumentNullException">If target is null.</exception>
        public IParseItem Visit(UnOpItem target)
        {
            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }

            ILGenerator gen = compiler.CurrentGenerator;

            //! push {Target}.Minus();
            target.Target.Accept(this);
            switch (target.OperationType)
            {
            case UnaryOperationType.Minus:
                gen.Emit(OpCodes.Callvirt, typeof(ILuaValue).GetMethod(nameof(ILuaValue.Minus)));
                break;

            case UnaryOperationType.Not:
                gen.Emit(OpCodes.Callvirt, typeof(ILuaValue).GetMethod(nameof(ILuaValue.Not)));
                break;

            case UnaryOperationType.Length:
                gen.Emit(OpCodes.Callvirt, typeof(ILuaValue).GetMethod(nameof(ILuaValue.Length)));
                break;
            }

            return(target);
        }
Esempio n. 2
0
        public IParseItem Visit(UnOpItem target)
        {
            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }

            target.Target.Accept(this);

            return(target);
        }
Esempio n. 3
0
        /// <summary>
        /// Reads an expression from the input.
        /// </summary>
        /// <param name="input">Where to read input from.</param>
        /// <param name="precedence">The precedence of the previous expression or -1 if a root.</param>
        /// <returns>The expression that was read.</returns>
        protected virtual IParseExp _readExp(Lexer input, out bool isParentheses, int precedence = -1)
        {
            Token     debug = input.Peek();
            IParseExp ret;
            var       unOpType = _getUnaryOperationType(input.Peek().Type);

            isParentheses = false;
            if (unOpType != UnaryOperationType.Unknown)
            {
                input.Read();
                int unaryPrec = 11;
                if (unaryPrec > precedence && precedence >= 0)
                {
                    unaryPrec = precedence;
                }
                ret = new UnOpItem(_readExp(input, out _, unaryPrec), unOpType)
                {
                    Debug = debug
                };
            }
            else if (input.ReadIfType(TokenType.Nil))
            {
                ret = new LiteralItem(null)
                {
                    Debug = debug
                };
            }
            else if (input.ReadIfType(TokenType.False))
            {
                ret = new LiteralItem(false)
                {
                    Debug = debug
                };
            }
            else if (input.ReadIfType(TokenType.True))
            {
                ret = new LiteralItem(true)
                {
                    Debug = debug
                };
            }
            else if (input.ReadIfType(TokenType.NumberLiteral))
            {
                ret = new LiteralItem(Helpers.ParseNumber(debug.Value))
                {
                    Debug = debug
                };
            }
            else if (input.ReadIfType(TokenType.StringLiteral))
            {
                ret = new LiteralItem(debug.Value)
                {
                    Debug = debug
                };
            }
            else if (input.ReadIfType(TokenType.Elipsis))
            {
                ret = new NameItem("...")
                {
                    Debug = debug
                };
            }
            else if (input.PeekType(TokenType.BeginTable))
            {
                ret = _readTable(input);
            }
            else if (input.PeekType(TokenType.Function))
            {
                ret = _readFunctionHelper(input, false, false);
            }
            else
            {
                ret = _readPrefixExp(input, out isParentheses);
            }

            while (true)
            {
                BinaryOperationType binOpType = _getBinaryOperationType(input.Peek().Type);
                int newPrecedence             = _getPrecedence(binOpType);
                if (binOpType == BinaryOperationType.Unknown ||
                    (newPrecedence < precedence && precedence >= 0))
                {
                    break;
                }
                input.Read();

                // For left-associative operations, use a lower precedence so the nested call doesn't read
                // more than it should.  a+b+c should be (a+b)+c, so we need the first add to be its own
                // item and then have that should be the lhs of another add.  Note this only works if
                // operations of the same precedence have the same associativity.
                int       extra = _isRightAssociative(binOpType) ? 0 : 1;
                IParseExp other = _readExp(input, out _, newPrecedence + extra);
                ret = new BinOpItem(ret, binOpType, other)
                {
                    Debug = debug
                };
                isParentheses = false;
            }
            return(ret);
        }