internal void AddFunctionNameInternal(ShaderFunction function)
        {
            if (!function.Exists)
            {
                Add("/* ERROR: non-existent function specified for function name */");
                return;
            }

            bool useDeferredDeclaration =
                (function.ParentBlock.Exists && !function.ParentBlock.IsValid) ||
                (!function.IsValid);

            if (useDeferredDeclaration)
            {
                Add(_tokenFunctionName, function.handle.ToString(), _tokenEnd);
            }
            else
            {
                // if there's a parent block, the type is in the block namespace
                if (function.ParentBlock.IsValid)
                {
                    Add(function.ParentBlock.Name, _blockNamespaceSuffix);
                }
                Add(function.Name);
            }
        }
        internal void FunctionCallInternal(ShaderFunction function, DeclarationMode mode, params string[] arguments)
        {
            if (!function.Exists)
            {
                Add("/* ERROR: non-existent function specified for function call */");
                return;
            }

            AddFunctionNameInternal(function);

            Add(_openParen);

            // Iterate across the list of parameters (if any) and emit each one
            for (int a = 0; a < arguments.Length; a++)
            {
                if (a > 0)
                {
                    Add(_comma);
                }
                Add(arguments[a]);
            }

            Add(_closeParen);

            if (mode == DeclarationMode.Semicolon)
            {
                Add(_semicolon);
            }
        }
        public void DeclareFunction(ShaderFunction function)
        {
            if (!function.IsValid)
            {
                AddLine("/* ERROR: cannot declare invalid function */");
                return;
            }

            var returnType = function.ReturnType;

            if (!returnType.IsValid)
            {
                AddLine("/* ERROR: cannot declare function with invalid return type */");
                return;
            }

            if (returnType.IsArray)
            {
                AddLine("/* ERROR: cannot declare a function with an array return type */");
                return;
            }

            Indentation();

            AddNonArrayTypeNameInternal(returnType);
            Add(_space, function.Name, _openParen);

            var paramIndex = 0;

            foreach (var param in function.Parameters)
            {
                if (paramIndex != 0)
                {
                    Add(_comma);
                }

                if (param.IsOutput)
                {
                    if (param.IsInput)
                    {
                        Add(_inout);
                    }
                    else
                    {
                        Add(_out);
                    }
                }

                VariableDeclarationInternal(param.Type, param.Name, DeclarationMode.NoSemicolon);
                ++paramIndex;
            }
            Add(_closeParen);
            NewLine();

            using (BlockScope())
            {
                AddWithTokenTranslation(function.Body, function.Container);
            }
        }
 public void CallFunctionWithDeclaredReturn(ShaderFunction function, ShaderType returnType, string returnVariable, params string[] arguments)
 {
     Indentation();
     VariableDeclarationInternal(returnType, returnVariable, DeclarationMode.NoSemicolon);
     Add(_equal);
     FunctionCallInternal(function, DeclarationMode.Semicolon, arguments);
     NewLine();
 }
 public void CallFunctionWithReturn(ShaderFunction function, string returnVariable, params string[] arguments)
 {
     Indentation();
     Add(returnVariable);
     Add(_equal);
     FunctionCallInternal(function, DeclarationMode.Semicolon, arguments);
     NewLine();
 }
        void ProcessToken(string str, int startOffsetInclusive, int endOffsetExclusive, ShaderContainer container)
        {
            int length = endOffsetExclusive - startOffsetInclusive;

            if (length <= 2)
            {
                return; // can't possibly be a valid token
            }
            // Special tokens are used to done ids that are to be replaced with actual identifiers later:
            // - "$T:{id}$": Replaces the string with the type name with the given id.
            // - "$F:{id}$": Replaces the string with the function name with the given id.
            // - "$V:{id},{varName}$": Replaces the string with the variable declaration with the given id.
            // Variable declarations also need the variable name due to how arrays have to be declared: "type name[size]".
            // This may go away if we ever add a variable instance object.
            int offset = startOffsetInclusive;

            switch (str[offset])
            {
            case 'V':     // variable declaration
            {
                ParseTokenWithName(str, startOffsetInclusive, endOffsetExclusive, 'V', out int shaderTypeIndex, out string varName);
                // declare it!
                FoundryHandle shaderTypeHandle = new FoundryHandle();
                shaderTypeHandle.Handle = (uint)shaderTypeIndex;
                var shaderType = new ShaderType(container, shaderTypeHandle);
                VariableDeclarationInternal(shaderType, varName, DeclarationMode.NoSemicolon);
                break;
            }

            case 'F':     // function call - function name
            {
                int           tokenId = ParseSimpleToken(str, startOffsetInclusive, endOffsetExclusive, 'F');
                FoundryHandle shaderFunctionHandle = new FoundryHandle();
                shaderFunctionHandle.Handle = (uint)tokenId;
                var shaderFunction = new ShaderFunction(container, shaderFunctionHandle);
                AddFunctionNameInternal(shaderFunction);
                break;
            }

            case 'T':     // type name
            {
                int           typeId           = ParseSimpleToken(str, startOffsetInclusive, endOffsetExclusive, 'T');
                FoundryHandle shaderTypeHandle = new FoundryHandle();
                shaderTypeHandle.Handle = (uint)typeId;
                var shaderType = new ShaderType(container, shaderTypeHandle);
                AddNonArrayTypeNameInternal(shaderType);
                break;
            }

            default:
            {
                var tokenSubStr = str.Substring(startOffsetInclusive, endOffsetExclusive - startOffsetInclusive);
                throw new Exception($"Malformed token found when parsing '{tokenSubStr}'. Identifier {str[offset]} was unexpected.");
            }
            }
        }
 // Get the input and output types for this function (assumed to be an entry point)
 static void GetInOutTypes(ShaderFunction function, out ShaderType inputType, out ShaderType outputType)
 {
     inputType = outputType = ShaderType.Invalid;
     if (function.IsValid)
     {
         outputType = function.ReturnType;
         var parameters = function.Parameters.GetEnumerator();
         if (parameters.MoveNext())
         {
             inputType = parameters.Current.Type;
         }
     }
 }
Example #8
0
            public ShaderFunction Build()
            {
                if (finalized)
                {
                    return(new ShaderFunction(Container, functionHandle));
                }
                finalized = true;

                FoundryHandle parentBlockHandle = parentBlockBuilder?.blockHandle ?? FoundryHandle.Invalid();
                var           returnTypeHandle  = container.AddShaderType(returnType, true);
                var           builtFunction     = new ShaderFunction(container, functionHandle, name, ConvertToString(), returnTypeHandle, parameters, parentBlockHandle);

                if (parentBlockBuilder != null)
                {
                    // Register the new function with the parent block
                    parentBlockBuilder.AddFunction(builtFunction);
                }

                return(builtFunction);
            }
 // These will emit a call to 'function' using the supplied arguments
 public void CallFunction(ShaderFunction function, params string[] arguments)
 {
     Indentation();
     FunctionCallInternal(function, DeclarationMode.Semicolon, arguments);
     NewLine();
 }
 public void SetEntryPointFunction(ShaderFunction function)
 {
     entryPointFunction = function; AddFunction(entryPointFunction);
 }
 public void AddReferencedFunction(ShaderFunction function)
 {
     referencedFunctions.Add(function);
 }
 public void AddFunction(ShaderFunction function)
 {
     functions.Add(function);
 }