diff --git a/README.md b/README.md index 4f2646c..a65032b 100644 --- a/README.md +++ b/README.md @@ -56,12 +56,12 @@ Please report any bugs with MRI, so development can progress smoothly. ### Known issues -* Currently it is only possible to run a single Ruby script +* Currently it is only possible to run a single actual Ruby script file * UTF-8 function and variable names defined in Crystal can lead to crashes in Ruby * Bytecode compilation functions are not available yet (and might never be) -* Some utility available in mruby are not available in MRI +* Some utility functions from mruby are not available in MRI * Gems need to be installed manually after installing Ruby -* Only GCC is supported as of now +* For now, only gcc is supported as compiler # Installing @@ -230,12 +230,12 @@ The term 'anyoli' means 'green' in the Maasai language, thus naming 'anyolite'. * [ ] Full MRI Ruby as alternative implementation (might be postponed to a later release) * * [X] Basic functionality similar to mruby +* * [X] Calling of script lines * * [ ] Bytecode compilation (might not be possible) -* * [ ] Calling of script lines -* * [ ] Tests +* * [ ] Even more tests * * [ ] Copy source in build directory and call compile scripts there * * [ ] Find solution for UTF-8 function names leading to crashes -* * [ ] Find solution for MRI crash at second script loading +* * [ ] Find solution for MRI crash at second script file loading * [X] AnyolitePointer helper class for accessing pointers * [X] Infrastructure to convert script files into bytecode at runtime and compiletime * [X] Support for setting and getting instance, class and global variables from Crystal @@ -302,3 +302,4 @@ Anyolite are already implemented. * [ ] Automatic wrappers for `initialize_copy` and similar methods * [ ] Class inheritance wrapping can be disabled for any class using annotations * [ ] General improvement of type resolving +* [ ] Return values from evaluated script lines diff --git a/examples/mri_test.rb b/examples/mri_test.rb index 6c0cd49..6b2d2ee 100644 --- a/examples/mri_test.rb +++ b/examples/mri_test.rb @@ -1,3 +1,2 @@ -require_relative "./bytecode_test.rb" require_relative "./test.rb" require_relative "./hp_example.rb" diff --git a/examples/test.rb b/examples/test.rb index 7d37e6a..c50520d 100644 --- a/examples/test.rb +++ b/examples/test.rb @@ -47,8 +47,6 @@ puts "Test constant is: #{TestModule::SOME_CONSTANT}" -puts a.methods.inspect - puts "Sum is #{(a + b).x}" a.keyword_test(strvar: "Hi there", intvar: -121212, floatvar: -0.313, strvarkw: "💎", othervar: b) @@ -265,4 +263,4 @@ def self.class_method_in_ruby(str, int) final_time = Time.now -puts "Total time for MRI test script: #{(final_time - start_time)} s" \ No newline at end of file +puts "Total time for MRI test script: #{(final_time - start_time)} s" diff --git a/glue/mri/script_helper.c b/glue/mri/script_helper.c index 34fa0ee..e80b206 100644 --- a/glue/mri/script_helper.c +++ b/glue/mri/script_helper.c @@ -1,37 +1,32 @@ #include -//! TODO: Is a cleanup maybe possible? For now, the state is kept. +//! TODO: Is a complete cleanup maybe possible? For now, the state is kept. extern void* open_interpreter(void) { - static int already_initialized = 0; + RUBY_INIT_STACK; + ruby_init(); - if(!already_initialized) { + return (void*) 0; - //printf("Initializing...\n"); - RUBY_INIT_STACK; - ruby_init(); - //printf("Done initializing.\n"); - already_initialized = 1; +} - } +extern void close_interpreter(void* rb) { - return (void*) 0; + ruby_cleanup(0); } -extern void close_interpreter(void* mrb) { +extern void load_script_from_file(void* rb, const char* filename) { - //printf("Finalizing...\n"); - //ruby_cleanup(0); - //printf("Done finalizing.\n"); + static int first_script = 1; -} + if(first_script) { -extern void load_script_from_file(void* mrb, const char* filename) { + ruby_script(filename); + first_script = 0; - //printf("Running...\n"); - ruby_script(filename); + } int error; @@ -39,7 +34,35 @@ extern void load_script_from_file(void* mrb, const char* filename) { void* options = ruby_options(2, args); - int return_value = ruby_run_node(options); - //printf("Done running.\n"); + int return_value = ruby_exec_node(options); + + VALUE exception = rb_errinfo(); + if(exception != Qnil) { + + VALUE exception_str = rb_inspect(exception); + + printf("%s\n", rb_string_value_cstr(&exception_str)); + + } + + //! TODO: Fix segfaults at second execution + +} + +extern void execute_script_line(void* rb, const char* text) { + + int status; + rb_eval_string_protect(text, &status); + + if(status) { + + VALUE exception = rb_errinfo(); + VALUE exception_str = rb_inspect(exception); + + //! TODO: Are there any internal methods to print this prettier? + + printf("%s\n", rb_string_value_cstr(&exception_str)); + + } } \ No newline at end of file diff --git a/src/implementations/mri/RbCore.cr b/src/implementations/mri/RbCore.cr index 7082287..730f97a 100644 --- a/src/implementations/mri/RbCore.cr +++ b/src/implementations/mri/RbCore.cr @@ -212,8 +212,7 @@ module Anyolite fun load_script_from_file(rb : State*, filename : LibC::Char*) : Void - # TODO - # fun execute_script_line(rb : State*, str : LibC::Char*) : RbValue + fun execute_script_line(rb : State*, str : LibC::Char*) : RbValue # UNUSED # fun execute_bytecode(rb : State*, bytecode : UInt8*) : RbValue diff --git a/test.cr b/test.cr index 9cd643c..5ac0e78 100644 --- a/test.cr +++ b/test.cr @@ -546,6 +546,12 @@ end Anyolite.wrap(rb, RPGTest) + rb.execute_script_line("puts TestModule::Test.new(x: 12345).inspect") + + rb.execute_script_line("require_relative './examples/bytecode_test.rb'") + rb.load_script_from_file("examples/mri_test.rb") + + rb.execute_script_line("puts TestModule::Test.new(x: 67890).inspect") end {% end %} \ No newline at end of file