示例#1
0
文件: Lambda.cs 项目: djlw78/crayon
        // This is called at the end of the TopLevelEntity's allocation phase and allocates
        // ID's to the lambda's code.
        internal void ResolveVariableOriginsForInnerCode(ParserContext parser, VariableScope scopeFromParent)
        {
            this.VariableScope = VariableScope.CreateClosure(scopeFromParent);
            List <VariableId> argVarIds = new List <VariableId>();

            for (int i = 0; i < this.Args.Length; ++i)
            {
                if (this.Args[i].Value == "xxxx")
                {
                }
                VariableId varId = this.VariableScope.RegisterVariableForcedReDeclaration(
                    this.ArgTypes[i],
                    this.Args[i].Value,
                    this.Args[i]);
                argVarIds.Add(varId);
            }
            this.ArgVarIds = argVarIds.ToArray();

            foreach (Executable ex in this.Code)
            {
                ex.ResolveVariableOrigins(parser, this.VariableScope, VariableIdAllocPhase.REGISTER_AND_ALLOC);
            }

            this.VariableScope.FinalizeScopeIds();

            foreach (Lambda lambda in this.Lambdas)
            {
                lambda.ResolveVariableOriginsForInnerCode(parser, this.VariableScope);
            }
        }
示例#2
0
文件: Lambda.cs 项目: djlw78/crayon
        internal override Expression ResolveTypes(ParserContext parser, TypeResolver typeResolver)
        {
            int argCount = this.ArgTypes.Length;

            this.ResolvedArgTypes = new ResolvedType[argCount];
            for (int i = 0; i < argCount; ++i)
            {
                ResolvedType argType = typeResolver.ResolveType(this.ArgTypes[i]);
                this.ResolvedArgTypes[i] = argType;

                // TODO: this variableId will not always be non-null when the argument in a lambda is used by a
                // closure of another lambda inside the lambda. I'll have to change my strategy here. Possibly
                // tracking the VariableId's as another Args field.
                VariableId variableId = this.VariableScope.GetVarId(this.Args[i]);
                variableId.ResolvedType = argType;
            }

            foreach (Executable ex in this.Code)
            {
                ex.ResolveTypes(parser, typeResolver);
            }

            // TODO: how do you define the lambda return type in Acrylic? Snoop the nested returns, maybe?
            ResolvedType returnType = ResolvedType.ANY;

            this.ResolvedType = ResolvedType.GetFunctionType(returnType, this.ResolvedArgTypes, 0);

            return(this);
        }
 public VariableNode(StatService statService, string id, StatId?parentId)
     : base(id, NodeType.Stat, 1)
 {
     _statService = statService;
     Id           = new VariableId(id, parentId);
     _parentId    = parentId;
 }
示例#4
0
 public Iteration(String iteratorName, VariableId listData, List <Brick> brickList)
 {
     this.iteratorName    = iteratorName;
     this.listData        = listData;
     this.brickList       = brickList;
     this.listOfParameter = IteratorStr.GetListofIndexParametters();
 }
示例#5
0
        /// <summary>
        /// Returns the number of bytes that the variable takes.
        /// </summary>
        private byte getVariableBytes(VariableId variableId)
        {
            switch (variableId)
            {
            case VariableId.TARGET_VCC_ALLOWED_MINIMUM:
            case VariableId.TARGET_VCC_ALLOWED_MAXIMUM_RANGE:
            case VariableId.TARGET_VCC_MEASURED_MINIMUM:
            case VariableId.TARGET_VCC_MEASURED_MAXIMUM:
            case VariableId.PROGRAMMING_ERROR:
            case VariableId.LINE_A_IDENTITY:
            case VariableId.LINE_B_IDENTITY:
            case VariableId.SLOSCOPE_STATE:
            case VariableId.SW_MINOR:
            case VariableId.SW_MAJOR:
            case VariableId.HW_VER:
            case VariableId.SCK_DURATION:
                return(1);

            case VariableId.FVR_ADC:
            case VariableId.SLOSCOPE_OUTPUT_STATE:
                return(2);

            default: throw new Exception("Unrecognized variabledId " + variableId.ToString());
            }
        }
示例#6
0
        private unsafe ushort getVariable(VariableId variableId)
        {
            byte bytes = getVariableBytes(variableId);

            ushort value = 0;

            byte[] array = new byte[bytes];
            try
            {
                controlTransfer(0xC0, 0x81, 0, (ushort)variableId, array);
            }
            catch (Exception e)
            {
                throw new Exception("There was an error getting variable " + variableId.ToString() + " from the device.", e);
            }
            if (bytes == 1)
            {
                // read a single byte
                fixed(byte *pointer = array)
                {
                    value = *(byte *)pointer;
                }
            }
            else
            {
                // read two bytes
                fixed(byte *pointer = array)
                {
                    value = *(ushort *)pointer;
                }
            }
            return(value);
        }
示例#7
0
 public bool Exists(VariableId id)
 {
     if (!Exists(id.StatId))
     {
         return(false);
     }
     return(Stats[id.StatId].TryGetVariable(id) != null);
 }
示例#8
0
 public void Remove(VariableId variableId)
 {
     if (!Exists(variableId))
     {
         throw new ArgumentOutOfRangeException(nameof(variableId));
     }
     //TODO check if used
     Stats[variableId.StatId].Variables.Remove(variableId);
 }
示例#9
0
 private void setVariable(VariableId variableId, ushort value)
 {
     try
     {
         controlTransfer(0x40, 0x82, value, (ushort)variableId);
     }
     catch (Exception e)
     {
         throw new Exception("There was an error setting variable " + variableId.ToString() + " on the device.", e);
     }
 }
示例#10
0
        public IEnumerable <string> AddOrUpdate(VariableId id, double value = 0)
        {
            var stat = Stats[id.StatId];

            if (stat.TryGetVariable(id) != null)
            {
                _cache.Clear();
            }
            stat.AddOrUpdateVariable(id, value);

            return(System.Array.Empty <string>());
        }
示例#11
0
        internal override void ResolveTypes(ParserContext parser, TypeResolver typeResolver)
        {
            this.Value = this.Value.ResolveTypes(parser, typeResolver);
            if (this.type == AssignmentType.TYPED_VARIABLE_DECLARATION)
            {
                VariableId varId        = this.TargetAsVariable.VarId;
                AType      variableType = varId.Type;
                varId.ResolvedType = typeResolver.ResolveType(varId.Type);
            }
            else if (this.type == AssignmentType.VARIABLE && this.CompilationScope.IsCrayon)
            {
                VariableId varId = this.TargetAsVariable.VarId;
                if (varId.ResolvedType == null)
                {
                    varId.ResolvedType = parser.TypeContext.ANY;
                }
            }

            this.Target = this.Target.ResolveTypes(parser, typeResolver);

            // These are special cases that are valid:
            //   list *= num,
            //   string *= num,
            //   string += any non-null value
            ResolvedTypeCategory leftCategory  = this.Target.ResolvedType.Category;
            ResolvedTypeCategory rightCategory = this.Value.ResolvedType.Category;
            bool specialCase = false;

            if ((leftCategory == ResolvedTypeCategory.STRING || leftCategory == ResolvedTypeCategory.LIST) &&
                rightCategory == ResolvedTypeCategory.INTEGER &&
                this.Op == Ops.MULTIPLICATION)
            {
                specialCase = true;
            }
            else if (leftCategory == ResolvedTypeCategory.STRING && this.Op == Ops.ADDITION)
            {
                if (rightCategory != ResolvedTypeCategory.NULL)
                {
                    specialCase = true;
                }
            }

            if (!this.Target.CanAssignTo)
            {
                throw new ParserException(this.Target, "Cannot assign to this type of expression.");
            }

            if (!specialCase)
            {
                this.Value.ResolvedType.EnsureCanAssignToA(this.Value.FirstToken, this.Target.ResolvedType);
            }
        }
示例#12
0
        public static void Compile(ParserContext parser, ByteBuffer buffer, Variable variable, bool outputUsed)
        {
            if (!outputUsed)
            {
                throw new ParserException(variable, "This expression does nothing.");
            }
            int        nameId = parser.GetId(variable.Name);
            Token      token  = variable.FirstToken;
            VariableId varId  = variable.VarId;

            if (varId == null)
            {
                throw new ParserException(token, "Variable used but not declared.");
            }
            bool isClosureVar = varId.UsedByClosure;

            buffer.Add(token, isClosureVar ? OpCode.DEREF_CLOSURE : OpCode.LOCAL, isClosureVar ? varId.ClosureID : varId.ID, nameId);
        }
示例#13
0
        private IEnumerable <string> SetVariable(Node node, ParsingContext context)
        {
            if (node.Value[0] == '.')
            {
                return new[] { $"Can not use shorthand variable name ({node.Value})" }
            }
            ;                                                                                           //TODO better msg

            var variableId             = new VariableId(node.Value);
            var variableExpressionNode = node.Children.First();

            var errors = _parser.Parse(out var expression, variableExpressionNode.Value, context).FormatErrors(variableExpressionNode).ToList();

            if (errors.Any())
            {
                return(errors);
            }

            _statService.Get(variableId.StatId).AddOrUpdateVariable(variableId, expression !);

            return(Enumerable.Empty <string>());
        }
示例#14
0
        // Shared code for functions/constructors/lambdas
        internal static void CompileFunctionArgs(
            ByteCodeCompiler bcc,
            ParserContext parser,
            ByteBuffer buffer,
            IList <Token> argNames,
            IList <Expression> argValues,
            List <int> offsetsForOptionalArgs,
            VariableId[] variableIds)
        {
            int bufferStartSize = buffer.Size;

            for (int i = 0; i < argNames.Count; ++i)
            {
                if (argValues[i] != null)
                {
                    bcc.CompileExpression(parser, buffer, argValues[i], true);
                    buffer.Add(argNames[i], OpCode.ASSIGN_LOCAL, i);
                    offsetsForOptionalArgs.Add(buffer.Size - bufferStartSize);
                }
            }

            // Arguments that are actually closure variables and not plain locals need to be converted.
            for (int i = 0; i < argValues.Count; ++i)
            {
                VariableId varId = variableIds[i];
                if (varId.UsedByClosure)
                {
                    // It's simple to copy all passed args at function invocation time to locals, which, on
                    // its own, is incorrect. Therefore add bytecode that will dereference those local ID's and
                    // assign them to the proper closure ID. This eliminates the need to make a dinstinction in
                    // CALL_FUNCTION between local and closure args.
                    buffer.Add(null, OpCode.LOCAL, i);
                    buffer.Add(null, OpCode.ASSIGN_CLOSURE, varId.ClosureID);
                }
            }
        }
示例#15
0
        public static void Compile(ByteCodeCompiler bcc, ParserContext parser, ByteBuffer buffer, Assignment assignment)
        {
            Expression target = assignment.Target;
            Expression value  = assignment.Value;

            ResolvedType targetAssignmentType = target.ResolvedType;

            if (targetAssignmentType == null)
            {
                throw new Exception();                               // should be ANY if no type is set.
            }
            if (value.ResolvedType == ResolvedType.ANY &&
                targetAssignmentType != ResolvedType.ANY)
            {
                value = new Cast(value.FirstToken, targetAssignmentType, value, value.Owner, false);
            }

            if (assignment.Op == Ops.EQUALS)
            {
                if (assignment.Target is Variable)
                {
                    Variable varTarget = (Variable)assignment.Target;
                    bcc.CompileExpression(parser, buffer, value, true);
                    VariableId varId = varTarget.VarId;
                    if (varId.UsedByClosure)
                    {
                        buffer.Add(assignment.OpToken, OpCode.ASSIGN_CLOSURE, varId.ClosureID);
                    }
                    else
                    {
                        buffer.Add(assignment.OpToken, OpCode.ASSIGN_LOCAL, varId.ID);
                    }
                }
                else if (assignment.Target is BracketIndex)
                {
                    BracketIndex bi = (BracketIndex)assignment.Target;
                    bcc.CompileExpression(parser, buffer, bi.Root, true);
                    bcc.CompileExpression(parser, buffer, bi.Index, true);
                    bcc.CompileExpression(parser, buffer, value, true);
                    buffer.Add(assignment.OpToken, OpCode.ASSIGN_INDEX, 0);
                }
                else if (assignment.Target is DotField)
                {
                    DotField dotStep = (DotField)assignment.Target;
                    if (dotStep.Root is ThisKeyword)
                    {
                        bcc.CompileExpression(parser, buffer, value, true);
                        buffer.Add(assignment.OpToken, OpCode.ASSIGN_THIS_FIELD, parser.GetId(dotStep.FieldToken.Value));
                    }
                    else
                    {
                        bcc.CompileExpression(parser, buffer, dotStep.Root, true);
                        bcc.CompileExpression(parser, buffer, value, true);
                        int nameId             = parser.GetId(dotStep.FieldToken.Value);
                        int localeScopedNameId = nameId * parser.GetLocaleCount() + parser.GetLocaleId(dotStep.Owner.FileScope.CompilationScope.Locale);
                        buffer.Add(
                            assignment.OpToken,
                            OpCode.ASSIGN_FIELD,
                            nameId,
                            0,
                            localeScopedNameId,
                            assignment.ClassOwner == null ? -1 : assignment.ClassOwner.ClassID,
                            assignment.CompilationScope.ScopeNumId,
                            -1, 0);
                    }
                }
                else if (assignment.Target is FieldReference)
                {
                    bcc.CompileExpression(parser, buffer, value, true);
                    FieldReference fieldReference = (FieldReference)assignment.Target;
                    if (fieldReference.Field.Modifiers.HasStatic)
                    {
                        buffer.Add(
                            assignment.OpToken,
                            OpCode.ASSIGN_STATIC_FIELD,
                            ((ClassDefinition)fieldReference.Field.Owner).ClassID,
                            fieldReference.Field.StaticMemberID);
                    }
                    else
                    {
                        buffer.Add(
                            assignment.OpToken,
                            OpCode.ASSIGN_THIS_FIELD,
                            fieldReference.Field.MemberID);
                    }
                }
                else
                {
                    throw new Exception("This shouldn't happen.");
                }
            }
            else
            {
                Ops op = assignment.Op;
                if (assignment.Target is Variable)
                {
                    Variable   varTarget = (Variable)assignment.Target;
                    VariableId varId     = varTarget.VarId;
                    bool       isClosure = varId.UsedByClosure;
                    int        scopeId   = isClosure ? varId.ClosureID : varId.ID;

                    buffer.Add(varTarget.FirstToken, isClosure ? OpCode.DEREF_CLOSURE : OpCode.LOCAL, scopeId);
                    bcc.CompileExpression(parser, buffer, value, true);
                    buffer.Add(assignment.OpToken, OpCode.BINARY_OP, (int)op);
                    buffer.Add(assignment.Target.FirstToken, isClosure ? OpCode.ASSIGN_CLOSURE : OpCode.ASSIGN_LOCAL, scopeId);
                }
                else if (assignment.Target is DotField)
                {
                    DotField dotExpr            = (DotField)assignment.Target;
                    int      fieldId            = parser.GetId(dotExpr.FieldToken.Value);
                    int      localeScopedStepId = parser.GetLocaleCount() * fieldId + parser.GetLocaleId(dotExpr.Owner.FileScope.CompilationScope.Locale);
                    bcc.CompileExpression(parser, buffer, dotExpr.Root, true);
                    if (!(dotExpr.Root is ThisKeyword))
                    {
                        buffer.Add(null, OpCode.DUPLICATE_STACK_TOP, 1);
                    }
                    buffer.Add(
                        dotExpr.DotToken,
                        OpCode.DEREF_DOT,
                        fieldId,
                        localeScopedStepId,
                        assignment.ClassOwner == null ? -1 : assignment.ClassOwner.ClassID,
                        assignment.CompilationScope.ScopeNumId,
                        -1, 0);
                    bcc.CompileExpression(parser, buffer, value, true);
                    buffer.Add(assignment.OpToken, OpCode.BINARY_OP, (int)op);
                    if (dotExpr.Root is ThisKeyword)
                    {
                        buffer.Add(assignment.OpToken, OpCode.ASSIGN_THIS_FIELD, fieldId);
                    }
                    else
                    {
                        int localeScopedNameId = fieldId * parser.GetLocaleCount() + parser.GetLocaleId(dotExpr.Owner.FileScope.CompilationScope.Locale);
                        buffer.Add(
                            assignment.OpToken,
                            OpCode.ASSIGN_FIELD,
                            fieldId,
                            0,
                            localeScopedNameId,
                            assignment.ClassOwner == null ? -1 : assignment.ClassOwner.ClassID,
                            assignment.CompilationScope.ScopeNumId,
                            -1, 0);
                    }
                }
                else if (assignment.Target is BracketIndex)
                {
                    BracketIndex indexExpr = (BracketIndex)assignment.Target;
                    bcc.CompileExpression(parser, buffer, indexExpr.Root, true);
                    bcc.CompileExpression(parser, buffer, indexExpr.Index, true);
                    buffer.Add(null, OpCode.DUPLICATE_STACK_TOP, 2);
                    buffer.Add(indexExpr.BracketToken, OpCode.INDEX);
                    bcc.CompileExpression(parser, buffer, value, true);
                    buffer.Add(assignment.OpToken, OpCode.BINARY_OP, (int)op);
                    buffer.Add(assignment.OpToken, OpCode.ASSIGN_INDEX, 0);
                }
                else if (assignment.Target is FieldReference)
                {
                    FieldReference fieldRef = (FieldReference)assignment.Target;
                    FieldReferenceEncoder.Compile(parser, buffer, fieldRef, true);
                    bcc.CompileExpression(parser, buffer, value, true);
                    buffer.Add(assignment.OpToken, OpCode.BINARY_OP, (int)op);

                    if (fieldRef.Field.Modifiers.HasStatic)
                    {
                        buffer.Add(
                            assignment.OpToken,
                            OpCode.ASSIGN_STATIC_FIELD,
                            ((ClassDefinition)fieldRef.Field.Owner).ClassID,
                            fieldRef.Field.StaticMemberID);
                    }
                    else
                    {
                        buffer.Add(
                            assignment.OpToken,
                            OpCode.ASSIGN_THIS_FIELD,
                            fieldRef.Field.MemberID);
                    }
                }
                else
                {
                    throw new ParserException(assignment.OpToken, "Assignment is not allowed on this sort of expression.");
                }
            }
        }
示例#16
0
        private unsafe ushort getVariable(VariableId variableId)
        {
            byte bytes = getVariableBytes(variableId);

            ushort value = 0;
            byte[] array = new byte[bytes];
            try
            {
                controlTransfer(0xC0, 0x81, 0, (ushort)variableId, array);
            }
            catch (Exception e)
            {
                throw new Exception("There was an error getting variable " + variableId.ToString() + " from the device.", e);
            }
            if (bytes == 1)
            {
                // read a single byte
                fixed (byte* pointer = array)
                {
                    value = *(byte*)pointer;
                }
            }
            else
            {
                // read two bytes
                fixed (byte* pointer = array)
                {
                    value = *(ushort*)pointer;
                }
            }
            return value;
        }
示例#17
0
        /// <summary>
        /// Returns the number of bytes that the variable takes.
        /// </summary>
        private byte getVariableBytes(VariableId variableId)
        {
            switch (variableId)
            {
                case VariableId.TARGET_VCC_ALLOWED_MINIMUM:
                case VariableId.TARGET_VCC_ALLOWED_MAXIMUM_RANGE:
                case VariableId.TARGET_VCC_MEASURED_MINIMUM:
                case VariableId.TARGET_VCC_MEASURED_MAXIMUM:
                case VariableId.PROGRAMMING_ERROR:
                case VariableId.LINE_A_IDENTITY:
                case VariableId.LINE_B_IDENTITY:
                case VariableId.SLOSCOPE_STATE:
                case VariableId.SW_MINOR:
                case VariableId.SW_MAJOR:
                case VariableId.HW_VER:
                case VariableId.SCK_DURATION:
                    return 1;

                case VariableId.FVR_ADC:
                case VariableId.SLOSCOPE_OUTPUT_STATE:
                    return 2;

                default: throw new Exception("Unrecognized variabledId " + variableId.ToString());
            }
        }
示例#18
0
 public IteratorStr(String iteratorName, VariableId listData)
 {
     this.iteratorName = iteratorName;
     this.listData     = listData;
 }
示例#19
0
 public double GetValue(VariableId id) => Stats[id.StatId].GetVariable(id);
示例#20
0
 private void setVariable(VariableId variableId, ushort value)
 {
     try
     {
         controlTransfer(0x40, 0x82, value, (ushort)variableId);
     }
     catch (Exception e)
     {
         throw new Exception("There was an error setting variable " + variableId.ToString() + " on the device.", e);
     }
 }
示例#21
0
        public static void Compile(ByteCodeCompiler bcc, ParserContext 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;
                VariableId varId        = variable.VarId;
                bool       isClosureVar = varId.UsedByClosure;
                int        scopeId      = isClosureVar ? varId.ClosureID : varId.ID;
                bcc.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)Ops.ADDITION : (int)Ops.SUBTRACTION);
                    buffer.Add(increment.IncrementToken, OpCode.DUPLICATE_STACK_TOP, 1);
                    buffer.Add(variable.FirstToken, isClosureVar ? OpCode.ASSIGN_CLOSURE : 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)Ops.ADDITION : (int)Ops.SUBTRACTION);
                    buffer.Add(variable.FirstToken, isClosureVar ? OpCode.ASSIGN_CLOSURE : OpCode.ASSIGN_LOCAL, scopeId);
                }
            }
            else if (increment.Root is BracketIndex)
            {
                BracketIndex bracketIndex = (BracketIndex)increment.Root;
                bcc.CompileExpression(parser, buffer, bracketIndex.Root, true);
                bcc.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)Ops.ADDITION : (int)Ops.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)Ops.ADDITION : (int)Ops.SUBTRACTION);
                    buffer.Add(increment.IncrementToken, OpCode.ASSIGN_INDEX, 0);
                }
            }
            else if (increment.Root is DotField)
            {
                DotField dotStep = (DotField)increment.Root;
                bcc.CompileExpression(parser, buffer, dotStep.Root, true);
                buffer.Add(increment.IncrementToken, OpCode.DUPLICATE_STACK_TOP, 1);
                int nameId             = parser.GetId(dotStep.FieldToken.Value);
                int localeScopedNameId = nameId * parser.GetLocaleCount() + parser.GetLocaleId(dotStep.Owner.FileScope.CompilationScope.Locale);
                int originClassId      = increment.ClassOwner == null ? -1 : increment.ClassOwner.ClassID;
                int originAssemblyId   = increment.CompilationScope.ScopeNumId;
                buffer.Add(
                    dotStep.DotToken,
                    OpCode.DEREF_DOT,
                    nameId,
                    localeScopedNameId,
                    originClassId,
                    increment.CompilationScope.ScopeNumId,
                    -1, 0);
                if (increment.IsPrefix)
                {
                    buffer.Add(increment.IncrementToken, OpCode.LITERAL, parser.GetIntConstant(1));
                    buffer.Add(increment.IncrementToken, OpCode.BINARY_OP, increment.IsIncrement ? (int)Ops.ADDITION : (int)Ops.SUBTRACTION);
                    buffer.Add(increment.IncrementToken, OpCode.ASSIGN_FIELD, nameId, 1, localeScopedNameId, originClassId, originAssemblyId, -1, 0);
                }
                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)Ops.ADDITION : (int)Ops.SUBTRACTION);
                    buffer.Add(increment.IncrementToken, OpCode.ASSIGN_FIELD, nameId, 0, localeScopedNameId, originClassId, originAssemblyId, -1, 0);
                    buffer.Add(increment.IncrementToken, OpCode.STACK_SWAP_POP);
                }
            }
            else if (increment.Root is FieldReference)
            {
                FieldReference  fr       = (FieldReference)increment.Root;
                bool            isStatic = fr.Field.Modifiers.HasStatic;
                ClassDefinition cd       = (ClassDefinition)fr.Field.Owner;
                int             memberId = isStatic ? fr.Field.StaticMemberID : fr.Field.MemberID;

                bcc.CompileExpression(parser, buffer, fr, true);
                if (increment.IsPrefix)
                {
                    buffer.Add(increment.IncrementToken, OpCode.LITERAL, parser.GetIntConstant(1));
                    buffer.Add(increment.IncrementToken, OpCode.BINARY_OP, increment.IsIncrement ? (int)Ops.ADDITION : (int)Ops.SUBTRACTION);
                    buffer.Add(increment.IncrementToken, OpCode.DUPLICATE_STACK_TOP, 1);
                }
                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)Ops.ADDITION : (int)Ops.SUBTRACTION);
                }
                Token token = increment.IsPrefix ? increment.FirstToken : fr.FirstToken;
                if (isStatic)
                {
                    buffer.Add(token, OpCode.ASSIGN_STATIC_FIELD, ((ClassDefinition)fr.Field.Owner).ClassID, memberId);
                }
                else
                {
                    buffer.Add(token, OpCode.ASSIGN_THIS_FIELD, memberId);
                }
            }
            else
            {
                throw new ParserException(increment.IncrementToken, "Cannot apply " + (increment.IsIncrement ? "++" : "--") + " to this sort of expression.");
            }
        }