1. # this is actually part of the Array class
  2. constant dim2role :=
  3. nqp::list(ShapedArray,Shaped1Array,Shaped2Array,Shaped3Array);
  4. sub set-shape(\base, \shape) is raw {
  5. nqp::stmts(
  6. (my $shape := nqp::decont(nqp::if(
  7. nqp::istype(shape,List),
  8. shape,
  9. shape.list
  10. ))),
  11. nqp::if(
  12. (my int $dims = $shape.elems), # reifies
  13. nqp::stmts(
  14. nqp::unless(
  15. nqp::iseq_i($dims,1)
  16. && nqp::istype( # ignore single [*] shape
  17. nqp::atpos(nqp::getattr($shape,List,'$!reified'),0),
  18. Whatever),
  19. nqp::stmts(
  20. (my $what := base.WHAT.^mixin(
  21. nqp::atpos(dim2role,nqp::isle_i($dims,3) && $dims))
  22. ),
  23. nqp::if( # correct name if needed
  24. nqp::isne_s($what.^name,base.^name),
  25. $what.^set_name(base.^name)
  26. ),
  27. nqp::p6bindattrinvres(
  28. nqp::p6bindattrinvres(
  29. nqp::create($what),List,'$!reified',
  30. Rakudo::Internals.SHAPED-ARRAY-STORAGE(
  31. $shape,nqp::knowhow,Mu)),
  32. $what,'$!shape',$shape)
  33. ),
  34. nqp::create(base.WHAT)
  35. )
  36. ),
  37. X::NotEnoughDimensions.new(
  38. operation => 'create',
  39. got-dimensions => 0,
  40. needed-dimensions => '',
  41. ).throw
  42. )
  43. )
  44. }