WGSLNodeFunction.js 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. import NodeFunction from '../core/NodeFunction.js';
  2. import NodeFunctionInput from '../core/NodeFunctionInput.js';
  3. const declarationRegexp = /^fn\s*([a-z_0-9]+)?\s*\(([\s\S]*?)\)\s*\-\>\s*([a-z_0-9]+)?/i;
  4. const propertiesRegexp = /[a-z_0-9]+/ig;
  5. const parse = ( source ) => {
  6. source = source.trim();
  7. const declaration = source.match( declarationRegexp );
  8. if ( declaration !== null && declaration.length === 4 ) {
  9. // tokenizer
  10. const inputsCode = declaration[ 2 ];
  11. const propsMatches = [];
  12. let nameMatch = null;
  13. while ( ( nameMatch = propertiesRegexp.exec( inputsCode ) ) !== null ) {
  14. propsMatches.push( nameMatch );
  15. }
  16. // parser
  17. const inputs = [];
  18. let i = 0;
  19. while ( i < propsMatches.length ) {
  20. // default
  21. const name = propsMatches[ i ++ ][ 0 ];
  22. const type = propsMatches[ i ++ ][ 0 ];
  23. // precision
  24. if ( i < propsMatches.length && /^[fui]\d{2}$/.test( propsMatches[ i ][ 0 ] ) === true )
  25. i ++;
  26. // add input
  27. inputs.push( new NodeFunctionInput( type, name ) );
  28. }
  29. //
  30. const blockCode = source.substring( declaration[ 0 ].length );
  31. const name = declaration[ 1 ] !== undefined ? declaration[ 1 ] : '';
  32. const type = declaration[ 3 ];
  33. return {
  34. type,
  35. inputs,
  36. name,
  37. inputsCode,
  38. blockCode
  39. };
  40. } else {
  41. throw new Error( 'FunctionNode: Function is not a WGSL code.' );
  42. }
  43. };
  44. class WGSLNodeFunction extends NodeFunction {
  45. constructor( source ) {
  46. const { type, inputs, name, inputsCode, blockCode } = parse( source );
  47. super( type, inputs, name );
  48. this.inputsCode = inputsCode;
  49. this.blockCode = blockCode;
  50. }
  51. getCode( name = this.name ) {
  52. return `fn ${ name } ( ${ this.inputsCode.trim() } ) -> ${ this.type }` + this.blockCode;
  53. }
  54. }
  55. export default WGSLNodeFunction;