Beispiel #1
0
        public override void Assignment(Token varName, bool withArrayIndex)
        {
            //This is slightly tricky. We need to have the address of the
            //variable to which we're doing the assignment on the stack,
            //and then everything is really easy. If it's an array, we need
            //the address of the array element to which we're doing the
            //assignment (its index is on the stack following the LHS value).

            if (MethodSymTable.HasSymbol(varName.Value))
            {
                Symbol symbol = MethodSymTable.GetSymbol(varName.Value);

                Contract.Assert(symbol.Kind == SymbolKind.Local ||
                                symbol.Kind == SymbolKind.Parameter);

                Output.WriteLine("  __PUSH((__WORD)&{0});", symbol.Name);
            }
            else
            {
                Contract.Assert(ClassSymTable.HasSymbol(varName.Value));
                Symbol symbol = ClassSymTable.GetSymbol(varName.Value);

                if (symbol.Kind == SymbolKind.Static)
                {
                    Output.WriteLine("  __PUSH((__WORD)&{0});", FormatStaticName(symbol.Name));
                }
                else if (symbol.Kind == SymbolKind.Field)
                {
                    Output.WriteLine("  __PUSH((__WORD)&((({0}*)THIS)->{1}));", _currentClassName, symbol.Name);
                }
            }

            //If it's an array, obtain the address of the right element by
            //adding the index which is on the stack. We need a scratch
            //location because issuing two __POP() calls in the same statement
            //does not guarantee left-to-right evaluation.
            if (withArrayIndex)
            {
                //The array address is now on the stack, but we really need the
                //address of the first element. Hence the dereference:
                Output.WriteLine("  __SCRATCH2 = *(__WORD*)__POP();");
                //This is the RHS value that we ought to put in the array element:
                Output.WriteLine("  __SCRATCH1 = __POP();");
                //Finally, the top of the stack contains the value of the array
                //indexing expression, i.e. the element index:
                Output.WriteLine("  * ( ((__WORD*)__SCRATCH2) + __POP() ) = __SCRATCH1;");
            }
            else
            {
                Output.WriteLine("  __SCRATCH1 = __POP();"); //This is the LHS
                Output.WriteLine("  * ((__WORD*)__SCRATCH1) = __POP();");
            }
        }
Beispiel #2
0
        public override void VariableRead(Token varName, bool withArrayIndex)
        {
            //Put the value of the variable on the top of the stack. If it's
            //an array, the value is the address of the array's first element.
            if (MethodSymTable.HasSymbol(varName.Value))
            {
                Symbol symbol = MethodSymTable.GetSymbol(varName.Value);

                Contract.Assert(symbol.Kind == SymbolKind.Local ||
                                symbol.Kind == SymbolKind.Parameter);

                Output.WriteLine("  __PUSH({0});", symbol.Name);
            }
            else
            {
                Contract.Assert(ClassSymTable.HasSymbol(varName.Value));
                Symbol symbol = ClassSymTable.GetSymbol(varName.Value);

                if (symbol.Kind == SymbolKind.Static)
                {
                    Output.WriteLine("  __PUSH({0});", FormatStaticName(symbol.Name));
                }
                else if (symbol.Kind == SymbolKind.Field)
                {
                    Output.WriteLine("  __PUSH((({0}*)THIS)->{1});", _currentClassName, symbol.Name);
                }
            }

            //If it's an array, dereference it using []. We need a scratch
            //location because issuing two __POP() calls in the same statement
            //does not guarantee left-to-right evaluation.
            if (withArrayIndex)
            {
                Output.WriteLine("  __SCRATCH1 = __POP();");
                Output.WriteLine("  __PUSH( ((__WORD*)__SCRATCH1)[ __POP() ] );");
            }
        }