/// <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; }
/// <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>(); }
/// <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); }
/// <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(); }
/// <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)); }