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);