source: EcnlProtoTool/trunk/mruby-1.2.0/mrbgems/mruby-proc-ext/src/proc.c@ 270

Last change on this file since 270 was 270, checked in by coas-nagasima, 7 years ago

mruby版ECNLプロトタイピング・ツールを追加

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