Extract takes a solved type out of a unification variable data slot, and returns it from the input container type. If there is no contained unification variable, or no type in the unification variable data field, then this simply returns the input type without modification. Fields in the type tree t
(typ *types.Type)
| 400 | // "after the sound it makes". (Thanks to Sam for the fun trivia!) |
| 401 | // TODO: Untested alternate version that copies everything if anything changes. |
| 402 | func Extract(typ *types.Type) *types.Type { |
| 403 | if typ == nil { |
| 404 | return typ // or panic? |
| 405 | } |
| 406 | if typ.Uni != nil { |
| 407 | return extract(typ) // call private helper, not a recursion! |
| 408 | } |
| 409 | |
| 410 | switch typ.Kind { |
| 411 | case types.KindBool: |
| 412 | return typ |
| 413 | case types.KindStr: |
| 414 | return typ |
| 415 | case types.KindInt: |
| 416 | return typ |
| 417 | case types.KindFloat: |
| 418 | return typ |
| 419 | |
| 420 | case types.KindList: |
| 421 | if typ.Val == nil { |
| 422 | panic("malformed list type") |
| 423 | } |
| 424 | val := Extract(typ.Val) |
| 425 | if val != typ.Val { |
| 426 | //t := UnifyCopy(typ) // don't copy at all for normal zonk |
| 427 | t := typ // bypass UnifyCopy for now |
| 428 | t.Val = val |
| 429 | return t |
| 430 | } |
| 431 | return typ |
| 432 | |
| 433 | case types.KindMap: |
| 434 | if typ.Key == nil || typ.Val == nil { |
| 435 | panic("malformed map type") |
| 436 | } |
| 437 | key := Extract(typ.Key) |
| 438 | val := Extract(typ.Val) |
| 439 | if key != typ.Key || val != typ.Val { |
| 440 | //t := UnifyCopy(typ) // don't copy at all for normal zonk |
| 441 | t := typ // bypass UnifyCopy for now |
| 442 | t.Key = key |
| 443 | t.Val = val |
| 444 | return t |
| 445 | } |
| 446 | |
| 447 | // Alternate version that copies everything if anything changes. |
| 448 | //key := Extract(typ.Key) |
| 449 | //val := Extract(typ.Val) |
| 450 | //if copied := key != typ.Key || val != typ.Val; copied { |
| 451 | // t := UnifyCopy(typ) // don't copy at all for normal zonk |
| 452 | // t.Key = key // assume |
| 453 | // t.Val = val |
| 454 | // |
| 455 | // if key == typ.Key { // val changed, so copy key |
| 456 | // t.Key = UnifyCopy(key) |
| 457 | // } |
| 458 | // if val == typ.Val { // key changed, so copy val |
| 459 | // t.Val = UnifyCopy(val) |