/// <name>ForwardReference</name>
 /// <type>Constructor</type>
 /// <summary>
 /// Creates a new forward reference object with initialization.
 /// </summary>
 /// <param name="instructionLocation">Instruction initialization parameter</param>
 /// <param name="reference">Reference symbol parameter</param>
 public ForwardReference(int instructionLocation, Symbol reference)
     : base()
 {
     this.instructionLocation = instructionLocation;
     this.reference = reference;
 }
예제 #2
0
 /// <name>Parser</name>
 /// <type>Constructor</type>
 /// <summary>
 /// Creates a parser object.
 /// </summary>
 public Parser()
     : base()
 {
     // Initalize class variables
     currentOperator = new Token(TokenType.NO_TOKEN, String.Empty);
     nextOperator = new Token(TokenType.NO_TOKEN, String.Empty);
     operand = null;
     literal = null;
     symbol = null;
     inExpression = false;
     nextLocation = 1;
     symbolTable = new Dictionary<string, Symbol>();
     literalTable = new Dictionary<string, Literal>();
     operatorStack = new Stack<Token>();
     structureStack = new Stack<Structure>();
     forwardRefStack = new Stack<ForwardReference>();
 }
예제 #3
0
        /// <name>Advance</name>
        /// <type>Method</type>
        /// <summary>
        /// Advances the current and next operators from the input file and 
        /// populates the operand token between the operators if one exists.
        /// </summary>
        private void Advance()
        {
            // Advance one token
            currentOperator = (Token)nextOperator.Clone();
            Token peekToken = source.GetNextToken();

            // Make sure operand, symbol and literal are null
            operand = null;
            symbol = null;
            literal = null;

            if (peekToken.Type == TokenType.SYMBOL)
            {
                // If the new token is a symbol then set operand to that token
                operand = (Token)peekToken.Clone();

                // Now check to see if the symbol is already defined - if
                // it is then assign to symbol, otherwise add it to the table
                if (symbolTable.ContainsKey(peekToken.Lexeme))
                {
                    symbol = symbolTable[peekToken.Lexeme];
                }
                else
                {
                    symbolTable.Add(peekToken.Lexeme, new Symbol(peekToken.Lexeme));
                    symbol = symbolTable[peekToken.Lexeme];
                }

                // Finally get the next token
                nextOperator = source.GetNextToken();
            }
            else if (peekToken.Type == TokenType.LITERAL)
            {
                // If the new token is a literal then set operand to that token
                operand = (Token)peekToken.Clone();

                // Now check to see if the literal is already defined - if
                // it is then assign to literal, otherwise add it to the table
                if (literalTable.ContainsKey(peekToken.Lexeme))
                {
                    literal = literalTable[peekToken.Lexeme];
                }
                else
                {
                    literalTable.Add(peekToken.Lexeme, new Literal(peekToken.Lexeme));
                    literal = literalTable[peekToken.Lexeme];
                }

                // Finally get the next token
                nextOperator = source.GetNextToken();
            }
            else
            {
                // Set the next operator to the token we just retrieved
                nextOperator = (Token)peekToken.Clone();
            }

            // Output debug information
            Compiler.WriteToDebug("Parser - Advance called (line " + Compiler.LineNumber + ")");
            Compiler.WriteToDebug("   current operator:\t" + currentOperator.Lexeme);
            if (operand != null)
            {
                Compiler.WriteToDebug("   operand:\t\t" + operand.Lexeme);
            }
            Compiler.WriteToDebug("   next operator:\t" + nextOperator.Lexeme);
            Compiler.WriteToDebug(String.Empty);
        }
예제 #4
0
        /// <name>CompileProcedures</name>
        /// <type>Method</type>
        /// <summary>
        /// Compile program procedures.
        /// </summary>
        private void CompileProcedures()
        {
            status = Status.CONTINUE;

            // If there's a procedure declaration in the program then we need a new
            // symbol to define the start on the main program's execution when we get
            // to it, so create the symbol now and save it as a forward reference
            if (nextOperator.Type == TokenType.PROC)
            {
                Symbol main = new Symbol("$MAIN");
                symbolTable.Add(main.Lexeme, main);
                SaveForwardReference(main, jvm.ProgramCounter);
                jvm.Emit(Opcode.GOTO, 0);
            }

            // Keep going until the end block of the program structure is reached
            while (structureStack.Count > 0)
            {
                CodeGenerator(currentOperator, nextOperator);
                Advance();
            }

            // Pop the forward references left and fill with the appropriate address
            FillForwardReferences();
        }
예제 #5
0
 /// <name>SaveForwardReference</name>
 /// <type>Method</type>
 /// <summary>
 /// Push a forward reference onto the stack.  This contains a symbol
 /// whose actual address in the code is not yet known.
 /// </summary>
 /// <param name="reference">Reference symbol</param>
 /// <param name="address">Address of the reference symbol</param>
 private void SaveForwardReference(Symbol reference, int address)
 {
     forwardRefStack.Push(new ForwardReference(address, reference));
 }