mbed I/F binding for mruby
Dependents: mruby_mbed_web mirb_mbed
mbed-mruby
How to use
Class
mrbgems/mruby-proc-ext/proc.c@0:158c61bb030f, 2015-03-25 (annotated)
- Committer:
- mzta
- Date:
- Wed Mar 25 17:36:16 2015 +0000
- Revision:
- 0:158c61bb030f
mirb_mbed initial commit;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mzta | 0:158c61bb030f | 1 | #include "mruby.h" |
mzta | 0:158c61bb030f | 2 | #include "mruby/proc.h" |
mzta | 0:158c61bb030f | 3 | #include "mruby/opcode.h" |
mzta | 0:158c61bb030f | 4 | #include "mruby/array.h" |
mzta | 0:158c61bb030f | 5 | #include "mruby/string.h" |
mzta | 0:158c61bb030f | 6 | #include "mruby/debug.h" |
mzta | 0:158c61bb030f | 7 | |
mzta | 0:158c61bb030f | 8 | static mrb_value |
mzta | 0:158c61bb030f | 9 | mrb_proc_lambda(mrb_state *mrb, mrb_value self) |
mzta | 0:158c61bb030f | 10 | { |
mzta | 0:158c61bb030f | 11 | struct RProc *p = mrb_proc_ptr(self); |
mzta | 0:158c61bb030f | 12 | return mrb_bool_value(MRB_PROC_STRICT_P(p)); |
mzta | 0:158c61bb030f | 13 | } |
mzta | 0:158c61bb030f | 14 | |
mzta | 0:158c61bb030f | 15 | static mrb_value |
mzta | 0:158c61bb030f | 16 | mrb_proc_source_location(mrb_state *mrb, mrb_value self) |
mzta | 0:158c61bb030f | 17 | { |
mzta | 0:158c61bb030f | 18 | struct RProc *p = mrb_proc_ptr(self); |
mzta | 0:158c61bb030f | 19 | |
mzta | 0:158c61bb030f | 20 | if (MRB_PROC_CFUNC_P(p)) { |
mzta | 0:158c61bb030f | 21 | return mrb_nil_value(); |
mzta | 0:158c61bb030f | 22 | } |
mzta | 0:158c61bb030f | 23 | else { |
mzta | 0:158c61bb030f | 24 | mrb_irep *irep = p->body.irep; |
mzta | 0:158c61bb030f | 25 | int32_t line; |
mzta | 0:158c61bb030f | 26 | const char *filename; |
mzta | 0:158c61bb030f | 27 | |
mzta | 0:158c61bb030f | 28 | filename = mrb_debug_get_filename(irep, 0); |
mzta | 0:158c61bb030f | 29 | line = mrb_debug_get_line(irep, 0); |
mzta | 0:158c61bb030f | 30 | |
mzta | 0:158c61bb030f | 31 | return (!filename && line == -1)? mrb_nil_value() |
mzta | 0:158c61bb030f | 32 | : mrb_assoc_new(mrb, mrb_str_new_cstr(mrb, filename), mrb_fixnum_value(line)); |
mzta | 0:158c61bb030f | 33 | } |
mzta | 0:158c61bb030f | 34 | } |
mzta | 0:158c61bb030f | 35 | |
mzta | 0:158c61bb030f | 36 | static mrb_value |
mzta | 0:158c61bb030f | 37 | mrb_proc_inspect(mrb_state *mrb, mrb_value self) |
mzta | 0:158c61bb030f | 38 | { |
mzta | 0:158c61bb030f | 39 | struct RProc *p = mrb_proc_ptr(self); |
mzta | 0:158c61bb030f | 40 | mrb_value str = mrb_str_new_lit(mrb, "#<Proc:"); |
mzta | 0:158c61bb030f | 41 | mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, mrb_cptr(self))); |
mzta | 0:158c61bb030f | 42 | |
mzta | 0:158c61bb030f | 43 | if (!MRB_PROC_CFUNC_P(p)) { |
mzta | 0:158c61bb030f | 44 | mrb_irep *irep = p->body.irep; |
mzta | 0:158c61bb030f | 45 | const char *filename; |
mzta | 0:158c61bb030f | 46 | int32_t line; |
mzta | 0:158c61bb030f | 47 | mrb_str_cat_lit(mrb, str, "@"); |
mzta | 0:158c61bb030f | 48 | |
mzta | 0:158c61bb030f | 49 | filename = mrb_debug_get_filename(irep, 0); |
mzta | 0:158c61bb030f | 50 | mrb_str_cat_cstr(mrb, str, filename ? filename : "-"); |
mzta | 0:158c61bb030f | 51 | mrb_str_cat_lit(mrb, str, ":"); |
mzta | 0:158c61bb030f | 52 | |
mzta | 0:158c61bb030f | 53 | line = mrb_debug_get_line(irep, 0); |
mzta | 0:158c61bb030f | 54 | if (line != -1) { |
mzta | 0:158c61bb030f | 55 | mrb_str_append(mrb, str, mrb_fixnum_value(line)); |
mzta | 0:158c61bb030f | 56 | } |
mzta | 0:158c61bb030f | 57 | else { |
mzta | 0:158c61bb030f | 58 | mrb_str_cat_lit(mrb, str, "-"); |
mzta | 0:158c61bb030f | 59 | } |
mzta | 0:158c61bb030f | 60 | } |
mzta | 0:158c61bb030f | 61 | |
mzta | 0:158c61bb030f | 62 | if (MRB_PROC_STRICT_P(p)) { |
mzta | 0:158c61bb030f | 63 | mrb_str_cat_lit(mrb, str, " (lambda)"); |
mzta | 0:158c61bb030f | 64 | } |
mzta | 0:158c61bb030f | 65 | |
mzta | 0:158c61bb030f | 66 | mrb_str_cat_lit(mrb, str, ">"); |
mzta | 0:158c61bb030f | 67 | return str; |
mzta | 0:158c61bb030f | 68 | } |
mzta | 0:158c61bb030f | 69 | |
mzta | 0:158c61bb030f | 70 | static mrb_value |
mzta | 0:158c61bb030f | 71 | mrb_kernel_proc(mrb_state *mrb, mrb_value self) |
mzta | 0:158c61bb030f | 72 | { |
mzta | 0:158c61bb030f | 73 | mrb_value blk; |
mzta | 0:158c61bb030f | 74 | |
mzta | 0:158c61bb030f | 75 | mrb_get_args(mrb, "&", &blk); |
mzta | 0:158c61bb030f | 76 | if (mrb_nil_p(blk)) { |
mzta | 0:158c61bb030f | 77 | mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block"); |
mzta | 0:158c61bb030f | 78 | } |
mzta | 0:158c61bb030f | 79 | |
mzta | 0:158c61bb030f | 80 | return blk; |
mzta | 0:158c61bb030f | 81 | } |
mzta | 0:158c61bb030f | 82 | |
mzta | 0:158c61bb030f | 83 | /* |
mzta | 0:158c61bb030f | 84 | * call-seq: |
mzta | 0:158c61bb030f | 85 | * prc.parameters -> array |
mzta | 0:158c61bb030f | 86 | * |
mzta | 0:158c61bb030f | 87 | * Returns the parameter information of this proc. |
mzta | 0:158c61bb030f | 88 | * |
mzta | 0:158c61bb030f | 89 | * prc = lambda{|x, y=42, *other|} |
mzta | 0:158c61bb030f | 90 | * prc.parameters #=> [[:req, :x], [:opt, :y], [:rest, :other]] |
mzta | 0:158c61bb030f | 91 | */ |
mzta | 0:158c61bb030f | 92 | |
mzta | 0:158c61bb030f | 93 | static mrb_value |
mzta | 0:158c61bb030f | 94 | mrb_proc_parameters(mrb_state *mrb, mrb_value self) |
mzta | 0:158c61bb030f | 95 | { |
mzta | 0:158c61bb030f | 96 | struct parameters_type { |
mzta | 0:158c61bb030f | 97 | int size; |
mzta | 0:158c61bb030f | 98 | const char *name; |
mzta | 0:158c61bb030f | 99 | } *p, parameters_list [] = { |
mzta | 0:158c61bb030f | 100 | {0, "req"}, |
mzta | 0:158c61bb030f | 101 | {0, "opt"}, |
mzta | 0:158c61bb030f | 102 | {0, "rest"}, |
mzta | 0:158c61bb030f | 103 | {0, "req"}, |
mzta | 0:158c61bb030f | 104 | {0, "block"}, |
mzta | 0:158c61bb030f | 105 | {0, NULL} |
mzta | 0:158c61bb030f | 106 | }; |
mzta | 0:158c61bb030f | 107 | const struct RProc *proc = mrb_proc_ptr(self); |
mzta | 0:158c61bb030f | 108 | const struct mrb_irep *irep = proc->body.irep; |
mzta | 0:158c61bb030f | 109 | mrb_aspec aspec; |
mzta | 0:158c61bb030f | 110 | mrb_value parameters; |
mzta | 0:158c61bb030f | 111 | int i, j; |
mzta | 0:158c61bb030f | 112 | |
mzta | 0:158c61bb030f | 113 | if (MRB_PROC_CFUNC_P(proc)) { |
mzta | 0:158c61bb030f | 114 | // TODO cfunc aspec is not implemented yet |
mzta | 0:158c61bb030f | 115 | return mrb_ary_new(mrb); |
mzta | 0:158c61bb030f | 116 | } |
mzta | 0:158c61bb030f | 117 | if (!irep->lv) { |
mzta | 0:158c61bb030f | 118 | return mrb_ary_new(mrb); |
mzta | 0:158c61bb030f | 119 | } |
mzta | 0:158c61bb030f | 120 | if (GET_OPCODE(*irep->iseq) != OP_ENTER) { |
mzta | 0:158c61bb030f | 121 | return mrb_ary_new(mrb); |
mzta | 0:158c61bb030f | 122 | } |
mzta | 0:158c61bb030f | 123 | |
mzta | 0:158c61bb030f | 124 | if (!MRB_PROC_STRICT_P(proc)) { |
mzta | 0:158c61bb030f | 125 | parameters_list[0].name = "opt"; |
mzta | 0:158c61bb030f | 126 | parameters_list[3].name = "opt"; |
mzta | 0:158c61bb030f | 127 | } |
mzta | 0:158c61bb030f | 128 | |
mzta | 0:158c61bb030f | 129 | aspec = GETARG_Ax(*irep->iseq); |
mzta | 0:158c61bb030f | 130 | parameters_list[0].size = MRB_ASPEC_REQ(aspec); |
mzta | 0:158c61bb030f | 131 | parameters_list[1].size = MRB_ASPEC_OPT(aspec); |
mzta | 0:158c61bb030f | 132 | parameters_list[2].size = MRB_ASPEC_REST(aspec); |
mzta | 0:158c61bb030f | 133 | parameters_list[3].size = MRB_ASPEC_POST(aspec); |
mzta | 0:158c61bb030f | 134 | parameters_list[4].size = MRB_ASPEC_BLOCK(aspec); |
mzta | 0:158c61bb030f | 135 | |
mzta | 0:158c61bb030f | 136 | parameters = mrb_ary_new_capa(mrb, irep->nlocals-1); |
mzta | 0:158c61bb030f | 137 | for (i = 0, p = parameters_list; p->name; p++) { |
mzta | 0:158c61bb030f | 138 | mrb_value sname = mrb_symbol_value(mrb_intern_cstr(mrb, p->name)); |
mzta | 0:158c61bb030f | 139 | for (j = 0; j < p->size; i++, j++) { |
mzta | 0:158c61bb030f | 140 | mrb_assert(i < (irep->nlocals-1)); |
mzta | 0:158c61bb030f | 141 | mrb_ary_push(mrb, parameters, mrb_assoc_new(mrb, |
mzta | 0:158c61bb030f | 142 | sname, |
mzta | 0:158c61bb030f | 143 | mrb_symbol_value(irep->lv[i].name) |
mzta | 0:158c61bb030f | 144 | )); |
mzta | 0:158c61bb030f | 145 | } |
mzta | 0:158c61bb030f | 146 | } |
mzta | 0:158c61bb030f | 147 | return parameters; |
mzta | 0:158c61bb030f | 148 | } |
mzta | 0:158c61bb030f | 149 | |
mzta | 0:158c61bb030f | 150 | void |
mzta | 0:158c61bb030f | 151 | mrb_mruby_proc_ext_gem_init(mrb_state* mrb) |
mzta | 0:158c61bb030f | 152 | { |
mzta | 0:158c61bb030f | 153 | struct RClass *p = mrb->proc_class; |
mzta | 0:158c61bb030f | 154 | mrb_define_method(mrb, p, "lambda?", mrb_proc_lambda, MRB_ARGS_NONE()); |
mzta | 0:158c61bb030f | 155 | mrb_define_method(mrb, p, "source_location", mrb_proc_source_location, MRB_ARGS_NONE()); |
mzta | 0:158c61bb030f | 156 | mrb_define_method(mrb, p, "to_s", mrb_proc_inspect, MRB_ARGS_NONE()); |
mzta | 0:158c61bb030f | 157 | mrb_define_method(mrb, p, "inspect", mrb_proc_inspect, MRB_ARGS_NONE()); |
mzta | 0:158c61bb030f | 158 | mrb_define_method(mrb, p, "parameters", mrb_proc_parameters, MRB_ARGS_NONE()); |
mzta | 0:158c61bb030f | 159 | |
mzta | 0:158c61bb030f | 160 | mrb_define_class_method(mrb, mrb->kernel_module, "proc", mrb_kernel_proc, MRB_ARGS_NONE()); |
mzta | 0:158c61bb030f | 161 | mrb_define_method(mrb, mrb->kernel_module, "proc", mrb_kernel_proc, MRB_ARGS_NONE()); |
mzta | 0:158c61bb030f | 162 | } |
mzta | 0:158c61bb030f | 163 | |
mzta | 0:158c61bb030f | 164 | void |
mzta | 0:158c61bb030f | 165 | mrb_mruby_proc_ext_gem_final(mrb_state* mrb) |
mzta | 0:158c61bb030f | 166 | { |
mzta | 0:158c61bb030f | 167 | } |
mzta | 0:158c61bb030f | 168 |