mbed I/F binding for mruby
Dependents: mruby_mbed_web mirb_mbed
proc.c
00001 #include "mruby.h" 00002 #include "mruby/proc.h" 00003 #include "mruby/opcode.h" 00004 #include "mruby/array.h" 00005 #include "mruby/string.h" 00006 #include "mruby/debug.h" 00007 00008 static mrb_value 00009 mrb_proc_lambda(mrb_state *mrb, mrb_value self) 00010 { 00011 struct RProc *p = mrb_proc_ptr(self); 00012 return mrb_bool_value(MRB_PROC_STRICT_P(p)); 00013 } 00014 00015 static mrb_value 00016 mrb_proc_source_location(mrb_state *mrb, mrb_value self) 00017 { 00018 struct RProc *p = mrb_proc_ptr(self); 00019 00020 if (MRB_PROC_CFUNC_P(p)) { 00021 return mrb_nil_value(); 00022 } 00023 else { 00024 mrb_irep *irep = p->body.irep; 00025 int32_t line; 00026 const char *filename; 00027 00028 filename = mrb_debug_get_filename(irep, 0); 00029 line = mrb_debug_get_line(irep, 0); 00030 00031 return (!filename && line == -1)? mrb_nil_value() 00032 : mrb_assoc_new(mrb, mrb_str_new_cstr(mrb, filename), mrb_fixnum_value(line)); 00033 } 00034 } 00035 00036 static mrb_value 00037 mrb_proc_inspect(mrb_state *mrb, mrb_value self) 00038 { 00039 struct RProc *p = mrb_proc_ptr(self); 00040 mrb_value str = mrb_str_new_lit(mrb, "#<Proc:"); 00041 mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, mrb_cptr(self))); 00042 00043 if (!MRB_PROC_CFUNC_P(p)) { 00044 mrb_irep *irep = p->body.irep; 00045 const char *filename; 00046 int32_t line; 00047 mrb_str_cat_lit(mrb, str, "@"); 00048 00049 filename = mrb_debug_get_filename(irep, 0); 00050 mrb_str_cat_cstr(mrb, str, filename ? filename : "-"); 00051 mrb_str_cat_lit(mrb, str, ":"); 00052 00053 line = mrb_debug_get_line(irep, 0); 00054 if (line != -1) { 00055 mrb_str_append(mrb, str, mrb_fixnum_value(line)); 00056 } 00057 else { 00058 mrb_str_cat_lit(mrb, str, "-"); 00059 } 00060 } 00061 00062 if (MRB_PROC_STRICT_P(p)) { 00063 mrb_str_cat_lit(mrb, str, " (lambda)"); 00064 } 00065 00066 mrb_str_cat_lit(mrb, str, ">"); 00067 return str; 00068 } 00069 00070 static mrb_value 00071 mrb_kernel_proc(mrb_state *mrb, mrb_value self) 00072 { 00073 mrb_value blk; 00074 00075 mrb_get_args(mrb, "&", &blk); 00076 if (mrb_nil_p(blk)) { 00077 mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block"); 00078 } 00079 00080 return blk; 00081 } 00082 00083 /* 00084 * call-seq: 00085 * prc.parameters -> array 00086 * 00087 * Returns the parameter information of this proc. 00088 * 00089 * prc = lambda{|x, y=42, *other|} 00090 * prc.parameters #=> [[:req, :x], [:opt, :y], [:rest, :other]] 00091 */ 00092 00093 static mrb_value 00094 mrb_proc_parameters(mrb_state *mrb, mrb_value self) 00095 { 00096 struct parameters_type { 00097 int size; 00098 const char *name; 00099 } *p, parameters_list [] = { 00100 {0, "req"}, 00101 {0, "opt"}, 00102 {0, "rest"}, 00103 {0, "req"}, 00104 {0, "block"}, 00105 {0, NULL} 00106 }; 00107 const struct RProc *proc = mrb_proc_ptr(self); 00108 const struct mrb_irep *irep = proc->body.irep; 00109 mrb_aspec aspec; 00110 mrb_value parameters; 00111 int i, j; 00112 00113 if (MRB_PROC_CFUNC_P(proc)) { 00114 // TODO cfunc aspec is not implemented yet 00115 return mrb_ary_new(mrb); 00116 } 00117 if (!irep->lv) { 00118 return mrb_ary_new(mrb); 00119 } 00120 if (GET_OPCODE(*irep->iseq) != OP_ENTER) { 00121 return mrb_ary_new(mrb); 00122 } 00123 00124 if (!MRB_PROC_STRICT_P(proc)) { 00125 parameters_list[0].name = "opt"; 00126 parameters_list[3].name = "opt"; 00127 } 00128 00129 aspec = GETARG_Ax(*irep->iseq); 00130 parameters_list[0].size = MRB_ASPEC_REQ(aspec); 00131 parameters_list[1].size = MRB_ASPEC_OPT(aspec); 00132 parameters_list[2].size = MRB_ASPEC_REST(aspec); 00133 parameters_list[3].size = MRB_ASPEC_POST(aspec); 00134 parameters_list[4].size = MRB_ASPEC_BLOCK(aspec); 00135 00136 parameters = mrb_ary_new_capa(mrb, irep->nlocals-1); 00137 for (i = 0, p = parameters_list; p->name; p++) { 00138 mrb_value sname = mrb_symbol_value(mrb_intern_cstr(mrb, p->name)); 00139 for (j = 0; j < p->size; i++, j++) { 00140 mrb_assert(i < (irep->nlocals-1)); 00141 mrb_ary_push(mrb, parameters, mrb_assoc_new(mrb, 00142 sname, 00143 mrb_symbol_value(irep->lv[i].name) 00144 )); 00145 } 00146 } 00147 return parameters; 00148 } 00149 00150 void 00151 mrb_mruby_proc_ext_gem_init(mrb_state* mrb) 00152 { 00153 struct RClass *p = mrb->proc_class; 00154 mrb_define_method(mrb, p, "lambda?", mrb_proc_lambda, MRB_ARGS_NONE()); 00155 mrb_define_method(mrb, p, "source_location", mrb_proc_source_location, MRB_ARGS_NONE()); 00156 mrb_define_method(mrb, p, "to_s", mrb_proc_inspect, MRB_ARGS_NONE()); 00157 mrb_define_method(mrb, p, "inspect", mrb_proc_inspect, MRB_ARGS_NONE()); 00158 mrb_define_method(mrb, p, "parameters", mrb_proc_parameters, MRB_ARGS_NONE()); 00159 00160 mrb_define_class_method(mrb, mrb->kernel_module, "proc", mrb_kernel_proc, MRB_ARGS_NONE()); 00161 mrb_define_method(mrb, mrb->kernel_module, "proc", mrb_kernel_proc, MRB_ARGS_NONE()); 00162 } 00163 00164 void 00165 mrb_mruby_proc_ext_gem_final(mrb_state* mrb) 00166 { 00167 } 00168
Generated on Tue Jul 12 2022 18:00:35 by 1.7.2