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)); }
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."); } }