Mercurial > octave-libgccjit
comparison src/pt-fcn-handle.cc @ 8906:ab87d08d9a1b
improve symbol inheritance for anonymous functions
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Tue, 03 Mar 2009 14:10:54 -0500 |
parents | 73c4516fae10 |
children | 35cd375d4bb3 |
comparison
equal
deleted
inserted
replaced
8905:24dd61b36591 | 8906:ab87d08d9a1b |
---|---|
29 #include "error.h" | 29 #include "error.h" |
30 #include "oct-obj.h" | 30 #include "oct-obj.h" |
31 #include "ov-fcn-handle.h" | 31 #include "ov-fcn-handle.h" |
32 #include "pt-fcn-handle.h" | 32 #include "pt-fcn-handle.h" |
33 #include "pager.h" | 33 #include "pager.h" |
34 #include "pt-const.h" | |
34 #include "pt-walk.h" | 35 #include "pt-walk.h" |
35 #include "variables.h" | 36 #include "variables.h" |
36 | 37 |
37 void | 38 void |
38 tree_fcn_handle::print (std::ostream& os, bool pr_as_read_syntax, | 39 tree_fcn_handle::print (std::ostream& os, bool pr_as_read_syntax, |
85 } | 86 } |
86 | 87 |
87 octave_value | 88 octave_value |
88 tree_anon_fcn_handle::rvalue1 (int) | 89 tree_anon_fcn_handle::rvalue1 (int) |
89 { | 90 { |
91 // FIXME -- should CMD_LIST be limited to a single expression? | |
92 // I think that is what Matlab does. | |
93 | |
90 tree_parameter_list *param_list = parameter_list (); | 94 tree_parameter_list *param_list = parameter_list (); |
91 tree_parameter_list *ret_list = return_list (); | 95 tree_parameter_list *ret_list = return_list (); |
92 tree_statement_list *cmd_list = body (); | 96 tree_statement_list *cmd_list = body (); |
93 symbol_table::scope_id this_scope = scope (); | 97 symbol_table::scope_id this_scope = scope (); |
94 | 98 |
125 octave_value fh (new octave_fcn_handle (ov_fcn, "@<anonymous>")); | 129 octave_value fh (new octave_fcn_handle (ov_fcn, "@<anonymous>")); |
126 | 130 |
127 return fh; | 131 return fh; |
128 } | 132 } |
129 | 133 |
134 /* | |
135 %!function r = f2 (f, x) | |
136 %! r = f (x); | |
137 %!function f = f1 (k) | |
138 %! f = @(x) f2 (@(y) y-k, x); | |
139 %!test | |
140 %! assert ((f1 (3)) (10) == 7) | |
141 %! | |
142 %!shared f, g, h | |
143 %! h = @(x) sin (x); | |
144 %! g = @(f, x) h (x); | |
145 %! f = @() g (@(x) h, pi); | |
146 %!assert (f () == sin (pi)) | |
147 */ | |
148 | |
130 octave_value_list | 149 octave_value_list |
131 tree_anon_fcn_handle::rvalue (int nargout) | 150 tree_anon_fcn_handle::rvalue (int nargout) |
132 { | 151 { |
133 octave_value_list retval; | 152 octave_value_list retval; |
134 | 153 |
138 retval = rvalue1 (nargout); | 157 retval = rvalue1 (nargout); |
139 | 158 |
140 return retval; | 159 return retval; |
141 } | 160 } |
142 | 161 |
162 #if 0 | |
143 tree_expression * | 163 tree_expression * |
144 tree_anon_fcn_handle::dup (symbol_table::scope_id parent_scope, | 164 tree_anon_fcn_handle::dup (symbol_table::scope_id parent_scope, |
145 symbol_table::context_id parent_context) | 165 symbol_table::context_id parent_context) |
146 { | 166 { |
147 tree_parameter_list *param_list = parameter_list (); | 167 tree_parameter_list *param_list = parameter_list (); |
162 | 182 |
163 new_afh->copy_base (*this); | 183 new_afh->copy_base (*this); |
164 | 184 |
165 return new_afh; | 185 return new_afh; |
166 } | 186 } |
187 #endif | |
188 | |
189 tree_expression * | |
190 tree_anon_fcn_handle::dup (symbol_table::scope_id, symbol_table::context_id) | |
191 { | |
192 // Instead of simply duplicating, transform to a tree_constant | |
193 // object that contains an octave_fcn_handle object with the symbol | |
194 // table of the referenced function primed with values from the | |
195 // current scope and context. | |
196 | |
197 tree_parameter_list *param_list = parameter_list (); | |
198 tree_parameter_list *ret_list = return_list (); | |
199 tree_statement_list *cmd_list = body (); | |
200 symbol_table::scope_id this_scope = scope (); | |
201 | |
202 symbol_table::scope_id new_scope = symbol_table::dup_scope (this_scope); | |
203 | |
204 if (new_scope > 0) | |
205 symbol_table::inherit (new_scope, symbol_table::current_scope (), | |
206 symbol_table::current_context ()); | |
207 | |
208 octave_user_function *uf | |
209 = new octave_user_function (new_scope, | |
210 param_list ? param_list->dup (new_scope, 0) : 0, | |
211 ret_list ? ret_list->dup (new_scope, 0) : 0, | |
212 cmd_list ? cmd_list->dup (new_scope, 0) : 0); | |
213 | |
214 octave_function *curr_fcn = octave_call_stack::current (); | |
215 | |
216 if (curr_fcn) | |
217 { | |
218 uf->stash_parent_fcn_name (curr_fcn->name ()); | |
219 | |
220 symbol_table::scope_id parent_scope = curr_fcn->parent_fcn_scope (); | |
221 | |
222 if (parent_scope < 0) | |
223 parent_scope = curr_fcn->scope (); | |
224 | |
225 uf->stash_parent_fcn_scope (parent_scope); | |
226 } | |
227 | |
228 uf->mark_as_inline_function (); | |
229 | |
230 octave_value ov_fcn (uf); | |
231 | |
232 octave_value fh (new octave_fcn_handle (ov_fcn, "@<anonymous>")); | |
233 | |
234 return new tree_constant (fh, line (), column ()); | |
235 } | |
167 | 236 |
168 void | 237 void |
169 tree_anon_fcn_handle::accept (tree_walker& tw) | 238 tree_anon_fcn_handle::accept (tree_walker& tw) |
170 { | 239 { |
171 tw.visit_anon_fcn_handle (*this); | 240 tw.visit_anon_fcn_handle (*this); |