@@ -59,7 +59,7 @@ var $idKey = x => {
59
59
} ;
60
60
61
61
// Creates constructor functions for array pointer types. Returns a new function
62
- // instace each time to make sure each type is independent of the other.
62
+ // instance each time to make sure each type is independent of the other.
63
63
var $arrayPtrCtor = ( ) => {
64
64
return function ( array ) {
65
65
this . $get = ( ) => { return array ; } ;
@@ -224,7 +224,10 @@ var $newType = (size, kind, string, named, pkg, exported, constructor) => {
224
224
typ . keyFor = $idKey ;
225
225
typ . init = elem => {
226
226
typ . elem = elem ;
227
- typ . wrapped = ( elem . kind === $kindArray ) ;
227
+ if ( elem . kind === $kindArray ) {
228
+ typ . wrapped = true ;
229
+ typ . wrap = ( v ) => ( ( v === typ . nil ) ? v : new typ ( v ) ) ;
230
+ }
228
231
typ . nil = new typ ( $throwNilPointerError , $throwNilPointerError ) ;
229
232
} ;
230
233
break ;
@@ -456,13 +459,26 @@ var $newType = (size, kind, string, named, pkg, exported, constructor) => {
456
459
case $kindInterface :
457
460
typ . convertFrom = ( src ) => $convertToInterface ( src , typ ) ;
458
461
break ;
459
- case $kindArray :
460
462
case $kindSlice :
463
+ typ . convertFrom = ( src ) => $convertToSlice ( src , typ ) ;
464
+ break ;
465
+ case $kindPtr :
466
+ typ . convertFrom = ( src ) => $convertToPointer ( src , typ ) ;
467
+ break ;
468
+ case $kindArray :
469
+ typ . convertFrom = ( src ) => $convertToArray ( src , typ ) ;
470
+ break ;
471
+ case $kindStruct :
472
+ typ . convertFrom = ( src ) => $convertToStruct ( src , typ ) ;
473
+ break ;
461
474
case $kindMap :
475
+ typ . convertFrom = ( src ) => $convertToMap ( src , typ ) ;
476
+ break ;
462
477
case $kindChan :
463
- case $kindPtr :
478
+ typ . convertFrom = ( src ) => $convertToChan ( src , typ ) ;
479
+ break ;
464
480
case $kindFunc :
465
- case $kindStruct :
481
+ typ . convertFrom = ( src ) => $convertToFunc ( src , typ ) ;
466
482
break ;
467
483
default :
468
484
$panic ( new $String ( "invalid kind: " + kind ) ) ;
@@ -1093,4 +1109,120 @@ const $convertToBool = (src, dstType) => {
1093
1109
*/
1094
1110
const $convertToInterface = ( src , dstType ) => {
1095
1111
return src ;
1096
- } ;
1112
+ } ;
1113
+
1114
+ /**
1115
+ * Convert to a slice value.
1116
+ *
1117
+ * dstType.kind must be $kindSlice. For wrapped types, src value must be wrapped.
1118
+ * The returned value is always a slice type.
1119
+ */
1120
+ const $convertToSlice = ( src , dstType ) => {
1121
+ const srcType = src . constructor ;
1122
+ if ( srcType === dstType ) {
1123
+ return src ;
1124
+ }
1125
+
1126
+ switch ( srcType . kind ) {
1127
+ case $kindString :
1128
+ if ( dstType . elem . kind === $kindInt32 ) { // Runes are int32.
1129
+ return new dstType ( $stringToRunes ( src . $val ) ) ;
1130
+ } else if ( dstType . elem . kind === $kindUint8 ) { // Bytes are uint8.
1131
+ return new dstType ( $stringToBytes ( src . $val ) ) ;
1132
+ }
1133
+ break ;
1134
+ case $kindSlice :
1135
+ return $convertSliceType ( src , dstType ) ;
1136
+ break ;
1137
+ }
1138
+ throw new Error ( `Unsupported conversion from ${ srcType . string } to ${ dstType . string } ` ) ;
1139
+ } ;
1140
+
1141
+ /**
1142
+ * Convert to a pointer value.
1143
+ *
1144
+ * dstType.kind must be $kindPtr. For wrapped types (specifically, pointers
1145
+ * to an array), src value must be wrapped. The returned value is a bare JS
1146
+ * array (typed or untyped), or a pointer object.
1147
+ */
1148
+ const $convertToPointer = ( src , dstType ) => {
1149
+ const srcType = src . constructor ;
1150
+
1151
+ if ( srcType === dstType ) {
1152
+ return src ;
1153
+ }
1154
+
1155
+ // []T → *[N]T
1156
+ if ( srcType . kind == $kindSlice && dstType . elem . kind == $kindArray ) {
1157
+ return $sliceToGoArray ( src , dstType ) ;
1158
+ }
1159
+
1160
+ if ( src === srcType . nil ) {
1161
+ return dstType . nil ;
1162
+ }
1163
+
1164
+ switch ( dstType . elem . kind ) {
1165
+ case $kindArray :
1166
+ // Pointers to arrays are a wrapped type, represented by a native JS array,
1167
+ // which we return directly.
1168
+ return src . $val ;
1169
+ case $kindStruct :
1170
+ return $pointerOfStructConversion ( src , dstType ) ;
1171
+ default :
1172
+ return new dstType ( src . $get , src . $set , src . $target ) ;
1173
+ }
1174
+ } ;
1175
+
1176
+ /**
1177
+ * Convert to struct types.
1178
+ *
1179
+ * dstType.kind must be $kindStruct. Src must be a wrapped struct value. Returned
1180
+ * value will always be a bare JavaScript object representing the struct.
1181
+ */
1182
+ const $convertToStruct = ( src , dstType ) => {
1183
+ // Since structs are passed by value, the conversion result must be a copy
1184
+ // of the original value, even if it is the same type.
1185
+ return $clone ( src . $val , dstType ) ;
1186
+ } ;
1187
+
1188
+ /**
1189
+ * Convert to array types.
1190
+ *
1191
+ * dstType.kind must be $kindArray. Src must be a wrapped array value. Returned
1192
+ * value will always be a bare JavaScript object representing the array.
1193
+ */
1194
+ const $convertToArray = ( src , dstType ) => {
1195
+ // Since arrays are passed by value, the conversion result must be a copy
1196
+ // of the original value, even if it is the same type.
1197
+ return $clone ( src . $val , dstType ) ;
1198
+ } ;
1199
+
1200
+ /**
1201
+ * Convert to map types.
1202
+ *
1203
+ * dstType.kind must be $kindMap. Src must be a wrapped map value. Returned
1204
+ * value will always be a bare JavaScript object representing the map.
1205
+ */
1206
+ const $convertToMap = ( src , dstType ) => {
1207
+ return src . $val ;
1208
+ } ;
1209
+
1210
+ /**
1211
+ * Convert to chan types.
1212
+ *
1213
+ * dstType.kind must be $kindChan. Src must be a wrapped chan value. Returned
1214
+ * value will always be a bare $Chan object representing the channel.
1215
+ */
1216
+ const $convertToChan = ( src , dstType ) => {
1217
+ return src . $val ;
1218
+ } ;
1219
+
1220
+ /**
1221
+ * Convert to function types.
1222
+ *
1223
+ * dstType.kind must be $kindFunc. Src must be a wrapped function value. Returned
1224
+ * value will always be a bare JavaScript function.
1225
+ */
1226
+ const $convertToFunc = ( src , dstType ) => {
1227
+ return src . $val ;
1228
+ } ;
0 commit comments