/// <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); }
public IParseItem Visit(UnOpItem target) { if (target == null) { throw new ArgumentNullException(nameof(target)); } target.Target.Accept(this); return(target); }
/// <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); }