package ACIS::MiLa::Eval;

use strict;


sub transform ($$) {
  my $data  = shift;  ###  a list
  my $names = shift;  ###  the environment
  
  my $counter = 0;
  while ( $counter < scalar @$data ) {

    my $st   = $data-> [$counter];

    die if $counter < 0;
    
    if ( not ref $st 
         or ref $st ne 'ARRAY' ) { next; }

    my $name = $st -> [0];
    my $last;
    if ( scalar @$st > 1 ) {
      $last = $st -> [ -1 ];
    }

#    warn "statement $name";
    
    if ( defined $last and
         ref $last eq 'ARRAY' ) {
      $st -> [-1] = transform( $last, $names );

    } else {
#      warn "last element: '$last', not a transformable list";
    }
    
    if ( $names -> {$name} ) {
      
      if ( $names -> {$name} {func} ) {
        my $f = $names -> {$name} {func}{func};
        shift @$st;
        
        my @res;
        { 
          no strict;
#          warn "Calling $f ( ", join( " ", @$st ), " )";
#          print "<$f>[$counter of $data]: ";
          @res = &$f ( @$st );
        }
        splice @$data, $counter, 1, @res;
        $counter += -1 + scalar @res;      

         
      } elsif ( $names -> {$name} {macro} ) {
        my $f = $names -> {$name} {macro}{func};
        shift @$st;

        my @res;
        { 
          no strict;
#          warn "Calling $f ( ", join( " ", @$st ), " )";
#          print "<$f>[$counter of $data] (macro) ";
          @res = &$f ( @$st );
        }

        splice @$data, $counter, 1, @res;
        $counter --;      
#        print " [redo at c$counter] ";
#        redo;
      } else {
        warn "name $name is not a macro, is not a func, what is it then?";
      }

    } else {
#      warn "unknown name $name";
    }
    
  } continue {
    $counter ++;
  }

  return $data;
}


1;
