// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. const INLINE_FUNC_DEF_REGEX = /@inline[\s\n\r]+(\w+)[\s\n\r]+([0-9a-zA-Z_]+)\s*\(([^)]*)\)\s*{(([^}]|[\n\r])*)}/gm; const FUNC_CALL_REGEX = '(\\w+)?\\s+([_0-9a-zA-Z]+)\\s+=\\s+__FUNC__\\((.*)\\)\\s*;'; /** * GLSL preprocessor responsible for resolving @inline directives */ export function replaceInlines(script: string): string { const inlineDefs: {[name: string]: {params: Array<{type: string; name: string}|null>; body: string}} = {}; let match; while ((match = INLINE_FUNC_DEF_REGEX.exec(script)) !== null) { const params = match[3] .split(',') .map(s => { const tokens = s.trim().split(' '); if (tokens && tokens.length === 2) { return {type: tokens[0], name: tokens[1]}; } return null; }) .filter(v => v !== null); inlineDefs[match[2]] = {params, body: match[4]}; } for (const name in inlineDefs) { const regexString = FUNC_CALL_REGEX.replace('__FUNC__', name); const regex = new RegExp(regexString, 'gm'); while ((match = regex.exec(script)) !== null) { const type = match[1]; const variable = match[2]; const params = match[3].split(','); const declLine = (type) ? `${type} ${variable};` : ''; let newBody: string = inlineDefs[name].body; let paramRedecLine = ''; inlineDefs[name].params.forEach((v, i) => { if (v) { paramRedecLine += `${v.type} ${v.name} = ${params[i]};\n`; } }); newBody = `${paramRedecLine}\n ${newBody}`; newBody = newBody.replace('return', `${variable} = `); const replacement = ` ${declLine} { ${newBody} } `; script = script.replace(match[0], replacement); } } script = script.replace(INLINE_FUNC_DEF_REGEX, ''); return script; }