shaderDefineExpression.ts 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /** @hidden */
  2. export class ShaderDefineExpression {
  3. public isTrue(preprocessors: { [key: string]: string }): boolean {
  4. return true;
  5. }
  6. private static _OperatorPriority: { [name: string]: number } = {
  7. ")": 0,
  8. "(": 1,
  9. "||": 2,
  10. "&&": 3,
  11. };
  12. private static _Stack = ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''];
  13. public static postfixToInfix(postfix: string[]): string {
  14. const stack: string[] = [];
  15. for (let c of postfix) {
  16. if (ShaderDefineExpression._OperatorPriority[c] === undefined) {
  17. stack.push(c);
  18. } else {
  19. const v1 = stack[stack.length - 1],
  20. v2 = stack[stack.length - 2];
  21. stack.length -= 2;
  22. stack.push(`(${v2}${c}${v1})`);
  23. }
  24. }
  25. return stack[stack.length - 1];
  26. }
  27. public static infixToPostfix(infix: string): string[] {
  28. const result: string[] = [];
  29. let stackIdx = -1;
  30. const pushOperand = () => {
  31. operand = operand.trim();
  32. if (operand !== '') {
  33. result.push(operand);
  34. operand = '';
  35. }
  36. };
  37. const push = (s: string) => {
  38. if (stackIdx < ShaderDefineExpression._Stack.length - 1) {
  39. ShaderDefineExpression._Stack[++stackIdx] = s;
  40. }
  41. };
  42. const peek = () => ShaderDefineExpression._Stack[stackIdx];
  43. const pop = () => stackIdx === -1 ? '!!INVALID EXPRESSION!!' : ShaderDefineExpression._Stack[stackIdx--];
  44. let idx = 0,
  45. operand = '';
  46. while (idx < infix.length) {
  47. const c = infix.charAt(idx),
  48. token = idx < infix.length - 1 ? infix.substr(idx, 2) : '';
  49. if (c === '(') {
  50. operand = '';
  51. push(c);
  52. } else if (c === ')') {
  53. pushOperand();
  54. while (stackIdx !== -1 && peek() !== '(') {
  55. result.push(pop());
  56. }
  57. pop();
  58. } else if (ShaderDefineExpression._OperatorPriority[token] > 1) {
  59. pushOperand();
  60. while (stackIdx !== -1 && ShaderDefineExpression._OperatorPriority[peek()] >= ShaderDefineExpression._OperatorPriority[token]) {
  61. result.push(pop());
  62. }
  63. push(token);
  64. idx++;
  65. } else {
  66. operand += c;
  67. }
  68. idx++;
  69. }
  70. pushOperand();
  71. while (stackIdx !== -1) {
  72. if (peek() === '(') {
  73. pop();
  74. } else {
  75. result.push(pop());
  76. }
  77. }
  78. return result;
  79. }
  80. }