internal void SetInput(InputScanner input, bool versionWillBeError)
        {
            Debug.Assert(inputStack.Count == 0);

            pushInput(new StringInput(this, input));

            errorOnVersion = versionWillBeError;
            versionSeen = false;
        }
Beispiel #2
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);
        }
        internal void setInput(InputScanner input, bool versionWillBeError)
        {
            if (inputStack.Count != 0)
            {
                throw new Exception ("Stack is use");
            }

            pushInput(new StringInput(this, input));

            errorOnVersion = versionWillBeError;
            versionSeen = false;
        }
Beispiel #4
0
 internal void setScanner(InputScanner scanner)
 {
     currentScanner = scanner;
 }
Beispiel #5
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);
        }
Beispiel #6
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;
        }
Beispiel #7
0
 internal void setScanner(InputScanner scanner)
 {
     currentScanner = scanner;
 }