Add examples/mrbgems/mruby-YOUR-bigint

This commit is contained in:
dearblue
2022-10-10 14:12:53 +09:00
parent 9fe5fc441a
commit 8f0dba2985
4 changed files with 123 additions and 0 deletions
@@ -0,0 +1,39 @@
# Hints for creating your own bigint GEM
This example gem, mruby-YOUR-bigint, is available under the Creative Commons Zero License (CC0).
This file is placed for the purpose of describing hints for creating a `mruby-bigint` compatible GEM to realize multiple integers.
The file structure in this example is as follows:
```
+- mruby-YOUR-bigint/ <- Make this directory public if necessary.
| Change the name of copied directory.
|
+- TODO-HINT.md <- This file is currently viewing by you.
| Remove this from copied directory.
|
+- core/
| |
| +- bigint.c <- Body of the implementation.
|
+- mrbgem.rake <- GEM name is "mruby-bigint".
May be depended on by other GEMs.
```
Implementors of own bigints should copy below this directory to another directory and do the following:
* Rewrite `spec.author`, `spec.license`, `spec.homepage` and `spec.summary` in `<gem-dir>/mrbgem.rake` file to those of your own implementors.
* Implement the respective functions in `<gem-dir>/core/bigint.c`.
* Define and use an object structure for `MRB_TT_BIGINT` type-tag.
It is recommended to use `mrb_static_assert_object_size()` to ensure that the size of the object structure is within 6 words.
* Delete this file from the destination of the copy.
If you wish to use it as an alternative to the `mruby-bigint` provided by mruby, please leave the GEM name in `<gem-dir>/mrbgem.rake` as it is.
This is an important factor when it is depended from other GEMs with `spec.add_dependency 'mruby-bigint'`.
The name of the top directory of GEM can be changed arbitrarily.
The name of the git repository can also be changed arbitrarily.
Note that there is no need for an initialization function as there is in normal GEM.
If you need it, create a file `<gem-dir>/src/bigint.c` for example, and implement the `mrb_mruby_bigint_gem_init()` function.
@@ -0,0 +1,70 @@
/*
* If placed under the "mruby/examples/mrbgems/mruby-YOUR-bigint" directory,
* this file is available under the Creative Commons Zero License (CC0).
* Note that file is incomplete.
*
* TODO: If this file is copied and another implementation is written,
* remove this comment block from the copied file.
*/
#include <mruby.h>
#include <mruby/numeric.h>
/*
* The "mruby/internal.h" file should be placed after the other mruby header files.
*/
#include <mruby/internal.h>
/*
* The "mruby/presym.h" file is placed at the end of the mruby header file.
*/
#include <mruby/presym.h>
/*
* Define your own struct RBigint.
*
* - Object type must be MRB_TT_BIGINT.
* - If the structure is named RBigint, MRB_OBJ_ALLOC() can be used as is.
*/
struct RBigint {
/*
* Put MRB_OBJECT_HEADER before the first member of the structure.
*/
MRB_OBJECT_HEADER;
/*
* Up to 3 words can be freely configured.
*/
size_t len;
size_t capa;
uintptr_t *num;
};
/*
* Assert with mrb_static_assert_object_size() that the entire structure is within 6 words.
*/
mrb_static_assert_object_size(struct RBigint);
/*
* The lower 16 bits of the object flags (`obj->flags`) can be used freely by the GEM author.
*/
#define MY_BIGINT_NEGATIVE_FLAG 1
#define MY_BIGINT_NEGATIVE_P(obj) ((obj)->flags & MY_BIGINT_NEGATIVE_FLAG)
/*
* Implement the functions declared in `#ifdef MRUBY_USE_BIGINT ... #endif` in the "mruby/internal.h" file.
*/
mrb_value
mrb_bint_new_int(mrb_state *mrb, mrb_int x)
{
struct RBigint *obj = MRB_OBJ_ALLOC(mrb, MRB_TT_BIGINT, mrb->integer_class);
...
return mrb_obj_value(obj);
}
/*
* The implementation function continues...
*/
@@ -0,0 +1,12 @@
MRuby::Gem::Specification.new('mruby-bigint') do |spec|
spec.author = 'YOUR-NAME-HERE'
spec.license = 'YOUR-LICENSE-HERE'
spec.summary = 'Yet another multi-precision Integer extension'
spec.homepage = 'https://gem.example/for/mruby-YOUR-bigint'
spec.build.defines << 'MRB_USE_BIGINT'
#spec.build.linker.libraries << 'gmp' # when uses libgmp
spec.build.libmruby_core_objs << Dir.glob(File.join(__dir__, 'core/**/*.c')).map { |fn|
objfile(fn.relative_path_from(__dir__).pathmap("#{spec.build_dir}/%X"))
}
end
+2
View File
@@ -3,3 +3,5 @@
This extension uses fgmp, which is a public domain implementation of a subset of the GNU gmp library by Mark Henderson <markh@wimsey.bc.ca>.
But it's heavily modified to fit with mruby. You can get the original source code from <https://github.com/deischi/fgmp.git>.
You can read the original README for fgmp in [README-fgmp.md](README-fgmp.md).
If you want to create your own Multi-precision Integer GEM, see [examples/mrbgems/mruby-YOUR-bigint/TODO-HINT.md](../../examples/mrbgems/mruby-YOUR-bigint/TODO-HINT.md).