comparison libinterp/parse-tree/oct-parse.in.yy @ 18262:69990d5edcc2

Allow to parse external methods declaration in classdef files. * libinterp/parse-tree/parser.h (octave_base_parser::start_classdef_external_method, octave_base_parser::finish_classdef_external_method): New methods. * libinterp/parse-tree/oct-parse.in.yy (octave_base_parser::start_classdef_external_method, octave_base_parser::finish_classdef_external_method): Likewise. (%destructor): Add missing directives for classdef-related types. (method, method_decl, method_decl1): New nonterminal rules. (methods_list): Use "method" on terminal. * libinterp/octave-value/ov-classdef.cc (cdef_package::cdef_package_rep::meta_subsref): When searching for package methods, only issue an error when error_state is not set.
author Michael Goffioul <michael.goffioul@gmail.com>
date Sun, 12 Jan 2014 15:54:43 -0500
parents bf638abc95de
children b5be1a2aa5ab
comparison
equal deleted inserted replaced
18260:bffa6c8255a9 18262:69990d5edcc2
296 %type <tree_classdef_events_list_type> events_list 296 %type <tree_classdef_events_list_type> events_list
297 %type <tree_classdef_events_block_type> events_block 297 %type <tree_classdef_events_block_type> events_block
298 %type <tree_classdef_enum_type> class_enum 298 %type <tree_classdef_enum_type> class_enum
299 %type <tree_classdef_enum_list_type> enum_list 299 %type <tree_classdef_enum_list_type> enum_list
300 %type <tree_classdef_enum_block_type> enum_block 300 %type <tree_classdef_enum_block_type> enum_block
301 %type <tree_function_def_type> method_decl method
302 %type <octave_user_function_type> method_decl1
301 303
302 // Precedence and associativity. 304 // Precedence and associativity.
303 %right '=' ADD_EQ SUB_EQ MUL_EQ DIV_EQ LEFTDIV_EQ POW_EQ EMUL_EQ EDIV_EQ ELEFTDIV_EQ EPOW_EQ OR_EQ AND_EQ LSHIFT_EQ RSHIFT_EQ 305 %right '=' ADD_EQ SUB_EQ MUL_EQ DIV_EQ LEFTDIV_EQ POW_EQ EMUL_EQ EDIV_EQ ELEFTDIV_EQ EPOW_EQ OR_EQ AND_EQ LSHIFT_EQ RSHIFT_EQ
304 %left EXPR_OR_OR 306 %left EXPR_OR_OR
305 %left EXPR_AND_AND 307 %left EXPR_AND_AND
332 %destructor { delete $$; } <tree_matrix_type> 334 %destructor { delete $$; } <tree_matrix_type>
333 %destructor { delete $$; } <tree_cell_type> 335 %destructor { delete $$; } <tree_cell_type>
334 %destructor { delete $$; } <tree_expression_type> 336 %destructor { delete $$; } <tree_expression_type>
335 %destructor { delete $$; } <tree_constant_type> 337 %destructor { delete $$; } <tree_constant_type>
336 %destructor { delete $$; } <tree_fcn_handle_type> 338 %destructor { delete $$; } <tree_fcn_handle_type>
339 %destructor { delete $$; } <tree_funcall>
340 %destructor { delete $$; } <tree_function_def>
337 %destructor { delete $$; } <tree_anon_fcn_handle_type> 341 %destructor { delete $$; } <tree_anon_fcn_handle_type>
338 %destructor { delete $$; } <tree_identifier_type> 342 %destructor { delete $$; } <tree_identifier_type>
339 %destructor { delete $$; } <tree_index_expression_type> 343 %destructor { delete $$; } <tree_index_expression_type>
340 %destructor { delete $$; } <tree_colon_expression_type> 344 %destructor { delete $$; } <tree_colon_expression_type>
341 %destructor { delete $$; } <tree_argument_list_type> 345 %destructor { delete $$; } <tree_argument_list_type>
351 %destructor { delete $$; } <tree_decl_init_list_type> 355 %destructor { delete $$; } <tree_decl_init_list_type>
352 %destructor { delete $$; } <tree_decl_command_type> 356 %destructor { delete $$; } <tree_decl_command_type>
353 %destructor { delete $$; } <tree_statement_type> 357 %destructor { delete $$; } <tree_statement_type>
354 %destructor { delete $$; } <tree_statement_list_type> 358 %destructor { delete $$; } <tree_statement_list_type>
355 %destructor { delete $$; } <octave_user_function_type> 359 %destructor { delete $$; } <octave_user_function_type>
360
361 %destructor { delete $$; } <tree_classdef_type>
362 %destructor { delete $$; } <tree_classdef_attribute_type>
363 %destructor { delete $$; } <tree_classdef_attribute_list_type>
364 %destructor { delete $$; } <tree_classdef_superclass_type>
365 %destructor { delete $$; } <tree_classdef_superclass_list_type>
366 %destructor { delete $$; } <tree_classdef_body_type>
367 %destructor { delete $$; } <tree_classdef_property_type>
368 %destructor { delete $$; } <tree_classdef_property_list_type>
369 %destructor { delete $$; } <tree_classdef_properties_block_type>
370 %destructor { delete $$; } <tree_classdef_methods_list_type>
371 %destructor { delete $$; } <tree_classdef_methods_block_type>
372 %destructor { delete $$; } <tree_classdef_event_type>
373 %destructor { delete $$; } <tree_classdef_events_list_type>
374 %destructor { delete $$; } <tree_classdef_events_block_type>
375 %destructor { delete $$; } <tree_classdef_enum_type>
376 %destructor { delete $$; } <tree_classdef_enum_list_type>
377 %destructor { delete $$; } <tree_classdef_enum_block_type>
356 378
357 %destructor { 379 %destructor {
358 warning_with_id 380 warning_with_id
359 ("Octave:parser-destructor", 381 ("Octave:parser-destructor",
360 "possible memory leak in cleanup following parse error"); 382 "possible memory leak in cleanup following parse error");
1603 ABORT_PARSE; 1625 ABORT_PARSE;
1604 } 1626 }
1605 } 1627 }
1606 ; 1628 ;
1607 1629
1608 methods_list : function 1630 method_decl1 : identifier
1631 {
1632 if (! ($$ = parser.start_classdef_external_method ($1, 0)))
1633 ABORT_PARSE;
1634 }
1635 | identifier param_list
1636 { if (! ($$ = parser.start_classdef_external_method ($1, $2)))
1637 ABORT_PARSE;
1638 }
1639 ;
1640
1641 method_decl : stash_comment method_decl1
1642 { $$ = parser.finish_classdef_external_method ($2, 0, $1); }
1643 | stash_comment return_list '=' method_decl1
1644 { $$ = parser.finish_classdef_external_method ($4, $2, $1); }
1645 ;
1646
1647 method : method_decl
1648 { $$ = $1; }
1649 | function
1650 { $$ = $1; }
1651 ;
1652
1653 methods_list : method
1609 { 1654 {
1610 octave_value fcn; 1655 octave_value fcn;
1611 if ($1) 1656 if ($1)
1612 fcn = $1->function (); 1657 fcn = $1->function ();
1613 delete $1; 1658 delete $1;
1614 $$ = new tree_classdef_methods_list (fcn); 1659 $$ = new tree_classdef_methods_list (fcn);
1615 } 1660 }
1616 | methods_list opt_sep function 1661 | methods_list opt_sep method
1617 { 1662 {
1618 octave_value fcn; 1663 octave_value fcn;
1619 if ($3) 1664 if ($3)
1620 fcn = $3->function (); 1665 fcn = $3->function ();
1621 delete $3; 1666 delete $3;
3195 delete a; 3240 delete a;
3196 delete elist; 3241 delete elist;
3197 } 3242 }
3198 3243
3199 return retval; 3244 return retval;
3245 }
3246
3247 octave_user_function*
3248 octave_base_parser::start_classdef_external_method (tree_identifier *id,
3249 tree_parameter_list *pl)
3250 {
3251 octave_user_function* retval = 0;
3252
3253 // External methods are only allowed within @-folders. In this case,
3254 // curr_class_name will be non-empty.
3255
3256 if (! curr_class_name.empty ())
3257 {
3258
3259 std::string mname = id->name ();
3260
3261 // Methods that cannot be declared outside the classdef file:
3262 // - methods with '.' character (e.g. property accessors)
3263 // - class constructor
3264 // - `delete'
3265
3266 if (mname.find_first_of (".") == std::string::npos
3267 && mname != "delete"
3268 && mname != curr_class_name)
3269 {
3270 // Create a dummy function that is used until the real method
3271 // is loaded.
3272
3273 retval = new octave_user_function (-1, pl);
3274
3275 retval->stash_function_name (mname);
3276
3277 int l = id->line ();
3278 int c = id->column ();
3279
3280 retval->stash_fcn_location (l, c);
3281 }
3282 else
3283 bison_error ("invalid external method declaration, an external "
3284 "method cannot be the class constructor, `delete' "
3285 "or have a dot (.) character in its name");
3286 }
3287 else
3288 bison_error ("external methods are only allowed in @-folders");
3289
3290 if (! retval)
3291 delete id;
3292
3293 return retval;
3294 }
3295
3296 tree_function_def *
3297 octave_base_parser::finish_classdef_external_method (octave_user_function *fcn,
3298 tree_parameter_list *ret_list,
3299 octave_comment_list *cl)
3300 {
3301 if (ret_list)
3302 fcn->define_ret_list (ret_list);
3303
3304 if (cl)
3305 fcn->stash_leading_comment (cl);
3306
3307 int l = fcn->beginning_line ();
3308 int c = fcn->beginning_column ();
3309
3310 return new tree_function_def (fcn, l, c);
3200 } 3311 }
3201 3312
3202 // Make an index expression. 3313 // Make an index expression.
3203 3314
3204 tree_index_expression * 3315 tree_index_expression *