1
1
import type { IObjectOf } from "@thi.ng/api" ;
2
2
import { writeText } from "@thi.ng/file-io" ;
3
3
import { ConsoleLogger } from "@thi.ng/logger" ;
4
- import { bytes , interpolate , wordWrapLines } from "@thi.ng/strings" ;
4
+ import { bytes , interpolate , lower , wordWrapLines } from "@thi.ng/strings" ;
5
5
import * as v from "@thi.ng/vectors" ;
6
6
7
- const OUT_DIR = "src2 " ;
8
- const API_PREFIX = "../src " ;
7
+ const OUT_DIR = "packages " ;
8
+ const API_IMPORT = "@thi.ng/vec-api " ;
9
9
const LOGGER = new ConsoleLogger ( "codegen" ) ;
10
10
11
11
let TOTAL_SIZE = 0 ;
12
12
13
13
interface FnSpec {
14
14
/** Function name */
15
15
name : string ;
16
+ /** Derived function name for import/filename, default: `lower(name)` */
17
+ importName ?: string ;
16
18
/** Function type */
17
19
type : string ;
18
20
/** Generic (nD) function type */
19
21
typeGeneric ?: string ;
22
+ /** Polymorphic (nD) function type */
23
+ typePoly ?: string ;
20
24
/** Higher order fn name (to replace `op` in original code) */
21
25
op ?: string ;
22
26
/** VOP dispatch argument index, default 1 */
@@ -75,8 +79,10 @@ const formatDocs = (
75
79
76
80
const emitFamily = ( {
77
81
name,
82
+ importName = lower ( name ) ,
78
83
type,
79
- typeGeneric = "Multi" + type ,
84
+ typeGeneric = type ,
85
+ typePoly = "Multi" + typeGeneric ,
80
86
dispatch = 1 ,
81
87
doc = [ ] ,
82
88
params,
@@ -88,19 +94,35 @@ const emitFamily = ({
88
94
multi = true ,
89
95
op,
90
96
} : FnSpec ) => {
97
+ LOGGER . debug ( "emitting family:" , name ) ;
91
98
const nakedType = type . replace ( / < [ a - z 0 - 9 , ] + > $ / i, "" ) ;
92
99
const nakedTypeGeneric = typeGeneric . replace ( / < [ a - z 0 - 9 , ] + > $ / i, "" ) ;
93
- const typeImport = `import type { ${ nakedType } } from "${ API_PREFIX } /api.js";` ;
100
+ const nakedTypePoly = typePoly . replace ( / < [ a - z 0 - 9 , ] + > $ / i, "" ) ;
101
+ const typeImport = `import type { ${ nakedType } } from "${ API_IMPORT } ";` ;
102
+ const typeImportGeneric = `import type { ${ nakedTypeGeneric } } from "${ API_IMPORT } ";` ;
94
103
const userImportsFixed = Object . entries ( imports ) . map (
95
104
( [ pkg , syms ] ) => `import { ${ syms } } from "${ pkg } ";`
96
105
) ;
97
106
const userImportsGeneric = Object . entries ( importsGeneric ?? imports ) . map (
98
107
( [ pkg , syms ] ) => `import { ${ syms } } from "${ pkg } ";`
99
108
) ;
100
- const $imports = [ ...userImportsGeneric ] ;
101
- if ( multi ) $imports . push ( `import { vop } from "${ API_PREFIX } /vop.js";` ) ;
109
+ const polyImports = [
110
+ `import { ${ name } as $${ name } } from "@thi.ng/vec-nd/${ importName } ";` ,
111
+ ] ;
102
112
const $docs = doc . join ( "\n" ) ;
103
- const generic = multi
113
+ const generic = [
114
+ ...formatDocs ( $docs , paramsGeneric , "n" , "" ) ,
115
+ formatFunction (
116
+ name ,
117
+ multi
118
+ ? ( < any > v ) [ name ] . impl ( ) . toString ( )
119
+ : ( < any > v ) [ name ] . toString ( ) ,
120
+ typeGeneric ,
121
+ undefined ,
122
+ op
123
+ ) + ";" ,
124
+ ] ;
125
+ let polymorphic = multi
104
126
? [
105
127
...formatDocs (
106
128
$docs +
@@ -109,25 +131,10 @@ const emitFamily = ({
109
131
"n" ,
110
132
""
111
133
) ,
112
- `export const ${ name } : ${ typeGeneric } = vop(${ dispatch } );` ,
113
- `${ name } .default(${ formatFunction (
114
- name ,
115
- ( < any > v ) [ name ] . impl ( ) . toString ( ) ,
116
- type ,
117
- "" ,
118
- op
119
- ) } );`,
134
+ `export const ${ name } : ${ typePoly } = vop(${ dispatch } );` ,
135
+ `${ name } .default($${ name } )` ,
120
136
]
121
- : [
122
- ...formatDocs ( $docs , paramsGeneric , "n" , "" ) ,
123
- `export const ${ name } : ${ typeGeneric } = ${ formatFunction (
124
- name ,
125
- ( < any > v ) [ name ] . toString ( ) ,
126
- type ,
127
- "" ,
128
- op
129
- ) } ;`,
130
- ] ;
137
+ : [ ] ;
131
138
let body : string ;
132
139
for ( let d of [ 2 , 3 , 4 ] ) {
133
140
const id = name + sep + d ;
@@ -141,22 +148,39 @@ const emitFamily = ({
141
148
formatFunction ( id , ( < any > v ) [ id ] . toString ( ) , type , undefined , op ) +
142
149
";" ,
143
150
] . join ( "\n" ) ;
144
- writeText ( `${ OUT_DIR } /${ id } .ts` , body , LOGGER ) ;
151
+ writeText ( `${ OUT_DIR } /vec ${ d } /src/ ${ importName } .ts` , body , LOGGER ) ;
145
152
TOTAL_SIZE += body . length ;
146
153
if ( multi ) {
147
- $imports . push ( `import { ${ id } } from "./${ id } .js";` ) ;
148
- generic . push ( `${ name } .add(${ d } , ${ id } );` ) ;
154
+ polyImports . push (
155
+ `import { ${ id } } from "@thi.ng/vec${ d } /${ importName } ";`
156
+ ) ;
157
+ polymorphic ! . push ( `${ name } .add(${ d } , ${ id } );` ) ;
149
158
}
150
159
}
160
+
161
+ // generic n-dimensional
151
162
body = [
152
- `import type { ${ nakedTypeGeneric } } from " ${ API_PREFIX } /api.js";` ,
153
- ... $imports ,
163
+ ... userImportsGeneric ,
164
+ typeImportGeneric ,
154
165
"" ,
155
166
...pre ,
156
167
...generic ,
157
168
] . join ( "\n" ) ;
158
- writeText ( `${ OUT_DIR } /${ name } .ts` , body , LOGGER ) ;
169
+ writeText ( `${ OUT_DIR } /vec-nd/src/ ${ importName } .ts` , body , LOGGER ) ;
159
170
TOTAL_SIZE += body . length ;
171
+
172
+ if ( multi ) {
173
+ // polymorphic
174
+ body = [
175
+ `import type { ${ nakedTypePoly } } from "./api.js";` ,
176
+ ...polyImports ,
177
+ `import { vop } from "./vop.js";` ,
178
+ "" ,
179
+ ...polymorphic ,
180
+ ] . join ( "\n" ) ;
181
+ writeText ( `${ OUT_DIR } /vec-poly/src/${ importName } .ts` , body , LOGGER ) ;
182
+ TOTAL_SIZE += body . length ;
183
+ }
160
184
} ;
161
185
162
186
const PARAMS_V = { o : "output vector" , a : "input vector" } ;
@@ -474,18 +498,21 @@ const SPECS: FnSpec[] = [
474
498
} ,
475
499
{
476
500
name : "asBVec" ,
501
+ importName : "as-bvec" ,
477
502
type : "ToBVecOpV" ,
478
503
doc : [ "Componentwise converts given {0}D vector to boolean." ] ,
479
504
params : PARAMS_V ,
480
505
} ,
481
506
{
482
507
name : "asIVec" ,
508
+ importName : "as-ivec" ,
483
509
type : "VecOpV" ,
484
510
doc : [ "Componentwise converts given {0}D vector to signed integer." ] ,
485
511
params : PARAMS_V ,
486
512
} ,
487
513
{
488
514
name : "asUVec" ,
515
+ importName : "as-uvec" ,
489
516
type : "VecOpV" ,
490
517
doc : [ "Componentwise converts given {0}D vector to unsigned integer." ] ,
491
518
params : PARAMS_V ,
@@ -506,6 +533,7 @@ const SPECS: FnSpec[] = [
506
533
// TODO fix original naming to: atan2_2 / atan2_3 ...
507
534
{
508
535
name : "atan_2" ,
536
+ importName : "atan2" ,
509
537
type : "VecOpVV" ,
510
538
doc : [
511
539
"Componentwise computes `Math.atan2` of the two given {0}D vectors." ,
@@ -693,6 +721,7 @@ const SPECS: FnSpec[] = [
693
721
} ,
694
722
{
695
723
name : "distChebyshev" ,
724
+ importName : "dist-chebyshev" ,
696
725
type : "VecOpRoVV<number>" ,
697
726
dispatch : 0 ,
698
727
doc : [
@@ -702,6 +731,7 @@ const SPECS: FnSpec[] = [
702
731
} ,
703
732
{
704
733
name : "distManhattan" ,
734
+ importName : "dist-manhattan" ,
705
735
type : "VecOpRoVV<number>" ,
706
736
dispatch : 0 ,
707
737
doc : [
@@ -801,7 +831,7 @@ const SPECS: FnSpec[] = [
801
831
importsGeneric : {
802
832
"@thi.ng/checks/implements-function" : "implementsFunction" ,
803
833
"@thi.ng/math/api" : "EPS" ,
804
- [ `${ API_PREFIX } /eqdelta` ] : "eqDeltaS" ,
834
+ [ `${ API_IMPORT } /eqdelta` ] : "eqDeltaS" ,
805
835
} ,
806
836
dispatch : 0 ,
807
837
} ,
@@ -818,6 +848,7 @@ const SPECS: FnSpec[] = [
818
848
} ,
819
849
{
820
850
name : "exp_2" ,
851
+ importName : "exp2" ,
821
852
type : "VecOpV" ,
822
853
doc : [ "Componentwise computes `2^x` of given {0}D vector." ] ,
823
854
params : PARAMS_V ,
@@ -890,6 +921,7 @@ const SPECS: FnSpec[] = [
890
921
} ,
891
922
{
892
923
name : "fromBVec" ,
924
+ importName : "from-bvec" ,
893
925
type : "FromBVecOpV" ,
894
926
doc : [
895
927
"Componentwise converts given {0}D boolean vector to floating point (0 or 1)." ,
@@ -928,6 +960,7 @@ const SPECS: FnSpec[] = [
928
960
} ,
929
961
{
930
962
name : "isInf" ,
963
+ importName : "is-inf" ,
931
964
type : "ToBVecOpV" ,
932
965
doc : [
933
966
"Componentwise checks if given {0}D vector is infinite and writes results to boolean output vector. If `out` is null, creates a new result vector." ,
@@ -936,6 +969,7 @@ const SPECS: FnSpec[] = [
936
969
} ,
937
970
{
938
971
name : "isNaN" ,
972
+ importName : "is-nan" ,
939
973
type : "ToBVecOpV" ,
940
974
doc : [
941
975
"Componentwise checks if given {0}D vector is NaN and writes results to boolean output vector. If `out` is null, creates a new result vector." ,
@@ -952,6 +986,7 @@ const SPECS: FnSpec[] = [
952
986
// TODO fix original naming to: log2_2, log2_3, log2_4
953
987
{
954
988
name : "log_2" ,
989
+ importName : "log2" ,
955
990
type : "VecOpV" ,
956
991
doc : [ "Componentwise `Math.log2` of given {0}D vector." ] ,
957
992
params : PARAMS_V ,
@@ -1114,6 +1149,7 @@ const SPECS: FnSpec[] = [
1114
1149
} ,
1115
1150
{
1116
1151
name : "mixBilinear" ,
1152
+ importName : "mix-bilinear" ,
1117
1153
type : "VecOpVVVVNN" ,
1118
1154
doc : [ "Componentwise {0}D vector bilinear interpolation." ] ,
1119
1155
params : {
@@ -1325,6 +1361,7 @@ const SPECS: FnSpec[] = [
1325
1361
} ,
1326
1362
{
1327
1363
name : "randDistrib" ,
1364
+ importName : "rand-distrib" ,
1328
1365
type : "VecOpFNO" ,
1329
1366
doc : [
1330
1367
"Sets `v` to random vector, with each component drawn from given random distribution function (default: gaussian/normal distribution) and scaled to `n` (default: 1). Creates new vector if `v` is null." ,
@@ -1348,6 +1385,7 @@ const SPECS: FnSpec[] = [
1348
1385
} ,
1349
1386
{
1350
1387
name : "randMinMax" ,
1388
+ importName : "rand-minmax" ,
1351
1389
type : "VecOpVVO<IRandom>" ,
1352
1390
doc : [ ] ,
1353
1391
params : {
@@ -1363,6 +1401,7 @@ const SPECS: FnSpec[] = [
1363
1401
} ,
1364
1402
{
1365
1403
name : "randMinMaxS" ,
1404
+ importName : "rand-minmaxs" ,
1366
1405
type : "VecOpSVVO<IRandom>" ,
1367
1406
typeGeneric : "VecOpSGVVO<IRandom>" ,
1368
1407
doc : [ "Like {@link randMinMax{1}} but for {0}D strided vectors." ] ,
0 commit comments