# Copyright (c) 2023 Yuki Kimoto
# MIT License
class Native {
version_from SPVM;
use Native::Env;
use Native::Stack;
use Native::Runtime;
use Native::Compiler;
use StringList;
# Class methods
native static method get_current_env : Native::Env ();
native static method get_current_stack : Native::Stack ();
static method get_current_runtime : Native::Runtime () {
my $current_env = Native->get_current_env;
my $current_stack = Native->get_current_stack;
my $current_runtime = $current_env->runtime;
return $current_runtime;
}
static method get_current_compiler : Native::Compiler () {
my $current_runtime = &get_current_runtime;
my $current_compiler = $current_runtime->get_compiler;
return $current_compiler;
}
native static method check_bootstrap_method : void ($basic_type_name : string);
static method use : void ($class_name : string, $file : string = undef, $line : int = -1) {
my $compiler = Native->get_current_compiler;
$file //= __FILE__;
$compiler->set_start_file($file);
$compiler->set_start_line($line > -1 ? $line : __LINE__ + 1);
$compiler->compile($class_name);
}
static method use_anon_class : string ($source : string, $file : string = undef, $line : int = -1) {
my $compiler = Native->get_current_compiler;
$file //= __FILE__;
$compiler->set_start_file($file);
$compiler->set_start_line($line > -1 ? $line : __LINE__ + 1);
my $anon_class_name = $compiler->compile_anon_class($source);
return $anon_class_name;
}
static method eval : object ($eval_source : string, $file : string = undef, $line : int = -1) {
unless ($eval_source) {
die "The eval source \$eval_source must be defined.";
}
my $source = "
class {
static method eval : object () {
#line 1
$eval_source
}
}
";
my $compiler = Native->get_current_compiler;
$file //= __FILE__;
$compiler->set_start_file($file);
$compiler->set_start_line($line > -1 ? $line : __LINE__ + 1);
my $anon_class_name = $compiler->compile_anon_class($source);
my $ret = Native::MethodCall->call_class_method($anon_class_name, "eval");
return $ret;
}
static method push_inc : void ($include_dir : string) {
my $compiler = Native->get_current_compiler;
$compiler->add_include_dir($include_dir);
}
static method unshift_inc : void ($include_dir : string) {
my $compiler = Native->get_current_compiler;
$compiler->prepend_include_dir($include_dir);
}
static method inc : string[] () {
my $compiler = Native->get_current_compiler;
my $length = $compiler->get_include_dirs_length;
my $include_dirs_list = StringList->new;
for (my $i = 0; $i < $length; $i++) {
my $include_dir = $compiler->get_include_dir($i);
$include_dirs_list->push($include_dir);
}
return $include_dirs_list->to_array;
}
static method set_inc : void ($include_dirs : string[]) {
unless ($include_dirs) {
die "The include directory \$include_dirs must be defined.";
}
my $compiler = Native->get_current_compiler;
$compiler->clear_include_dirs;
for my $_ (@$include_dirs) {
$compiler->add_include_dir($_);
}
}
}