|
1 | 1 | package function |
2 | 2 |
|
3 | 3 | import ( |
4 | | - "runtime/debug" |
| 4 | + "fmt" |
5 | 5 | "slices" |
6 | 6 |
|
7 | 7 | "github.com/brimdata/super" |
@@ -40,15 +40,15 @@ func (d *downcast) Cast(from super.Value, to super.Type) (super.Value, bool) { |
40 | 40 | } |
41 | 41 |
|
42 | 42 | func (d *downcast) downcast(typ super.Type, bytes scode.Bytes, to super.Type) (super.Value, *super.Value) { |
43 | | - //fmt.Println("DOWNCAST", sup.String(super.NewValue(typ, bytes)), "TO", sup.String(to)) |
| 43 | + fmt.Println("DOWNCAST", sup.String(super.NewValue(typ, bytes)), "TO", sup.String(to)) |
44 | 44 | // XXX typ, bytes = deunion(typ, bytes) |
45 | 45 | if _, ok := to.(*super.TypeUnion); !ok { |
46 | 46 | if fusionType, ok := typ.(*super.TypeFusion); ok { |
47 | 47 | superBytes, subtype := fusionType.Deref(d.sctx, bytes) |
48 | 48 | return d.downcast(fusionType.Type, superBytes, subtype) |
49 | 49 | } |
50 | 50 | } |
51 | | - typ, bytes = deunion(typ, bytes) |
| 51 | + //typ, bytes = deunion(typ, bytes) |
52 | 52 | switch to := to.(type) { |
53 | 53 | case *super.TypeRecord: |
54 | 54 | return d.toRecord(typ, bytes, to) |
@@ -210,6 +210,7 @@ func (d *downcast) toError(typ super.Type, bytes scode.Bytes, to *super.TypeErro |
210 | 210 | } |
211 | 211 |
|
212 | 212 | func (d *downcast) toNamed(typ super.Type, bytes scode.Bytes, to *super.TypeNamed) (super.Value, *super.Value) { |
| 213 | + fmt.Println("TO NAMED", sup.String(super.NewValue(typ, bytes)), "TO", sup.String(to)) |
213 | 214 | /* |
214 | 215 | fromType, ok := typ.(*super.TypeNamed) |
215 | 216 | if !ok { |
@@ -239,59 +240,61 @@ func (d *downcast) toNamed(typ super.Type, bytes scode.Bytes, to *super.TypeName |
239 | 240 | } |
240 | 241 | return super.NewValue(to, val.Bytes()), errVal |
241 | 242 | */ |
| 243 | + if unionType, ok := typ.(*super.TypeUnion); ok { |
| 244 | + typ, bytes = deunion(typ, bytes) |
| 245 | + // If we are casting a union type to a named, we need to look through the |
| 246 | + // union for the named type in question since type fusion fuses named |
| 247 | + // types by name. Then when we find the name, we need to form the subtype |
| 248 | + // from the union options present. XXX devise a torture test that |
| 249 | + // reconstruct nested unions from the flattened named union...? |
| 250 | + for _, t := range unionType.Types { |
| 251 | + if named, ok := t.(*super.TypeNamed); ok && named.Name == to.Name { |
| 252 | + val, errVal := d.downcast(typ, bytes, to.Type) |
| 253 | + if errVal != nil { |
| 254 | + return super.Value{}, errVal |
| 255 | + } |
| 256 | + return super.NewValue(to, val.Bytes()), nil |
| 257 | + } |
| 258 | + |
| 259 | + } |
| 260 | + return super.Value{}, d.errMismatch(typ, bytes, to) |
| 261 | + } |
242 | 262 | /* |
243 | | - if unionType, ok := typ.(*super.TypeUnion); !ok { |
244 | | - // If we are casting a union type to a named, we need to look through the |
245 | | - // union for the named type in question since type fusion fuses named |
246 | | - // types by name. Then when we find the name, we need to form the subtype |
247 | | - // from the union options present. XXX devise a torture test that |
248 | | - // reconstruct nested unions from the flattened named union...? |
249 | | - for _, t := range unionType.Types { |
250 | | - if named, ok := t.(*super.TypeNamed); ok && t.Name == to.Name { |
251 | | - val, errVal := d.downcast(named.Type, bytes, to.Type) |
| 263 | + fromType, ok := typ.(*super.TypeNamed) |
| 264 | + if !ok { |
| 265 | + if unionType, ok := typ.(*super.TypeUnion); ok { |
| 266 | + if unionType.TagOf(to) >= 0 { |
| 267 | + typ, bytes = deunion(typ, bytes) |
| 268 | + val, errVal := d.downcast(typ, bytes, to) |
252 | 269 | if errVal != nil { |
253 | 270 | return super.Value{}, errVal |
254 | 271 | } |
255 | | - return super.NewValue(to, val.Bytes()), nil |
256 | | - } |
257 | | - fused := noFusion(f.fuse(existingNamed.Type, noFusion(named.Type))) |
258 | | - var err error |
259 | | - out[i], err = f.sctx.LookupTypeNamed(named.Name, fused) |
260 | | - if err != nil { |
261 | | - panic(err) |
| 272 | + return super.NewValue(to, val.Bytes()), errVal |
262 | 273 | } |
263 | | -
|
264 | 274 | } |
265 | | -
|
266 | | - } |
267 | | - if !ok { |
| 275 | + //fmt.Println("MISS", sup.String(typ)) |
268 | 276 | return super.Value{}, d.errMismatch(typ, bytes, to) |
269 | 277 | } |
270 | 278 | */ |
271 | | - fromType, ok := typ.(*super.TypeNamed) |
272 | | - if !ok { |
273 | | - if unionType, ok := typ.(*super.TypeUnion); ok { |
274 | | - if unionType.TagOf(to) >= 0 { |
275 | | - typ, bytes = deunion(typ, bytes) |
276 | | - val, errVal := d.downcast(typ, bytes, to) |
277 | | - if errVal != nil { |
278 | | - return super.Value{}, errVal |
279 | | - } |
280 | | - return super.NewValue(to, val.Bytes()), errVal |
281 | | - } |
| 279 | + if fromType, ok := typ.(*super.TypeNamed); ok { |
| 280 | + if fromType.Name != to.Name { |
| 281 | + return super.Value{}, d.errMismatch(typ, bytes, to) |
282 | 282 | } |
283 | | - //fmt.Println("MISS", sup.String(typ)) |
284 | | - return super.Value{}, d.errMismatch(typ, bytes, to) |
| 283 | + val, errVal := d.downcast(fromType.Type, bytes, to.Type) |
| 284 | + if errVal != nil { |
| 285 | + return super.Value{}, errVal |
| 286 | + } |
| 287 | + return super.NewValue(to, val.Bytes()), errVal |
285 | 288 | } |
286 | | - val, errVal := d.downcast(fromType.Type, bytes, to.Type) |
| 289 | + val, errVal := d.downcast(typ, bytes, to.Type) |
287 | 290 | if errVal != nil { |
288 | 291 | return super.Value{}, errVal |
289 | 292 | } |
290 | 293 | return super.NewValue(to, val.Bytes()), errVal |
291 | 294 | } |
292 | 295 |
|
293 | 296 | func (d *downcast) errMismatch(typ super.Type, bytes []byte, to super.Type) *super.Value { |
294 | | - debug.PrintStack() |
| 297 | + //debug.PrintStack() |
295 | 298 | return d.sctx.WrapError("downcast: type mismatch to "+sup.FormatType(to), super.NewValue(typ, bytes)).Ptr() |
296 | 299 | } |
297 | 300 |
|
|
0 commit comments