1616* limitations under the License.
1717*/
1818
19+ /* eslint-disable max-lines */
20+
1921'use strict' ;
2022
2123// MODULES //
@@ -24,6 +26,9 @@ var join = require( 'path' ).join;
2426var writeFileSync = require ( '@stdlib/fs/write-file' ) . sync ;
2527var licenseHeader = require ( '@stdlib/_tools/licenses/header' ) ;
2628var currentYear = require ( '@stdlib/time/current-year' ) ;
29+ var capitalize = require ( '@stdlib/string/capitalize' ) ;
30+ var objectKeys = require ( '@stdlib/utils/keys' ) ;
31+ var hasOwnProp = require ( '@stdlib/assert/has-own-property' ) ;
2732var generateMatchesTable = require ( './script.js' ) ;
2833var pkg = require ( './../package.json' ) ;
2934
@@ -34,7 +39,7 @@ var pkg = require( './../package.json' );
3439* Groups matches by input data type and returns grouped data, input types, and reordered matches.
3540*
3641* @private
37- * @param {Array } matches - array of match arrays, where each match is [ input_dtype, output_dtype, package, needs_to_promote, promoted_input_dtype, promoted_output_dtype, c_function_name, loop_kernel ]
42+ * @param {Array } matches - array of match arrays
3843* @returns {Object } object containing grouped matches, input types, and reordered matches
3944*/
4045function groupMatchesByInputType ( matches ) {
@@ -97,7 +102,7 @@ function generateTypesFile( matches, header ) {
97102 jsOut += '// MAIN //\n\n' ;
98103 jsOut += 'var types = [\n' ;
99104
100- // Group matches by input dtype...
105+ // Group matches by input dtype:
101106 result = groupMatchesByInputType ( matches ) ;
102107 grouped = result . grouped ;
103108 inputTypes = result . inputTypes ;
@@ -115,7 +120,7 @@ function generateTypesFile( matches, header ) {
115120 }
116121 }
117122
118- // Add blank line between input type groups ( except for the last one )...
123+ // Blank line between input type groups:
119124 if ( i < inputTypes . length - 1 ) {
120125 jsOut += '\n' ;
121126 }
@@ -127,6 +132,127 @@ function generateTypesFile( matches, header ) {
127132 return jsOut ;
128133}
129134
135+ /**
136+ * Generates the meta.json file content.
137+ *
138+ * @private
139+ * @returns {string } meta.json file content
140+ */
141+ function generateMetaFile ( ) {
142+ var meta = {
143+ 'nargs' : 2 ,
144+ 'nin' : 1 ,
145+ 'nout' : 1
146+ } ;
147+ return JSON . stringify ( meta , null , 2 ) + '\n' ;
148+ }
149+
150+ /**
151+ * Generates the data.js file content.
152+ *
153+ * @private
154+ * @param {Array } matches - array of match entries
155+ * @param {string } header - license header
156+ * @returns {string } data.js file content
157+ */
158+ function generateDataFile ( matches , header ) {
159+ var uniquePackages ;
160+ var packageKeys ;
161+ var outputTypes ;
162+ var importName ;
163+ var inputTypes ;
164+ var matchIndex ;
165+ var packageMap ;
166+ var inputType ;
167+ var grouped ;
168+ var pkgPath ;
169+ var result ;
170+ var parts ;
171+ var dtype ;
172+ var jsOut ;
173+ var i ;
174+ var j ;
175+ var k ;
176+
177+ uniquePackages = { } ;
178+ packageMap = { } ;
179+
180+ for ( i = 0 ; i < matches . length ; i ++ ) {
181+ pkgPath = matches [ i ] [ 2 ] ;
182+ if ( ! hasOwnProp ( uniquePackages , pkgPath ) ) {
183+ uniquePackages [ pkgPath ] = true ;
184+ if ( pkgPath . indexOf ( '/identity' ) === - 1 ) {
185+ importName = pkgPath . split ( '/' ) . pop ( ) ;
186+ } else {
187+ // For identity functions, include dtype in the name:
188+ parts = pkgPath . split ( '/' ) ;
189+
190+ // In future, we can get this dtype from the structured package data, once we have it:
191+ dtype = parts [ parts . length - 3 ] ; // For example, 'int32' from '@stdlib/number/int32/base/identity'
192+ importName = 'identity' + capitalize ( dtype ) ;
193+ }
194+ packageMap [ pkgPath ] = importName ;
195+ }
196+ }
197+
198+ jsOut = header ;
199+ jsOut += '\n/* eslint-disable stdlib/capitalized-comments */\n\n' ;
200+ jsOut += '\'use strict\';\n\n' ;
201+ jsOut += '// MODULES //\n\n' ;
202+
203+ // Add imports for all unique packages:
204+ packageKeys = objectKeys ( uniquePackages ) ;
205+ for ( i = 0 ; i < packageKeys . length ; i ++ ) {
206+ pkgPath = packageKeys [ i ] ;
207+ importName = packageMap [ pkgPath ] ;
208+ jsOut += 'var ' + importName + ' = require( \'' + pkgPath + '\' );\n' ;
209+ }
210+
211+ jsOut += '\n\n// MAIN //\n\n' ;
212+ jsOut += 'var data = [\n' ;
213+ jsOut += '\t// NOTE: the following **must** match the order in `./types.js`. The order should be according to likelihood of use (e.g., if `float64` arrays are more likely, then `float64` types/data should come before `uint8`).\n\n' ;
214+
215+ // Group matches by input dtype:
216+ result = groupMatchesByInputType ( matches ) ;
217+ grouped = result . grouped ;
218+ inputTypes = result . inputTypes ;
219+
220+ for ( i = 0 ; i < inputTypes . length ; i ++ ) {
221+ inputType = inputTypes [ i ] ;
222+ outputTypes = grouped [ inputType ] ;
223+ jsOut += '\t// ' + inputType + '\n' ;
224+
225+ for ( j = 0 ; j < outputTypes . length ; j ++ ) {
226+ matchIndex = 0 ;
227+ for ( k = 0 ; k < matches . length ; k ++ ) {
228+ if ( matches [ k ] [ 0 ] === inputType &&
229+ matches [ k ] [ 1 ] === outputTypes [ j ] ) {
230+ matchIndex = k ;
231+ break ;
232+ }
233+ }
234+ pkgPath = matches [ matchIndex ] [ 2 ] ;
235+ importName = packageMap [ pkgPath ] ;
236+ jsOut += '\t' + importName ;
237+ if ( i < inputTypes . length - 1 || j < outputTypes . length - 1 ) {
238+ jsOut += ',\n' ;
239+ } else {
240+ jsOut += '\n' ;
241+ }
242+ }
243+
244+ // Blank line between input type groups:
245+ if ( i < inputTypes . length - 1 ) {
246+ jsOut += '\n' ;
247+ }
248+ }
249+
250+ jsOut += '];\n\n\n' ;
251+ jsOut += '// EXPORTS //\n\n' ;
252+ jsOut += 'module.exports = data;\n' ;
253+ return jsOut ;
254+ }
255+
130256/**
131257* Generates the addon.c file content.
132258*
@@ -153,13 +279,13 @@ function generateAddonFile( matches, header, basePkg ) {
153279 uniqueIncludes = { } ;
154280 for ( i = 0 ; i < matches . length ; i ++ ) {
155281 // Extract the full package path from the scalar kernel path:
156- kernelPath = matches [ i ] [ 2 ] ; // Package path is at index 2
282+ kernelPath = matches [ i ] [ 2 ] ;
157283
158284 includePath = kernelPath . replace ( '@stdlib/' , 'stdlib/' ) + '.h' ;
159285 uniqueIncludes [ '#include "' + includePath + '"' ] = true ;
160286 }
161287
162- // Group matches by input type...
288+ // Group matches by input type:
163289 result = groupMatchesByInputType ( matches ) ;
164290 grouped = result . grouped ;
165291 matches = result . reorderedMatches ;
@@ -267,6 +393,8 @@ function generateAddonFile( matches, header, basePkg ) {
267393*/
268394function main ( ) {
269395 var filteredMatches ;
396+ var metaOut ;
397+ var dataOut ;
270398 var basePkg ;
271399 var matches ;
272400 var header ;
@@ -301,6 +429,18 @@ function main() {
301429 'encoding' : 'utf8'
302430 } ) ;
303431
432+ // Generate meta.json:
433+ metaOut = generateMetaFile ( ) ;
434+ writeFileSync ( join ( __dirname , '../lib/meta.json' ) , metaOut , {
435+ 'encoding' : 'utf8'
436+ } ) ;
437+
438+ // Generate data.js:
439+ dataOut = generateDataFile ( matches , header ) ;
440+ writeFileSync ( join ( __dirname , '../lib/data.js' ) , dataOut , {
441+ 'encoding' : 'utf8'
442+ } ) ;
443+
304444 // Generate addon.c:
305445 cOut = generateAddonFile ( filteredMatches , header , basePkg ) ;
306446 writeFileSync ( join ( __dirname , '../src/addon.c' ) , cOut , {
0 commit comments