diff --git a/index.js b/index.js index 9711418..9274ea5 100644 --- a/index.js +++ b/index.js @@ -15,6 +15,8 @@ function minifier(safe_words, mutate_storages) { var _ = {} , seen_names = {} + , variable_type = new Map() + , function_type = {} , counter for(var i = 0, len = safe_words.length; i < len; ++i) @@ -51,6 +53,14 @@ function minifier(safe_words, mutate_storages) { } } + if(is_variable(node)) { + var scope = variable_type.get(node.scope) || {} + scope[node.data] = node.parent.parent.token.data + variable_type.set(node.scope, scope) + } + + if(is_function(node)) function_type[node.data] = node.parent.parent.token.data + // 1.0 => 1. // 0.1 => .1 // 0.0 => .0 if(node.type === 'literal') { if(/0\.\d/.test(node.data)) node.data = node.data.replace(/^0\./, '.') @@ -60,6 +70,25 @@ function minifier(safe_words, mutate_storages) { this.emit('data', node) } + function get_type(node) { + if (node.type === 'ident') return variable_type.get(node.scope)[node.data] || 'unidentified' + if (node.type === 'literal') { + if (node.data === 'true' || node.data === 'false') return 'bool' + if (node.data.includes('.')) return 'float' + return 'int' + } + if (node.type === 'call') { + if (/^int|float|bool|[ib]?vec[234]|mat[234]$/.test(node.children[0].data)) return node.children[0].data + return function_type[node.children[0].data] || 'unidentified' + } + if (node.type === 'binary') { + if (node.data === '==' || node.data === '&&' || node.data === '||' || node.data === '^^') return 'bool' + if (node.data === '+' || node.data === '-' || node.data === '/') return get_type(node.children[0]) + } + if (node.type === 'unary' || node.type === 'group' || node.type === 'suffix') return get_type(node.children[0]) + return 'unidentified' + } + function should_mutate(node) { var base = ( is_variable(node) || @@ -72,12 +101,21 @@ function minifier(safe_words, mutate_storages) { } function is_unnecessary_group(node) { + function is_commutative_multiply(node) { + if(node.data !== '*') return false + var type_a = get_type(node.children[0]) + , type_b = get_type(node.children[1]) + if(/^unidentified|mat[234]$/.test(type_a) && /^unidentified|[ib]?vec[234]|mat[234]$/.test(type_b)) return false + if(/^[ib]?vec[234]$/.test(type_a) && /^unidentified|mat[234]$/.test(type_b)) return false + return true + } if(node.type !== 'group') return false if(node.children[0].lbp > node.parent.lbp) return true if(node.children[0].lbp === node.parent.lbp) { for(var i = 0; i < commutative_operators.length; i++) { if(node.parent.data === commutative_operators[i] && node.children[0].data === commutative_operators[i]) return true } + if(is_commutative_multiply(node.parent) && is_commutative_multiply(node.children[0])) return true } return false } diff --git a/tap-snapshots/test-basic.js-TAP.test.js b/tap-snapshots/test-basic.js-TAP.test.js index 3272e44..f4942f0 100644 --- a/tap-snapshots/test-basic.js-TAP.test.js +++ b/tap-snapshots/test-basic.js-TAP.test.js @@ -740,8 +740,16 @@ exports[`test/basic.js TAP grouping removal test > output 1`] = ` float a = 2e10 + .2e2 + 1.e3 * (0xFaBc09 + 3); float b = 2e10 + (.2e2 - 1.e3 / (0xFaBc09 + 3)); -bool c = 1. && true && true; -bool d = 0. || false || true; +float c = 1 * 2 * 3; +mat3 d = mat3(1, 2, 3, 4, 5, 6, 7, 8, 9); +mat3 e = 2 * (vec3(1, 2, 3) * d); +vec2 f() { + return vec2(1); +} +vec2 g = (2 + 3) * vec2(2) * f(); +vec2 h = (2 + 3) * (d * vec2(2)); +bool i = 1. && true && true; +bool j = 0. || false || true; ` exports[`test/basic.js TAP vec shorthand > output 1`] = ` diff --git a/test/commutative-operators.glsl b/test/commutative-operators.glsl index e48b55a..c88f04e 100644 --- a/test/commutative-operators.glsl +++ b/test/commutative-operators.glsl @@ -1,5 +1,16 @@ float x = 2e10 + (.2e2 + (1.e3 * (0xFaBc09 + 3))); float y = 2e10 + (.2e2 - (1.e3 / (0xFaBc09 + 3))); +float z = 1 * (2 * 3); + +mat3 m = mat3(1, 2, 3, 4, 5, 6, 7, 8, 9); +mat3 n = 2 * (vec3(1, 2, 3) * m); + +vec2 f() { + return vec2(1, 1); +} + +vec2 v = (2 + 3) * (vec2(2, 2) * f()); +vec2 w = (2 + 3) * (m * vec2(2, 2)); bool a = 1. && (true && true);