# Copyright (c) 2023 Yuki Kimoto
# MIT License

class Native::Runtime : pointer {
  use Native::Compiler;
  use Native::Env;
  use Native::Stack;
  use Native::BasicType;
  use Native::Method;
  use Native::Arg;
  use Native::ClassVar;
  use Native::Field;
  
  use Fn;
  
  # Fields
  has compiler : Native::Compiler;
  
  # Instance Methods
  native method get_basic_types_length : int ();
  
  native method get_basic_type_by_id : Native::BasicType ($id : int);
  
  native method get_basic_type_by_name : Native::BasicType ($name : string);
  
  native method build_precompile_class_source : string ($basic_type : Native::BasicType);
  
  native method build_precompile_method_source : string ($method : Native::Method);
  
  # Private Instance Methods - Only used in core.
  
  method _get_user_defined_basic_type_names : string[] () {
    
    my $basic_types_length = $self->get_basic_types_length;
    
    my $user_defined_basic_type_names_tmp = new string [$basic_types_length];
    
    my $user_defined_basic_type_names_length = 0;
    
    for (my $basic_type_id = 0; $basic_type_id < $basic_types_length; $basic_type_id++) {
      my $basic_type = $self->get_basic_type_by_id($basic_type_id);
      my $basic_type_name = $basic_type->get_name;
      if (($basic_type_name->[0] >= 'A' && $basic_type_name->[0] <= 'Z') && !Fn->contains($basic_type_name, "::anon::")) {
        $user_defined_basic_type_names_tmp->[$user_defined_basic_type_names_length] = $basic_type_name;
        $user_defined_basic_type_names_length++;
      }
    }
    
    my $user_defined_basic_type_names = new string [$user_defined_basic_type_names_length];
    
    for (my $i = 0; $i < $user_defined_basic_type_names_length; $i++) {
      $user_defined_basic_type_names->[$i] = $user_defined_basic_type_names_tmp->[$i];
    }
    
    return $user_defined_basic_type_names;
  }
  
  native method get_compiler : Native::Compiler ();
}