comparison src/oct-parse.yy @ 15037:56b8eb7c9c04 classdef

improvements in parsing classdef * liboctave/base-list.h (octave_base_list::octave_base_list (void), octave_base_list::octave_base_list (const std::list<elt_type>&), octave_base_list::operator = (const octave_base_list&), octave_base_list::~octave_base_list (void)): Now public. * pt-classdef.h, pt-classdef.cc: New files. * src/Makefile.am (PT_INCLUDES): Add pt-classdef.h to the list. (PT_SRC): Add pt-classdef.cc to the list. * pt-all.h: Include pt-classdef.h. * ov.cc: Include ov-classdef.h. * ov-classdef.cc: Include pt-classdef.h. (cdef_class:make_meta_class): New method. (F__meta_get_class__): Delete. (F__superclass_reference__, F__meta_class_query__): New functions. * pt-id.h: Include oct-lvalue.h. * pt-walk.h (tree_walker::visit_classdef (tree_classdef&), tree_walker::visit_classdef_attribute (tree_classdef_attribute&), tree_walker::visit_classdef_attribute_list (tree_classdef_attribute_list&), tree_walker::visit_classdef_superclass (tree_classdef_superclass&), tree_walker::visit_classdef_superclass_list (tree_classdef_superclass_list&), tree_walker::visit_classdef_property (tree_classdef_property&), tree_walker::visit_classdef_property_list (tree_classdef_property_list&), tree_walker::visit_classdef_properties_block (tree_classdef_properties_block&), tree_walker::visit_classdef_methods_list (tree_classdef_methods_list&), tree_walker::visit_classdef_methods_block (tree_classdef_methods_block&), tree_walker::visit_classdef_event (tree_classdef_event&), tree_walker::visit_classdef_events_list (tree_classdef_events_list&), tree_walker::visit_classdef_events_block (tree_classdef_events_block&), tree_walker::visit_classdef_enum (tree_classdef_enum&), tree_walker::visit_classdef_enum_list (tree_classdef_enum_list&), tree_walker::visit_classdef_enum_block (tree_classdef_enum_block&), tree_walker::visit_classdef_body (tree_classdef_body&)): New virtual functions. * token.h, token.cc (token::sc::mr, token::sc::cr, token::sc::pr, token::mc::mr, token::mc::pr): Delete. (token::sc::method_name, token::sc::package_name, token::sc::class_name, token::mc::package_name, token::mc::class_name): New member variables. (token::method_rec, token::class_rec, token::package_rec, token::meta_class_rec, token::meta_package_rec): Delete. (token::superclass_method_name, token::superclass_package_name, token::superclass_class_name, token::meta_package_name, token::meta_class_name): New methods. (token::token (symbol_table::symbol_record*, int, int), token::token (symbol_table::symbol_record*, symbol_table::symbol_record*, int, int), token::token (symbol_table::symbol_record*, symbol_table::symbol_record*, symbol_table::symbol_record*, int, int)): Delete. (token::token (const std::string&, const std::string&, int, int), token::token (const std::string&, const std::string&, const std::string&, int, int)): New constructors. (token::scls_rec_token, token::meta_rec_token): Delete enum values. (token::scls_name_token, token::meta_rec_token): New enum values. (token::~token): Delete sc and mc struct memebers. * lex.ll, lex.h (lexical_feedback::parsing_classdef_get_method, lexical_feedback::parsing_classdef_set_method)): New data members. (lexical_feedback::lexical_feedback, lexical_feedback::init): Initialize new data members. (prep_lexer_for_classdef_file): New function. (CLASSDEF_FILE_BEGIN): New exclusive start state. (handle_superclass_identifier, handle_meta_identifier): Split identifier here and create token with character strings. (display_token): Handle CLASSDEF_FILE. (display_state): Handle CLASSDEF_FILE_BEGIN. * oct-parse.yy: Include ov-classdef.h and pt-funcall.h. (classdef_object): New static variable. (make_superclass_ref, make_meta_class_query, make_classdef, make_classdef_properties_block, make_classdef_methods_block, make_classdef_events_block, make_classdef_enum_block)): New functions. (dummy_type): Delete unused nonterminal type. (tok_type, tree_funcall_type, tree_function_def_type, tree_classdef_type, tree_classdef_attribute_type, tree_classdef_attribute_list_type, tree_classdef_superclass_type, tree_classdef_superclass_list_type, tree_classdef_body_type, tree_classdef_property_type, tree_classdef_property_list_type, tree_classdef_properties_block_type, tree_classdef_methods_list_type, tree_classdef_methods_block_type, tree_classdef_event_type, tree_classdef_events_list_type, tree_classdef_events_block_type, tree_classdef_enum_type, tree_classdef_enum_list_type, tree_classdef_enum_block_type): New types for nonterminals. (CLASSDEF): Declare to have a tok_val token value. (CLASSDEF_FILE): New token. (classdef_end, properties_beg, methods_beg, events_beg, enum_beg, classdef1): Delete nonterminals. (property_list): Rename from properties_list. (attr, class_event, class_enum, class_property, property_list, properties_block, methods_list, methods_block, opt_attr_list, attr_list, events_list, events_blcok, enum_list, enum_block, class_body, classdef): Declare with specific types. Create parse tree objects for these nonterminals. (classdef_file): New nonterminal. (parse_fcn_file): Handle classdef files. Don't treat classdef files as scripts. (command): Don't handle classdef here. (input): Accept classdef_file here. (fcn_name): If GET, set lexer_flags.parsing_classdef_get_method. If SET, set lexer_flags.parsing_classdef_set_method.
author John W. Eaton <jwe@octave.org>
date Fri, 27 Jul 2012 17:10:25 -0400
parents 460a3c6d8bf1
children
comparison
equal deleted inserted replaced
15036:aa1f9e479c6e 15037:56b8eb7c9c04
60 #include "input.h" 60 #include "input.h"
61 #include "lex.h" 61 #include "lex.h"
62 #include "load-path.h" 62 #include "load-path.h"
63 #include "oct-hist.h" 63 #include "oct-hist.h"
64 #include "oct-map.h" 64 #include "oct-map.h"
65 #include "ov-classdef.h"
65 #include "ov-fcn-handle.h" 66 #include "ov-fcn-handle.h"
66 #include "ov-usr-fcn.h" 67 #include "ov-usr-fcn.h"
67 #include "ov-null-mat.h" 68 #include "ov-null-mat.h"
68 #include "toplev.h" 69 #include "toplev.h"
69 #include "pager.h" 70 #include "pager.h"
70 #include "parse.h" 71 #include "parse.h"
71 #include "parse-private.h" 72 #include "parse-private.h"
72 #include "pt-all.h" 73 #include "pt-all.h"
73 #include "pt-eval.h" 74 #include "pt-eval.h"
75 #include "pt-funcall.h"
74 #include "symtab.h" 76 #include "symtab.h"
75 #include "token.h" 77 #include "token.h"
76 #include "unwind-prot.h" 78 #include "unwind-prot.h"
77 #include "utils.h" 79 #include "utils.h"
78 #include "variables.h" 80 #include "variables.h"
150 152
151 // Scope where we install all subfunctions and nested functions. Only 153 // Scope where we install all subfunctions and nested functions. Only
152 // used while reading function files. 154 // used while reading function files.
153 static symbol_table::scope_id primary_fcn_scope; 155 static symbol_table::scope_id primary_fcn_scope;
154 156
157 // Pointer to the classdef object we just parsed, if any.
158 static tree_classdef *classdef_object = 0;
159
155 // List of autoloads (function -> file mapping). 160 // List of autoloads (function -> file mapping).
156 static std::map<std::string, std::string> autoload_map; 161 static std::map<std::string, std::string> autoload_map;
157 162
158 // Forward declarations for some functions defined at the bottom of 163 // Forward declarations for some functions defined at the bottom of
159 // the file. 164 // the file.
353 358
354 // Append a statement to an existing statement list. 359 // Append a statement to an existing statement list.
355 static tree_statement_list * 360 static tree_statement_list *
356 append_statement_list (tree_statement_list *list, char sep, 361 append_statement_list (tree_statement_list *list, char sep,
357 tree_statement *stmt, bool warn_missing_semi); 362 tree_statement *stmt, bool warn_missing_semi);
363
364 static tree_funcall *
365 make_superclass_ref (const std::string& method_nm,
366 const std::string& package_nm,
367 const std::string& class_nm,
368 int l, int c);
369
370 static tree_funcall *
371 make_meta_class_query (const std::string& package_nm,
372 const std::string& class_nm,
373 int l, int c);
374
375 static tree_classdef *
376 make_classdef (token *tok_val, tree_classdef_attribute_list *a,
377 tree_identifier *id, tree_classdef_superclass_list *sc,
378 tree_classdef_body *body, token *end_tok,
379 octave_comment_list *lc);
380
381 static tree_classdef_properties_block *
382 make_classdef_properties_block (token *tok_val,
383 tree_classdef_attribute_list *a,
384 tree_classdef_property_list *plist,
385 token *end_tok, octave_comment_list *lc);
386
387 static tree_classdef_methods_block *
388 make_classdef_methods_block (token *tok_val,
389 tree_classdef_attribute_list *a,
390 tree_classdef_methods_list *mlist,
391 token *end_tok, octave_comment_list *lc);
392
393 static tree_classdef_events_block *
394 make_classdef_events_block (token *tok_val,
395 tree_classdef_attribute_list *a,
396 tree_classdef_events_list *elist,
397 token *end_tok, octave_comment_list *lc);
398
399 static tree_classdef_enum_block *
400 make_classdef_enum_block (token *tok_val,
401 tree_classdef_attribute_list *a,
402 tree_classdef_enum_list *elist,
403 token *end_tok, octave_comment_list *lc);
358 404
359 // Finish building a statement. 405 // Finish building a statement.
360 template <class T> 406 template <class T>
361 static tree_statement * 407 static tree_statement *
362 make_statement (T *arg) 408 make_statement (T *arg)
398 // Comment strings that we need to deal with mid-rule. 444 // Comment strings that we need to deal with mid-rule.
399 octave_comment_list *comment_type; 445 octave_comment_list *comment_type;
400 446
401 // Types for the nonterminals we generate. 447 // Types for the nonterminals we generate.
402 char sep_type; 448 char sep_type;
449 token *tok_type;
403 tree *tree_type; 450 tree *tree_type;
404 tree_matrix *tree_matrix_type; 451 tree_matrix *tree_matrix_type;
405 tree_cell *tree_cell_type; 452 tree_cell *tree_cell_type;
406 tree_expression *tree_expression_type; 453 tree_expression *tree_expression_type;
407 tree_constant *tree_constant_type; 454 tree_constant *tree_constant_type;
408 tree_fcn_handle *tree_fcn_handle_type; 455 tree_fcn_handle *tree_fcn_handle_type;
456 tree_funcall *tree_funcall_type;
457 tree_function_def *tree_function_def_type;
409 tree_anon_fcn_handle *tree_anon_fcn_handle_type; 458 tree_anon_fcn_handle *tree_anon_fcn_handle_type;
410 tree_identifier *tree_identifier_type; 459 tree_identifier *tree_identifier_type;
411 tree_index_expression *tree_index_expression_type; 460 tree_index_expression *tree_index_expression_type;
412 tree_colon_expression *tree_colon_expression_type; 461 tree_colon_expression *tree_colon_expression_type;
413 tree_argument_list *tree_argument_list_type; 462 tree_argument_list *tree_argument_list_type;
423 tree_decl_init_list *tree_decl_init_list_type; 472 tree_decl_init_list *tree_decl_init_list_type;
424 tree_decl_command *tree_decl_command_type; 473 tree_decl_command *tree_decl_command_type;
425 tree_statement *tree_statement_type; 474 tree_statement *tree_statement_type;
426 tree_statement_list *tree_statement_list_type; 475 tree_statement_list *tree_statement_list_type;
427 octave_user_function *octave_user_function_type; 476 octave_user_function *octave_user_function_type;
428 void *dummy_type; 477
478 tree_classdef *tree_classdef_type;
479 tree_classdef_attribute* tree_classdef_attribute_type;
480 tree_classdef_attribute_list* tree_classdef_attribute_list_type;
481 tree_classdef_superclass* tree_classdef_superclass_type;
482 tree_classdef_superclass_list* tree_classdef_superclass_list_type;
483 tree_classdef_body* tree_classdef_body_type;
484 tree_classdef_property* tree_classdef_property_type;
485 tree_classdef_property_list* tree_classdef_property_list_type;
486 tree_classdef_properties_block* tree_classdef_properties_block_type;
487 tree_classdef_methods_list* tree_classdef_methods_list_type;
488 tree_classdef_methods_block* tree_classdef_methods_block_type;
489 tree_classdef_event* tree_classdef_event_type;
490 tree_classdef_events_list* tree_classdef_events_list_type;
491 tree_classdef_events_block* tree_classdef_events_block_type;
492 tree_classdef_enum* tree_classdef_enum_type;
493 tree_classdef_enum_list* tree_classdef_enum_list_type;
494 tree_classdef_enum_block* tree_classdef_enum_block_type;
429 } 495 }
430 496
431 // Tokens with line and column information. 497 // Tokens with line and column information.
432 %token <tok_val> '=' ':' '-' '+' '*' '/' 498 %token <tok_val> '=' ':' '-' '+' '*' '/'
433 %token <tok_val> ADD_EQ SUB_EQ MUL_EQ DIV_EQ LEFTDIV_EQ POW_EQ 499 %token <tok_val> ADD_EQ SUB_EQ MUL_EQ DIV_EQ LEFTDIV_EQ POW_EQ
450 %token <tok_val> BREAK CONTINUE FUNC_RET 516 %token <tok_val> BREAK CONTINUE FUNC_RET
451 %token <tok_val> UNWIND CLEANUP 517 %token <tok_val> UNWIND CLEANUP
452 %token <tok_val> TRY CATCH 518 %token <tok_val> TRY CATCH
453 %token <tok_val> GLOBAL PERSISTENT 519 %token <tok_val> GLOBAL PERSISTENT
454 %token <tok_val> FCN_HANDLE 520 %token <tok_val> FCN_HANDLE
521 %token <tok_val> CLASSDEF
455 %token <tok_val> PROPERTIES METHODS EVENTS ENUMERATION 522 %token <tok_val> PROPERTIES METHODS EVENTS ENUMERATION
456 %token <tok_val> METAQUERY 523 %token <tok_val> METAQUERY
457 %token <tok_val> SUPERCLASSREF 524 %token <tok_val> SUPERCLASSREF
458 %token <tok_val> GET SET 525 %token <tok_val> GET SET
459 526
460 // Other tokens. 527 // Other tokens.
461 %token END_OF_INPUT LEXICAL_ERROR 528 %token END_OF_INPUT LEXICAL_ERROR
462 %token FCN SCRIPT_FILE FUNCTION_FILE CLASSDEF 529 %token FCN SCRIPT_FILE CLASSDEF_FILE FUNCTION_FILE
463 // %token VARARGIN VARARGOUT 530 // %token VARARGIN VARARGOUT
464 %token CLOSE_BRACE 531 %token CLOSE_BRACE
465 532
466 // Nonterminals we construct. 533 // Nonterminals we construct.
467 %type <comment_type> stash_comment function_beg classdef_beg 534 %type <comment_type> stash_comment function_beg
468 %type <comment_type> properties_beg methods_beg events_beg enum_beg 535 %type <tok_type> classdef_beg
469 %type <sep_type> sep_no_nl opt_sep_no_nl sep opt_sep opt_comma 536 %type <sep_type> sep_no_nl opt_sep_no_nl sep opt_sep opt_comma
470 %type <tree_type> input 537 %type <tree_type> input
471 %type <tree_constant_type> string constant magic_colon 538 %type <tree_constant_type> string constant magic_colon
472 %type <tree_anon_fcn_handle_type> anon_fcn_handle 539 %type <tree_anon_fcn_handle_type> anon_fcn_handle
473 %type <tree_fcn_handle_type> fcn_handle 540 %type <tree_fcn_handle_type> fcn_handle
475 %type <tree_cell_type> cell_rows cell_rows1 542 %type <tree_cell_type> cell_rows cell_rows1
476 %type <tree_expression_type> matrix cell 543 %type <tree_expression_type> matrix cell
477 %type <tree_expression_type> primary_expr oper_expr 544 %type <tree_expression_type> primary_expr oper_expr
478 %type <tree_expression_type> simple_expr colon_expr assign_expr expression 545 %type <tree_expression_type> simple_expr colon_expr assign_expr expression
479 %type <tree_identifier_type> identifier fcn_name magic_tilde 546 %type <tree_identifier_type> identifier fcn_name magic_tilde
480 %type <tree_identifier_type> superclass_identifier meta_identifier 547 %type <tree_funcall_type> superclass_identifier meta_identifier
481 %type <octave_user_function_type> function1 function2 classdef1 548 %type <octave_user_function_type> function1 function2
482 %type <tree_index_expression_type> word_list_cmd 549 %type <tree_index_expression_type> word_list_cmd
483 %type <tree_colon_expression_type> colon_expr1 550 %type <tree_colon_expression_type> colon_expr1
484 %type <tree_argument_list_type> arg_list word_list assign_lhs 551 %type <tree_argument_list_type> arg_list word_list assign_lhs
485 %type <tree_argument_list_type> cell_or_matrix_row 552 %type <tree_argument_list_type> cell_or_matrix_row
486 %type <tree_parameter_list_type> param_list param_list1 param_list2 553 %type <tree_parameter_list_type> param_list param_list1 param_list2
487 %type <tree_parameter_list_type> return_list return_list1 554 %type <tree_parameter_list_type> return_list return_list1
488 %type <tree_parameter_list_type> superclasses opt_superclasses
489 %type <tree_command_type> command select_command loop_command 555 %type <tree_command_type> command select_command loop_command
490 %type <tree_command_type> jump_command except_command function 556 %type <tree_command_type> jump_command except_command
491 %type <tree_command_type> script_file classdef 557 %type <tree_function_def_type> function
558 %type <tree_classdef_type> classdef
559 %type <tree_command_type> script_file classdef_file
492 %type <tree_command_type> function_file function_list 560 %type <tree_command_type> function_file function_list
493 %type <tree_if_command_type> if_command 561 %type <tree_if_command_type> if_command
494 %type <tree_if_clause_type> elseif_clause else_clause 562 %type <tree_if_clause_type> elseif_clause else_clause
495 %type <tree_if_command_list_type> if_cmd_list1 if_cmd_list 563 %type <tree_if_command_list_type> if_cmd_list1 if_cmd_list
496 %type <tree_switch_command_type> switch_command 564 %type <tree_switch_command_type> switch_command
497 %type <tree_switch_case_type> switch_case default_case 565 %type <tree_switch_case_type> switch_case default_case
498 %type <tree_switch_case_list_type> case_list1 case_list 566 %type <tree_switch_case_list_type> case_list1 case_list
499 %type <tree_decl_elt_type> decl2 567 %type <tree_decl_elt_type> decl2
500 %type <tree_decl_init_list_type> decl1 568 %type <tree_decl_init_list_type> decl1
501 %type <tree_decl_command_type> declaration 569 %type <tree_decl_command_type> declaration
502 %type <tree_statement_type> statement function_end classdef_end 570 %type <tree_statement_type> statement function_end
503 %type <tree_statement_list_type> simple_list simple_list1 list list1 571 %type <tree_statement_list_type> simple_list simple_list1 list list1
504 %type <tree_statement_list_type> opt_list input1 572 %type <tree_statement_list_type> opt_list input1
505 // These types need to be specified. 573
506 %type <dummy_type> attr 574 %type <tree_classdef_attribute_type> attr
507 %type <dummy_type> class_event 575 %type <tree_classdef_attribute_list_type> attr_list opt_attr_list
508 %type <dummy_type> class_enum 576 %type <tree_classdef_superclass_type> superclass
509 %type <dummy_type> class_property 577 %type <tree_classdef_superclass_list_type> superclass_list opt_superclass_list
510 %type <dummy_type> properties_list 578 %type <tree_classdef_body_type> class_body
511 %type <dummy_type> properties_block 579 %type <tree_classdef_property_type> class_property
512 %type <dummy_type> methods_list 580 %type <tree_classdef_property_list_type> property_list
513 %type <dummy_type> methods_block 581 %type <tree_classdef_properties_block_type> properties_block
514 %type <dummy_type> opt_attr_list 582 %type <tree_classdef_methods_list_type> methods_list
515 %type <dummy_type> attr_list 583 %type <tree_classdef_methods_block_type> methods_block
516 %type <dummy_type> events_list 584 %type <tree_classdef_event_type> class_event
517 %type <dummy_type> events_block 585 %type <tree_classdef_events_list_type> events_list
518 %type <dummy_type> enum_list 586 %type <tree_classdef_events_block_type> events_block
519 %type <dummy_type> enum_block 587 %type <tree_classdef_enum_type> class_enum
520 %type <dummy_type> class_body 588 %type <tree_classdef_enum_list_type> enum_list
589 %type <tree_classdef_enum_block_type> enum_block
521 590
522 // Precedence and associativity. 591 // Precedence and associativity.
523 %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 592 %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
524 %left EXPR_OR_OR 593 %left EXPR_OR_OR
525 %left EXPR_AND_AND 594 %left EXPR_AND_AND
550 promptflag = 1; 619 promptflag = 1;
551 YYACCEPT; 620 YYACCEPT;
552 } 621 }
553 | function_file 622 | function_file
554 { YYACCEPT; } 623 { YYACCEPT; }
624 | classdef_file
625 { YYACCEPT; }
555 | simple_list parse_error 626 | simple_list parse_error
556 { ABORT_PARSE; } 627 { ABORT_PARSE; }
557 | parse_error 628 | parse_error
558 { ABORT_PARSE; } 629 { ABORT_PARSE; }
559 ; 630 ;
639 } 710 }
640 ; 711 ;
641 712
642 superclass_identifier 713 superclass_identifier
643 : SUPERCLASSREF 714 : SUPERCLASSREF
644 { $$ = new tree_identifier ($1->line (), $1->column ()); } 715 {
716 std::string method_nm = $1->superclass_method_name ();
717 std::string package_nm = $1->superclass_package_name ();
718 std::string class_nm = $1->superclass_class_name ();
719
720 $$ = make_superclass_ref (method_nm, package_nm, class_nm,
721 $1->line (), $1->column ());
722 }
645 ; 723 ;
646 724
647 meta_identifier : METAQUERY 725 meta_identifier : METAQUERY
648 { $$ = new tree_identifier ($1->line (), $1->column ()); } 726 {
727 std::string package_nm = $1->meta_package_name ();
728 std::string class_nm = $1->meta_class_name ();
729
730 $$ = make_meta_class_query (package_nm, class_nm,
731 $1->line (), $1->column ());
732 }
649 ; 733 ;
650 734
651 string : DQ_STRING 735 string : DQ_STRING
652 { $$ = make_constant (DQ_STRING, $1); } 736 { $$ = make_constant (DQ_STRING, $1); }
653 | SQ_STRING 737 | SQ_STRING
982 { $$ = $1; } 1066 { $$ = $1; }
983 | function 1067 | function
984 { $$ = $1; } 1068 { $$ = $1; }
985 | script_file 1069 | script_file
986 { $$ = $1; } 1070 { $$ = $1; }
987 | classdef
988 { $$ = $1; }
989 ; 1071 ;
990 1072
991 // ===================== 1073 // =====================
992 // Declaration statemnts 1074 // Declaration statemnts
993 // ===================== 1075 // =====================
1402 } 1484 }
1403 | GET '.' identifier 1485 | GET '.' identifier
1404 { 1486 {
1405 lexer_flags.parsed_function_name.top () = true; 1487 lexer_flags.parsed_function_name.top () = true;
1406 lexer_flags.maybe_classdef_get_set_method = false; 1488 lexer_flags.maybe_classdef_get_set_method = false;
1489 lexer_flags.parsing_classdef_get_method = true;
1407 $$ = $3; 1490 $$ = $3;
1408 } 1491 }
1409 | SET '.' identifier 1492 | SET '.' identifier
1410 { 1493 {
1411 lexer_flags.parsed_function_name.top () = true; 1494 lexer_flags.parsed_function_name.top () = true;
1412 lexer_flags.maybe_classdef_get_set_method = false; 1495 lexer_flags.maybe_classdef_get_set_method = false;
1496 lexer_flags.parsing_classdef_set_method = true;
1413 $$ = $3; 1497 $$ = $3;
1414 } 1498 }
1415 ; 1499 ;
1416 1500
1417 function1 : fcn_name function2 1501 function1 : fcn_name function2
1472 $$ = make_end ("endfunction", input_line_number, 1556 $$ = make_end ("endfunction", input_line_number,
1473 current_input_column); 1557 current_input_column);
1474 } 1558 }
1475 ; 1559 ;
1476 1560
1561 // =============
1562 // Classdef file
1563 // =============
1564
1565 classdef_file : CLASSDEF_FILE classdef opt_sep END_OF_INPUT
1566 {
1567 classdef_object = $2;
1568 $$ = 0;
1569 }
1570 ;
1571
1477 // ======== 1572 // ========
1478 // Classdef 1573 // Classdef
1479 // ======== 1574 // ========
1480 1575
1481 classdef_beg : CLASSDEF stash_comment 1576 classdef_beg : CLASSDEF
1482 { 1577 {
1483 $$ = 0; 1578 if (! reading_classdef_file)
1579 {
1580 yyerror ("classdef must appear inside a file containing only a class definition");
1581 YYABORT;
1582 }
1583
1484 lexer_flags.parsing_classdef = true; 1584 lexer_flags.parsing_classdef = true;
1485 } 1585 $$ = $1;
1486 ; 1586 }
1487 1587 ;
1488 classdef_end : END 1588
1589 classdef : classdef_beg stash_comment opt_attr_list identifier opt_superclass_list opt_sep class_body opt_sep END
1489 { 1590 {
1490 lexer_flags.parsing_classdef = false; 1591 lexer_flags.parsing_classdef = false;
1491 1592 $$ = make_classdef ($1, $3, $4, $5, $7, $9, $2);
1492 if (end_token_ok ($1, token::classdef_end)) 1593 }
1493 $$ = make_end ("endclassdef", $1->line (), $1->column ());
1494 else
1495 ABORT_PARSE;
1496 }
1497 ;
1498
1499 classdef1 : classdef_beg opt_attr_list identifier opt_superclasses
1500 { $$ = 0; }
1501 ;
1502
1503 classdef : classdef1 opt_sep class_body opt_sep stash_comment classdef_end
1504 { $$ = 0; }
1505 ; 1594 ;
1506 1595
1507 opt_attr_list : // empty 1596 opt_attr_list : // empty
1508 { $$ = 0; } 1597 { $$ = 0; }
1509 | '(' attr_list ')' 1598 | '(' attr_list ')'
1510 { $$ = 0; } 1599 { $$ = $2; }
1511 ; 1600 ;
1512 1601
1513 attr_list : attr 1602 attr_list : attr
1514 { $$ = 0; } 1603 { $$ = new tree_classdef_attribute_list ($1); }
1515 | attr_list ',' attr 1604 | attr_list ',' attr
1516 { $$ = 0; } 1605 {
1606 $1->append ($3);
1607 $$ = $1;
1608 }
1517 ; 1609 ;
1518 1610
1519 attr : identifier 1611 attr : identifier
1520 { $$ = 0; } 1612 { $$ = new tree_classdef_attribute ($1); }
1521 | identifier '=' decl_param_init expression 1613 | identifier '=' decl_param_init expression
1522 { $$ = 0; } 1614 {
1615 lexer_flags.looking_at_initializer_expression = false;
1616 $$ = new tree_classdef_attribute ($1, $4);
1617 }
1523 | EXPR_NOT identifier 1618 | EXPR_NOT identifier
1524 { $$ = 0; } 1619 { $$ = new tree_classdef_attribute ($2, false); }
1525 ; 1620 ;
1526 1621
1527 opt_superclasses 1622 opt_superclass_list
1528 : // empty 1623 : // empty
1529 { $$ = 0; } 1624 { $$ = 0; }
1530 | superclasses 1625 | superclass_list
1531 { $$ = 0; } 1626 { $$ = $1; }
1532 ; 1627 ;
1533 1628
1534 superclasses : EXPR_LT identifier '.' identifier 1629 superclass_list : EXPR_LT superclass
1535 { $$ = 0; } 1630 { $$ = new tree_classdef_superclass_list ($2); }
1536 | EXPR_LT identifier 1631 | superclass_list EXPR_AND superclass
1537 { $$ = 0; } 1632 {
1538 | superclasses EXPR_AND identifier '.' identifier 1633 $1->append ($3);
1539 { $$ = 0; } 1634 $$ = $1;
1540 | superclasses EXPR_AND identifier 1635 }
1541 { $$ = 0; } 1636 ;
1637
1638 superclass : identifier
1639 { $$ = new tree_classdef_superclass ($1); }
1640 | identifier '.' identifier
1641 { $$ = new tree_classdef_superclass ($3, $1); }
1542 ; 1642 ;
1543 1643
1544 class_body : properties_block 1644 class_body : properties_block
1545 { $$ = 0; } 1645 { $$ = new tree_classdef_body ($1); }
1546 | methods_block 1646 | methods_block
1547 { $$ = 0; } 1647 { $$ = new tree_classdef_body ($1); }
1548 | events_block 1648 | events_block
1549 { $$ = 0; } 1649 { $$ = new tree_classdef_body ($1); }
1550 | enum_block 1650 | enum_block
1551 { $$ = 0; } 1651 { $$ = new tree_classdef_body ($1); }
1552 | class_body opt_sep properties_block 1652 | class_body opt_sep properties_block
1553 { $$ = 0; } 1653 {
1654 $1->append ($3);
1655 $$ = $1;
1656 }
1554 | class_body opt_sep methods_block 1657 | class_body opt_sep methods_block
1555 { $$ = 0; } 1658 {
1659 $1->append ($3);
1660 $$ = $1;
1661 }
1556 | class_body opt_sep events_block 1662 | class_body opt_sep events_block
1557 { $$ = 0; } 1663 {
1664 $1->append ($3);
1665 $$ = $1;
1666 }
1558 | class_body opt_sep enum_block 1667 | class_body opt_sep enum_block
1559 { $$ = 0; } 1668 {
1560 ; 1669 $1->append ($3);
1561 1670 $$ = $1;
1562 properties_beg : PROPERTIES stash_comment 1671 }
1563 { $$ = 0; }
1564 ; 1672 ;
1565 1673
1566 properties_block 1674 properties_block
1567 : properties_beg opt_attr_list opt_sep properties_list opt_sep END 1675 : PROPERTIES stash_comment opt_attr_list opt_sep property_list opt_sep END
1568 { $$ = 0; } 1676 {
1569 ; 1677 if (! ($$ = make_classdef_properties_block ($1, $3, $5, $7, $2)))
1570 1678 ABORT_PARSE;
1571 properties_list 1679 }
1680 ;
1681
1682 property_list
1572 : class_property 1683 : class_property
1573 { $$ = 0; } 1684 { $$ = new tree_classdef_property_list ($1); }
1574 | properties_list opt_sep class_property 1685 | property_list opt_sep class_property
1575 { $$ = 0; } 1686 {
1687 $1->append ($3);
1688 $$ = $1;
1689 }
1576 ; 1690 ;
1577 1691
1578 class_property : identifier 1692 class_property : identifier
1579 { $$ = 0; } 1693 { $$ = new tree_classdef_property ($1); }
1580 | identifier '=' decl_param_init expression ';' 1694 | identifier '=' decl_param_init expression ';'
1581 { $$ = 0; } 1695 {
1582 ; 1696 lexer_flags.looking_at_initializer_expression = false;
1583 1697 $$ = new tree_classdef_property ($1, $4);
1584 methods_beg : METHODS stash_comment 1698 }
1585 { $$ = 0; } 1699 ;
1586 ; 1700
1587 1701 methods_block : METHODS stash_comment opt_attr_list opt_sep methods_list opt_sep END
1588 methods_block : methods_beg opt_attr_list opt_sep methods_list opt_sep END 1702 {
1589 { $$ = 0; } 1703 if (! ($$ = make_classdef_methods_block ($1, $3, $5, $7, $2)))
1704 ABORT_PARSE;
1705 }
1590 ; 1706 ;
1591 1707
1592 methods_list : function 1708 methods_list : function
1593 { $$ = 0; } 1709 {
1710 octave_value fcn;
1711 if ($1)
1712 fcn = $1->function ();
1713 delete $1;
1714 $$ = new tree_classdef_methods_list (fcn);
1715 }
1594 | methods_list opt_sep function 1716 | methods_list opt_sep function
1595 { $$ = 0; } 1717 {
1596 ; 1718 octave_value fcn;
1597 1719 if ($3)
1598 events_beg : EVENTS stash_comment 1720 fcn = $3->function ();
1599 { $$ = 0; } 1721 delete $3;
1600 ; 1722
1601 1723 $1->append (fcn);
1602 events_block : events_beg opt_attr_list opt_sep events_list opt_sep END 1724 $$ = $1;
1603 { $$ = 0; } 1725 }
1726 ;
1727
1728 events_block : EVENTS stash_comment opt_attr_list opt_sep events_list opt_sep END
1729 {
1730 if (! ($$ = make_classdef_events_block ($1, $3, $5, $7, $2)))
1731 ABORT_PARSE;
1732 }
1604 ; 1733 ;
1605 1734
1606 events_list : class_event 1735 events_list : class_event
1607 { $$ = 0; } 1736 { $$ = new tree_classdef_events_list ($1); }
1608 | events_list opt_sep class_event 1737 | events_list opt_sep class_event
1609 { $$ = 0; } 1738 {
1739 $1->append ($3);
1740 $$ = $1;
1741 }
1610 ; 1742 ;
1611 1743
1612 class_event : identifier 1744 class_event : identifier
1613 { $$ = 0; } 1745 { $$ = new tree_classdef_event ($1); }
1614 ; 1746 ;
1615 1747
1616 enum_beg : ENUMERATION stash_comment 1748 enum_block : ENUMERATION stash_comment opt_attr_list opt_sep enum_list opt_sep END
1617 { $$ = 0; } 1749 {
1618 ; 1750 if (! ($$ = make_classdef_enum_block ($1, $3, $5, $7, $2)))
1619 1751 ABORT_PARSE;
1620 enum_block : enum_beg opt_attr_list opt_sep enum_list opt_sep END 1752 }
1621 { $$ = 0; }
1622 ; 1753 ;
1623 1754
1624 enum_list : class_enum 1755 enum_list : class_enum
1625 { $$ = 0; } 1756 { $$ = new tree_classdef_enum_list ($1); }
1626 | enum_list opt_sep class_enum 1757 | enum_list opt_sep class_enum
1627 { $$ = 0; } 1758 {
1759 $1->append ($3);
1760 $$ = $1;
1761 }
1628 ; 1762 ;
1629 1763
1630 class_enum : identifier '(' expression ')' 1764 class_enum : identifier '(' expression ')'
1631 { $$ = 0; } 1765 { $$ = new tree_classdef_enum ($1, $3); }
1632 ; 1766 ;
1633 1767
1634 // ============= 1768 // =============
1635 // Miscellaneous 1769 // Miscellaneous
1636 // ============= 1770 // =============
3266 list->append (stmt); 3400 list->append (stmt);
3267 3401
3268 return list; 3402 return list;
3269 } 3403 }
3270 3404
3405 static tree_funcall *
3406 make_superclass_ref (const std::string& method_nm,
3407 const std::string& package_nm,
3408 const std::string& class_nm,
3409 int l, int c)
3410 {
3411 octave_value_list args;
3412
3413 args(2) = class_nm;
3414 args(1) = package_nm;
3415 args(0) = method_nm;
3416
3417 octave_value fcn
3418 = symbol_table::find_built_in_function ("__superclass_reference__");
3419
3420 return new tree_funcall (fcn, args);
3421 }
3422
3423 static tree_funcall *
3424 make_meta_class_query (const std::string& package_nm,
3425 const std::string& class_nm,
3426 int l, int c)
3427 {
3428 octave_value_list args;
3429
3430 args(1) = class_nm;
3431 args(0) = package_nm;
3432
3433 octave_value fcn
3434 = symbol_table::find_built_in_function ("__meta_class_query__");
3435
3436 return new tree_funcall (fcn, args);
3437 }
3438
3439 // A CLASSDEF block defines a class that has a constructor and other
3440 // methods, but it is not an executable command. Parsing the block
3441 // makes some changes in the symbol table (inserting the constructor
3442 // and methods, and adding to the list of known objects) and creates
3443 // a parse tree containing meta information about the class.
3444
3445 static tree_classdef *
3446 make_classdef (token *tok_val, tree_classdef_attribute_list *a,
3447 tree_identifier *id, tree_classdef_superclass_list *sc,
3448 tree_classdef_body *body, token *end_tok,
3449 octave_comment_list *lc)
3450 {
3451 tree_classdef *retval = 0;
3452
3453 if (end_token_ok (end_tok, token::classdef_end))
3454 {
3455 octave_comment_list *tc = octave_comment_buffer::get_comment ();
3456
3457 int l = tok_val->line ();
3458 int c = tok_val->column ();
3459
3460 retval = new tree_classdef (a, id, sc, body, lc, tc, l, c);
3461 }
3462
3463 return retval;
3464 }
3465
3466 static tree_classdef_properties_block *
3467 make_classdef_properties_block (token *tok_val,
3468 tree_classdef_attribute_list *a,
3469 tree_classdef_property_list *plist,
3470 token *end_tok, octave_comment_list *lc)
3471 {
3472 tree_classdef_properties_block *retval = 0;
3473
3474 if (end_token_ok (end_tok, token::properties_end))
3475 {
3476 octave_comment_list *tc = octave_comment_buffer::get_comment ();
3477
3478 int l = tok_val->line ();
3479 int c = tok_val->column ();
3480
3481 retval = new tree_classdef_properties_block (a, plist, lc, tc, l, c);
3482 }
3483
3484 return retval;
3485 }
3486
3487 static tree_classdef_methods_block *
3488 make_classdef_methods_block (token *tok_val,
3489 tree_classdef_attribute_list *a,
3490 tree_classdef_methods_list *mlist,
3491 token *end_tok, octave_comment_list *lc)
3492 {
3493 tree_classdef_methods_block *retval = 0;
3494
3495 if (end_token_ok (end_tok, token::methods_end))
3496 {
3497 octave_comment_list *tc = octave_comment_buffer::get_comment ();
3498
3499 int l = tok_val->line ();
3500 int c = tok_val->column ();
3501
3502 retval = new tree_classdef_methods_block (a, mlist, lc, tc, l, c);
3503 }
3504
3505 return retval;
3506 }
3507
3508 static tree_classdef_events_block *
3509 make_classdef_events_block (token *tok_val,
3510 tree_classdef_attribute_list *a,
3511 tree_classdef_events_list *elist,
3512 token *end_tok, octave_comment_list *lc)
3513 {
3514 tree_classdef_events_block *retval = 0;
3515
3516 if (end_token_ok (end_tok, token::events_end))
3517 {
3518 octave_comment_list *tc = octave_comment_buffer::get_comment ();
3519
3520 int l = tok_val->line ();
3521 int c = tok_val->column ();
3522
3523 retval = new tree_classdef_events_block (a, elist, lc, tc, l, c);
3524 }
3525
3526 return retval;
3527 }
3528
3529 static tree_classdef_enum_block *
3530 make_classdef_enum_block (token *tok_val,
3531 tree_classdef_attribute_list *a,
3532 tree_classdef_enum_list *elist,
3533 token *end_tok, octave_comment_list *lc)
3534 {
3535 tree_classdef_enum_block *retval = 0;
3536
3537 if (end_token_ok (end_tok, token::enumeration_end))
3538 {
3539 octave_comment_list *tc = octave_comment_buffer::get_comment ();
3540
3541 int l = tok_val->line ();
3542 int c = tok_val->column ();
3543
3544 retval = new tree_classdef_enum_block (a, elist, lc, tc, l, c);
3545 }
3546
3547 return retval;
3548 }
3549
3271 static void 3550 static void
3272 safe_fclose (FILE *f) 3551 safe_fclose (FILE *f)
3273 { 3552 {
3274 // FIXME -- comments at the end of an input file are 3553 // FIXME -- comments at the end of an input file are
3275 // discarded (otherwise, they would be appended to the next 3554 // discarded (otherwise, they would be appended to the next
3544 3823
3545 Vecho_executing_commands = ECHO_OFF; 3824 Vecho_executing_commands = ECHO_OFF;
3546 3825
3547 reading_classdef_file = true; 3826 reading_classdef_file = true;
3548 reading_fcn_file = false; 3827 reading_fcn_file = false;
3549 // FIXME -- Should classdef files be handled as 3828 reading_script_file = false;
3550 // scripts or separately? Currently, without setting up
3551 // for reading script files, parsing classdef files
3552 // fails.
3553 reading_script_file = true;
3554 } 3829 }
3555 else 3830 else
3556 { 3831 {
3557 file_type = "script"; 3832 file_type = "script";
3558 3833
3571 3846
3572 switch_to_buffer (new_buf); 3847 switch_to_buffer (new_buf);
3573 3848
3574 frame.protect_var (primary_fcn_ptr); 3849 frame.protect_var (primary_fcn_ptr);
3575 primary_fcn_ptr = 0; 3850 primary_fcn_ptr = 0;
3851
3852 frame.protect_var (classdef_object);
3853 classdef_object = 0;
3576 3854
3577 reset_parser (); 3855 reset_parser ();
3578 3856
3579 // Do this with an unwind-protect cleanup function so that 3857 // Do this with an unwind-protect cleanup function so that
3580 // the forced variables will be unmarked in the event of an 3858 // the forced variables will be unmarked in the event of an
3585 if (! help_txt.empty ()) 3863 if (! help_txt.empty ())
3586 help_buf.push (help_txt); 3864 help_buf.push (help_txt);
3587 3865
3588 if (reading_script_file) 3866 if (reading_script_file)
3589 prep_lexer_for_script_file (); 3867 prep_lexer_for_script_file ();
3868 else if (reading_classdef_file)
3869 prep_lexer_for_classdef_file ();
3590 else 3870 else
3591 prep_lexer_for_function_file (); 3871 prep_lexer_for_function_file ();
3592 3872
3593 lexer_flags.parsing_class_method = ! dispatch_type.empty (); 3873 lexer_flags.parsing_class_method = ! dispatch_type.empty ();
3594 3874
3604 3884
3605 frame.add_fcn (cleanup_statement_list, &global_command); 3885 frame.add_fcn (cleanup_statement_list, &global_command);
3606 3886
3607 fcn_ptr = primary_fcn_ptr; 3887 fcn_ptr = primary_fcn_ptr;
3608 3888
3609 if (status != 0) 3889 if (status == 0)
3610 error ("parse error while reading %s file %s", 3890 {
3611 file_type.c_str (), ff.c_str ()); 3891 if (reading_classdef_file && classdef_object)
3892 {
3893 // Convert parse tree for classdef object to
3894 // meta.class info (and stash it in the symbol
3895 // table?). Return pointer to constructor?
3896
3897 octave_value meta_class = classdef_object->make_meta_class ();
3898 }
3899 }
3900 else
3901 {
3902 error ("parse error while reading %s file %s",
3903 file_type.c_str(), ff.c_str ());
3904 }
3612 } 3905 }
3613 else 3906 else
3614 { 3907 {
3615 tree_statement *end_of_script 3908 tree_statement *end_of_script
3616 = make_end ("endscript", input_line_number, current_input_column); 3909 = make_end ("endscript", input_line_number, current_input_column);