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); } }
internal void VariableDeclarationInternal(ShaderType type, string name, DeclarationMode mode, string defaultValue = null) { if (!type.Exists) { Add("/* ERROR: non-existent type specified for variable ", name, " */"); return; } bool useDeferredDeclaration = (type.ParentBlock.Exists && !type.ParentBlock.IsValid) || (!type.IsValid) || (type.IsArray && !type.ArrayElementType.IsValid); // we must catch unfinished array element types in the var decl to correctly handle arrays of arrays of unfinished types // this is because the array count must be appended in reverse order, so we must use the $V: token if (useDeferredDeclaration) { Add(_tokenDeclareVariable, type.handle.ToString(), ",", name, _tokenEnd); } else { if (type.IsVoid) { Add("/* ERROR: cannot declare a variable of type void ", name, " */"); return; } else if (type.IsArray) { // have to declare arrays in reverse order (standard HLSL/C syntax) // this is not ideal in terms of string allocations, but I think any approach requires some form of allocation.. var nameSuffix = _openSquare + (type.ArrayElements > 0 ? type.ArrayElements.ToString() : "") + _closeSquare; var modifiedName = name + nameSuffix; VariableDeclarationInternal(type.ArrayElementType, modifiedName, DeclarationMode.NoSemicolon); } else { AddNonArrayTypeNameInternal(type); Add(_space, name); } } if (defaultValue != null) { Add(_equal, defaultValue); } if (mode == DeclarationMode.Semicolon) { Add(_semicolon); } }