static bool EvalIfCondition(Dictionary <string, Define> defines, Token[] tokens) { try { var report = new Report(); var expressions = new Dictionary <string, Expression> (); foreach (var d in defines) { if (d.Value.Body.Length == 0) { continue; } var e = CParser.TryParseExpression(report, d.Value.Body); if (e != null) { expressions[d.Key] = e; } } var expression = CParser.TryParseExpression(report, tokens); if (expression == null) { return(false); } var context = new PreprocessorContext(report, defines, expressions); var value = expression.EvalConstant(context); return(value.Int32Value != 0); } catch (Exception ex) { Debug.WriteLine(ex); return(false); } }
public override ResolvedVariable?TryResolveVariable(string name, CType[]?argTypes) { if (expressions.TryGetValue(name, out var expression)) { // New context to prevent infinitie recursion var nex = new Dictionary <string, Expression> (expressions); var nctx = new PreprocessorContext(Report, defines, nex); var value = expression.EvalConstant(nctx); return(new ResolvedVariable(value, CBasicType.SignedInt)); } return(base.TryResolveVariable(name, argTypes)); }
internal bool DoStuff(ParseContext parseContext, PreprocessorContext ppContext, InputScanner input, bool versionWillBeError) { //bool versionWillBeError = true; var unNeededSpaceTokens = new HashSet <char>(new char[] { ';', '(', ')', '[', ']' }); var noSpaceBeforeTokens = new HashSet <char>(new char[] { ',' }); var outputStream = new StringBuilder(); int lastLine = -1; // lastLine is the line number of the last token // processed. It is tracked in order for new-lines to be inserted when // a token appears on a new line. int lastToken = -1; parseContext.setScanner(input); ppContext.setInput(input, versionWillBeError); // Inserts newlines and incremnets lastLine until // lastLine >= line. Action <int> adjustLine = (line) => { int tokenLine = line - 1; while (lastLine < tokenLine) { if (lastLine >= 0) { outputStream.AppendLine(); } ++lastLine; } }; parseContext.ExtensionCallback = (int line, string extension, string behavior) => { adjustLine(line); outputStream.Append("#extension ").Append(extension).Append(" : ").Append(behavior); }; parseContext.LineCallback = (int line, bool hasSource, int sourceNum) => { // SourceNum is the number of the source-string that is being parsed. if (lastLine != -1) { outputStream.AppendLine(); } outputStream.Append("#line ").Append(line); if (hasSource) { outputStream.Append(" ").Append(sourceNum); } outputStream.AppendLine(); lastLine = System.Math.Max(line - 1, 1); }; parseContext.VersionCallback = (int line, int version, string str) => { adjustLine(line); outputStream.Append("#version ").Append(version); if (str != null) { outputStream.Append(" ").Append(str); } outputStream.AppendLine(); ++lastLine; }; parseContext.PragmaCallback = (int line, List <string> ops) => { adjustLine(line); outputStream.Append("#pragma "); foreach (var op in ops) { outputStream.Append(op); } }; parseContext.ErrorCallback = (int line, string errorMessage) => { adjustLine(line); outputStream.Append("#error ").Append(errorMessage); }; var token = new PreprocessorToken(); string tok = ppContext.tokenize(ref token); while (tok != null) { int tokenLine = token.loc.line - 1; // start at 0; bool newLine = false; while (lastLine < tokenLine) { if (lastLine > -1) { outputStream.AppendLine(); newLine = true; } ++lastLine; if (lastLine == tokenLine) { // Don't emit whitespace onto empty lines. // Copy any whitespace characters at the start of a line // from the input to the output. for (int i = 0; i < token.loc.column - 1; ++i) { outputStream.Append(" "); } } } // Output a space in between tokens, but not at the start of a line, // and also not around special tokens. This helps with readability // and consistency. if (!newLine && lastToken != -1 && (!unNeededSpaceTokens.Contains((char)token.token)) && (!unNeededSpaceTokens.Contains((char)lastToken)) && (!noSpaceBeforeTokens.Contains((char)token.token))) { outputStream.Append(" "); } lastToken = token.token; outputStream.Append(tok); tok = ppContext.tokenize(ref token); } outputStream.AppendLine(); Output = outputStream.ToString(); return(true); }
internal ZeroInput(PreprocessorContext pp) : base(pp) { }
/// <summary> /// From PpScanner.cpp /// </summary> /// <param name="pp">Pp.</param> /// <param name="i">The index.</param> internal StringInput(PreprocessorContext pp, InputScanner i) : base(pp) { input = i; }
protected BasePreprocessorInput(PreprocessorContext p) { done = false; pp = p; }
internal void setPpContext(PreprocessorContext pp) { ppContext = pp; }
internal MarkerInput(PreprocessorContext pp) : base(pp) { }
/// <summary> /// Processes the deferred. /// </summary> /// <returns><c>true</c>, if deferred was processed, <c>false</c> otherwise.</returns> /// <param name="shaderStrings">Shader strings.</param> /// <param name="defaultVersion">use 100 for ES environment, 110 for desktop</param> /// <param name="defaultProfile">Default profile.</param> /// <param name="forceDefaultVersionAndProfile">set version/profile to defaultVersion/defaultProfile regardless of the #version directive in the source code </param> /// <param name="forwardCompatible">give errors for use of deprecated features</param> /// <param name="messages">warnings/errors/AST; things to print out</param> /// <param name="processingContext">Processing context.</param> private bool ProcessDeferred( string[] shaderStrings, int defaultVersion, Profile defaultProfile, bool forceDefaultVersionAndProfile, bool forwardCompatible, MessageType messages, Func <ParseContext, PreprocessorContext, InputScanner, bool, bool> processingContext) { if (shaderStrings.Length == 0) { return(true); } // First, without using the preprocessor or parser, find the #version, so we know what // symbol tables, processing rules, etc. to set up. This does not need the extra strings // outlined above, just the user shader. int version; Profile profile; var userInput = new InputScanner(shaderStrings, 0, 0); // no preamble bool versionNotFirstToken; bool versionNotFirst = userInput.scanVersion(out version, out profile, out versionNotFirstToken); bool versionNotFound = version == 0; if (forceDefaultVersionAndProfile) { if (((messages & MessageType.SuppressWarnings) == 0) && !versionNotFound && (version != defaultVersion || profile != defaultProfile)) { mInfoSink.Info .Append("Warning, (version, profile) forced to be (") .Append(defaultVersion.ToString()) .Append(", ") .Append(ProfileName(defaultProfile)) .Append("), while in source code it is (") .Append(version.ToString()) .Append(", ") .Append(ProfileName(profile)) .Append(")\n"); } if (versionNotFound) { versionNotFirstToken = false; versionNotFirst = false; versionNotFound = false; } version = defaultVersion; profile = defaultProfile; } bool goodVersion = DeduceVersionProfile( mInfoSink, mLanguage, versionNotFirst, defaultVersion, ref version, ref profile); bool versionWillBeError = (versionNotFound || (profile == Profile.EsProfile && version >= 300 && versionNotFirst)); bool warnVersionNotFirst = false; if (!versionWillBeError && versionNotFirstToken) { if ((messages & MessageType.RelaxedErrors) > 0) { warnVersionNotFirst = true; } else { versionWillBeError = true; } } mIntermediate.setVersion(version); mIntermediate.setProfile(profile); // // Now we can process the full shader under proper symbols and rules. // var parseContext = new ParseContext(version, profile, mInfoSink, forwardCompatible, mSymbols, mIntermediate); var ppContext = new PreprocessorContext(parseContext, mSymbols); parseContext.setPpContext(ppContext); if (!goodVersion) { parseContext.addError(); } if (warnVersionNotFirst) { SourceLocation loc = new SourceLocation(); parseContext.Warn(loc, "Illegal to have non-comment, non-whitespace tokens before #version", "#version", ""); } parseContext.initializeExtensionBehavior(); var fullInput = new InputScanner(shaderStrings, 0, 0); bool success = processingContext(parseContext, ppContext, fullInput, versionWillBeError); return(success); }
internal TokenInput(PreprocessorContext pp, TokenStream t) : base(pp) { tokens = t; }
internal UngotTokenInput(PreprocessorContext pp, int t, PreprocessorToken p) : base(pp) { token = t; lval = p; }