Commit e6d9b450 authored by Asmod4n's avatar Asmod4n

Merge remote-tracking branch 'mruby/master'

parents 13a2cc3e 070e04ea
# no installation...
language: c
matrix:
include:
- os: linux
sudo: 9000
- os: osx
osx_image: xcod6.4
install:
- sudo apt-get -q install gperf
- if [ $TRAVIS_OS_NAME = 'linux' ]; then sudo apt-get update -qq; sudo apt-get -q install gperf; fi
env: MRUBY_CONFIG=travis_config.rb
script: "./minirake all test"
......
......@@ -26,6 +26,7 @@ Original Authors "mruby developers" are:
Hiroshi Mimaki
Satoshi Odawara
Mitsubishi Electric Micro-Computer Application Software Co.,Ltd.
Ralph Desir(Mav7)
Hiroyuki Matsuzaki
Yuhei Okazaki
Manycolors, Inc.
......
......@@ -45,7 +45,7 @@ on-demand.
#### Don't use C++ style comments
/* This is the prefered comment style */
/* This is the preferred comment style */
Use C++ style comments only for temporary comment e.g. commenting out some code lines.
......
......@@ -3,6 +3,7 @@
# basic build file for mruby
MRUBY_ROOT = File.dirname(File.expand_path(__FILE__))
MRUBY_BUILD_HOST_IS_CYGWIN = RUBY_PLATFORM.include?('cygwin')
MRUBY_BUILD_HOST_IS_OPENBSD = RUBY_PLATFORM.include?('openbsd')
# load build systems
load "#{MRUBY_ROOT}/tasks/ruby_ext.rake"
......@@ -21,21 +22,17 @@ end
# load custom rules
load "#{MRUBY_ROOT}/src/mruby_core.rake"
load "#{MRUBY_ROOT}/mrblib/mrblib.rake"
load "#{MRUBY_ROOT}/tools/mrbc/mrbc.rake"
load "#{MRUBY_ROOT}/tasks/mrbgems.rake"
load "#{MRUBY_ROOT}/tasks/libmruby.rake"
load "#{MRUBY_ROOT}/tasks/mrbgems_test.rake"
load "#{MRUBY_ROOT}/test/mrbtest.rake"
load "#{MRUBY_ROOT}/tasks/benchmark.rake"
##############################
# generic build targets, rules
task :default => :all
bin_path = "#{MRUBY_ROOT}/bin"
bin_path = ENV['INSTALL_DIR'] || "#{MRUBY_ROOT}/bin"
FileUtils.mkdir_p bin_path, { :verbose => $verbose }
depfiles = MRuby.targets['host'].bins.map do |bin|
......@@ -74,7 +71,7 @@ MRuby.each_target do |target|
end
if target == MRuby.targets['host']
install_path = MRuby.targets['host'].exefile("#{MRUBY_ROOT}/bin/#{bin}")
install_path = MRuby.targets['host'].exefile("#{bin_path}/#{bin}")
file install_path => exec do |t|
FileUtils.rm_f t.name, { :verbose => $verbose }
......@@ -83,7 +80,7 @@ MRuby.each_target do |target|
depfiles += [ install_path ]
elsif target == MRuby.targets['host-debug']
unless MRuby.targets['host'].gems.map {|g| g.bins}.include?([bin])
install_path = MRuby.targets['host-debug'].exefile("#{MRUBY_ROOT}/bin/#{bin}")
install_path = MRuby.targets['host-debug'].exefile("#{bin_path}/#{bin}")
file install_path => exec do |t|
FileUtils.rm_f t.name, { :verbose => $verbose }
......@@ -117,9 +114,9 @@ task :all => depfiles do
end
desc "run all mruby tests"
task :test => ["all"] + MRuby.targets.values.map { |t| t.build_mrbtest_lib_only? ? t.libfile("#{t.build_dir}/test/mrbtest") : t.exefile("#{t.build_dir}/test/mrbtest") } do
task :test => ["all"] do
MRuby.each_target do
run_test unless build_mrbtest_lib_only?
run_test if test_enabled?
end
end
......
......@@ -108,6 +108,16 @@ MRuby::Build.new('host-debug') do |conf|
# conf.enable_bintest
end
MRuby::Build.new('test') do |conf|
toolchain :gcc
enable_debug
conf.enable_bintest
conf.enable_test
conf.gembox 'default'
end
# Define cross build settings
# MRuby::CrossBuild.new('32bit') do |conf|
# toolchain :gcc
......
......@@ -8,23 +8,23 @@ Header name|Features
-----------|--------
[mrbconf.h](../mrbconf/README.md)|Defines macros for mruby configurations.
[mruby.h](./mruby.h.md)|Main header of mruby C API. Include this first.
[mruby/array.h](./mruby.array.h.md)|`Array` class.
[mruby/class.h](./mruby.class.h.md)|`Class` class.
[mruby/compile.h](./mruby.compile.h.md)|mruby compiler.
[mruby/data.h](./mruby.data.h.md)|User defined object.
[mruby/debug.h](./mruby.debug.h.md)|Debugging.
[mruby/dump.h](./mruby.dump.h.md)|Dumping compiled mruby script.
[mruby/error.h](./mruby.error.h.md)|Error handling.
[mruby/gc.h](./mruby.gc.h.md)|Uncommon memory management stuffs.
[mruby/hash.h](./mruby.hash.h.md)|`Hash` class.
[mruby/irep.h](./mruby.irep.h.md)|Compiled mruby script.
[mruby/khash.h](./mruby.khash.h.md)|Defines of khash which is used in hash table of mruby.
[mruby/numeric.h](./mruby.numeric.h.md)|`Numeric` class and sub-classes of it.
[mruby/opode.h](./mruby.opcode.h.md)|Operation codes used in mruby VM.
[mruby/proc.h](./mruby.proc.h.md)|`Proc` class.
[mruby/range.h](./mruby.range.h.md)|`Range` class.
[mruby/re.h](./mruby.re.h.md)|`Regexp` class.
[mruby/string.h](./mruby.string.h.md)|`String` class.
[mruby/value.h](./mruby.value.h.md)|`mrb_value` functions and macros.
[mruby/variable.h](./mruby.variable.h.md)|Functions to access to mruby variables.
[mruby/version.h](./mruby.version.h.md)|Macros of mruby version.
[mruby/array.h](./mruby/array.h.md)|`Array` class.
[mruby/class.h](./mruby/class.h.md)|`Class` class.
[mruby/compile.h](./mruby/compile.h.md)|mruby compiler.
[mruby/data.h](./mruby/data.h.md)|User defined object.
[mruby/debug.h](./mruby/debug.h.md)|Debugging.
[mruby/dump.h](./mruby/dump.h.md)|Dumping compiled mruby script.
[mruby/error.h](./mruby/error.h.md)|Error handling.
[mruby/gc.h](./mruby/gc.h.md)|Uncommon memory management stuffs.
[mruby/hash.h](./mruby/hash.h.md)|`Hash` class.
[mruby/irep.h](./mruby/irep.h.md)|Compiled mruby script.
[mruby/khash.h](./mruby/khash.h.md)|Defines of khash which is used in hash table of mruby.
[mruby/numeric.h](./mruby/numeric.h.md)|`Numeric` class and sub-classes of it.
[mruby/opode.h](./mruby/opcode.h.md)|Operation codes used in mruby VM.
[mruby/proc.h](./mruby/proc.h.md)|`Proc` class.
[mruby/range.h](./mruby/range.h.md)|`Range` class.
[mruby/re.h](./mruby/re.h.md)|`Regexp` class.
[mruby/string.h](./mruby/string.h.md)|`String` class.
[mruby/value.h](./mruby/value.h.md)|`mrb_value` functions and macros.
[mruby/variable.h](./mruby/variable.h.md)|Functions to access to mruby variables.
[mruby/version.h](./mruby/version.h.md)|Macros of mruby version.
......@@ -43,20 +43,22 @@ Deletes `mrb_state`.
int mrb_get_args(mrb_state *mrb, const char *format, ...);
```
Retrieve arguments from `mrb_state`.
When applicable, implicit conversions (such as `to_str`,
`to_ary`, `to_hash`) are applied to received arguments.
Use it inside a function pointed by `mrb_func_t`.
It returns number of function retrieved.
`format` is a list of following format specifier:
It returns the number of arguments retrieved.
`format` is a list of following format specifiers:
char|mruby type|retrieve types|note
:---:|----------|--------------|---
`o`|`Object`|`mrb_value`|Could be used to retrieve any type of argument
`C`|`Class`/`Module`|`mrb_value`|
`S`|`String`|`mrb_value`|
`A`|`Array`|`mrb_value`|
`H`|`Hash`|`mrb_value`|
`s`|`String`|`char*`, `mrb_int`|
`z`|`String`|`char*`|
`a`|`Array`|`mrb_value*`, `mrb_int`|
`S`|`String`|`mrb_value`|when ! follows, the value may be nil
`A`|`Array`|`mrb_value`|when ! follows, the value may be nil
`H`|`Hash`|`mrb_value`|when ! follows, the value may be nil
`s`|`String`|`char*`, `mrb_int`|Receive two arguments; s! gives (NULL,0) for nil
`z`|`String`|`char*`|NUL terminated string; z! gives NULL for nil
`a`|`Array`|`mrb_value*`, `mrb_int`|Receive two arguments; a! gives (NULL,0) for nil
`f`|`Float`|`mrb_float`|
`i`|`Integer`|`mrb_int`|
`b`|boolean|`mrb_bool`|
......@@ -67,3 +69,149 @@ char|mruby type|retrieve types|note
`?`|optional given|`mrb_bool`|True if preceding argument is given. Used to check optional argument is given.
The passing variadic arguments must be a pointer of retrieving type.
### mrb_define_class
```C
MRB_API struct RClass *mrb_define_class(mrb_state *, const char*, struct RClass*);
```
Defines a new class. If you're creating a gem it may look something like this:
```C
void mrb_example_gem_init(mrb_state* mrb) {
struct RClass *example_class;
example_class = mrb_define_class(mrb, "Example_Class", mrb->object_class);
}
void mrb_example_gem_final(mrb_state* mrb) {
//free(TheAnimals);
}
```
### mrb_define_method
```C
MRB_API void mrb_define_method(mrb_state*, struct RClass*, const char*, mrb_func_t, mrb_aspec);
```
Defines a global function in ruby. If you're creating a gem it may look something like this:
```C
mrb_value example_method(mrb_state* mrb, mrb_value self){
puts("Executing example command!");
return self;
}
void mrb_example_gem_init(mrb_state* mrb) {
mrb_define_method(mrb, mrb->kernel_module, "example_method", example_method, MRB_ARGS_NONE());
}
void mrb_example_gem_final(mrb_state* mrb) {
//free(TheAnimals);
}
```
Or maybe you want to create a class method for a class? It might look something like this:
```C
mrb_value example_method(mrb_state* mrb, mrb_value self){
puts("Examples are like pizza...");
return self;
}
void mrb_example_gem_init(mrb_state* mrb) {
struct RClass *example_class;
example_class = mrb_define_class(mrb, "Example_Class", mrb->object_class);
mrb_define_method(mrb, example_class, "example_method", example_method, MRB_ARGS_NONE());
}
void mrb_example_gem_final(mrb_state* mrb) {
//free(TheAnimals);
}
```
### mrb_define_module
```C
MRB_API struct RClass *mrb_define_module(mrb_state *, const char*);
```
Defines a module. If you're creating a gem it may look something like this:
```C
mrb_value example_method(mrb_state* mrb, mrb_value self){
puts("Examples are like tacos...");
return self;
}
void mrb_example_gem_init(mrb_state* mrb) {
struct RClass *example_module;
example_module = mrb_define_module(mrb, "Example_Module");
}
void mrb_example_gem_final(mrb_state* mrb) {
//free(TheAnimals);
}
```
### mrb_define_module_function
```C
MRB_API void mrb_define_module_function(mrb_state*, struct RClass*, const char*, mrb_func_t, mrb_aspec);
```
Defines a module function. If you're creating a gem it may look something like this:
```C
mrb_value example_method(mrb_state* mrb, mrb_value self){
puts("Examples are like hot wings...");
return self;
}
void mrb_example_gem_init(mrb_state* mrb) {
struct RClass *example_module;
example_module = mrb_define_module(mrb, "Example_Module");
mrb_define_module_function(mrb, example_module, "example_method", example_method, MRB_ARGS_NONE());
}
void mrb_example_gem_final(mrb_state* mrb) {
//free(TheAnimals);
}
```
### mrb_define_const
```C
MRB_API void mrb_define_const(mrb_state*, struct RClass*, const char *name, mrb_value);
```
Defines a constant. If you're creating a gem it may look something like this:
```C
mrb_value example_method(mrb_state* mrb, mrb_value self){
puts("Examples are like hot wings...");
return self;
}
void mrb_example_gem_init(mrb_state* mrb) {
mrb_define_const(mrb, mrb->kernel_module, "EXAPMLE_CONSTANT", mrb_fixnum_value(0x00000001));
}
void mrb_example_gem_final(mrb_state* mrb) {
//free(TheAnimals);
}
```
### mrb_str_new_cstr
```C
MRB_API mrb_value mrb_str_new_cstr(mrb_state*, const char*);
```
Turns a C string into a Ruby string value.
### mrb_value mrb_funcall
```C
MRB_API mrb_value mrb_funcall(mrb_state*, mrb_value, const char*, mrb_int,...);
```
Call existing ruby functions.
### mrb_ary_new
```C
mrb_value mrb_ary_new(mrb_state *mrb);
```
Initializes an array.
#### Example
In this example we read from a Ruby file inside C. The Ruby code will print what you pass as an argument and what class the passed in value is. In this case we are declaring a variable new_ary of data type mrb_value. Then we are initializing it with the mrb_ary_new function which only takes an mruby state as an argument.
```C
#include <stdio.h>
#include <mruby.h>
#include "mruby/array.h" // Needs the array header.
#include "mruby/compile.h"
int main(int argc, char *argv[])
{
mrb_value new_ary; // Declare variable.
mrb_state *mrb = mrb_open();
if (!mrb) { /* handle error */ }
FILE *fp = fopen("test.rb","r");
new_ary = mrb_ary_new(mrb);
mrb_value obj = mrb_load_file(mrb,fp);
mrb_funcall(mrb, obj, "method_name", 1, new_ary);
fclose(fp);
mrb_close(mrb);
return 0;
}
```
test.rb
```Ruby
class Example_Class
def method_name(a)
puts a
puts a.class
end
end
Example_Class.new
```
### mrb_ary_push
```C
void mrb_ary_push(mrb_state*, mrb_value, mrb_value);
```
Pushes given value into an array.
#### Example
In this example we read from a Ruby file inside C. The Ruby code will print what you pass as an argument and what class the passed in value is. In this case after initializing our array. We are declaring two variables with the mrb_int data type random_value1 & random_value2 and we initialize them 70 and 60 respectively. Then we use the mrb_ary_push function to push values those values into the array.
```C
#include <stdio.h>
#include <mruby.h>
#include "mruby/array.h" // Needs the array header.
#include "mruby/compile.h"
int main(int argc, char *argv[])
{
mrb_value new_ary; // Declare variable.
mrb_int random_value1 = 70; // Initialize variable
mrb_int random_value2 = 60; // Initialize variable
mrb_state *mrb = mrb_open();
if (!mrb) { /* handle error */ }
FILE *fp = fopen("test.rb","r");
new_ary = mrb_ary_new(mrb); // Initialize ruby array.
/* Pushes the fixnum value from random_value1 to the new_ary instance. */
mrb_ary_push(mrb, new_ary, mrb_fixnum_value(random_value1));
/* Pushes the fixnum value from random_value2 to the new_ary instance. */
mrb_ary_push(mrb, new_ary, mrb_fixnum_value(random_value2));
mrb_value obj = mrb_load_file(mrb,fp);
mrb_funcall(mrb, obj, "method_name", 1, new_ary);
fclose(fp);
mrb_close(mrb);
return 0;
}
```
test.rb
```Ruby
class Example_Class
def method_name(a)
puts a
puts a.class
end
end
Example_Class.new
```
#### Result
After compiling you should get these results.
```Ruby
[70, 60]
Array
```
## mrb_ary_pop
```C
mrb_value mrb_ary_pop(mrb_state *mrb, mrb_value ary);
```
Pops the last element from the array.
#### Example
In this example we read from a Ruby file inside C. The Ruby code will print what you pass as an argument and what class the passed in value is. In this case after initializing our array. We are declaring two variables with the mrb_int data type random_value1 & random_value2 and we initialize them 70 and 60 respectively. Then we use the mrb_ary_push function to push values those values into the array. Now here in the Ruby files we add another method
called pop_ary that will return the array alone(just to be clean) and you should see the last element gone.
```C
#include <stdio.h>
#include <mruby.h>
#include "mruby/array.h" // Needs the array header.
#include "mruby/compile.h"
int main(int argc, char *argv[])
{
mrb_value new_ary; // Declare variable.
mrb_int random_value1 = 70; // Initialize variable
mrb_int random_value2 = 60; // Initialize variable
mrb_state *mrb = mrb_open();
if (!mrb) { /* handle error */ }
FILE *fp = fopen("test.rb","r");
new_ary = mrb_ary_new(mrb); // Initialize ruby array.
/* Pushes the fixnum value from random_value1 to the new_ary instance. */
mrb_ary_push(mrb, new_ary, mrb_fixnum_value(random_value1));
/* Pushes the fixnum value from random_value2 to the new_ary instance. */
mrb_ary_push(mrb, new_ary, mrb_fixnum_value(random_value2));
mrb_value obj = mrb_load_file(mrb,fp);
mrb_funcall(mrb, obj, "method_name", 1, new_ary);
mrb_ary_pop(mrb, new_ary); // Pops the last element of the array. In this case 60.
mrb_funcall(mrb, obj, "pop_ary", 1, new_ary); // Calls the method again to show the results.
fclose(fp);
mrb_close(mrb);
return 0;
}
```
test.rb
```Ruby
class Example_Class
def method_name(a)
puts a
puts a.class
end
def pop_ary(a)
puts a
end
end
Example_Class.new
```
#### Result
After compiling you should get these results.
```Ruby
[70, 60]
Array
[70]
```
## mrb_ary_ref
```C
mrb_value mrb_ary_ref(mrb_state *mrb, mrb_value ary, mrb_int n);
```
Returns a reference to an element of the array. Specified by the value given to mrb_int n.
#### Example
In this example we read from a Ruby file inside C. The Ruby code will print what you pass as an argument and what class the passed in value is. In this case we're declaring a variable ary_ref with the data type of mrb_value. Then we assign mrb_ary_ref to it getting new_ary's value at index 1.
```C
#include <stdio.h>
#include <mruby.h>
#include "mruby/array.h" // Needs the array header.
#include "mruby/compile.h"
int main(int argc, char *argv[])
{
mrb_value ary_ref; // Declare variable.
mrb_value new_ary; // Declare variable.
mrb_int random_value1 = 70; // Initialize variable
mrb_int random_value2 = 60; // Initialize variable
mrb_state *mrb = mrb_open();
if (!mrb) { /* handle error */ }
FILE *fp = fopen("test.rb","r");
new_ary = mrb_ary_new(mrb); // Initialize ruby array.
/* Pushes the fixnum value from random_value1 to the new_ary instance. */
mrb_ary_push(mrb, new_ary, mrb_fixnum_value(random_value1));
/* Pushes the fixnum value from random_value2 to the new_ary instance. */
mrb_ary_push(mrb, new_ary, mrb_fixnum_value(random_value2));
ary_ref = mrb_ary_ref(mrb, new_ary, 1); // Gets the value of new_ary's second element at index 1.
mrb_value obj = mrb_load_file(mrb,fp);
/* Passing the value from ary_ref to the method method_name.*/
mrb_funcall(mrb, obj, "method_name", 1, ary_ref);
fclose(fp);
mrb_close(mrb);
return 0;
}
```
test.rb
```Ruby
class Example_Class
def method_name(a)
puts a
puts a.class
end
end
Example_Class.new
```
#### Result
After compiling you should get these results.
```Ruby
60
Fixnum
```
### mrb_ary_set
```C
void mrb_ary_set(mrb_state *mrb, mrb_value ary, mrb_int n, mrb_value val);
```
Sets a value to an index.
#### Example
In this example we read from a Ruby file inside C. The Ruby code will print what you pass as an argument and what class the passed in value is. In this case we're declaring a variable ary_ref with the data type of mrb_value. Then we assign mrb_ary_ref to it getting new_ary's value at index 1.
```C
#include <stdio.h>
#include <mruby.h>
#include "mruby/array.h" // Needs the array header.
#include "mruby/compile.h"
int main(int argc, char *argv[])
{
mrb_value new_ary;
mrb_value ary_obj;
mrb_int random_value1 = 70;
mrb_int random_value2 = 60;
mrb_state *mrb = mrb_open();
if (!mrb) { /* handle error */ }
FILE *fp = fopen("test.rb","r");
new_ary = mrb_ary_new(mrb);
mrb_ary_push(mrb, new_ary, mrb_fixnum_value(random_value1));
mrb_ary_push(mrb, new_ary, mrb_fixnum_value(random_value2));
/* Sets the fixnum value of 7 to the second index of the array.*/
mrb_ary_set(mrb, new_ary, 2, mrb_fixnum_value(7));
mrb_value obj = mrb_load_file(mrb,fp);
mrb_funcall(mrb, obj, "before_after", 1, new_ary);
fclose(fp);
mrb_close(mrb);
return 0;
}
```
test.rb
```Ruby
class Example_Class
def method_name(a)
puts a
puts a.class
end
def before_after(a)
puts a
end
end
Example_Class.new
```
#### Result
After compiling you should get these results.
```Ruby
[70, 60, 7]
```
This diff is collapsed.
#### mrb_range_new
```C
mrb_value mrb_range_new(mrb_state*, mrb_value, mrb_value, mrb_bool);
```
Initializes a Range. The first mrb_value being the beginning value and second being the ending value.
The third parameter is an mrb_bool value that represents the inclusion or exclusion of the last value.
If the third parameter is 0 then it includes the last value in the range. If the third parameter is 1
then it excludes the last value in the range.
C code
```C
#include <stdio.h>
#include <mruby.h>
#include "mruby/range.h" // Needs the range header.
#include "mruby/compile.h"
int main(int argc, char *argv[])
{
mrb_int beg = 0;
mrb_int end = 2;
mrb_bool exclude = 1;
mrb_value range_obj;
mrb_state *mrb = mrb_open();
if (!mrb) { /* handle error */ }
FILE *fp = fopen("test.rb","r");
range_obj = mrb_range_new(mrb, mrb_fixnum_value(beg), mrb_fixnum_value(end), exclude);
mrb_value obj = mrb_load_file(mrb,fp);
mrb_funcall(mrb, obj, "method_name", 1, range_obj);
fclose(fp);
mrb_close(mrb);
return 0;
}
```
Ruby code
```Ruby
class Example_Class
def method_name(a)
puts a
puts a.class
end
end
Example_Class.new
```
This returns the following:
```Ruby
0...2
Range
```
### Macros
#### REGEXP_CLASS
A string with the name of the REGEXP class.
## Macros
### mrb_str_ptr(s)
Returns a pointer from a Ruby string.
## Functions
### mrb_str_plus
```C
mrb_value mrb_str_plus(mrb_state*, mrb_value, mrb_value);
```
Adds to strings together.
### mrb_ptr_to_str
```C
mrb_value mrb_ptr_to_str(mrb_state *, void*);
```
Converts pointer into a Ruby string.
### mrb_obj_as_string
```C
mrb_value mrb_obj_as_string(mrb_state *mrb, mrb_value obj);
```
Returns an object as a Ruby string.
### mrb_str_resize
```C
mrb_value mrb_str_resize(mrb_state *mrb, mrb_value str, mrb_int len);
```
Resizes the string's length.
### mrb_str_substr
```C
mrb_value mrb_str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len);
```
Returns a sub string.
### mrb_string_type
```C
mrb_value mrb_string_type(mrb_state *mrb, mrb_value str);
```
Returns a Ruby string type.
### mrb_str_new_cstr
```C
const char *mrb_string_value_cstr(mrb_state *mrb, mrb_value *ptr);
```
Returns a Ruby string as a C string.
### mrb_str_dup
```C
mrb_value mrb_str_dup(mrb_state *mrb, mrb_value str);
```
Duplicates a string object.
### mrb_str_intern
```C
mrb_value mrb_str_intern(mrb_state *mrb, mrb_value self);
```
Returns a symbol from a passed in string.
### mrb_str_to_str
```C
mrb_value mrb_str_to_str(mrb_state *mrb, mrb_value str);
```
Returns a converted string type.
### mrb_str_equal
```C
mrb_bool mrb_str_equal(mrb_state *mrb, mrb_value str1, mrb_value str2);
```
Returns true if the strings match and false if the strings don't match.
### mrb_str_cat
```C
mrb_value mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len);
```
Returns a concated string comprised of a Ruby string and a C string.
### mrb_str_cat_cstr
```C
mrb_value mrb_str_cat_str(mrb_state *mrb, mrb_value str, mrb_value str2);
```
Returns a concated string comprised of a Ruby string and a C string(A shorter alternative to mrb_str_cat).
### mrb_str_append
```C
mrb_value mrb_str_append(mrb_state *mrb, mrb_value str1, mrb_value str2);
```
Adds str2 to the end of str1.
### mrb_str_cmp
```C
int mrb_str_cmp(mrb_state *mrb, mrb_value str1, mrb_value str2);
```
Returns 0 if both Ruby strings are equal.
Returns a value < 0 if Ruby str1 is less than Ruby str2.
Returns a value > 0 if Ruby str2 is greater than Ruby str1.
### mrb_str_to_cstr
```C
char *mrb_str_to_cstr(mrb_state *mrb, mrb_value str);
```
Returns a C string from a Ruby string.
### mrb_str_inspect
```C
mrb_str_inspect(mrb_state *mrb, mrb_value str);
```
Returns a printable version of str, surrounded by quote marks, with special characters escaped.
### mrb_float_value
```C
static inline mrb_value mrb_float_value(struct mrb_state *mrb, mrb_float f)
```
Returns a float in Ruby.
##### Example
In this example we read from a Ruby file inside C. The Ruby code will print what you pass as an argument
and what class the passed in value is. In this case we are passing in mrb_float f = 0.09. Alternatively
double i = 0.09 could also be used.
example.c
```C
#include <stdio.h>
#include <mruby.h>
#include "mruby/compile.h"
#include "mruby/string.h"
int
main(void)
{
mrb_float f = 0.09;// or double i = 0.09;
mrb_state *mrb = mrb_open();
if (!mrb) { /* handle error */ }
FILE *fp = fopen("test.rb","r");
mrb_value obj = mrb_load_file(mrb,fp);
mrb_funcall(mrb, obj, "method_name", 1, mrb_float_value(mrb, f));
fclose(fp);
mrb_close(mrb);
return 0;
}
```
test.rb
```Ruby
class My_Class
def method_name(s)
puts s
puts s.class
end
end
a = My_Class.new
```
### mrb_fixnum_value
```C
static inline mrb_value mrb_fixnum_value(mrb_int i)
```
Returns a fixnum in Ruby.
##### Example
In this example we read from a Ruby file inside C. The Ruby code will print what you pass as an argument
and what class the passed in value is. In this case we are passing in mrb_int i = 99. Alternativly int i = 99
could also be used.
example.c
```C
#include <stdio.h>
#include <mruby.h>
#include "mruby/compile.h"
int
main(void)
{
mrb_int i = 99; // or int i = 99;
mrb_state *mrb = mrb_open();
if (!mrb) { /* handle error */ }
FILE *fp = fopen("test.rb","r");
mrb_value obj = mrb_load_file(mrb,fp);
mrb_funcall(mrb, obj, "method_name", 1, mrb_fixnum_value(i));
fclose(fp);
mrb_close(mrb);
return 0;
}
```
test.rb
```Ruby
class My_Class
def method_name(s)
puts s
puts s.class
end
end
a = My_Class.new
```
### mrb_nil_value
```C
static inline mrb_value mrb_nil_value(void)
```
Returns nil in Ruby.
##### Example
In this example we read from a Ruby file inside C. The Ruby code will print what you pass as an argument
and what class the passed in value is. In this case we are passing in nothing and we will get NillClass.
example.c
```C
#include <stdio.h>
#include <mruby.h>
#include "mruby/compile.h"
int
main(void)
{
mrb_state *mrb = mrb_open();
if (!mrb) { /* handle error */ }
FILE *fp = fopen("test.rb","r");
mrb_value obj = mrb_load_file(mrb,fp);
mrb_funcall(mrb, obj, "method_name", 1, mrb_nil_value());
fclose(fp);
mrb_close(mrb);
return 0;
}
```
test.rb
```Ruby
class My_Class
def method_name(s)
puts s
puts s.class
end
end
a = My_Class.new
```
### mrb_false_value
```C
static inline mrb_value mrb_false_value(void)
```
Returns false in Ruby.
##### Example
In this example we read from a Ruby file inside C. The Ruby code will print what you pass as an argument
and what class the passed in value is. In this case we are passing in nothing and we will get FalseClass.
example.c
```C
#include <stdio.h>
#include <mruby.h>
#include "mruby/compile.h"
int
main(void)
{
mrb_state *mrb = mrb_open();
if (!mrb) { /* handle error */ }
FILE *fp = fopen("test.rb","r");
mrb_value obj = mrb_load_file(mrb,fp);
mrb_funcall(mrb, obj, "method_name", 1, mrb_false_value());
fclose(fp);
mrb_close(mrb);
return 0;
}
```
test.rb
```Ruby
class My_Class
def method_name(s)
puts s
puts s.class
end
end
a = My_Class.new
```
### mrb_true_value
```C
static inline mrb_value mrb_true_value(void)
```
Returns true in Ruby.
##### Example
In this example we read from a Ruby file inside C. The Ruby code will print what you pass as an argument
and what class the passed in value is. In this case we are passing in nothing and we will get TrueClass.
example.c
```C
#include <stdio.h>
#include <mruby.h>
#include "mruby/compile.h"
int
main(void)
{
mrb_state *mrb = mrb_open();
if (!mrb) { /* handle error */ }
FILE *fp = fopen("test.rb","r");
mrb_value obj = mrb_load_file(mrb,fp);
mrb_funcall(mrb, obj, "method_name", 1, mrb_true_value());
fclose(fp);
mrb_close(mrb);
return 0;
}
```
test.rb
```Ruby
class My_Class
def method_name(s)
puts s
puts s.class
end
end
a = My_Class.new
```
### Macros
#### MRUBY_RUBY_VERSION
The version of Ruby used by mruby.
#### MRUBY_RUBY_ENGINE
Ruby engine.
#### MRUBY_VERSION
The mruby version.
#### MRUBY_RELEASE_MAJOR
Major release version.
#### MRUBY_RELEASE_MINOR
Minor release version.
#### MRUBY_RELEASE_NO
Release number.
#### MRUBY_RELEASE_DATE
Release date as a string.
#### MRUBY_RELEASE_YEAR
Release year.
#### MRUBY_RELEASE_MONTH
Release month.
#### MRUBY_RELEASE_DAY
Release day.
#### MRUBY_BIRTH_YEAR
The year mruby was first created.
#### MRUBY_AUTHOR
Mruby's authors.
#### MRB_STRINGIZE0(expr)
A passed in expression.
#### MRB_STRINGIZE(expr)
Passes in an expression to MRB_STRINGIZE0.
#### MRUBY_DESCRIPTION
mruby's version, and release date.
#### MRUBY_COPYRIGHT
mruby's copyright information.
......@@ -13,7 +13,7 @@ This file documents the mruby debugger ('mrdb') methods.
The trunk of the mruby source tree, with the most recent mrdb, can be checked out with the following command:
```bash
$ git clone https://github.com/mruby-Forum/mruby.git
$ git clone https://github.com/mruby/mruby.git
```
To run the `make` command:
......
......@@ -26,6 +26,15 @@ conf.gem :github => 'masuidrive/mrbgems-example', :branch => 'master'
conf.gem :bitbucket => 'mruby/mrbgems-example', :branch => 'master'
```
To use mrbgem from [mgem-list](https://github.com/mruby/mgem-list) use `:mgem` option:
```ruby
conf.gem :mgem => 'mruby-yaml'
conf.gem :mgem => 'yaml' # 'mruby-' prefix could be omitted
```
If there is missing dependencies, mrbgem dependencies solver will reference
mrbgem from core or mgem-list.
To pull all gems from remote GIT repository on build, call ```./minirake -p```,
or ```./minirake --pull-gems```.
......@@ -142,7 +151,7 @@ MRuby::Gem::Specification.new('c_and_ruby_extension_example') do |spec|
# Use any version of mruby-uv from github.
spec.add_dependency('mruby-uv', '>= 0.0.0', :github => 'mattn/mruby-uv')
# Use latest mruby-onig-regexp from github. (version requirements can be ignored)
# Use latest mruby-onig-regexp from github. (version requirements can be omitted)
spec.add_dependency('mruby-onig-regexp', :github => 'mattn/mruby-onig-regexp')
end
```
......@@ -189,17 +198,21 @@ end
In case your GEM has more complex build requirements you can use
the following options additionally inside of your GEM specification:
* `spec.cflags` (C compiler flags)
* `spec.mruby_cflags` (global C compiler flags for everything)
* `spec.mruby_ldflags` (global linker flags for everything)
* `spec.mruby_libs` (global libraries for everything)
* `spec.mruby_includes` (global includes for everything)
* `spec.cc.flags` (C compiler flags)
* `spec.cc.defines` (C compiler defines)
* `spec.cc.include_paths` (C compiler include paths)
* `spec.linker.flags` (Linker flags)
* `spec.linker.libraries` (Linker libraries)
* `spec.linker.library_paths` (Linker additional library path)
* `spec.bins` (Generate binary file)
* `spec.rbfiles` (Ruby files to compile)
* `spec.objs` (Object files to compile)
* `spec.test_rbfiles` (Ruby test files for integration into mrbtest)
* `spec.test_objs` (Object test files for integration into mrbtest)
* `spec.test_preload` (Initialization files for mrbtest)
You also can use `spec.mruby.cc` and `spec.mruby.linker` to add extra global parameters for compiler and linker.
### include_paths and dependency
Your GEM can export include paths to another GEMs that depends on your GEM.
......
......@@ -192,10 +192,13 @@ typedef struct mrb_state {
# define mrb_noreturn _Noreturn
#elif defined __GNUC__ && !defined __STRICT_ANSI__
# define mrb_noreturn __attribute__((noreturn))
# define mrb_deprecated __attribute__((deprecated))
#elif defined _MSC_VER
# define mrb_noreturn __declspec(noreturn)
# define mrb_deprecated __declspec(deprecated)
#else
# define mrb_noreturn
# define mrb_deprecated
#endif
typedef mrb_value (*mrb_func_t)(mrb_state *mrb, mrb_value);
......@@ -203,6 +206,7 @@ MRB_API struct RClass *mrb_define_class(mrb_state *, const char*, struct RClass*
MRB_API struct RClass *mrb_define_module(mrb_state *, const char*);
MRB_API mrb_value mrb_singleton_class(mrb_state*, mrb_value);
MRB_API void mrb_include_module(mrb_state*, struct RClass*, struct RClass*);
MRB_API void mrb_prepend_module(mrb_state*, struct RClass*, struct RClass*);
MRB_API void mrb_define_method(mrb_state*, struct RClass*, const char*, mrb_func_t, mrb_aspec);
MRB_API void mrb_define_class_method(mrb_state *, struct RClass *, const char *, mrb_func_t, mrb_aspec);
......@@ -250,16 +254,6 @@ MRB_API struct RClass * mrb_define_module_under(mrb_state *mrb, struct RClass *o
/* accept no arguments */
#define MRB_ARGS_NONE() ((mrb_aspec)0)
/* compatibility macros; will be removed */
#define ARGS_REQ(n) MRB_ARGS_REQ(n)
#define ARGS_OPT(n) MRB_ARGS_OPT(n)
#define ARGS_REST() MRB_ARGS_REST()
#define ARGS_POST(n) MRB_ARGS_POST()
#define ARGS_KEY(n1,n2) MRB_ARGS_KEY(n1,n2)
#define ARGS_BLOCK() MRB_ARGS_BLOCK()
#define ARGS_ANY() MRB_ARGS_ANY()
#define ARGS_NONE() MRB_ARGS_NONE()
MRB_API mrb_int mrb_get_args(mrb_state *mrb, const char *format, ...);
/* `strlen` for character string literals (use with caution or `strlen` instead)
......@@ -298,6 +292,18 @@ MRB_API mrb_value mrb_str_new_cstr(mrb_state*, const char*);
MRB_API mrb_value mrb_str_new_static(mrb_state *mrb, const char *p, size_t len);
#define mrb_str_new_lit(mrb, lit) mrb_str_new_static(mrb, (lit), mrb_strlen_lit(lit))
#ifdef _WIN32
char* mrb_utf8_from_locale(const char *p, size_t len);
char* mrb_locale_from_utf8(const char *p, size_t len);
#define mrb_locale_free(p) free(p)
#define mrb_utf8_free(p) free(p)
#else
#define mrb_utf8_from_locale(p, l) (p)
#define mrb_locale_from_utf8(p, l) (p)
#define mrb_locale_free(p)
#define mrb_utf8_free(p)
#endif
MRB_API mrb_state* mrb_open(void);
MRB_API mrb_state* mrb_open_allocf(mrb_allocf, void *ud);
MRB_API mrb_state* mrb_open_core(mrb_allocf, void *ud);
......
......@@ -48,8 +48,20 @@ mrb_class(mrb_state *mrb, mrb_value v)
}
}
#define MRB_SET_INSTANCE_TT(c, tt) c->flags = ((c->flags & ~0xff) | (char)tt)
#define MRB_INSTANCE_TT(c) (enum mrb_vtype)(c->flags & 0xff)
// TODO: figure out where to put user flags
#define MRB_FLAG_IS_PREPENDED (1 << 19)
#define MRB_FLAG_IS_ORIGIN (1 << 20)
#define MRB_CLASS_ORIGIN(c) do {\
if (c->flags & MRB_FLAG_IS_PREPENDED) {\
c = c->super;\
while (!(c->flags & MRB_FLAG_IS_ORIGIN)) {\
c = c->super;\
}\
}\
} while (0)
#define MRB_INSTANCE_TT_MASK (0xFF)
#define MRB_SET_INSTANCE_TT(c, tt) c->flags = ((c->flags & ~MRB_INSTANCE_TT_MASK) | (char)tt)
#define MRB_INSTANCE_TT(c) (enum mrb_vtype)(c->flags & MRB_INSTANCE_TT_MASK)
MRB_API struct RClass* mrb_define_class_id(mrb_state*, mrb_sym, struct RClass*);
MRB_API struct RClass* mrb_define_module_id(mrb_state*, mrb_sym);
......
......@@ -55,8 +55,8 @@ enum mrb_lex_state_enum {
EXPR_CMDARG, /* newline significant, +/- is an operator. */
EXPR_MID, /* newline significant, +/- is an operator. */
EXPR_FNAME, /* ignore newline, no reserved words. */
EXPR_DOT, /* right after `.' or `::', no reserved words. */
EXPR_CLASS, /* immediate after `class', no here document. */
EXPR_DOT, /* right after '.' or '::', no reserved words. */
EXPR_CLASS, /* immediate after 'class', no here document. */
EXPR_VALUE, /* alike EXPR_BEG but label is disallowed. */
EXPR_MAX_STATE
};
......
......@@ -17,8 +17,8 @@ extern "C" {
#define DUMP_DEBUG_INFO 1
#define DUMP_ENDIAN_BIG 2
#define DUMP_ENDIAN_LIL 4
#define DUMP_ENDIAN_NAT 6
#define DUMP_ENDIAN_MASK 6
#define DUMP_ENDIAN_NAT 6
#define DUMP_ENDIAN_MASK 6
int mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, uint8_t flags, uint8_t **bin, size_t *bin_size);
#ifdef ENABLE_STDIO
......
......@@ -24,11 +24,21 @@ MRB_API mrb_value mrb_exc_new_str(mrb_state *mrb, struct RClass* c, mrb_value st
MRB_API mrb_value mrb_make_exception(mrb_state *mrb, int argc, const mrb_value *argv);
MRB_API mrb_value mrb_exc_backtrace(mrb_state *mrb, mrb_value exc);
MRB_API mrb_value mrb_get_backtrace(mrb_state *mrb);
MRB_API mrb_noreturn void mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_int argc, const mrb_value *argv, const char *fmt, ...);
MRB_API mrb_noreturn void mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_value args, const char *fmt, ...);
/* declaration for fail method */
MRB_API mrb_value mrb_f_raise(mrb_state*, mrb_value);
/* functions defined in mruby-error mrbgem */
MRB_API mrb_value mrb_protect(mrb_state *mrb, mrb_func_t body, mrb_value data, mrb_bool *state);
MRB_API mrb_value mrb_ensure(mrb_state *mrb, mrb_func_t body, mrb_value b_data,
mrb_func_t ensure, mrb_value e_data);
MRB_API mrb_value mrb_rescue(mrb_state *mrb, mrb_func_t body, mrb_value b_data,
mrb_func_t rescue, mrb_value r_data);
MRB_API mrb_value mrb_rescue_exceptions(mrb_state *mrb, mrb_func_t body, mrb_value b_data,
mrb_func_t rescue, mrb_value r_data,
mrb_int len, struct RClass **classes);
#if defined(__cplusplus)
} /* extern "C" { */
#endif
......
......@@ -14,6 +14,8 @@
struct RClass *c;\
struct RBasic *gcnext
#define MRB_FLAG_TEST(obj, flag) ((obj)->flags & flag)
/* white: 011, black: 100, gray: 000 */
#define MRB_GC_GRAY 0
#define MRB_GC_WHITE_A 1
......
......@@ -8,7 +8,7 @@
#define MRUBY_OPCODE_H
#define MAXARG_Bx (0xffff)
#define MAXARG_sBx (MAXARG_Bx>>1) /* `sBx' is signed */
#define MAXARG_sBx (MAXARG_Bx>>1) /* 'sBx' is signed */
/* instructions: packed 32 bit */
/* ------------------------------- */
......
......@@ -59,6 +59,10 @@ struct RString {
#define RSTR_SET_NOFREE_FLAG(s) ((s)->flags |= MRB_STR_NOFREE)
#define RSTR_UNSET_NOFREE_FLAG(s) ((s)->flags &= ~MRB_STR_NOFREE)
#define RSTR_FROZEN_P(s) ((s)->flags & MRB_STR_FROZEN)
#define RSTR_SET_FROZEN_FLAG(s) ((s)->flags |= MRB_STR_FROZEN)
#define RSTR_UNSET_FROZEN_FLAG(s) ((s)->flags &= ~MRB_STR_FROZEN)
#define mrb_str_ptr(s) ((struct RString*)(mrb_ptr(s)))
#define RSTRING(s) mrb_str_ptr(s)
#define RSTRING_PTR(s) RSTR_PTR(RSTRING(s))
......@@ -70,9 +74,10 @@ mrb_int mrb_str_strlen(mrb_state*, struct RString*);
#define MRB_STR_SHARED 1
#define MRB_STR_NOFREE 2
#define MRB_STR_EMBED 4
#define MRB_STR_EMBED_LEN_MASK 0xf8
#define MRB_STR_EMBED_LEN_SHIFT 3
#define MRB_STR_FROZEN 4
#define MRB_STR_EMBED 8
#define MRB_STR_EMBED_LEN_MASK 0x1f0
#define MRB_STR_EMBED_LEN_SHIFT 4
void mrb_gc_free_str(mrb_state*, struct RString*);
MRB_API void mrb_str_modify(mrb_state*, struct RString*);
......
......@@ -7,25 +7,27 @@
#ifndef MRUBY_VERSION_H
#define MRUBY_VERSION_H
#define MRB_STRINGIZE0(expr) #expr
#define MRB_STRINGIZE(expr) MRB_STRINGIZE0(expr)
#define MRUBY_RUBY_VERSION "1.9"
#define MRUBY_RUBY_ENGINE "mruby"
#define MRUBY_VERSION "1.1.0"
#define MRUBY_RELEASE_MAJOR 1
#define MRUBY_RELEASE_MINOR 1
#define MRUBY_RELEASE_TEENY 1
#define MRUBY_RELEASE_NO 10101
#define MRUBY_RELEASE_DATE "2014-11-19"
#define MRUBY_VERSION MRB_STRINGIZE(MRUBY_RELEASE_MAJOR) "." MRB_STRINGIZE(MRUBY_RELEASE_MINOR) "." MRB_STRINGIZE(MRUBY_RELEASE_TEENY)
#define MRUBY_RELEASE_NO (MRUBY_RELEASE_MAJOR * 100 * 100 + MRUBY_RELEASE_MINOR * 100 + MRUBY_RELEASE_TEENY)
#define MRUBY_RELEASE_YEAR 2014
#define MRUBY_RELEASE_MONTH 11
#define MRUBY_RELEASE_DAY 19
#define MRUBY_RELEASE_DATE MRB_STRINGIZE(MRUBY_RELEASE_YEAR) "-" MRB_STRINGIZE(MRUBY_RELEASE_MONTH) "-" MRB_STRINGIZE(MRUBY_RELEASE_DAY)
#define MRUBY_BIRTH_YEAR 2010
#define MRUBY_AUTHOR "mruby developers"
#define MRB_STRINGIZE0(expr) #expr
#define MRB_STRINGIZE(expr) MRB_STRINGIZE0(expr)
#define MRUBY_DESCRIPTION \
"mruby " MRUBY_VERSION \
......
......@@ -14,34 +14,34 @@ MRuby::GemBox.new do |conf|
# Use standard Struct class
conf.gem :core => "mruby-struct"
# Use extensional Enumerable module
# Use Enumerable module extension
conf.gem :core => "mruby-enum-ext"
# Use extensional String class
# Use String class extension
conf.gem :core => "mruby-string-ext"
# Use extensional Numeric class
# Use Numeric class extension
conf.gem :core => "mruby-numeric-ext"
# Use extensional Array class
# Use Array class extension
conf.gem :core => "mruby-array-ext"
# Use extensional Hash class
# Use Hash class extension
conf.gem :core => "mruby-hash-ext"
# Use extensional Range class
# Use Range class extension
conf.gem :core => "mruby-range-ext"
# Use extensional Proc class
# Use Proc class extension
conf.gem :core => "mruby-proc-ext"
# Use extensional Symbol class
# Use Symbol class extension
conf.gem :core => "mruby-symbol-ext"
# Use Random class
conf.gem :core => "mruby-random"
# Use extensional Object class
# Use Object class extension
conf.gem :core => "mruby-object-ext"
# Use ObjectSpace class
......@@ -56,7 +56,7 @@ MRuby::GemBox.new do |conf|
# Use Enumerable::Lazy class (require mruby-enumerator)
conf.gem :core => "mruby-enum-lazy"
# Use extended toplevel object (main) methods
# Use toplevel object (main) methods extension
conf.gem :core => "mruby-toplevel-ext"
# Generate mirb command
......@@ -68,6 +68,9 @@ MRuby::GemBox.new do |conf|
# Generate mruby-strip command
conf.gem :core => "mruby-bin-strip"
# Use extensional Kernel module
# Use Kernel module extension
conf.gem :core => "mruby-kernel-ext"
# Use mruby-compiler to build other mrbgems
conf.gem :core => "mruby-compiler"
end
......@@ -4,6 +4,6 @@ MRuby::GemBox.new do |conf|
Dir.glob("#{root}/mrbgems/mruby-*/mrbgem.rake") do |x|
g = File.basename File.dirname x
conf.gem :core => g unless g =~ /^mruby-(print|sprintf|bin-debugger)$/
conf.gem :core => g unless g =~ /^mruby-(print|sprintf|bin-debugger|test)$/
end
end
MRuby::Gem::Specification.new('mruby-array-ext') do |spec|
spec.license = 'MIT'
spec.author = 'mruby developers'
spec.summary = 'extensional Array class'
spec.summary = 'Array class extension'
end
......@@ -217,7 +217,7 @@ class Array
# [ "a", "b", "c" ].compact! #=> nil
#
def compact!
result = self.select { |e| e != nil }
result = self.select { |e| !e.nil? }
if result.size == self.size
nil
else
......@@ -262,7 +262,7 @@ class Array
#
def fetch(n=nil, ifnone=NONE, &block)
warn "block supersedes default value argument" if n != nil && ifnone != NONE && block
warn "block supersedes default value argument" if !n.nil? && ifnone != NONE && block
idx = n
if idx < 0
......@@ -312,51 +312,51 @@ class Array
#
def fill(arg0=nil, arg1=nil, arg2=nil, &block)
if arg0 == nil && arg1 == nil && arg2 == nil && !block
if arg0.nil? && arg1.nil? && arg2.nil? && !block
raise ArgumentError, "wrong number of arguments (0 for 1..3)"
end
beg = len = 0
ary = []
if block
if arg0 == nil && arg1 == nil && arg2 == nil
if arg0.nil? && arg1.nil? && arg2.nil?
# ary.fill { |index| block } -> ary
beg = 0
len = self.size
elsif arg0 != nil && arg0.kind_of?(Range)
elsif !arg0.nil? && arg0.kind_of?(Range)
# ary.fill(range) { |index| block } -> ary
beg = arg0.begin
beg += self.size if beg < 0
len = arg0.end
len += self.size if len < 0
len += 1 unless arg0.exclude_end?
elsif arg0 != nil
elsif !arg0.nil?
# ary.fill(start [, length] ) { |index| block } -> ary
beg = arg0
beg += self.size if beg < 0
if arg1 == nil
if arg1.nil?
len = self.size
else
len = arg0 + arg1
end
end
else
if arg0 != nil && arg1 == nil && arg2 == nil
if !arg0.nil? && arg1.nil? && arg2.nil?
# ary.fill(obj) -> ary
beg = 0
len = self.size
elsif arg0 != nil && arg1 != nil && arg1.kind_of?(Range)
elsif !arg0.nil? && !arg1.nil? && arg1.kind_of?(Range)
# ary.fill(obj, range ) -> ary
beg = arg1.begin
beg += self.size if beg < 0
len = arg1.end
len += self.size if len < 0
len += 1 unless arg1.exclude_end?
elsif arg0 != nil && arg1 != nil
elsif !arg0.nil? && !arg1.nil?
# ary.fill(obj, start [, length]) -> ary
beg = arg1
beg += self.size if beg < 0
if arg2 == nil
if arg2.nil?
len = self.size
else
len = beg + arg2
......@@ -582,7 +582,7 @@ class Array
elsif v == true
satisfied = true
smaller = true
elsif v == false || v == nil
elsif v == false || v.nil?
smaller = false
end
if smaller
......
MRuby::Gem::Specification.new('mruby-bin-debugger') do |spec|
spec.license = 'MIT'
spec.author = 'mruby developers'
spec.summary = 'mruby debuggeer command'
spec.summary = 'mruby debugger command'
spec.add_dependency('mruby-eval', :core => 'mruby-eval')
......
......@@ -33,7 +33,7 @@ static help_msg help_msg_list[] = {
"\n"
"Continue program stopped by a breakpoint.\n"
"If N, which is non negative value, is passed,\n"
"proceed program until the N-th breakpoint is comming.\n"
"proceed program until the N-th breakpoint is coming.\n"
"If N is not passed, N is assumed 1.\n"
},
{
......
......@@ -222,9 +222,9 @@ mrb_debug_context_free(mrb_state *mrb)
static mrdb_state*
mrdb_state_new(mrb_state *mrb)
{
mrdb_state *mrdb = mrb_malloc(mrb, sizeof(mrb_state));
mrdb_state *mrdb = mrb_malloc(mrb, sizeof(mrdb_state));
memset(mrdb, 0, sizeof(mrb_state));
memset(mrdb, 0, sizeof(mrdb_state));
mrdb->dbg = mrb_debug_context_get(mrb);
mrdb->command = mrb_malloc(mrb, MAX_COMMAND_LINE+1);
......
......@@ -6,20 +6,28 @@ MRuby::Gem::Specification.new('mruby-bin-mirb') do |spec|
if spec.build.cc.search_header_path 'readline/readline.h'
spec.cc.defines << "ENABLE_READLINE"
if spec.build.cc.search_header_path 'termcap.h'
if MRUBY_BUILD_HOST_IS_CYGWIN then
spec.linker.libraries << 'ncurses'
else
spec.linker.libraries << 'termcap'
if MRUBY_BUILD_HOST_IS_CYGWIN || MRUBY_BUILD_HOST_IS_OPENBSD
if spec.build.cc.search_header_path 'termcap.h'
if MRUBY_BUILD_HOST_IS_CYGWIN then
spec.linker.libraries << 'ncurses'
else
spec.linker.libraries << 'termcap'
end
end
end
end
if RUBY_PLATFORM.include?('netbsd')
spec.linker.libraries << 'edit'
else
spec.linker.libraries << 'readline'
if spec.build.cc.search_header_path 'curses.h'
spec.linker.libraries << 'ncurses'
end
end
elsif spec.build.cc.search_header_path 'linenoise.h'
spec.cc.defines << "ENABLE_LINENOISE"
end
spec.bins = %w(mirb)
spec.add_dependency('mruby-compiler', :core => 'mruby-compiler')
end
......@@ -366,6 +366,8 @@ main(int argc, char **argv)
ai = mrb_gc_arena_save(mrb);
while (TRUE) {
char *utf8;
#ifndef ENABLE_READLINE
print_cmdline(code_block_open);
......@@ -415,17 +417,21 @@ main(int argc, char **argv)
strcpy(ruby_code, last_code_line);
}
utf8 = mrb_utf8_from_locale(ruby_code, -1);
if (!utf8) abort();
/* parse code */
parser = mrb_parser_new(mrb);
if (parser == NULL) {
fputs("create parser state error\n", stderr);
break;
}
parser->s = ruby_code;
parser->send = ruby_code + strlen(ruby_code);
parser->s = utf8;
parser->send = utf8 + strlen(utf8);
parser->lineno = cxt->lineno;
mrb_parser_parse(parser, cxt);
code_block_open = is_code_block_open(parser);
mrb_utf8_free(utf8);
if (code_block_open) {
/* no evaluation of code */
......
MRuby::Gem::Specification.new 'mruby-bin-mrbc' do |spec|
spec.license = 'MIT'
spec.author = 'mruby developers'
spec.summary = 'mruby compiler executable'
spec.add_dependency 'mruby-compiler', :core => 'mruby-compiler'
exec = exefile("#{build.build_dir}/bin/mrbc")
mrbc_objs = Dir.glob("#{spec.dir}/tools/mrbc/*.c").map { |f| objfile(f.pathmap("#{spec.build_dir}/tools/mrbc/%n")) }.flatten
file exec => mrbc_objs + [libfile("#{build.build_dir}/lib/libmruby_core")] do |t|
build.linker.run t.name, t.prerequisites
end
build.bins << 'mrbc' unless build.bins.find { |v| v == 'mrbc' }
end
......@@ -119,10 +119,10 @@ parse_args(mrb_state *mrb, int argc, char **argv, struct mrbc_args *args)
args->flags |= DUMP_DEBUG_INFO;
break;
case 'E':
args->flags = DUMP_ENDIAN_BIG | (args->flags & DUMP_DEBUG_INFO);
args->flags = DUMP_ENDIAN_BIG | (args->flags & ~DUMP_ENDIAN_MASK);
break;
case 'e':
args->flags = DUMP_ENDIAN_LIL | (args->flags & DUMP_DEBUG_INFO);
args->flags = DUMP_ENDIAN_LIL | (args->flags & ~DUMP_ENDIAN_MASK);
break;
case 'h':
return -1;
......@@ -161,8 +161,7 @@ parse_args(mrb_state *mrb, int argc, char **argv, struct mrbc_args *args)
static void
cleanup(mrb_state *mrb, struct mrbc_args *args)
{
if (args->outfile)
mrb_free(mrb, (void*)args->outfile);
mrb_free(mrb, (void*)args->outfile);
mrb_close(mrb);
}
......
......@@ -3,4 +3,5 @@ MRuby::Gem::Specification.new('mruby-bin-mruby') do |spec|
spec.author = 'mruby developers'
spec.summary = 'mruby command'
spec.bins = %w(mruby)
spec.add_dependency('mruby-compiler', :core => 'mruby-compiler')
end
......@@ -11,12 +11,8 @@
static void
p(mrb_state *mrb, mrb_value obj)
{
mrb_value val;
mrb_value val = mrb_inspect(mrb, obj);
val = mrb_funcall(mrb, obj, "inspect", 0);
if (!mrb_string_p(val)) {
val = mrb_obj_as_string(mrb, obj);
}
fwrite(RSTRING_PTR(val), RSTRING_LEN(val), 1, stdout);
putc('\n', stdout);
}
......@@ -163,10 +159,9 @@ cleanup(mrb_state *mrb, struct _args *args)
{
if (args->rfp && args->rfp != stdin)
fclose(args->rfp);
if (args->cmdline && !args->fname)
if (!args->fname)
mrb_free(mrb, args->cmdline);
if (args->argv)
mrb_free(mrb, args->argv);
mrb_free(mrb, args->argv);
mrb_close(mrb);
}
......@@ -196,7 +191,11 @@ main(int argc, char **argv)
ARGV = mrb_ary_new_capa(mrb, args.argc);
for (i = 0; i < args.argc; i++) {
mrb_ary_push(mrb, ARGV, mrb_str_new_cstr(mrb, args.argv[i]));
char* utf8 = mrb_utf8_from_locale(args.argv[i], -1);
if (utf8) {
mrb_ary_push(mrb, ARGV, mrb_str_new_cstr(mrb, utf8));
mrb_utf8_free(utf8);
}
}
mrb_define_global_const(mrb, "ARGV", ARGV);
......@@ -227,7 +226,10 @@ main(int argc, char **argv)
v = mrb_load_file_cxt(mrb, args.rfp, c);
}
else {
v = mrb_load_string_cxt(mrb, args.cmdline, c);
char* utf8 = mrb_utf8_from_locale(args.cmdline, -1);
if (!utf8) abort();
v = mrb_load_string_cxt(mrb, utf8, c);
mrb_utf8_free(utf8);
}
mrbc_context_free(mrb, c);
......
......@@ -188,6 +188,11 @@ genop_peep(codegen_scope *s, mrb_code i, int val)
if (val) break;
switch (c0) {
case OP_MOVE:
if (GETARG_A(i) == GETARG_A(i0)) {
/* skip overriden OP_MOVE */
s->pc--;
s->iseq[s->pc] = i;
}
if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i) == GETARG_B(i0)) {
/* skip swapping OP_MOVE */
return 0;
......@@ -406,7 +411,18 @@ push_(codegen_scope *s)
nregs_update;
}
static void
push_n_(codegen_scope *s, size_t n)
{
if (s->sp+n > 511) {
codegen_error(s, "too complex expression");
}
s->sp+=n;
nregs_update;
}
#define push() push_(s)
#define push_n(n) push_n_(s,n)
#define pop_(s) ((s)->sp--)
#define pop() pop_(s)
#define pop_n(n) (s->sp-=(n))
......@@ -957,13 +973,6 @@ gen_assignment(codegen_scope *s, node *tree, int sp, int val)
gen_vmassignment(s, tree->car, sp, val);
break;
push();
gen_call(s, tree, attrsym(s, sym(tree->cdr->car)), sp, NOVAL);
pop();
if (val) {
genop_peep(s, MKOP_AB(OP_MOVE, cursp(), sp), val);
}
break;
/* splat without assignment */
case NODE_NIL:
break;
......@@ -1008,6 +1017,8 @@ gen_vmassignment(codegen_scope *s, node *tree, int rhs, int val)
else {
pop();
}
push_n(post);
pop_n(post);
genop(s, MKOP_ABC(OP_APOST, cursp(), n, post));
n = 1;
if (t->car) { /* rest */
......@@ -1622,8 +1633,14 @@ codegen(codegen_scope *s, node *tree, int val)
}
}
if (t->car) { /* rest (len - pre - post) */
int rn = len - post - n;
int rn;
if (len < post + n) {
rn = 0;
}
else {
rn = len - post - n;
}
genop(s, MKOP_ABC(OP_ARRAY, cursp(), rhs+n, rn));
gen_assignment(s, t->car, cursp(), NOVAL);
n += rn;
......@@ -1912,7 +1929,7 @@ codegen(codegen_scope *s, node *tree, int val)
break;
case NODE_GVAR:
{
if (val) {
int sym = new_sym(s, sym(tree));
genop(s, MKOP_ABx(OP_GETGLOBAL, cursp(), sym));
......@@ -1921,7 +1938,7 @@ codegen(codegen_scope *s, node *tree, int val)
break;
case NODE_IVAR:
{
if (val) {
int sym = new_sym(s, sym(tree));
genop(s, MKOP_ABx(OP_GETIV, cursp(), sym));
......@@ -1930,7 +1947,7 @@ codegen(codegen_scope *s, node *tree, int val)
break;
case NODE_CVAR:
{
if (val) {
int sym = new_sym(s, sym(tree));
genop(s, MKOP_ABx(OP_GETCV, cursp(), sym));
......@@ -1943,7 +1960,9 @@ codegen(codegen_scope *s, node *tree, int val)
int sym = new_sym(s, sym(tree));
genop(s, MKOP_ABx(OP_GETCONST, cursp(), sym));
push();
if (val) {
push();
}
}
break;
......@@ -1952,7 +1971,7 @@ codegen(codegen_scope *s, node *tree, int val)
break;
case NODE_BACK_REF:
{
if (val) {
char buf[2] = { '$' };
mrb_value str;
int sym;
......@@ -1966,7 +1985,7 @@ codegen(codegen_scope *s, node *tree, int val)
break;
case NODE_NTH_REF:
{
if (val) {
int sym;
mrb_state *mrb = s->mrb;
mrb_value fix = mrb_fixnum_value((intptr_t)tree);
......@@ -2651,13 +2670,17 @@ loop_break(codegen_scope *s, node *tree)
}
loop = s->loop;
while (loop->type == LOOP_BEGIN) {
while (loop && loop->type == LOOP_BEGIN) {
genop_peep(s, MKOP_A(OP_POPERR, 1), NOVAL);
loop = loop->prev;
}
while (loop->type == LOOP_RESCUE) {
while (loop && loop->type == LOOP_RESCUE) {
loop = loop->prev;
}
if (!loop) {
codegen_error(s, "unexpected break");
}
if (loop->type == LOOP_NORMAL) {
int tmp;
......
/* ANSI-C code produced by gperf version 3.0.3 */
/* Command-line: gperf -L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k'1,3,$' src/keywords */
/* ANSI-C code produced by gperf version 3.0.4 */
/* Command-line: gperf -L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k'1,3,$' /home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords */
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
......@@ -28,13 +28,13 @@
#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
#endif
#line 1 "src/keywords"
#line 1 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
struct kwtable {const char *name; int id[2]; enum mrb_lex_state_enum state;};
const struct kwtable *mrb_reserved_word(const char *, unsigned int);
static const struct kwtable *reserved_word(const char *, unsigned int);
#define mrb_reserved_word(str, len) reserved_word(str, len)
#line 8 "src/keywords"
#line 8 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
struct kwtable;
#define TOTAL_KEYWORDS 40
......@@ -100,7 +100,7 @@ hash (register const char *str, register unsigned int len)
#ifdef __GNUC__
__inline
#ifdef __GNUC_STDC_INLINE__
#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
__attribute__ ((__gnu_inline__))
#endif
#endif
......@@ -110,87 +110,87 @@ mrb_reserved_word (register const char *str, register unsigned int len)
static const struct kwtable wordlist[] =
{
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
#line 18 "src/keywords"
#line 18 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"break", {keyword_break, keyword_break}, EXPR_MID},
#line 23 "src/keywords"
#line 23 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"else", {keyword_else, keyword_else}, EXPR_BEG},
#line 33 "src/keywords"
#line 33 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"nil", {keyword_nil, keyword_nil}, EXPR_END},
#line 26 "src/keywords"
#line 26 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"ensure", {keyword_ensure, keyword_ensure}, EXPR_BEG},
#line 25 "src/keywords"
#line 25 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"end", {keyword_end, keyword_end}, EXPR_END},
#line 42 "src/keywords"
#line 42 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"then", {keyword_then, keyword_then}, EXPR_BEG},
#line 34 "src/keywords"
#line 34 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"not", {keyword_not, keyword_not}, EXPR_ARG},
#line 27 "src/keywords"
#line 27 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"false", {keyword_false, keyword_false}, EXPR_END},
#line 40 "src/keywords"
#line 40 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"self", {keyword_self, keyword_self}, EXPR_END},
#line 24 "src/keywords"
#line 24 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"elsif", {keyword_elsif, keyword_elsif}, EXPR_VALUE},
#line 37 "src/keywords"
#line 37 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"rescue", {keyword_rescue, modifier_rescue}, EXPR_MID},
#line 43 "src/keywords"
#line 43 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"true", {keyword_true, keyword_true}, EXPR_END},
#line 46 "src/keywords"
#line 46 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"until", {keyword_until, modifier_until}, EXPR_VALUE},
#line 45 "src/keywords"
#line 45 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"unless", {keyword_unless, modifier_unless}, EXPR_VALUE},
#line 39 "src/keywords"
#line 39 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"return", {keyword_return, keyword_return}, EXPR_MID},
#line 21 "src/keywords"
#line 21 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"def", {keyword_def, keyword_def}, EXPR_FNAME},
#line 16 "src/keywords"
#line 16 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"and", {keyword_and, keyword_and}, EXPR_VALUE},
#line 22 "src/keywords"
#line 22 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"do", {keyword_do, keyword_do}, EXPR_BEG},
#line 49 "src/keywords"
#line 49 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"yield", {keyword_yield, keyword_yield}, EXPR_ARG},
#line 28 "src/keywords"
#line 28 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"for", {keyword_for, keyword_for}, EXPR_VALUE},
#line 44 "src/keywords"
#line 44 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"undef", {keyword_undef, keyword_undef}, EXPR_FNAME},
#line 35 "src/keywords"
#line 35 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"or", {keyword_or, keyword_or}, EXPR_VALUE},
#line 30 "src/keywords"
#line 30 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"in", {keyword_in, keyword_in}, EXPR_VALUE},
#line 47 "src/keywords"
#line 47 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"when", {keyword_when, keyword_when}, EXPR_VALUE},
#line 38 "src/keywords"
#line 38 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"retry", {keyword_retry, keyword_retry}, EXPR_END},
#line 29 "src/keywords"
#line 29 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"if", {keyword_if, modifier_if}, EXPR_VALUE},
#line 19 "src/keywords"
#line 19 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"case", {keyword_case, keyword_case}, EXPR_VALUE},
#line 36 "src/keywords"
#line 36 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"redo", {keyword_redo, keyword_redo}, EXPR_END},
#line 32 "src/keywords"
#line 32 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"next", {keyword_next, keyword_next}, EXPR_MID},
#line 41 "src/keywords"
#line 41 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"super", {keyword_super, keyword_super}, EXPR_ARG},
#line 31 "src/keywords"
#line 31 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"module", {keyword_module, keyword_module}, EXPR_VALUE},
#line 17 "src/keywords"
#line 17 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"begin", {keyword_begin, keyword_begin}, EXPR_BEG},
#line 12 "src/keywords"
#line 12 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"__LINE__", {keyword__LINE__, keyword__LINE__}, EXPR_END},
#line 11 "src/keywords"
#line 11 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"__FILE__", {keyword__FILE__, keyword__FILE__}, EXPR_END},
#line 10 "src/keywords"
#line 10 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"__ENCODING__", {keyword__ENCODING__, keyword__ENCODING__}, EXPR_END},
#line 14 "src/keywords"
#line 14 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"END", {keyword_END, keyword_END}, EXPR_END},
#line 15 "src/keywords"
#line 15 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"alias", {keyword_alias, keyword_alias}, EXPR_FNAME},
#line 13 "src/keywords"
#line 13 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"BEGIN", {keyword_BEGIN, keyword_BEGIN}, EXPR_END},
{""},
#line 20 "src/keywords"
#line 20 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"class", {keyword_class, keyword_class}, EXPR_CLASS},
{""}, {""},
#line 48 "src/keywords"
#line 48 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"while", {keyword_while, modifier_while}, EXPR_VALUE}
};
......@@ -208,5 +208,5 @@ mrb_reserved_word (register const char *str, register unsigned int len)
}
return 0;
}
#line 50 "src/keywords"
#line 50 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
......@@ -2154,6 +2154,7 @@ primary : literal
$$ = new_lambda(p, $3, $5);
local_unnest(p);
p->cmdarg_stack = $<stack>4;
CMDARG_LEXPOP();
}
| keyword_if expr_value then
compstmt
......@@ -2941,7 +2942,7 @@ backref : tNTH_REF
| tBACK_REF
;
superclass : term
superclass : /* term */
{
$$ = 0;
}
......@@ -2953,12 +2954,12 @@ superclass : term
expr_value term
{
$$ = $3;
}
} /*
| error term
{
yyerrok;
$$ = 0;
}
} */
;
f_arglist : '(' f_args rparen
......@@ -3604,10 +3605,13 @@ toklast(parser_state *p)
static void
tokfix(parser_state *p)
{
if (p->bidx >= MRB_PARSER_BUF_SIZE) {
int i = p->bidx, imax = MRB_PARSER_BUF_SIZE - 1;
if (i > imax) {
i = imax;
yyerror(p, "string too long (truncated)");
}
p->buf[p->bidx] = '\0';
p->buf[i] = '\0';
}
static const char*
......@@ -4204,7 +4208,7 @@ parser_yylex(parser_state *p)
}
pushback(p, c);
if (IS_SPCARG(c)) {
yywarning(p, "`*' interpreted as argument prefix");
yywarning(p, "'*' interpreted as argument prefix");
c = tSTAR;
}
else if (IS_BEG()) {
......@@ -4455,7 +4459,7 @@ parser_yylex(parser_state *p)
}
pushback(p, c);
if (IS_SPCARG(c)) {
yywarning(p, "`&' interpreted as argument prefix");
yywarning(p, "'&' interpreted as argument prefix");
c = tAMPER;
}
else if (IS_BEG()) {
......@@ -4761,7 +4765,7 @@ parser_yylex(parser_state *p)
nondigit = c;
break;
case '_': /* `_' in number just ignored */
case '_': /* '_' in number just ignored */
if (nondigit) goto decode_num;
nondigit = c;
break;
......@@ -4776,7 +4780,7 @@ parser_yylex(parser_state *p)
pushback(p, c);
if (nondigit) {
trailing_uc:
yyerror_i(p, "trailing `%c' in number", nondigit);
yyerror_i(p, "trailing '%c' in number", nondigit);
}
tokfix(p);
if (is_float) {
......@@ -4802,6 +4806,7 @@ parser_yylex(parser_state *p)
case ')':
case ']':
p->paren_nest--;
/* fall through */
case '}':
COND_LEXPOP();
CMDARG_LEXPOP();
......@@ -5133,6 +5138,7 @@ parser_yylex(parser_state *p)
pushback(p, c);
return '$';
}
/* fall through */
case '0':
tokadd(p, '$');
}
......@@ -5157,10 +5163,10 @@ parser_yylex(parser_state *p)
}
else if (isdigit(c)) {
if (p->bidx == 1) {
yyerror_i(p, "`@%c' is not allowed as an instance variable name", c);
yyerror_i(p, "'@%c' is not allowed as an instance variable name", c);
}
else {
yyerror_i(p, "`@@%c' is not allowed as a class variable name", c);
yyerror_i(p, "'@@%c' is not allowed as a class variable name", c);
}
return 0;
}
......@@ -5176,7 +5182,7 @@ parser_yylex(parser_state *p)
default:
if (!identchar(c)) {
yyerror_i(p, "Invalid char `\\x%02X' in expression", c);
yyerror_i(p, "Invalid char '\\x%02X' in expression", c);
goto retry;
}
......
MRuby::Gem::Specification.new 'mruby-compiler' do |spec|
spec.license = 'MIT'
spec.author = 'mruby developers'
spec.summary = 'mruby compiler library'
current_dir = spec.dir
current_build_dir = spec.build_dir
lex_def = "#{current_dir}/core/lex.def"
core_objs = Dir.glob("#{current_dir}/core/*.c").map { |f|
next nil if build.cxx_abi_enabled? and f =~ /(codegen).c$/
objfile(f.pathmap("#{current_build_dir}/core/%n"))
}.compact
if build.cxx_abi_enabled?
core_objs <<
build.compile_as_cxx("#{current_build_dir}/core/y.tab.c", "#{current_build_dir}/core/y.tab.cxx",
objfile("#{current_build_dir}/y.tab"), ["#{current_dir}/core"]) <<
build.compile_as_cxx("#{current_dir}/core/codegen.c", "#{current_build_dir}/core/codegen.cxx")
else
core_objs << objfile("#{current_build_dir}/core/y.tab")
file objfile("#{current_build_dir}/core/y.tab") => "#{current_build_dir}/core/y.tab.c" do |t|
cc.run t.name, t.prerequisites.first, [], ["#{current_dir}/core"]
end
end
file objfile("#{current_build_dir}/core/y.tab") => lex_def
# Parser
file "#{current_build_dir}/core/y.tab.c" => ["#{current_dir}/core/parse.y"] do |t|
yacc.run t.name, t.prerequisites.first
end
# Lexical analyzer
file lex_def => "#{current_dir}/core/keywords" do |t|
gperf.run t.name, t.prerequisites.first
end
file libfile("#{build.build_dir}/lib/libmruby_core") => core_objs
build.libmruby << core_objs
end
MRuby::Gem::Specification.new('mruby-enum-ext') do |spec|
spec.license = 'MIT'
spec.author = 'mruby developers'
spec.summary = 'extensional Enumerable module'
spec.summary = 'Enumerable module extension'
end
......@@ -515,7 +515,7 @@ module Enumerable
#
def each_with_object(obj=nil, &block)
raise ArgumentError, "wrong number of arguments (0 for 1)" if obj == nil
raise ArgumentError, "wrong number of arguments (0 for 1)" if obj.nil?
return to_enum(:each_with_object, obj) unless block
......@@ -574,10 +574,10 @@ module Enumerable
#
def cycle(n=nil, &block)
return to_enum(:cycle, n) if !block && n == nil
return to_enum(:cycle, n) if !block && n.nil?
ary = []
if n == nil
if n.nil?
self.each do|*val|
ary.push val
block.call(*val)
......
MRuby::Gem::Specification.new('mruby-error') do |spec|
spec.license = 'MIT'
spec.author = 'mruby developers'
spec.summary = 'extensional error handling'
if build.cxx_abi_enabled?
@objs << build.compile_as_cxx("#{spec.dir}/src/exception.c", "#{spec.build_dir}/src/exception.cxx")
@objs.delete_if { |v| v == objfile("#{spec.build_dir}/src/exception") }
end
end
#include "mruby.h"
#include "mruby/throw.h"
#include "mruby/error.h"
MRB_API mrb_value
mrb_protect(mrb_state *mrb, mrb_func_t body, mrb_value data, mrb_bool *state)
{
struct mrb_jmpbuf *prev_jmp = mrb->jmp;
struct mrb_jmpbuf c_jmp;
mrb_value result = mrb_nil_value();
if (state) { *state = FALSE; }
MRB_TRY(&c_jmp) {
mrb->jmp = &c_jmp;
result = body(mrb, data);
mrb->jmp = prev_jmp;
} MRB_CATCH(&c_jmp) {
mrb->jmp = prev_jmp;
result = mrb_obj_value(mrb->exc);
mrb->exc = NULL;
if (state) { *state = TRUE; }
} MRB_END_EXC(&c_jmp);
mrb_gc_protect(mrb, result);
return result;
}
MRB_API mrb_value
mrb_ensure(mrb_state *mrb, mrb_func_t body, mrb_value b_data, mrb_func_t ensure, mrb_value e_data)
{
struct mrb_jmpbuf *prev_jmp = mrb->jmp;
struct mrb_jmpbuf c_jmp;
mrb_value result;
MRB_TRY(&c_jmp) {
mrb->jmp = &c_jmp;
result = body(mrb, b_data);
mrb->jmp = prev_jmp;
} MRB_CATCH(&c_jmp) {
mrb->jmp = prev_jmp;
ensure(mrb, e_data);
MRB_THROW(mrb->jmp); /* rethrow catched exceptions */
} MRB_END_EXC(&c_jmp);
ensure(mrb, e_data);
mrb_gc_protect(mrb, result);
return result;
}
MRB_API mrb_value
mrb_rescue(mrb_state *mrb, mrb_func_t body, mrb_value b_data,
mrb_func_t rescue, mrb_value r_data)
{
return mrb_rescue_exceptions(mrb, body, b_data, rescue, r_data, 1, &mrb->eStandardError_class);
}
MRB_API mrb_value
mrb_rescue_exceptions(mrb_state *mrb, mrb_func_t body, mrb_value b_data, mrb_func_t rescue, mrb_value r_data,
mrb_int len, struct RClass **classes)
{
struct mrb_jmpbuf *prev_jmp = mrb->jmp;
struct mrb_jmpbuf c_jmp;
mrb_value result;
mrb_bool error_matched = FALSE;
mrb_int i;
MRB_TRY(&c_jmp) {
mrb->jmp = &c_jmp;
result = body(mrb, b_data);
mrb->jmp = prev_jmp;
} MRB_CATCH(&c_jmp) {
mrb->jmp = prev_jmp;
for (i = 0; i < len; ++i) {
if (mrb_obj_is_kind_of(mrb, mrb_obj_value(mrb->exc), classes[i])) {
error_matched = TRUE;
break;
}
}
if (!error_matched) { MRB_THROW(mrb->jmp); }
mrb->exc = NULL;
result = rescue(mrb, r_data);
} MRB_END_EXC(&c_jmp);
mrb_gc_protect(mrb, result);
return result;
}
void
mrb_mruby_error_gem_init(mrb_state *mrb)
{
}
void
mrb_mruby_error_gem_final(mrb_state *mrb)
{
}
#include "mruby.h"
#include "mruby/error.h"
#include "mruby/array.h"
static mrb_value
protect_cb(mrb_state *mrb, mrb_value b)
{
return mrb_yield_argv(mrb, b, 0, NULL);
}
static mrb_value
run_protect(mrb_state *mrb, mrb_value self)
{
mrb_value b;
mrb_value ret[2];
mrb_bool state;
mrb_get_args(mrb, "&", &b);
ret[0] = mrb_protect(mrb, protect_cb, b, &state);
ret[1] = mrb_bool_value(state);
return mrb_ary_new_from_values(mrb, 2, ret);
}
static mrb_value
run_ensure(mrb_state *mrb, mrb_value self)
{
mrb_value b, e;
mrb_get_args(mrb, "oo", &b, &e);
return mrb_ensure(mrb, protect_cb, b, protect_cb, e);
}
static mrb_value
run_rescue(mrb_state *mrb, mrb_value self)
{
mrb_value b, r;
mrb_get_args(mrb, "oo", &b, &r);
return mrb_rescue(mrb, protect_cb, b, protect_cb, r);
}
static mrb_value
run_rescue_exceptions(mrb_state *mrb, mrb_value self)
{
mrb_value b, r;
struct RClass *cls[1];
mrb_get_args(mrb, "oo", &b, &r);
cls[0] = E_TYPE_ERROR;
return mrb_rescue_exceptions(mrb, protect_cb, b, protect_cb, r, 1, cls);
}
void
mrb_mruby_error_gem_test(mrb_state *mrb)
{
struct RClass *cls;
cls = mrb_define_class(mrb, "ExceptionTest", mrb->object_class);
mrb_define_module_function(mrb, cls, "mrb_protect", run_protect, MRB_ARGS_NONE() | MRB_ARGS_BLOCK());
mrb_define_module_function(mrb, cls, "mrb_ensure", run_ensure, MRB_ARGS_REQ(2));
mrb_define_module_function(mrb, cls, "mrb_rescue", run_rescue, MRB_ARGS_REQ(2));
mrb_define_module_function(mrb, cls, "mrb_rescue_exceptions", run_rescue_exceptions, MRB_ARGS_REQ(2));
}
assert 'mrb_protect' do
# no failure in protect returns [result, false]
assert_equal ['test', false] do
ExceptionTest.mrb_protect { 'test' }
end
# failure in protect returns [exception, true]
result = ExceptionTest.mrb_protect { raise 'test' }
assert_kind_of RuntimeError, result[0]
assert_true result[1]
end
assert 'mrb_ensure' do
a = false
assert_equal 'test' do
ExceptionTest.mrb_ensure Proc.new { 'test' }, Proc.new { a = true }
end
assert_true a
a = false
assert_raise RuntimeError do
ExceptionTest.mrb_ensure Proc.new { raise 'test' }, Proc.new { a = true }
end
assert_true a
end
assert 'mrb_rescue' do
assert_equal 'test' do
ExceptionTest.mrb_rescue Proc.new { 'test' }, Proc.new {}
end
class CustomExp < Exception
end
assert_raise CustomExp do
ExceptionTest.mrb_rescue Proc.new { raise CustomExp.new 'test' }, Proc.new { 'rescue' }
end
assert_equal 'rescue' do
ExceptionTest.mrb_rescue Proc.new { raise 'test' }, Proc.new { 'rescue' }
end
end
assert 'mrb_rescue_exceptions' do
assert_equal 'test' do
ExceptionTest.mrb_rescue_exceptions Proc.new { 'test' }, Proc.new {}
end
assert_raise RangeError do
ExceptionTest.mrb_rescue_exceptions Proc.new { raise RangeError.new 'test' }, Proc.new { 'rescue' }
end
assert_equal 'rescue' do
ExceptionTest.mrb_rescue_exceptions Proc.new { raise TypeError.new 'test' }, Proc.new { 'rescue' }
end
end
......@@ -2,4 +2,6 @@ MRuby::Gem::Specification.new('mruby-eval') do |spec|
spec.license = 'MIT'
spec.author = 'mruby developers'
spec.summary = 'standard Kernel#eval method'
add_dependency 'mruby-compiler', :core => 'mruby-compiler'
end
......@@ -235,12 +235,12 @@ f_instance_eval(mrb_state *mrb, mrb_value self)
mrb_int len;
char *file = NULL;
mrb_int line = 1;
mrb_value cv;
mrb_get_args(mrb, "s|zi", &s, &len, &file, &line);
c->ci->acc = CI_ACC_SKIP;
if (c->ci->target_class->tt == MRB_TT_ICLASS) {
c->ci->target_class = c->ci->target_class->c;
}
cv = mrb_singleton_class(mrb, self);
c->ci->target_class = mrb_class_ptr(cv);
return mrb_run(mrb, create_proc_from_string(mrb, s, len, mrb_nil_value(), file, line), self);
}
else {
......
......@@ -167,7 +167,7 @@ fiber_switch(mrb_state *mrb, mrb_value self, mrb_int len, const mrb_value *a, mr
}
}
if (resume && c->status == MRB_FIBER_TRANSFERRED) {
mrb_raise(mrb, E_FIBER_ERROR, "resuming transfered fiber");
mrb_raise(mrb, E_FIBER_ERROR, "resuming transferred fiber");
}
if (c->status == MRB_FIBER_RUNNING || c->status == MRB_FIBER_RESUMING) {
mrb_raise(mrb, E_FIBER_ERROR, "double resume");
......@@ -265,8 +265,8 @@ fiber_eq(mrb_state *mrb, mrb_value self)
* call-seq:
* fiber.transfer(args, ...) -> obj
*
* Transfers control to reciever fiber of the method call.
* Unlike <code>resume</code> the reciever wouldn't be pushed to call
* Transfers control to receiver fiber of the method call.
* Unlike <code>resume</code> the receiver wouldn't be pushed to call
* stack of fibers. Instead it will switch to the call stack of
* transferring fiber.
* When resuming a fiber that was transferred to another fiber it would
......
MRuby::Gem::Specification.new('mruby-hash-ext') do |spec|
spec.license = 'MIT'
spec.author = 'mruby developers'
spec.summary = 'extensional Hash class'
spec.summary = 'Hash class extension'
spec.add_dependency 'mruby-enum-ext', :core => 'mruby-enum-ext'
spec.add_dependency 'mruby-array-ext', :core => 'mruby-array-ext'
end
......@@ -119,14 +119,14 @@ class Hash
#
# <em>produces:</em>
#
# prog.rb:2:in `fetch': key not found (KeyError)
# prog.rb:2:in 'fetch': key not found (KeyError)
# from prog.rb:2
#
def fetch(key, none=NONE, &block)
unless self.key?(key)
if block
block.call
block.call(key)
elsif none != NONE
none
else
......
......@@ -75,6 +75,7 @@ assert('Hash#fetch') do
assert_equal "feline", h.fetch("cat")
assert_equal "mickey", h.fetch("mouse", "mickey")
assert_equal "minny", h.fetch("mouse"){"minny"}
assert_equal "mouse", h.fetch("mouse"){|k| k}
begin
h.fetch("gnu")
rescue => e
......
MRuby::Gem::Specification.new('mruby-kernel-ext') do |spec|
spec.license = 'MIT'
spec.author = 'mruby developers'
spec.summary = 'extensional Kernel module'
spec.summary = 'Kernel module extension'
end
MRuby::Gem::Specification.new('mruby-numeric-ext') do |spec|
spec.license = 'MIT'
spec.author = 'mruby developers'
spec.summary = 'extensional Numeric class'
spec.summary = 'Numeric class extension'
end
MRuby::Gem::Specification.new('mruby-object-ext') do |spec|
spec.license = 'MIT'
spec.author = 'mruby developers'
spec.summary = 'extensional Object class'
spec.summary = 'Object class extension'
end
#include "mruby.h"
#include "mruby/string.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
static void
printstr(mrb_state *mrb, mrb_value obj)
{
char *s;
mrb_int len;
if (mrb_string_p(obj)) {
s = RSTRING_PTR(obj);
len = RSTRING_LEN(obj);
fwrite(s, len, 1, stdout);
char* ptr = mrb_locale_from_utf8(RSTRING_PTR(obj), RSTRING_LEN(obj));
if (ptr) {
fwrite(ptr, strlen(ptr), 1, stdout);
mrb_locale_free(ptr);
}
}
}
......
MRuby::Gem::Specification.new('mruby-proc-ext') do |spec|
spec.license = 'MIT'
spec.author = 'mruby developers'
spec.summary = 'extensional Proc class'
spec.summary = 'Proc class extension'
end
......@@ -13,9 +13,11 @@ class Proc
end
def curry(arity=self.arity)
type = :proc
abs = lambda {|a| a < 0 ? -a - 1 : a}
arity = abs[arity]
if lambda?
type = :lambda
self_arity = self.arity
if (self_arity >= 0 && arity != self_arity) ||
(self_arity < 0 && abs[self_arity] > arity)
......@@ -25,7 +27,7 @@ class Proc
pproc = self
make_curry = proc do |given_args=[]|
proc do |*args|
send(type) do |*args|
new_args = given_args + args
if new_args.size >= arity
pproc[*new_args]
......
......@@ -41,6 +41,9 @@ assert('Proc#curry') do
assert_raise(ArgumentError) { b.curry[1, 2][3, 4] }
assert_raise(ArgumentError) { b.curry(5) }
assert_raise(ArgumentError) { b.curry(1) }
assert_false(proc{}.curry.lambda?)
assert_true(lambda{}.curry.lambda?)
end
assert('Proc#parameters') do
......
MRuby::Gem::Specification.new('mruby-range-ext') do |spec|
spec.license = 'MIT'
spec.author = 'mruby developers'
spec.summary = 'extensional Range class'
spec.summary = 'Range class extension'
end
This diff is collapsed.
MRuby::Gem::Specification.new('mruby-string-ext') do |spec|
spec.license = 'MIT'
spec.author = 'mruby developers'
spec.summary = 'extensional String class'
spec.summary = 'String class extension'
end
......@@ -164,9 +164,9 @@ class String
# string #=> "thsa sting"
#
def slice!(arg1, arg2=nil)
raise "wrong number of arguments (for 1..2)" if arg1 == nil && arg2 == nil
raise "wrong number of arguments (for 1..2)" if arg1.nil? && arg2.nil?
if arg1 != nil && arg2 != nil
if !arg1.nil? && !arg2.nil?
idx = arg1
idx += self.size if arg1 < 0
if idx >= 0 && idx <= self.size && arg2 > 0
......@@ -196,8 +196,8 @@ class String
return nil
end
end
unless str == nil || str == ""
if arg1 != nil && arg2 !=nil
unless str.nil? || str == ""
if !arg1.nil? && !arg2.nil?
idx = arg1 >= 0 ? arg1 : self.size+arg1
str2 = self[0...idx] + self[idx+arg2..-1].to_s
else
......@@ -207,13 +207,13 @@ class String
str2 = self[0...idx] + self[idx2+1..-1].to_s
elsif arg1.kind_of?(String)
idx = self.index(arg1)
str2 = self[0...idx] + self[idx+arg1.size..-1] unless idx == nil
str2 = self[0...idx] + self[idx+arg1.size..-1] unless idx.nil?
else
idx = arg1 >= 0 ? arg1 : self.size+arg1
str2 = self[0...idx] + self[idx+1..-1].to_s
end
end
self.replace(str2) unless str2 == nil
self.replace(str2) unless str2.nil?
end
str
end
......
......@@ -3,6 +3,7 @@
#include "mruby/array.h"
#include "mruby/class.h"
#include "mruby/string.h"
#include "mruby/range.h"
static mrb_value
mrb_str_getbyte(mrb_state *mrb, mrb_value str)
......@@ -18,6 +19,59 @@ mrb_str_getbyte(mrb_state *mrb, mrb_value str)
return mrb_fixnum_value((unsigned char)RSTRING_PTR(str)[pos]);
}
static mrb_value
mrb_str_setbyte(mrb_state *mrb, mrb_value str)
{
mrb_int pos, byte;
long len = RSTRING_LEN(str);
mrb_get_args(mrb, "ii", &pos, &byte);
if (pos < -len || len <= pos)
mrb_raisef(mrb, E_INDEX_ERROR, "index %S is out of array", mrb_fixnum_value(pos));
if (pos < 0)
pos += len;
mrb_str_modify(mrb, mrb_str_ptr(str));
byte &= 0xff;
RSTRING_PTR(str)[pos] = byte;
return mrb_fixnum_value((unsigned char)byte);
}
static mrb_value
mrb_str_byteslice(mrb_state *mrb, mrb_value str)
{
mrb_value a1;
mrb_int len;
int argc;
argc = mrb_get_args(mrb, "o|i", &a1, &len);
if (argc == 2) {
return mrb_str_substr(mrb, str, mrb_fixnum(a1), len);
}
switch (mrb_type(a1)) {
case MRB_TT_RANGE:
{
mrb_int beg;
len = RSTRING_LEN(str);
if (mrb_range_beg_len(mrb, a1, &beg, &len, len)) {
return mrb_str_substr(mrb, str, beg, len);
}
return mrb_nil_value();
}
case MRB_TT_FLOAT:
a1 = mrb_fixnum_value((mrb_int)mrb_float(a1));
/* fall through */
case MRB_TT_FIXNUM:
return mrb_str_substr(mrb, str, mrb_fixnum(a1), 1);
default:
mrb_raise(mrb, E_TYPE_ERROR, "wrong type of argument");
}
/* not reached */
return mrb_nil_value();
}
/*
* call-seq:
* str.swapcase! -> str or nil
......@@ -375,6 +429,8 @@ mrb_mruby_string_ext_gem_init(mrb_state* mrb)
mrb_define_method(mrb, s, "dump", mrb_str_dump, MRB_ARGS_NONE());
mrb_define_method(mrb, s, "getbyte", mrb_str_getbyte, MRB_ARGS_REQ(1));
mrb_define_method(mrb, s, "setbyte", mrb_str_setbyte, MRB_ARGS_REQ(2));
mrb_define_method(mrb, s, "byteslice", mrb_str_byteslice, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1));
mrb_define_method(mrb, s, "swapcase!", mrb_str_swapcase_bang, MRB_ARGS_NONE());
mrb_define_method(mrb, s, "swapcase", mrb_str_swapcase, MRB_ARGS_NONE());
mrb_define_method(mrb, s, "concat", mrb_str_concat2, MRB_ARGS_REQ(1));
......
......@@ -13,6 +13,22 @@ assert('String#getbyte') do
assert_equal bytes2[0], str2.getbyte(0)
end
assert('String#setbyte') do
str1 = "hello"
h = "H".getbyte(0)
str1.setbyte(0, h)
assert_equal(h, str1.getbyte(0))
assert_equal("Hello", str1)
end
assert('String#byteslice') do
str1 = "hello"
assert_equal("e", str1.byteslice(1))
assert_equal("o", str1.byteslice(-1))
assert_equal("ell", str1.byteslice(1..3))
assert_equal("el", str1.byteslice(1...3))
end
assert('String#dump') do
("\1" * 100).dump # should not raise an exception - regress #1210
"\0".inspect == "\"\\000\"" and
......
......@@ -259,6 +259,7 @@ mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value indx)
switch (mrb_type(indx)) {
case MRB_TT_FLOAT:
indx = mrb_flo_to_fixnum(mrb, indx);
/* fall through */
case MRB_TT_FIXNUM:
idx = mrb_fixnum(indx);
......
......@@ -114,7 +114,7 @@ mrb_struct_getmember(mrb_state *mrb, mrb_value obj, mrb_sym id)
return ptr[i];
}
}
mrb_raisef(mrb, E_INDEX_ERROR, "`%S' is not a struct member", mrb_sym2str(mrb, id));
mrb_raisef(mrb, E_INDEX_ERROR, "'%S' is not a struct member", mrb_sym2str(mrb, id));
return mrb_nil_value(); /* not reached */
}
......@@ -193,7 +193,7 @@ mrb_struct_set(mrb_state *mrb, mrb_value obj, mrb_value val)
return ptr[i] = val;
}
}
mrb_raisef(mrb, E_INDEX_ERROR, "`%S' is not a struct member", mrb_sym2str(mrb, mid));
mrb_raisef(mrb, E_INDEX_ERROR, "'%S' is not a struct member", mrb_sym2str(mrb, mid));
return mrb_nil_value(); /* not reached */
}
......@@ -749,8 +749,8 @@ mrb_struct_values_at(mrb_state *mrb, mrb_value self)
* The <code>Struct</code> class is a generator of specific classes,
* each one of which is defined to hold a set of variables and their
* accessors. In these examples, we'll call the generated class
* ``<i>Customer</i>Class,'' and we'll show an example instance of that
* class as ``<i>Customer</i>Inst.''
* "<i>Customer</i>Class," and we'll show an example instance of that
* class as "<i>Customer</i>Inst."
*
* In the descriptions that follow, the parameter <i>symbol</i> refers
* to a symbol, which is either a quoted string or a
......
MRuby::Gem::Specification.new('mruby-symbol-ext') do |spec|
spec.license = 'MIT'
spec.author = 'mruby developers'
spec.summary = 'extensional Symbol class'
spec.summary = 'Symbol class extension'
end
MRuby.each_target do
gem_table = gems.generate_gem_table self
MRuby::Gem::Specification.new('mruby-test') do |spec|
spec.license = 'MIT'
spec.author = 'mruby developers'
spec.summary = 'mruby test'
gems.each do |g|
build.bins << 'mrbtest'
spec.add_dependency('mruby-compiler', :core => 'mruby-compiler')
clib = "#{build_dir}/mrbtest.c"
mlib = clib.ext(exts.object)
mrbs = Dir.glob("#{MRUBY_ROOT}/test/t/*.rb")
exec = exefile("#{build.build_dir}/bin/mrbtest")
libmruby = libfile("#{build.build_dir}/lib/libmruby")
libmruby_core = libfile("#{build.build_dir}/lib/libmruby_core")
mrbtest_lib = libfile("#{build_dir}/mrbtest")
mrbtest_objs = []
driver_obj = objfile("#{build_dir}/driver")
driver = "#{spec.dir}/driver.c"
assert_c = "#{build_dir}/assert.c"
assert_rb = "#{MRUBY_ROOT}/test/assert.rb"
assert_lib = assert_c.ext(exts.object)
mrbtest_objs << assert_lib
file assert_lib => assert_c
file assert_c => [build.mrbcfile, assert_rb] do |t|
open(t.name, 'w') do |f|
mrbc.run f, assert_rb, 'mrbtest_assert_irep'
end
end
gem_table = build.gems.generate_gem_table build
build.gems.each do |g|
test_rbobj = g.test_rbireps.ext(exts.object)
g.test_objs << test_rbobj
dep_list = gems.tsort_dependencies(g.test_dependencies, gem_table).select(&:generate_functions)
dep_list = build.gems.tsort_dependencies(g.test_dependencies, gem_table).select(&:generate_functions)
file test_rbobj => g.test_rbireps
file g.test_rbireps => [g.test_rbfiles].flatten + [File.join(g.dir, 'mrbgem.rake'), g.build.mrbcfile, __FILE__, "#{MRUBY_ROOT}/tasks/mrbgem_spec.rake"] do |t|
file g.test_rbireps => [g.test_rbfiles].flatten + [File.join(g.dir, 'mrbgem.rake'), g.build.mrbcfile, "#{MRUBY_ROOT}/tasks/mrbgem_spec.rake"] do |t|
FileUtils.mkdir_p File.dirname(t.name)
open(t.name, 'w') do |f|
g.print_gem_test_header(f)
......@@ -91,4 +124,51 @@ MRuby.each_target do
end
end
end
build.gems.each do |v|
mrbtest_objs.concat v.test_objs
end
file mrbtest_lib => mrbtest_objs do |t|
build.archiver.run t.name, t.prerequisites
end
unless build.build_mrbtest_lib_only?
file exec => [driver_obj, mlib, mrbtest_lib, libmruby_core, libmruby] do |t|
gem_flags = build.gems.map { |g| g.linker.flags }
gem_flags_before_libraries = build.gems.map { |g| g.linker.flags_before_libraries }
gem_flags_after_libraries = build.gems.map { |g| g.linker.flags_after_libraries }
gem_libraries = build.gems.map { |g| g.linker.libraries }
gem_library_paths = build.gems.map { |g| g.linker.library_paths }
build.linker.run t.name, t.prerequisites, gem_libraries, gem_library_paths, gem_flags, gem_flags_before_libraries
end
end
init = "#{spec.dir}/init_mrbtest.c"
file mlib => clib
file clib => [build.mrbcfile, init] do |t|
_pp "GEN", "*.rb", "#{clib.relative_path}"
FileUtils.mkdir_p File.dirname(clib)
open(clib, 'w') do |f|
f.puts %Q[/*]
f.puts %Q[ * This file contains a list of all]
f.puts %Q[ * test functions.]
f.puts %Q[ *]
f.puts %Q[ * IMPORTANT:]
f.puts %Q[ * This file was generated!]
f.puts %Q[ * All manual changes will get lost.]
f.puts %Q[ */]
f.puts %Q[]
f.puts IO.read(init)
mrbc.run f, mrbs, 'mrbtest_irep'
build.gems.each do |g|
f.puts %Q[void GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb_state *mrb);]
end
f.puts %Q[void mrbgemtest_init(mrb_state* mrb) {]
build.gems.each do |g|
f.puts %Q[ GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb);]
end
f.puts %Q[}]
end
end
end
......@@ -4,12 +4,17 @@
** See Copyright Notice in mruby.h
*/
#include <math.h>
#include <stdio.h>
#include <time.h>
#include "mruby.h"
#include "mruby/class.h"
#include "mruby/data.h"
#if !defined(__MINGW64__) && defined(_WIN32)
# define llround(x) round(x)
#endif
#if defined(__MINGW64__) || defined(__MINGW32__)
# include <sys/time.h>
#endif
......@@ -200,20 +205,23 @@ time_alloc(mrb_state *mrb, double sec, double usec, enum mrb_timezone timezone)
struct mrb_time *tm;
tm = (struct mrb_time *)mrb_malloc(mrb, sizeof(struct mrb_time));
tm->sec = (time_t)sec;
if (sizeof(time_t) == 4 && (sec > (double)INT32_MAX || (double)INT32_MIN > sec)) {
goto out_of_range;
}
else if ((sec > 0 && tm->sec < 0) || (sec < 0 && (double)tm->sec > sec)) {
if (sizeof(time_t) == 8 && (sec > (double)INT64_MAX || (double)INT64_MIN > sec)) {
goto out_of_range;
}
tm->sec = (time_t)sec;
if ((sec > 0 && tm->sec < 0) || (sec < 0 && (double)tm->sec > sec)) {
out_of_range:
mrb_raisef(mrb, E_ARGUMENT_ERROR, "%S out of Time range", mrb_float_value(mrb, sec));
}
tm->usec = (time_t)((sec - tm->sec) * 1.0e6 + usec);
tm->usec = (time_t)llround((sec - tm->sec) * 1.0e6 + usec);
while (tm->usec < 0) {
tm->sec--;
tm->usec += 1000000;
}
while (tm->usec > 1000000) {
while (tm->usec >= 1000000) {
tm->sec++;
tm->usec -= 1000000;
}
......
......@@ -203,3 +203,11 @@ assert('day of week methods') do
assert_false t.friday?
assert_false t.saturday?
end
assert('2000 times 500us make a second') do
t = Time.utc 2015
2000.times do
t += 0.0005
end
t.usec == 0
end
MRuby::Gem::Specification.new('mruby-toplevel-ext') do |spec|
spec.license = 'MIT'
spec.author = 'mruby developers'
spec.summary = 'extended toplevel object (main) methods'
spec.summary = 'toplevel object (main) methods extension'
end
......@@ -16,7 +16,7 @@ class Array
while idx < length and length <= self.length and length = self.length-1
elm = self[idx += 1]
unless elm
if elm == nil and length >= self.length
if elm.nil? and length >= self.length
break
end
end
......@@ -34,7 +34,7 @@ class Array
return to_enum :each_index unless block_given?
idx = 0
while(idx < length)
while idx < length
block.call(idx)
idx += 1
end
......@@ -50,9 +50,7 @@ class Array
def collect!(&block)
return to_enum :collect! unless block_given?
self.each_index{|idx|
self[idx] = block.call(self[idx])
}
self.each_index { |idx| self[idx] = block.call(self[idx]) }
self
end
......@@ -72,10 +70,10 @@ class Array
self.clear
if size > 0
self[size - 1] = nil # allocate
self[size - 1] = nil # allocate
idx = 0
while(idx < size)
while idx < size
self[idx] = (block)? block.call(idx): obj
idx += 1
end
......@@ -146,7 +144,7 @@ class Array
# equal, then that inequality is the return value. If all the
# values found are equal, then the return is based on a
# comparison of the array lengths. Thus, two arrays are
# ``equal'' according to <code>Array#<=></code> if and only if they have
# "equal" according to <code>Array#<=></code> if and only if they have
# the same length and the value of each element is equal to the
# value of the corresponding element in the other array.
#
......@@ -158,14 +156,11 @@ class Array
len = self.size
n = other.size
if len > n
len = n
end
len = n if len > n
i = 0
while i < len
n = (self[i] <=> other[i])
return n if n == nil
return n if n != 0
return n if n.nil? || n != 0
i += 1
end
len = self.size - other.size
......@@ -185,20 +180,14 @@ class Array
self.delete_at(i)
ret = key
end
if ret == nil && block
block.call
else
ret
end
return block.call if ret.nil? && block
ret
end
# internal method to convert multi-value to single value
def __svalue
if self.size < 2
self.first
else
self
end
return self.first if self.size < 2
self
end
end
......
......@@ -24,17 +24,9 @@ module Enumerable
# ISO 15.3.2.2.1
def all?(&block)
if block
self.each{|*val|
unless block.call(*val)
return false
end
}
self.each{|*val| return false unless block.call(*val)}
else
self.each{|*val|
unless val.__svalue
return false
end
}
self.each{|*val| return false unless val.__svalue}
end
true
end
......@@ -49,17 +41,9 @@ module Enumerable
# ISO 15.3.2.2.2
def any?(&block)
if block
self.each{|*val|
if block.call(*val)
return true
end
}
self.each{|*val| return true if block.call(*val)}
else
self.each{|*val|
if val.__svalue
return true
end
}
self.each{|*val| return true if val.__svalue}
end
false
end
......@@ -75,9 +59,7 @@ module Enumerable
return to_enum :collect unless block
ary = []
self.each{|*val|
ary.push(block.call(*val))
}
self.each{|*val| ary.push(block.call(*val))}
ary
end
......@@ -183,9 +165,7 @@ module Enumerable
# ISO 15.3.2.2.10
def include?(obj)
self.each{|*val|
if val.__svalue == obj
return true
end
return true if val.__svalue == obj
}
false
end
......@@ -402,8 +382,11 @@ module Enumerable
# redefine #hash 15.3.1.3.15
def hash
h = 12347
i = 0
self.each do |e|
h ^= e.hash
n = e.hash << (i % 16)
h ^= n
i += 1
end
h
end
......
##
# Exception
#
# ISO 15.2.22
class Exception
##
# Raise an exception.
#
# ISO 15.2.22.4.1
def self.exception(*args, &block)
self.new(*args, &block)
end
end
# ISO 15.2.24
class ArgumentError < StandardError
end
......
......@@ -10,7 +10,7 @@ class Hash
# hash.
#
# ISO 15.2.13.4.1
def == (hash)
def ==(hash)
return true if self.equal?(hash)
begin
hash = hash.to_hash
......@@ -54,7 +54,7 @@ class Hash
#
# ISO 15.2.13.4.8
def delete(key, &block)
if block && ! self.has_key?(key)
if block && !self.has_key?(key)
block.call(key)
else
self.__delete(key)
......@@ -319,6 +319,29 @@ class Hash
h
end
##
# call-seq:
# hsh.rehash -> hsh
#
# Rebuilds the hash based on the current hash values for each key. If
# values of key objects have changed since they were inserted, this
# method will reindex <i>hsh</i>.
#
# h = {"AAA" => "b"}
# h.keys[0].chop!
# h #=> {"AA"=>"b"}
# h["AA"] #=> nil
# h.rehash #=> {"AA"=>"b"}
# h["AA"] #=> "b"
#
def rehash
h = {}
self.each{|k,v|
h[k] = v
}
self.replace(h)
end
def __update(h)
h.each_key{|k| self[k] = h[k]}
self
......
......@@ -27,7 +27,7 @@ module Kernel
def loop(&block)
return to_enum :loop unless block
while(true)
while true
yield
end
rescue StopIteration
......
......@@ -48,7 +48,7 @@ module Integral
return to_enum(:downto, num) unless block_given?
i = self.to_i
while(i >= num)
while i >= num
block.call(i)
i -= 1
end
......@@ -89,7 +89,7 @@ module Integral
return to_enum(:upto, num) unless block_given?
i = self.to_i
while(i <= num)
while i <= num
block.call(i)
i += 1
end
......@@ -100,18 +100,18 @@ module Integral
# Calls the given block from +self+ to +num+
# incremented by +step+ (default 1).
#
def step(num, step=1, &block)
def step(num, step = 1, &block)
raise ArgumentError, "step can't be 0" if step == 0
return to_enum(:step, num, step) unless block_given?
i = if num.kind_of? Float then self.to_f else self end
if step > 0
while(i <= num)
while i <= num
block.call(i)
i += step
end
else
while(i >= num)
while i >= num
block.call(i)
i += step
end
......@@ -165,16 +165,30 @@ class Float
# floats should be compatible to integers.
def >> other
n = self.to_i
other.to_i.times {
n /= 2
}
n
other = other.to_i
if other < 0
n << -other
else
other.times { n /= 2 }
if n.abs < 1
if n >= 0
0
else
-1
end
else
n.to_i
end
end
end
def << other
n = self.to_i
other.to_i.times {
n *= 2
}
n.to_i
other = other.to_i
if other < 0
n >> -other
else
other.times { n *= 2 }
n
end
end
end
......@@ -26,29 +26,23 @@ class Range
return self
end
unless val.respond_to? :succ
raise TypeError, "can't iterate"
end
raise TypeError, "can't iterate" unless val.respond_to? :succ
return self if (val <=> last) > 0
while((val <=> last) < 0)
while (val <=> last) < 0
block.call(val)
val = val.succ
end
if not exclude_end? and (val <=> last) == 0
block.call(val)
end
block.call(val) if !exclude_end? && (val <=> last) == 0
self
end
# redefine #hash 15.3.1.3.15
def hash
h = first.hash ^ last.hash
if self.exclude_end?
h += 1
end
h += 1 if self.exclude_end?
h
end
end
......
......@@ -12,7 +12,7 @@ class String
def each_line(&block)
# expect that str.index accepts an Integer for 1st argument as a byte data
offset = 0
while(pos = self.index(0x0a, offset))
while pos = self.index(0x0a, offset)
block.call(self[offset, pos + 1 - offset])
offset = pos + 1
end
......@@ -20,6 +20,30 @@ class String
self
end
# private method for gsub/sub
def __sub_replace(pre, m, post)
s = ""
i = 0
while j = index("\\", i)
break if j == length-1
t = case self[j+1]
when "\\"
"\\"
when "`"
pre
when "&", "0"
m
when "'"
post
else
self[j, 2]
end
s += self[i, j-i] + t
i = j + 2
end
s + self[i, length-i]
end
##
# Replace all matches of +pattern+ with +replacement+.
# Call block (if given) for each match and replace
......@@ -29,7 +53,17 @@ class String
# ISO 15.2.10.5.18
def gsub(*args, &block)
if args.size == 2
split(args[0], -1).join(args[1])
s = ""
i = 0
while j = index(args[0], i)
seplen = args[0].length
k = j + seplen
pre = self[0, j]
post = self[k, length-k]
s += self[i, j-i] + args[1].__sub_replace(pre, args[0], post)
i = k
end
s + self[i, length-i]
elsif args.size == 1 && block
split(args[0], -1).join(block.call(args[0]))
else
......@@ -46,12 +80,8 @@ class String
# ISO 15.2.10.5.19
def gsub!(*args, &block)
str = self.gsub(*args, &block)
if str != self
self.replace(str)
self
else
nil
end
return nil if str == self
self.replace(str)
end
##
......@@ -76,7 +106,9 @@ class String
# ISO 15.2.10.5.36
def sub(*args, &block)
if args.size == 2
split(args[0], 2).join(args[1])
pre, post = split(args[0], 2)
return self unless post # The sub target wasn't found in the string
pre + args[1].__sub_replace(pre, args[0], post) + post
elsif args.size == 1 && block
split(args[0], 2).join(block.call(args[0]))
else
......@@ -93,12 +125,8 @@ class String
# ISO 15.2.10.5.37
def sub!(*args, &block)
str = self.sub(*args, &block)
if str != self
self.replace(str)
self
else
nil
end
return nil if str == self
self.replace(str)
end
##
......@@ -106,7 +134,7 @@ class String
# +self+.
def each_char(&block)
pos = 0
while(pos < self.size)
while pos < self.size
block.call(self[pos])
pos += 1
end
......@@ -118,7 +146,7 @@ class String
def each_byte(&block)
bytes = self.bytes
pos = 0
while(pos < bytes.size)
while pos < bytes.size
block.call(bytes[pos])
pos += 1
end
......@@ -126,23 +154,54 @@ class String
end
##
# Modify +self+ by replacing the content of +self+
# at the position +pos+ with +value+.
def []=(pos, value)
if pos < 0
pos += self.length
# Modify +self+ by replacing the content of +self+.
# The portion of the string affected is determined using the same criteria as +String#[]+.
def []=(*args)
anum = args.size
if anum == 2
pos, value = args
if pos.kind_of? String
posnum = self.index(pos)
if posnum
b = self[0, posnum.to_i]
a = self[(posnum + pos.length)..-1]
self.replace([b, value, a].join(''))
return value
else
raise IndexError, "string not matched"
end
else
pos += self.length if pos < 0
if pos < 0 || pos > self.length
raise IndexError, "index #{args[0]} out of string"
end
b = self[0, pos.to_i]
a = self[pos + 1..-1]
self.replace([b, value, a].join(''))
return value
end
elsif anum == 3
pos, len, value = args
pos += self.length if pos < 0
if pos < 0 || pos > self.length
raise IndexError, "index #{args[0]} out of string"
end
if len < 0
raise IndexError, "negative length #{len}"
end
b = self[0, pos.to_i]
a = self[pos + len..-1]
self.replace([b, value, a].join(''))
return value
else
raise ArgumentError, "wrong number of arguments (#{anum} for 2..3)"
end
b = self[0, pos]
a = self[pos+1..-1]
self.replace([b, value, a].join(''))
end
##
# ISO 15.2.10.5.3
def =~(re)
if re.respond_to? :to_str
raise TypeError, "type mismatch: String given"
end
raise TypeError, "type mismatch: String given" if re.respond_to? :to_str
re =~ self
end
......
......@@ -19,7 +19,6 @@
static inline mrb_value
ary_elt(mrb_value ary, mrb_int offset)
{
if (RARRAY_LEN(ary) == 0) return mrb_nil_value();
if (offset < 0 || RARRAY_LEN(ary) <= offset) {
return mrb_nil_value();
}
......@@ -88,15 +87,12 @@ array_copy(mrb_value *dst, const mrb_value *src, mrb_int size)
MRB_API mrb_value
mrb_ary_new_from_values(mrb_state *mrb, mrb_int size, const mrb_value *vals)
{
mrb_value ary;
struct RArray *a;
struct RArray *a = ary_new_capa(mrb, size);
ary = mrb_ary_new_capa(mrb, size);
a = mrb_ary_ptr(ary);
array_copy(a->ptr, vals, size);
a->len = size;
return ary;
return mrb_obj_value(a);
}
MRB_API mrb_value
......@@ -293,18 +289,19 @@ mrb_ary_plus(mrb_state *mrb, mrb_value self)
{
struct RArray *a1 = mrb_ary_ptr(self);
struct RArray *a2;
mrb_value ary;
mrb_value *ptr;
mrb_int blen;
mrb_get_args(mrb, "a", &ptr, &blen);
ary = mrb_ary_new_capa(mrb, a1->len + blen);
a2 = mrb_ary_ptr(ary);
if (ARY_MAX_SIZE - blen < a1->len) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big");
}
a2 = ary_new_capa(mrb, a1->len + blen);
array_copy(a2->ptr, a1->ptr, a1->len);
array_copy(a2->ptr + a1->len, ptr, blen);
a2->len = a1->len + blen;
return ary;
return mrb_obj_value(a2);
}
static void
......@@ -342,7 +339,6 @@ mrb_ary_times(mrb_state *mrb, mrb_value self)
{
struct RArray *a1 = mrb_ary_ptr(self);
struct RArray *a2;
mrb_value ary;
mrb_value *ptr;
mrb_int times;
......@@ -351,9 +347,10 @@ mrb_ary_times(mrb_state *mrb, mrb_value self)
mrb_raise(mrb, E_ARGUMENT_ERROR, "negative argument");
}
if (times == 0) return mrb_ary_new(mrb);
ary = mrb_ary_new_capa(mrb, a1->len * times);
a2 = mrb_ary_ptr(ary);
if (ARY_MAX_SIZE / times < a1->len) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big");
}
a2 = ary_new_capa(mrb, a1->len * times);
ptr = a2->ptr;
while (times--) {
array_copy(ptr, a1->ptr, a1->len);
......@@ -361,7 +358,7 @@ mrb_ary_times(mrb_state *mrb, mrb_value self)
a2->len += a1->len;
}
return ary;
return mrb_obj_value(a2);
}
static mrb_value
......@@ -388,11 +385,8 @@ mrb_ary_reverse_bang(mrb_state *mrb, mrb_value self)
static mrb_value
mrb_ary_reverse(mrb_state *mrb, mrb_value self)
{
struct RArray *a = mrb_ary_ptr(self), *b;
mrb_value ary;
struct RArray *a = mrb_ary_ptr(self), *b = ary_new_capa(mrb, a->len);
ary = mrb_ary_new_capa(mrb, a->len);
b = mrb_ary_ptr(ary);
if (a->len > 0) {
mrb_value *p1, *p2, *e;
......@@ -404,7 +398,7 @@ mrb_ary_reverse(mrb_state *mrb, mrb_value self)
}
b->len = a->len;
}
return ary;
return mrb_obj_value(b);
}
MRB_API void
......@@ -1036,7 +1030,7 @@ mrb_ary_join_m(mrb_state *mrb, mrb_value ary)
{
mrb_value sep = mrb_nil_value();
mrb_get_args(mrb, "|S", &sep);
mrb_get_args(mrb, "|S!", &sep);
return mrb_ary_join(mrb, ary, sep);
}
......@@ -1047,7 +1041,6 @@ mrb_ary_eq(mrb_state *mrb, mrb_value ary1)
mrb_get_args(mrb, "o", &ary2);
if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_true_value();
if (mrb_immediate_p(ary2)) return mrb_false_value();
if (!mrb_array_p(ary2)) {
return mrb_false_value();
}
......@@ -1063,7 +1056,6 @@ mrb_ary_cmp(mrb_state *mrb, mrb_value ary1)
mrb_get_args(mrb, "o", &ary2);
if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_fixnum_value(0);
if (mrb_immediate_p(ary2)) return mrb_nil_value();
if (!mrb_array_p(ary2)) {
return mrb_nil_value();
}
......
This diff is collapsed.
......@@ -16,7 +16,7 @@
#define FLAG_BYTEORDER_NONATIVE 0
#ifdef MRB_USE_FLOAT
#define MRB_FLOAT_FMT "%.9e"
#define MRB_FLOAT_FMT "%.8e"
#else
#define MRB_FLOAT_FMT "%.16e"
#endif
......@@ -819,7 +819,6 @@ write_rite_binary_header(mrb_state *mrb, size_t binary_size, uint8_t *bin, uint8
uint32_t offset;
switch (flags & DUMP_ENDIAN_NAT) {
default:
endian_big:
case DUMP_ENDIAN_BIG:
memcpy(header->binary_ident, RITE_BINARY_IDENT, sizeof(header->binary_ident));
......@@ -979,12 +978,8 @@ error_exit:
mrb_free(mrb, *bin);
*bin = NULL;
}
if (lv_syms) {
mrb_free(mrb, lv_syms);
}
if (filenames) {
mrb_free(mrb, filenames);
}
mrb_free(mrb, lv_syms);
mrb_free(mrb, filenames);
return result;
}
......
......@@ -152,7 +152,7 @@ exc_inspect(mrb_state *mrb, mrb_value exc)
mrb_str_append(mrb, str, line);
mrb_str_cat_lit(mrb, str, ": ");
if (append_mesg) {
mrb_str_append(mrb, str, mesg);
mrb_str_cat_str(mrb, str, mesg);
mrb_str_cat_lit(mrb, str, " (");
}
mrb_str_cat_cstr(mrb, str, mrb_obj_classname(mrb, exc));
......@@ -165,7 +165,7 @@ exc_inspect(mrb_state *mrb, mrb_value exc)
str = mrb_str_new_cstr(mrb, cname);
mrb_str_cat_lit(mrb, str, ": ");
if (append_mesg) {
mrb_str_append(mrb, str, mesg);
mrb_str_cat_str(mrb, str, mesg);
}
else {
mrb_str_cat_cstr(mrb, str, cname);
......@@ -424,15 +424,14 @@ mrb_sys_fail(mrb_state *mrb, const char *mesg)
}
MRB_API mrb_noreturn void
mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_int argc, const mrb_value *argv, char const* fmt, ...)
mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_value args, char const* fmt, ...)
{
mrb_value exc;
va_list ap;
va_start(ap, fmt);
exc = mrb_funcall(mrb, mrb_obj_value(E_NOMETHOD_ERROR), "new", 3,
mrb_vformat(mrb, fmt, ap), mrb_symbol_value(id),
mrb_ary_new_from_values(mrb, argc, argv));
mrb_vformat(mrb, fmt, ap), mrb_symbol_value(id), args);
va_end(ap);
mrb_exc_raise(mrb, exc);
}
......
......@@ -26,7 +26,7 @@ mrb_data_object_alloc(mrb_state *mrb, struct RClass *klass, void *ptr, const mrb
MRB_API void
mrb_data_check_type(mrb_state *mrb, mrb_value obj, const mrb_data_type *type)
{
if (mrb_immediate_p(obj) || (mrb_type(obj) != MRB_TT_DATA)) {
if (mrb_type(obj) != MRB_TT_DATA) {
mrb_check_type(mrb, obj, MRB_TT_DATA);
}
if (DATA_TYPE(obj) != type) {
......@@ -48,7 +48,7 @@ mrb_data_check_type(mrb_state *mrb, mrb_value obj, const mrb_data_type *type)
MRB_API void*
mrb_data_check_get_ptr(mrb_state *mrb, mrb_value obj, const mrb_data_type *type)
{
if (mrb_immediate_p(obj) || (mrb_type(obj) != MRB_TT_DATA)) {
if (mrb_type(obj) != MRB_TT_DATA) {
return NULL;
}
if (DATA_TYPE(obj) != type) {
......@@ -67,17 +67,15 @@ mrb_data_get_ptr(mrb_state *mrb, mrb_value obj, const mrb_data_type *type)
MRB_API mrb_sym
mrb_obj_to_sym(mrb_state *mrb, mrb_value name)
{
mrb_value tmp;
mrb_sym id;
switch (mrb_type(name)) {
default:
tmp = mrb_check_string_type(mrb, name);
if (mrb_nil_p(tmp)) {
tmp = mrb_inspect(mrb, name);
mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", tmp);
name = mrb_check_string_type(mrb, name);
if (mrb_nil_p(name)) {
name = mrb_inspect(mrb, name);
mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", name);
}
name = tmp;
/* fall through */
case MRB_TT_STRING:
name = mrb_str_intern(mrb, name);
......
......@@ -90,12 +90,9 @@ fmt_u(uint32_t x, char *s)
typedef char compiler_defines_long_double_incorrectly[9-(int)sizeof(long double)];
#endif
#if defined(__CYGWIN32__) || defined(__NetBSD__) || defined(mips)
static long double
frexpl (long double x, int *eptr)
{
return frexp(x, eptr);
}
#if ((defined(__CYGWIN__) || defined(__NetBSD__) || defined(mips)) && !defined(__linux__)) || defined(__android__)
#undef frexpl
#define frexpl frexp
#endif
static int
......
......@@ -498,7 +498,12 @@ gc_mark_children(mrb_state *mrb, struct RBasic *obj)
mrb_gc_mark(mrb, (struct RBasic*)obj->c);
switch (obj->tt) {
case MRB_TT_ICLASS:
mrb_gc_mark(mrb, (struct RBasic*)((struct RClass*)obj)->super);
{
struct RClass *c = (struct RClass*)obj;
if (MRB_FLAG_TEST(c, MRB_FLAG_IS_ORIGIN))
mrb_gc_mark_mt(mrb, c);
mrb_gc_mark(mrb, (struct RBasic*)((struct RClass*)obj)->super);
}
break;
case MRB_TT_CLASS:
......@@ -624,7 +629,10 @@ obj_free(mrb_state *mrb, struct RBasic *obj)
mrb_gc_free_mt(mrb, (struct RClass*)obj);
mrb_gc_free_iv(mrb, (struct RObject*)obj);
break;
case MRB_TT_ICLASS:
if (MRB_FLAG_TEST(obj, MRB_FLAG_IS_ORIGIN))
mrb_gc_free_mt(mrb, (struct RClass*)obj);
break;
case MRB_TT_ENV:
{
struct REnv *e = (struct REnv*)obj;
......
......@@ -104,10 +104,11 @@ static void mrb_hash_modify(mrb_state *mrb, mrb_value hash);
static inline mrb_value
mrb_hash_ht_key(mrb_state *mrb, mrb_value key)
{
if (mrb_string_p(key))
return mrb_str_dup(mrb, key);
else
return key;
if (mrb_string_p(key) && !RSTR_FROZEN_P(mrb_str_ptr(key))) {
key = mrb_str_dup(mrb, key);
RSTR_SET_FROZEN_FLAG(mrb_str_ptr(key));
}
return key;
}
#define KEY(key) mrb_hash_ht_key(mrb, key)
......
......@@ -240,14 +240,12 @@ mrb_singleton_class_clone(mrb_state *mrb, mrb_value obj)
/* copy singleton(unnamed) class */
struct RClass *clone = (struct RClass*)mrb_obj_alloc(mrb, klass->tt, mrb->class_class);
if ((mrb_type(obj) == MRB_TT_CLASS) ||
(mrb_type(obj) == MRB_TT_SCLASS)) { /* BUILTIN_TYPE(obj) == T_CLASS */
if ((mrb_type(obj) == MRB_TT_CLASS) || (mrb_type(obj) == MRB_TT_SCLASS)) {
clone->c = clone;
}
else {
clone->c = mrb_singleton_class_clone(mrb, mrb_obj_value(klass));
}
clone->super = klass->super;
if (klass->iv) {
mrb_iv_copy(mrb, mrb_obj_value(clone), mrb_obj_value(klass));
......@@ -269,6 +267,21 @@ copy_class(mrb_state *mrb, mrb_value dst, mrb_value src)
{
struct RClass *dc = mrb_class_ptr(dst);
struct RClass *sc = mrb_class_ptr(src);
/* if the origin is not the same as the class, then the origin and
the current class need to be copied */
if (sc->flags & MRB_FLAG_IS_PREPENDED) {
struct RClass *c0 = sc->super;
struct RClass *c1 = dc;
/* copy prepended iclasses */
while (!(c0->flags & MRB_FLAG_IS_ORIGIN)) {
c1->super = mrb_class_ptr(mrb_obj_dup(mrb, mrb_obj_value(c0)));
c1 = c1->super;
c0 = c0->super;
}
c1->super = mrb_class_ptr(mrb_obj_dup(mrb, mrb_obj_value(c0)));
c1->super->flags |= MRB_FLAG_IS_ORIGIN;
}
dc->mt = kh_copy(mt, mrb, sc->mt);
dc->super = sc->super;
}
......@@ -330,6 +343,9 @@ mrb_obj_clone(mrb_state *mrb, mrb_value self)
if (mrb_immediate_p(self)) {
mrb_raisef(mrb, E_TYPE_ERROR, "can't clone %S", self);
}
if (mrb_type(self) == MRB_TT_SCLASS) {
mrb_raise(mrb, E_TYPE_ERROR, "can't clone singleton class");
}
p = (struct RObject*)mrb_obj_alloc(mrb, mrb_type(self), mrb_obj_class(mrb, self));
p->c = mrb_singleton_class_clone(mrb, self);
clone = mrb_obj_value(p);
......@@ -366,6 +382,9 @@ mrb_obj_dup(mrb_state *mrb, mrb_value obj)
if (mrb_immediate_p(obj)) {
mrb_raisef(mrb, E_TYPE_ERROR, "can't dup %S", obj);
}
if (mrb_type(obj) == MRB_TT_SCLASS) {
mrb_raise(mrb, E_TYPE_ERROR, "can't dup singleton class");
}
p = mrb_obj_alloc(mrb, mrb_type(obj), mrb_obj_class(mrb, obj));
dup = mrb_obj_value(p);
init_copy(mrb, dup, obj);
......@@ -635,13 +654,19 @@ mrb_class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClass* kl
{
khint_t i;
mrb_value ary;
mrb_bool prepended;
struct RClass* oldklass;
khash_t(st)* set = kh_init(st, mrb);
if (!recur && (klass->flags & MRB_FLAG_IS_PREPENDED)) {
MRB_CLASS_ORIGIN(klass);
prepended = 1;
}
oldklass = 0;
while (klass && (klass != oldklass)) {
method_entry_loop(mrb, klass, set);
if ((klass->tt == MRB_TT_ICLASS) ||
if ((klass->tt == MRB_TT_ICLASS && !prepended) ||
(klass->tt == MRB_TT_SCLASS)) {
}
else {
......
......@@ -529,7 +529,7 @@ read_binary_header(const uint8_t *bin, size_t *bin_size, uint16_t *crc, uint8_t
else if (memcmp(header->binary_ident, RITE_BINARY_IDENT_LIL, sizeof(header->binary_ident)) == 0) {
if (bigendian_p())
*flags |= FLAG_BYTEORDER_LIL;
else
else
*flags |= FLAG_BYTEORDER_NATIVE;
}
else {
......
......@@ -3,76 +3,17 @@ MRuby.each_target do
relative_from_root = File.dirname(__FILE__).relative_path_from(MRUBY_ROOT)
current_build_dir = "#{build_dir}/#{relative_from_root}"
lex_def = "#{current_dir}/lex.def"
objs = Dir.glob("#{current_dir}/*.c").map { |f|
next nil if cxx_abi_enabled? and f =~ /(codegen|error|vm).c$/
next nil if cxx_abi_enabled? and f =~ /(error|vm).c$/
objfile(f.pathmap("#{current_build_dir}/%n"))
}.compact
if cxx_abi_enabled?
cxx_abi_dependency = %w(codegen error vm)
cxx_abi_objs = cxx_abi_dependency.map { |v|
src = "#{current_build_dir}/#{v}.cxx"
file src => ["#{current_dir}/#{v}.c", __FILE__] do |t|
File.open(t.name, 'w') do |f|
f.write <<EOS
#define __STDC_CONSTANT_MACROS
#define __STDC_LIMIT_MACROS
extern "C" {
#include "#{MRUBY_ROOT}/#{t.prerequisites.first}"
}
#{v == 'error'? 'mrb_int mrb_jmpbuf::jmpbuf_id = 0;' : ''}
EOS
end
end
file objfile(src) => src do |t|
cxx.run t.name, t.prerequisites.first, [], [current_dir]
end
objfile src
}
cxx_abi_objs << objfile("#{current_build_dir}/y.tab")
file "#{current_build_dir}/y.tab.cxx" => ["#{current_build_dir}/y.tab.c", __FILE__] do |t|
File.open(t.name, 'w') do |f|
f.write <<EOS
#define __STDC_CONSTANT_MACROS
#define __STDC_LIMIT_MACROS
extern "C" {
#include "#{t.prerequisites.first}"
}
EOS
end
end
file objfile("#{current_build_dir}/y.tab") => ["#{current_build_dir}/y.tab.cxx", lex_def] do |t|
cxx.run t.name, t.prerequisites.first, [], [current_dir]
end
objs += cxx_abi_objs
else
objs += [objfile("#{current_build_dir}/y.tab")]
file objfile("#{current_build_dir}/y.tab") => ["#{current_build_dir}/y.tab.c", lex_def] do |t|
cc.run t.name, t.prerequisites.first, [], [current_dir]
end
objs += %w(vm error).map { |v| compile_as_cxx "#{current_dir}/#{v}.c", "#{current_build_dir}/#{v}.cxx" }
end
self.libmruby << objs
file libfile("#{build_dir}/lib/libmruby_core") => objs do |t|
archiver.run t.name, t.prerequisites
end
# Parser
file "#{current_build_dir}/y.tab.c" => ["#{current_dir}/parse.y"] do |t|
yacc.run t.name, t.prerequisites.first
end
# Lexical analyzer
file lex_def => "#{current_dir}/keywords" do |t|
gperf.run t.name, t.prerequisites.first
end
end
......@@ -55,7 +55,8 @@ num_pow(mrb_state *mrb, mrb_value x)
mrb_get_args(mrb, "o", &y);
yv = mrb_to_flo(mrb, y);
d = pow(mrb_to_flo(mrb, x), yv);
if (mrb_fixnum_p(x) && mrb_fixnum_p(y) && FIXABLE(d) && yv > 0)
if (mrb_fixnum_p(x) && mrb_fixnum_p(y) && FIXABLE(d) && yv > 0 &&
(d < 0 || (d > 0 && (mrb_int)d > 0)))
return mrb_fixnum_value((mrb_int)d);
return mrb_float_value(mrb, d);
}
......@@ -110,8 +111,8 @@ num_div(mrb_state *mrb, mrb_value x)
*
* Returns a string containing a representation of self. As well as a
* fixed or exponential form of the number, the call may return
* ``<code>NaN</code>'', ``<code>Infinity</code>'', and
* ``<code>-Infinity</code>''.
* "<code>NaN</code>", "<code>Infinity</code>", and
* "<code>-Infinity</code>".
*/
static mrb_value
......@@ -436,7 +437,7 @@ flo_round(mrb_state *mrb, mrb_value num)
{
double number, f;
mrb_int ndigits = 0;
int i;
mrb_int i;
mrb_get_args(mrb, "|i", &ndigits);
number = mrb_float(num);
......@@ -451,7 +452,7 @@ flo_round(mrb_state *mrb, mrb_value num)
}
f = 1.0;
i = abs(ndigits);
i = ndigits >= 0 ? ndigits : -ndigits;
while (--i >= 0)
f = f*10.0;
......@@ -819,11 +820,13 @@ fix_xor(mrb_state *mrb, mrb_value x)
static mrb_value
lshift(mrb_state *mrb, mrb_int val, mrb_int width)
{
mrb_assert(width >= 0);
mrb_assert(width > 0);
if (width > NUMERIC_SHIFT_WIDTH_MAX) {
mrb_raisef(mrb, E_RANGE_ERROR, "width(%S) > (%S:MRB_INT_BIT-1)",
mrb_fixnum_value(width),
mrb_fixnum_value(NUMERIC_SHIFT_WIDTH_MAX));
mrb_float f = (mrb_float)val;
while (width--) {
f *= 2;
}
return mrb_float_value(mrb, f);
}
return mrb_fixnum_value(val << width);
}
......@@ -831,7 +834,7 @@ lshift(mrb_state *mrb, mrb_int val, mrb_int width)
static mrb_value
rshift(mrb_int val, mrb_int width)
{
mrb_assert(width >= 0);
mrb_assert(width > 0);
if (width >= NUMERIC_SHIFT_WIDTH_MAX) {
if (val < 0) {
return mrb_fixnum_value(-1);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment