/// <summary> /// /// </summary> public String LogicalOrExpression(ref TTokens Operator) { String Identifier = LogicalAndExpression(ref Operator); do { if (m_LexScanner.NextToken() == TTokens.OROP) { m_LexScanner.Match(TTokens.OROP); Operator = TTokens.OROP; m_CodeGen.AddInstruction(m_MachineCodeOps.ByteOperations.MovWF( (Byte)m_TempStoreMemoryLocation++)); LogicalAndExpression(ref Operator); m_CodeGen.AddInstruction(m_MachineCodeOps.ByteOperations.AndWF(TRegisters.WORKING_REGISTER, Convert.ToByte(--m_TempStoreMemoryLocation))); } } while (m_LexScanner.NextToken() == TTokens.OROP); return Identifier; }
/// <summary> /// /// </summary> public String RelationalExpression(ref TTokens Operator) { String Identifier = ShiftExpression(); do { if (m_LexScanner.NextToken() == TTokens.LTOP) { m_LexScanner.Match(TTokens.LTOP); m_CodeGen.AddInstruction(m_MachineCodeOps.ByteOperations.MovWF( (Byte)m_TempStoreMemoryLocation++)); ShiftExpression(); m_CodeGen.AddInstruction(m_MachineCodeOps.ByteOperations.SubWF(TRegisters.WORKING_REGISTER, Convert.ToByte(--m_TempStoreMemoryLocation))); Operator = TTokens.LTOP; } else if (m_LexScanner.NextToken() == TTokens.GTOP) { m_LexScanner.Match(TTokens.GTOP); m_CodeGen.AddInstruction(m_MachineCodeOps.ByteOperations.MovWF( (Byte)m_TempStoreMemoryLocation++)); ShiftExpression(); m_CodeGen.AddInstruction(m_MachineCodeOps.ByteOperations.SubWF(TRegisters.WORKING_REGISTER, Convert.ToByte(--m_TempStoreMemoryLocation))); Operator = TTokens.GTOP; } else if (m_LexScanner.NextToken() == TTokens.LTEOP) { m_LexScanner.Match(TTokens.LTEOP); m_CodeGen.AddInstruction(m_MachineCodeOps.ByteOperations.MovWF( (Byte)m_TempStoreMemoryLocation++)); ShiftExpression(); m_CodeGen.AddInstruction(m_MachineCodeOps.ByteOperations.SubWF(TRegisters.WORKING_REGISTER, Convert.ToByte(--m_TempStoreMemoryLocation))); Operator = TTokens.LTEOP; } else if (m_LexScanner.NextToken() == TTokens.GTEOP) { m_LexScanner.Match(TTokens.GTEOP); m_CodeGen.AddInstruction(m_MachineCodeOps.ByteOperations.MovWF( (Byte)m_TempStoreMemoryLocation++)); ShiftExpression(); m_CodeGen.AddInstruction(m_MachineCodeOps.ByteOperations.SubWF(TRegisters.WORKING_REGISTER, Convert.ToByte(--m_TempStoreMemoryLocation))); Operator = TTokens.GTEOP; } } while (m_LexScanner.NextToken() == TTokens.LTOP || m_LexScanner.NextToken() == TTokens.GTOP || m_LexScanner.NextToken() == TTokens.LTEOP || m_LexScanner.NextToken() == TTokens.GTEOP); return Identifier; }
/// <summary> /// /// </summary> public String Expression(ref TTokens Operator) { return AssignmentExpression(ref Operator); }
/// <summary> /// /// </summary> public String InclusiveOrExpression(ref TTokens Operator) { String Identifier = ExclusiveOrExpression(ref Operator); if (m_LexScanner.NextToken() == TTokens.ORBITOP) { m_LexScanner.Match(TTokens.ORBITOP); m_CodeGen.AddInstruction(m_MachineCodeOps.ByteOperations.MovWF( (Byte)m_TempStoreMemoryLocation++)); ExclusiveOrExpression(ref Operator); m_CodeGen.AddInstruction(m_MachineCodeOps.ByteOperations.IorWF(TRegisters.WORKING_REGISTER, Convert.ToByte(--m_TempStoreMemoryLocation))); } return Identifier; }
/// <summary> /// /// </summary> /// <param name="Operator"></param> public void BuildBitTestInstruction(TTokens Operator) { switch (Operator) { case TTokens.EQUALOP: m_CodeGen.AddInstruction(m_MachineCodeOps.BitOperations.Btfss(TBits.BIT2, 0x03)); break; case TTokens.NOTEQLOP: m_CodeGen.AddInstruction(m_MachineCodeOps.BitOperations.Btfsc(TBits.BIT2, 0x03)); break; case TTokens.GTOP: // check carry is 0 and zero is 0 m_CodeGen.AddInstruction(m_MachineCodeOps.BitOperations.Btfss(TBits.BIT0, 0x03)); m_CodeGen.AddInstruction(m_MachineCodeOps.ControlOperations.Goto( (Byte)(m_CodeGen.CurrentCodeMemoryLocation + 2))); m_CodeGen.AddInstruction(m_MachineCodeOps.BitOperations.Btfsc(TBits.BIT2, 0x03)); break; case TTokens.GTEOP: // check carry is 0 OR zero is 1 m_CodeGen.AddInstruction(m_MachineCodeOps.BitOperations.Btfsc(TBits.BIT0, 0x03)); m_CodeGen.AddInstruction(m_MachineCodeOps.ControlOperations.Goto( (Byte)(m_CodeGen.CurrentCodeMemoryLocation + 3))); m_CodeGen.AddInstruction(m_MachineCodeOps.BitOperations.Btfss(TBits.BIT2, 0x03)); break; case TTokens.LTOP: // check carry is 1 and zero 0 m_CodeGen.AddInstruction(m_MachineCodeOps.BitOperations.Btfsc(TBits.BIT0, 0x03)); m_CodeGen.AddInstruction(m_MachineCodeOps.ControlOperations.Goto( (Byte)(m_CodeGen.CurrentCodeMemoryLocation + 2))); m_CodeGen.AddInstruction(m_MachineCodeOps.BitOperations.Btfsc(TBits.BIT2, 0x03)); break; case TTokens.LTEOP: // check carry is 1 or zero 1 m_CodeGen.AddInstruction(m_MachineCodeOps.BitOperations.Btfss(TBits.BIT0, 0x03)); m_CodeGen.AddInstruction(m_MachineCodeOps.ControlOperations.Goto( (Byte)(m_CodeGen.CurrentCodeMemoryLocation + 3))); m_CodeGen.AddInstruction(m_MachineCodeOps.BitOperations.Btfss(TBits.BIT2, 0x03)); break; } }
/// <summary> /// /// </summary> public String ConditionalExpression(ref TTokens Operator) { return LogicalOrExpression(ref Operator); }
/// <summary> /// The result will be stored in the working register. /// This method moves the value stored in the working /// register into the L-Value. (The identifier on the left /// side of the assignment operator.) /// </summary> public String AssignmentExpression(ref TTokens Operator) { // The file register, which will store the value // of the assignment operation. String FileRegister = m_LexScanner.TokenValue; Boolean BitLevel = false; UnaryExpression(); BitLevel = m_BitLevelManipulation; do { if (m_LexScanner.NextToken() == TTokens.ASSIGNMENT) { m_LexScanner.Match(TTokens.ASSIGNMENT); ConditionalExpression(ref Operator); // move the result of the expression into the FileRegister. // check the variable is in the symbol table. CVariable T = null; if (m_SymbolTable.Contains(FileRegister) == true) T = (CVariable)m_SymbolTable[FileRegister]; if (BitLevel == true) { // check the value stored in the working register. m_CodeGen.AddInstruction(m_MachineCodeOps.BitOperations.Bcf((TBits)m_VariableIndex, (Byte)T.MemoryAddress)); m_CodeGen.AddInstruction(m_MachineCodeOps.ControlOperations.SubLW(0)); m_CodeGen.AddInstruction(m_MachineCodeOps.BitOperations.Btfss(TBits.BIT2, 3)); m_CodeGen.AddInstruction(m_MachineCodeOps.BitOperations.Bsf((TBits)m_VariableIndex, (Byte)T.MemoryAddress)); } else { if (IsInSecondBank(FileRegister) == true) m_CodeGen.AddInstruction(m_MachineCodeOps.BitOperations.Bsf(TBits.BIT5, 3)); m_CodeGen.AddInstruction(m_MachineCodeOps.ByteOperations.MovWF((Byte)T.MemoryAddress)); m_CodeGen.AddInstruction(m_MachineCodeOps.ByteOperations.Nop()); if (IsInSecondBank(FileRegister) == true) m_CodeGen.AddInstruction(m_MachineCodeOps.BitOperations.Bcf(TBits.BIT5, 3)); } } } while (m_LexScanner.NextToken() == TTokens.ASSIGNMENT); if (m_LexScanner.NextToken() != TTokens.SEMICOL) ConditionalExpression(ref Operator); return FileRegister; }
/// <summary> /// Checks to see if CurrentToken is a data type. /// </summary> /// <param name="CurrentToken">The token to be compared with the datatype tokens.</param> /// <returns>True if CurrentToken is a datatype. Otherwise returns false.</returns> private Boolean IsDataType(TTokens CurrentToken) { switch (CurrentToken) { case TTokens.INT: case TTokens.SIGNED: case TTokens.UNSIGNED: case TTokens.VOID: return true; default: return false; } }
/// <summary> /// Reads the next token from the input stream and stores the tokens /// type in m_CurrentToken. /// </summary> /// <exception cref="Compiler.CLexicalException">Thrown when lexical errors are detected.</exception> private void ReadNextToken() { StringBuilder TokenBuffer = new StringBuilder(""); Char CurrentChar = ' '; if (m_SourceFileStream == null) return; // throw exception. while(m_SourceFileStream.EndOfStream == false) { CurrentChar = (Char)m_SourceFileStream.Peek(); if (CurrentChar == '\n') ++m_LineCount; if (Char.IsWhiteSpace(CurrentChar) != true) { // first check for identifiers and keywords. if (Char.IsLetter(CurrentChar) == true) { TokenBuffer.Append((Char)m_SourceFileStream.Read()); CurrentChar = (Char)m_SourceFileStream.Peek(); // Identifiers can be made up of letters, digits and the underscore. while (Char.IsLetterOrDigit(CurrentChar) || CurrentChar == '_') { TokenBuffer.Append((Char)m_SourceFileStream.Read()); CurrentChar = (Char)m_SourceFileStream.Peek(); } // check to see if the current token is a keyword or an identifer. if(m_Keywords.IndexOf(TokenBuffer.ToString()) == -1) { m_CurrentToken = TTokens.IDENTIFIER; } else { GetKeywordEnumType(TokenBuffer.ToString()); } m_TokenValue = TokenBuffer.ToString(); TokenBuffer.Remove(0, TokenBuffer.Length); return; } else if (Char.IsDigit(CurrentChar) == true) { TokenBuffer.Append((Char)m_SourceFileStream.Read()); CurrentChar = (Char)m_SourceFileStream.Peek(); while (Char.IsDigit(CurrentChar) == true) { TokenBuffer.Append((Char)m_SourceFileStream.Read()); CurrentChar = (Char)m_SourceFileStream.Peek(); } m_CurrentToken = TTokens.LITERAL; m_TokenValue = TokenBuffer.ToString(); TokenBuffer.Remove(0, TokenBuffer.Length); return; } else if (CurrentChar == '(') { m_CurrentToken = TTokens.LPAREN; m_SourceFileStream.Read(); return; } else if (CurrentChar == ')') { m_CurrentToken = TTokens.RPAREN; m_SourceFileStream.Read(); return; } else if (CurrentChar == '{') { m_CurrentToken = TTokens.LCURLY; m_SourceFileStream.Read(); ++m_ScopeLevelCount; return; } else if (CurrentChar == '}') { m_CurrentToken = TTokens.RCURLY; m_SourceFileStream.Read(); --m_ScopeLevelCount; return; } else if (CurrentChar == '[') { m_CurrentToken = TTokens.LBRACKET; m_SourceFileStream.Read(); return; } else if (CurrentChar == ']') { m_CurrentToken = TTokens.RBRACKET; m_SourceFileStream.Read(); return; } else if (CurrentChar == ',') { m_CurrentToken = TTokens.COMMA; m_SourceFileStream.Read(); return; } else if (CurrentChar == ';') { m_CurrentToken = TTokens.SEMICOL; m_SourceFileStream.Read(); return; } else if (CurrentChar == '*') { m_CurrentToken = TTokens.MULOP; m_SourceFileStream.Read(); return; } else if (CurrentChar == '/') { m_SourceFileStream.Read(); if ((Char)m_SourceFileStream.Peek() == '/') { // strip out the comments. do { m_SourceFileStream.Read(); } while ((Char)m_SourceFileStream.Peek() != '\n'); ++m_LineCount; } else { m_CurrentToken = TTokens.DIVOP; m_SourceFileStream.Read(); return; } } else if (CurrentChar == '^') { m_CurrentToken = TTokens.XOROP; m_SourceFileStream.Read(); return; } else if (CurrentChar == '<') { m_SourceFileStream.Read(); if ((Char)m_SourceFileStream.Peek() == '<') { m_SourceFileStream.Read(); m_CurrentToken = TTokens.LSHIFTOP; return; } else if ((Char)m_SourceFileStream.Peek() == '=') { m_CurrentToken = TTokens.LTEOP; m_SourceFileStream.Read(); return; } else { m_CurrentToken = TTokens.LTOP; return; } } else if (CurrentChar == '>') { m_SourceFileStream.Read(); if ((Char)m_SourceFileStream.Peek() == '>') { m_CurrentToken = TTokens.RSHIFTOP; m_SourceFileStream.Read(); return; } else if ((Char)m_SourceFileStream.Peek() == '=') { m_CurrentToken = TTokens.GTEOP; m_SourceFileStream.Read(); return; } else { m_CurrentToken = TTokens.GTOP; return; } } else if (CurrentChar == '+') { m_SourceFileStream.Read(); if ((Char)m_SourceFileStream.Peek() == '+') { m_CurrentToken = TTokens.INCOP; m_SourceFileStream.Read(); return; } else { m_CurrentToken = TTokens.ADDOP; return; } } else if (CurrentChar == '-') { m_SourceFileStream.Read(); if ((Char)m_SourceFileStream.Peek() == '-') { m_CurrentToken = TTokens.DECOP; m_SourceFileStream.Read(); return; } else { m_CurrentToken = TTokens.SUBOP; return; } } else if (CurrentChar == '=') { m_SourceFileStream.Read(); if ((Char)m_SourceFileStream.Peek() == '=') { m_CurrentToken = TTokens.EQUALOP; m_SourceFileStream.Read(); return; } else { m_CurrentToken = TTokens.ASSIGNMENT; return; } } else if (CurrentChar == '!') { m_SourceFileStream.Read(); if ((Char)m_SourceFileStream.Peek() == '=') { m_CurrentToken = TTokens.NOTEQLOP; m_SourceFileStream.Read(); return; } else { m_CurrentToken = TTokens.NOTOP; return; } } else if (CurrentChar == '&') { m_SourceFileStream.Read(); if ((Char)m_SourceFileStream.Peek() == '&') { m_CurrentToken = TTokens.ANDOP; m_SourceFileStream.Read(); return; } else { m_CurrentToken = TTokens.ANDBITOP; return; } } else if (CurrentChar == '|') { m_SourceFileStream.Read(); if ((Char)m_SourceFileStream.Peek() == '|') { m_CurrentToken = TTokens.OROP; m_SourceFileStream.Read(); return; } else { m_CurrentToken = TTokens.ORBITOP; return; } } else throw new CCompilerException("Lexical Error", m_LineCount, TErrorCodes.LEXICAL_ERROR); } else m_SourceFileStream.Read(); } m_CurrentToken = TTokens.EOF; }
/// <summary> /// Assigns the correct enumeration constant to m_CurrentToken. /// </summary> /// <param name="Token">The current token read from the inputstream.</param> private void GetKeywordEnumType(String Token) { switch (Token) { case "if": m_CurrentToken = TTokens.IF; break; case "while": m_CurrentToken = TTokens.WHILE; break; case "int": m_CurrentToken = TTokens.INT; break; case "void": m_CurrentToken = TTokens.VOID; break; case "signed": m_CurrentToken = TTokens.SIGNED; break; case "unsigned": m_CurrentToken = TTokens.UNSIGNED; break; case "do": m_CurrentToken = TTokens.DOWHILE; break; case "return": m_CurrentToken = TTokens.RETURN; break; } }
/// <summary> /// If the token passed to the function matches m_CurrentToken the function reads /// the next token from the source file and return true. /// </summary> /// <param name="Token">The token to me matched with m_CurrentToken</param> /// <returns>Returns true if <c>Token</c> equals <c>m_CurrentToken</c> else the false /// is returned.</returns> public Boolean Match(TTokens Token) { if (Token == m_CurrentToken) { ReadNextToken(); return true; } else return false; }