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; } } }
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); }