private PPNode ParsePreprocessorDirective() { PPNode result = null; int startLine = lineCount; inPPDirective = true; Advance(); // over hash IdentifierExpression ie = (IdentifierExpression)ParseIdentifierOrKeyword(false, false, false, false); string ppKind = ie.Identifier; PreprocessorID id = PreprocessorID.Empty; if (preprocessor.ContainsKey(ppKind)) { id = preprocessor[ppKind]; } else { ReportError("Preprocessor directive must be valid identifier, rather than \"" + ppKind + "\"."); } switch (id) { case PreprocessorID.Define: // conditional-symbol pp-newline IdentifierExpression def = (IdentifierExpression)ParseIdentifierOrKeyword(false, false, false, false); if (!ppDefs.ContainsKey(def.Identifier)) { ppDefs.Add(def.Identifier, PreprocessorID.Empty); } result = new PPDefineNode(def ); break; case PreprocessorID.Undef: // conditional-symbol pp-newline IdentifierExpression undef = (IdentifierExpression)ParseIdentifierOrKeyword(false, false, false, false); if(ppDefs.ContainsKey(undef.Identifier)) { ppDefs.Remove(undef.Identifier); } result = new PPDefineNode(undef ); break; case PreprocessorID.If: // pp-expression pp-newline conditional-section(opt) if (curtok.ID == TokenID.LParen) { Advance(); } //int startCount = lineCount; ppCondition = false; // todo: account for true, false, ||, &&, ==, !=, ! //IdentifierExpression ifexpr = (IdentifierExpression)ParseIdentifierOrKeyword(false, false, false, false); ExpressionNode ifexpr = ParseExpression(true); // TODO : Parse and interpret identifier : mono file test-345.cs -> #if (!TEST && !DUNNO && !DUNNO) if ( (ifexpr is IdentifierExpression) && ppDefs.ContainsKey(((IdentifierExpression)ifexpr).Identifier)) { ppCondition = true; } //result = new PPIfNode(ParseExpressionToNewline()); if (curtok.ID == TokenID.RParen) { Advance(); } if (ppCondition == false) { // skip this block SkipToElseOrEndIf(); } break; case PreprocessorID.Elif: // pp-expression pp-newline conditional-section(opt) SkipToEOL(startLine); break; case PreprocessorID.Else: // pp-newline conditional-section(opt) if (ppCondition) { // skip this block SkipToElseOrEndIf(); } break; case PreprocessorID.Endif: // pp-newline result = new PPEndIfNode(curtok); ppCondition = false; break; case PreprocessorID.Line: // line-indicator pp-newline SkipToEOL(startLine); break; case PreprocessorID.Error: // pp-message SkipToEOL(startLine); break; case PreprocessorID.Warning: // pp-message SkipToEOL(startLine); break; case PreprocessorID.Region: // pp-message SkipToEOL(startLine); break; case PreprocessorID.Endregion: // pp-message SkipToEOL(startLine); break; case PreprocessorID.Pragma: // pp-message //pragma-warning-body: // warning whitespace warning-action // warning whitespace warning-action whitespace warning-list int start_line = curtok.Line; result = new PPPragmaNode(curtok); if (curtok.Line == start_line) { ((PPPragmaNode)result).Identifier = (IdentifierExpression)ParseIdentifierOrKeyword(false, false, false, false); } if (curtok.Line == start_line) { string paction = ((IdentifierExpression)ParseIdentifierOrKeyword(false, false, false, false)).Identifier; ((PPPragmaNode)result).Action = (PragmaAction)Enum.Parse(typeof(PragmaAction), paction); } while (curtok.Line == start_line) { if (curtok.ID != TokenID.Comma) { if (curtok.ID == TokenID.IntLiteral) { ((PPPragmaNode)result).Value.Add(new ConstantExpression(new IntegralPrimitive(strings[curtok.Data], IntegralType.Int, curtok) )); } else { if (curtok.ID == TokenID.UIntLiteral) { ((PPPragmaNode)result).Value.Add(new ConstantExpression(new IntegralPrimitive(strings[curtok.Data], IntegralType.UInt,curtok) )); } else { if (curtok.ID == TokenID.LongLiteral) { ((PPPragmaNode)result).Value.Add(new ConstantExpression(new IntegralPrimitive(strings[curtok.Data], IntegralType.Long, curtok) )); } else { if (curtok.ID == TokenID.ULongLiteral) { ((PPPragmaNode)result).Value.Add(new ConstantExpression(new IntegralPrimitive(strings[curtok.Data], IntegralType.ULong, curtok) )); } else { RecoverFromError(TokenID.IntLiteral); } } } } } Advance(); } ppCondition = true; break; default: break; } inPPDirective = false; return result; }
private PPNode ParsePreprocessorDirective() { PPNode result = null; int startLine = lineCount; inPPDirective = true; Advance(); // over hash IdentifierExpression ie = (IdentifierExpression)ParseIdentifierOrKeyword(false, false, false, false, false); string ppKind = ie.Identifier; PreprocessorID id = PreprocessorID.Empty; if (preprocessor.ContainsKey(ppKind)) { id = preprocessor[ppKind]; } else { ReportError("Preprocessor directive must be valid identifier, rather than \"" + ppKind + "\"."); } switch (id) { case PreprocessorID.Define: // conditional-symbol pp-newline if (curtok.ID == TokenID.True || curtok.ID == TokenID.False) { ReportError("Conditional symbol may neither be true nor false"); Advance(); break; } IdentifierExpression def = (IdentifierExpression)ParseIdentifierOrKeyword(false, false, false, false, false); if (!cu.PPDefs.ContainsKey(def.Identifier)) { cu.PPDefs.Add(def.Identifier, PreprocessorID.Empty); } result = new PPDefineNode(def); break; case PreprocessorID.Undef: // conditional-symbol pp-newline IdentifierExpression undef = (IdentifierExpression)ParseIdentifierOrKeyword(false, false, false, false, false); if (cu.PPDefs.ContainsKey(undef.Identifier)) { cu.PPDefs.Remove(undef.Identifier); } // result = new PPDefineNode(undef ); break; case PreprocessorID.If: // pp-expression pp-newline conditional-section(opt) ppCondition = EvalPPExpression(ParsePreprocessorExpression()); //result = new PPIfNode(ParseExpressionToNewline()); if (!ppCondition) { // skip this block SkipToElseOrEndIf(); } break; case PreprocessorID.Elif: // pp-expression pp-newline conditional-section(opt) if (ppCondition) // a previous part was already true? { SkipToElseOrEndIf(); break; } ppCondition = EvalPPExpression(ParsePreprocessorExpression()); if (!ppCondition) { // skip this block SkipToElseOrEndIf(); } break; case PreprocessorID.Else: // pp-newline conditional-section(opt) if (ppCondition) { // skip this block SkipToElseOrEndIf(); } break; case PreprocessorID.Endif: // pp-newline result = new PPEndIfNode(curtok); ppCondition = false; break; case PreprocessorID.Line: // line-indicator pp-newline SkipToEOL(startLine); break; case PreprocessorID.Error: // pp-message SkipToEOL(startLine); break; case PreprocessorID.Warning: // pp-message SkipToEOL(startLine); break; case PreprocessorID.Region: // pp-message SkipToEOL(startLine); break; case PreprocessorID.Endregion: // pp-message SkipToEOL(startLine); break; case PreprocessorID.Pragma: { // pp-message //pragma-warning-body: // warning whitespace warning-action // warning whitespace warning-action whitespace warning-list int start_line = curtok.Line; PPPragmaNode pppnode = new PPPragmaNode(curtok); result = pppnode; if (curtok.Line == start_line) { pppnode.Identifier = (IdentifierExpression)ParseIdentifierOrKeyword(false, false, false, false, false); } if (curtok.Line == start_line) { string paction = ((IdentifierExpression)ParseIdentifierOrKeyword(false, false, false, false, false)).Identifier; pppnode.Action = (PragmaAction)Enum.Parse(typeof(PragmaAction), paction); } while (curtok.Line == start_line) { if (curtok.ID != TokenID.Comma) { if (curtok.ID == TokenID.IntLiteral) { pppnode.Value.Add(new ConstantExpression(new IntegralPrimitive(strings[curtok.Data], IntegralType.Int, curtok))); } else { if (curtok.ID == TokenID.UIntLiteral) { pppnode.Value.Add(new ConstantExpression(new IntegralPrimitive(strings[curtok.Data], IntegralType.UInt, curtok))); } else { if (curtok.ID == TokenID.LongLiteral) { pppnode.Value.Add(new ConstantExpression(new IntegralPrimitive(strings[curtok.Data], IntegralType.Long, curtok))); } else { if (curtok.ID == TokenID.ULongLiteral) { pppnode.Value.Add(new ConstantExpression(new IntegralPrimitive(strings[curtok.Data], IntegralType.ULong, curtok))); } else { RecoverFromError(TokenID.IntLiteral); } } } } } Advance(); } break; } default: break; } inPPDirective = false; return result; }