示例#1
0
 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);
     }
 }
示例#2
0
 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));
 }
示例#3
0
        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);
        }
示例#4
0
 internal ZeroInput(PreprocessorContext pp) : base(pp)
 {
 }
示例#5
0
 /// <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;
 }
示例#7
0
 internal void setPpContext(PreprocessorContext pp)
 {
     ppContext = pp;
 }
示例#8
0
 internal MarkerInput(PreprocessorContext pp) : base(pp)
 {
 }
示例#9
0
        /// <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);
        }
示例#10
0
 protected BasePreprocessorInput(PreprocessorContext p)
 {
     done = false;
     pp   = p;
 }
示例#11
0
 /// <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;
 }
示例#12
0
 internal TokenInput(PreprocessorContext pp, TokenStream t) : base(pp)
 {
     tokens = t;
 }
示例#13
0
 internal UngotTokenInput(PreprocessorContext pp, int t, PreprocessorToken p)
     : base(pp)
 {
     token = t;
     lval  = p;
 }