예제 #1
0
        internal override IList <Executable> Resolve(Parser parser)
        {
            this.Expression = this.Expression.Resolve(parser);

            if (this.Expression == null)
            {
                return(new Executable[0]);
            }

            if (this.Expression is Increment)
            {
                Increment  inc    = (Increment)this.Expression;
                Assignment output = new Assignment(
                    inc.Root,
                    inc.IncrementToken,
                    inc.IsIncrement ? "+=" : "-=",
                    new IntegerConstant(inc.IncrementToken, 1, this.FunctionOrClassOwner),
                    this.FunctionOrClassOwner);
                return(output.Resolve(parser));
            }

            return(Listify(this));
        }
예제 #2
0
		private void CompileIncrement(Parser parser, ByteBuffer buffer, Increment increment, bool outputUsed)
		{
			if (!outputUsed)
			{
				throw new Exception("This should have been optimized into a += or -=");
			}

			if (increment.Root is Variable)
			{
				// OpCode re-use be damned. This should be not one, but two top-level op codes.
				// INCREMENT_INLINE and INCREMENT_POP (depending on whether outputUsed is true)
				// In fact, the code here in its current form is actually WRONG because someString++ will have 
				// a '1' appended to it when it really should be an error if the variable is not an integer.
				// Same for the others below. Ideally the DUPLICATE_STACK_TOP op should be removed.
				Variable variable = (Variable)increment.Root;
				int scopeId = variable.LocalScopeId;
				this.CompileExpression(parser, buffer, increment.Root, true);
				if (increment.IsPrefix)
				{
					buffer.Add(increment.IncrementToken, OpCode.LITERAL, parser.GetIntConstant(1));
					buffer.Add(increment.IncrementToken, OpCode.BINARY_OP, increment.IsIncrement ? (int)BinaryOps.ADDITION : (int)BinaryOps.SUBTRACTION);
					buffer.Add(increment.IncrementToken, OpCode.DUPLICATE_STACK_TOP, 1);
					buffer.Add(variable.FirstToken, OpCode.ASSIGN_LOCAL, scopeId);
				}
				else
				{
					buffer.Add(increment.IncrementToken, OpCode.DUPLICATE_STACK_TOP, 1);
					buffer.Add(increment.IncrementToken, OpCode.LITERAL, parser.GetIntConstant(1));
					buffer.Add(increment.IncrementToken, OpCode.BINARY_OP, increment.IsIncrement ? (int)BinaryOps.ADDITION : (int)BinaryOps.SUBTRACTION);
					buffer.Add(variable.FirstToken, OpCode.ASSIGN_LOCAL, scopeId);
				}
			}
			else if (increment.Root is BracketIndex)
			{
				BracketIndex bracketIndex = (BracketIndex)increment.Root;
				this.CompileExpression(parser, buffer, bracketIndex.Root, true);
				this.CompileExpression(parser, buffer, bracketIndex.Index, true);
				buffer.Add(increment.IncrementToken, OpCode.DUPLICATE_STACK_TOP, 2);
				buffer.Add(bracketIndex.BracketToken, OpCode.INDEX);
				if (increment.IsPrefix)
				{
					buffer.Add(increment.IncrementToken, OpCode.LITERAL, parser.GetIntConstant(1));
					buffer.Add(increment.IncrementToken, OpCode.BINARY_OP, increment.IsIncrement ? (int)BinaryOps.ADDITION : (int)BinaryOps.SUBTRACTION);
					buffer.Add(increment.IncrementToken, OpCode.ASSIGN_INDEX, 1);
				}
				else
				{
					buffer.Add(increment.IncrementToken, OpCode.STACK_INSERTION_FOR_INCREMENT);
					buffer.Add(increment.IncrementToken, OpCode.LITERAL, parser.GetIntConstant(1));
					buffer.Add(increment.IncrementToken, OpCode.BINARY_OP, increment.IsIncrement ? (int)BinaryOps.ADDITION : (int)BinaryOps.SUBTRACTION);
					buffer.Add(increment.IncrementToken, OpCode.ASSIGN_INDEX, 0);
				}
			}
			else if (increment.Root is DotStep)
			{
				DotStep dotStep = (DotStep)increment.Root;
				this.CompileExpression(parser, buffer, dotStep.Root, true);
				buffer.Add(increment.IncrementToken, OpCode.DUPLICATE_STACK_TOP, 1);
				buffer.Add(dotStep.DotToken, OpCode.DEREF_DOT, parser.GetId(dotStep.StepToken.Value));
				if (increment.IsPrefix)
				{
					buffer.Add(increment.IncrementToken, OpCode.LITERAL, parser.GetIntConstant(1));
					buffer.Add(increment.IncrementToken, OpCode.BINARY_OP, increment.IsIncrement ? (int)BinaryOps.ADDITION : (int)BinaryOps.SUBTRACTION);
					buffer.Add(increment.IncrementToken, OpCode.ASSIGN_STEP, parser.GetId(dotStep.StepToken.Value), 1);
				}
				else
				{
					buffer.Add(increment.IncrementToken, OpCode.DUPLICATE_STACK_TOP, 2);
					buffer.Add(increment.IncrementToken, OpCode.LITERAL, parser.GetIntConstant(1));
					buffer.Add(increment.IncrementToken, OpCode.BINARY_OP, increment.IsIncrement ? (int)BinaryOps.ADDITION : (int)BinaryOps.SUBTRACTION);
					buffer.Add(increment.IncrementToken, OpCode.ASSIGN_STEP, parser.GetId(dotStep.StepToken.Value), 0);
					buffer.Add(increment.IncrementToken, OpCode.STACK_SWAP_POP);
				}
			}
			else
			{
				throw new ParserException(increment.IncrementToken, "Cannot apply " + (increment.IsIncrement ? "++" : "--") + " to this sort of expression.");
			}
		}