浏览代码

Transpiler: Bidirectional associative (#28710)

sunag 1 年之前
父节点
当前提交
9a3bf42e81
共有 1 个文件被更改,包括 46 次插入4 次删除
  1. 46 4
      examples/jsm/transpiler/GLSLDecoder.js

+ 46 - 4
examples/jsm/transpiler/GLSLDecoder.js

@@ -22,6 +22,14 @@ const precedenceOperators = [
 	','
 	','
 ].reverse();
 ].reverse();
 
 
+const associativityRightToLeft = [
+	'=',
+	'+=', '-=', '*=', '/=', '%=', '^=', '&=', '|=', '<<=', '>>=',
+	',',
+	'?',
+	':'
+];
+
 const spaceRegExp = /^((\t| )\n*)+/;
 const spaceRegExp = /^((\t| )\n*)+/;
 const lineRegExp = /^\n+/;
 const lineRegExp = /^\n+/;
 const commentRegExp = /^\/\*[\s\S]*?\*\//;
 const commentRegExp = /^\/\*[\s\S]*?\*\//;
@@ -297,13 +305,13 @@ class GLSLDecoder {
 
 
 		for ( const operator of precedenceOperators ) {
 		for ( const operator of precedenceOperators ) {
 
 
-			for ( let i = 0; i < tokens.length; i ++ ) {
+			const parseToken = ( i, inverse = false ) => {
 
 
 				const token = tokens[ i ];
 				const token = tokens[ i ];
 
 
 				groupIndex += getGroupDelta( token.str );
 				groupIndex += getGroupDelta( token.str );
 
 
-				if ( ! token.isOperator || i === 0 || i === tokens.length - 1 ) continue;
+				if ( ! token.isOperator || i === 0 || i === tokens.length - 1 ) return;
 
 
 				if ( groupIndex === 0 && token.str === operator ) {
 				if ( groupIndex === 0 && token.str === operator ) {
 
 
@@ -330,9 +338,43 @@ class GLSLDecoder {
 
 
 				}
 				}
 
 
-				if ( groupIndex < 0 ) {
+				if ( inverse ) {
+
+					if ( groupIndex > 0 ) {
+
+						return this.parseExpressionFromTokens( tokens.slice( i ) );
+
+					}
+
+				} else {
+
+					if ( groupIndex < 0 ) {
+
+						return this.parseExpressionFromTokens( tokens.slice( 0, i ) );
+
+					}
+
+				}
+
+			};
+
+			if ( associativityRightToLeft.includes( operator ) ) {
+
+				for ( let i = 0; i < tokens.length; i ++ ) {
+
+					const result = parseToken( i );
+
+					if ( result ) return result;
+
+				}
+
+			} else {
+
+				for ( let i = tokens.length - 1; i >= 0; i -- ) {
+
+					const result = parseToken( i, true );
 
 
-					return this.parseExpressionFromTokens( tokens.slice( 0, i ) );
+					if ( result ) return result;
 
 
 				}
 				}