|
1 | | -import { Program, FunctionDeclaration, Switch, For, AccessorElements, Ternary, Varying, DynamicElement, StaticElement, FunctionParameter, Unary, Conditional, VariableDeclaration, Operator, Number, String, FunctionCall, Return, Accessor, Uniform, Discard, SwitchCase, Continue, Break, While, Comment } from './AST.js'; |
| 1 | +import { Program, FunctionDeclaration, Switch, For, AccessorElements, Ternary, Varying, DynamicElement, StaticElement, FunctionParameter, Unary, Conditional, VariableDeclaration, Operator, Number, String, FunctionCall, Return, Accessor, Uniform, Discard, SwitchCase, Continue, Break, While, Comment, StructMember, StructDefinition } from './AST.js'; |
2 | 2 |
|
3 | | -import { isType } from './TranspilerUtils.js'; |
| 3 | +import { isBuiltinType } from './TranspilerUtils.js'; |
4 | 4 |
|
5 | 5 | const unaryOperators = [ |
6 | 6 | '+', '-', '~', '!', '++', '--' |
@@ -255,6 +255,7 @@ class GLSLDecoder { |
255 | 255 | this.index = 0; |
256 | 256 | this.tokenizer = null; |
257 | 257 | this.keywords = []; |
| 258 | + this.structTypes = new Map(); |
258 | 259 |
|
259 | 260 | this.addPolyfill( 'gl_FragCoord', 'vec3 gl_FragCoord = vec3( screenCoordinate.x, screenCoordinate.y.oneMinus(), screenCoordinate.z );' ); |
260 | 261 |
|
@@ -780,6 +781,54 @@ class GLSLDecoder { |
780 | 781 |
|
781 | 782 | } |
782 | 783 |
|
| 784 | + parseStructDefinition() { |
| 785 | + |
| 786 | + const tokens = this.readTokensUntil( ';' ); |
| 787 | + |
| 788 | + const structName = tokens[ 1 ].str; |
| 789 | + |
| 790 | + if ( tokens[ 2 ].str !== '{' ) { |
| 791 | + |
| 792 | + throw new Error( 'Expected \'{\' after struct name ' ); |
| 793 | + |
| 794 | + } |
| 795 | + |
| 796 | + const structMembers = []; |
| 797 | + for ( let i = 3; i < tokens.length - 2; i += 3 ) { |
| 798 | + |
| 799 | + const typeToken = tokens[ i ]; |
| 800 | + const nameToken = tokens[ i + 1 ]; |
| 801 | + |
| 802 | + if ( typeToken.type != 'literal' || nameToken.type != 'literal' ) { |
| 803 | + |
| 804 | + throw new Error( 'Invalid struct declaration' ); |
| 805 | + |
| 806 | + } |
| 807 | + |
| 808 | + if ( tokens[ i + 2 ].str !== ';' ) { |
| 809 | + |
| 810 | + throw new Error( 'Missing \';\' after struct member name' ); |
| 811 | + |
| 812 | + } |
| 813 | + |
| 814 | + const member = new StructMember( typeToken.str, nameToken.str ); |
| 815 | + structMembers.push( member ); |
| 816 | + |
| 817 | + } |
| 818 | + |
| 819 | + if ( tokens[ tokens.length - 2 ].str !== '}' ) { |
| 820 | + |
| 821 | + throw new Error( 'Missing closing \'}\' for struct ' + structName ); |
| 822 | + |
| 823 | + } |
| 824 | + |
| 825 | + const definition = new StructDefinition( structName, structMembers ); |
| 826 | + this.structTypes.set( structName, definition ); |
| 827 | + |
| 828 | + return definition; |
| 829 | + |
| 830 | + } |
| 831 | + |
783 | 832 | parseReturn() { |
784 | 833 |
|
785 | 834 | this.readToken(); // skip 'return' |
@@ -827,7 +876,9 @@ class GLSLDecoder { |
827 | 876 |
|
828 | 877 | let initialization; |
829 | 878 |
|
830 | | - if ( initializationTokens[ 0 ] && isType( initializationTokens[ 0 ].str ) ) { |
| 879 | + const firstToken = initializationTokens[ 0 ]; |
| 880 | + |
| 881 | + if ( firstToken && ( isBuiltinType( firstToken.str ) || this.structTypes.has( firstToken.str ) ) ) { |
831 | 882 |
|
832 | 883 | initialization = this.parseVariablesFromToken( initializationTokens ); |
833 | 884 |
|
@@ -1079,7 +1130,11 @@ class GLSLDecoder { |
1079 | 1130 |
|
1080 | 1131 | statement = this.parseVarying(); |
1081 | 1132 |
|
1082 | | - } else if ( isType( token.str ) ) { |
| 1133 | + } else if ( token.str === 'struct' ) { |
| 1134 | + |
| 1135 | + statement = this.parseStructDefinition(); |
| 1136 | + |
| 1137 | + } else if ( isBuiltinType( token.str ) || this.structTypes.has( token.str ) ) { |
1083 | 1138 |
|
1084 | 1139 | if ( this.getToken( 2 ).str === '(' ) { |
1085 | 1140 |
|
@@ -1159,7 +1214,9 @@ class GLSLDecoder { |
1159 | 1214 | this.tokenizer = new Tokenizer( polyfill + source ).tokenize(); |
1160 | 1215 |
|
1161 | 1216 | const body = this.parseBlock(); |
| 1217 | + |
1162 | 1218 | const program = new Program( body ); |
| 1219 | + program.structTypes = this.structTypes; |
1163 | 1220 |
|
1164 | 1221 | return program; |
1165 | 1222 |
|
|
0 commit comments