# HG changeset patch # User John W. Eaton # Date 1343423425 14400 # Node ID 56b8eb7c9c043f069867116f4df79c70dd31322a # Parent aa1f9e479c6e54f7b17453a633b7f2f963092910 improvements in parsing classdef * liboctave/base-list.h (octave_base_list::octave_base_list (void), octave_base_list::octave_base_list (const std::list&), 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. diff -r aa1f9e479c6e -r 56b8eb7c9c04 liboctave/base-list.h --- a/liboctave/base-list.h Fri Jul 27 16:02:01 2012 -0400 +++ b/liboctave/base-list.h Fri Jul 27 17:10:25 2012 -0400 @@ -87,8 +87,6 @@ // For backward compatibility. void append (const elt_type& s) { lst.push_back (s); } -protected: - octave_base_list (void) : lst () { } octave_base_list (const std::list& l) : lst (l) { } diff -r aa1f9e479c6e -r 56b8eb7c9c04 src/Makefile.am --- a/src/Makefile.am Fri Jul 27 16:02:01 2012 -0400 +++ b/src/Makefile.am Fri Jul 27 17:10:25 2012 -0400 @@ -211,6 +211,7 @@ pt-cbinop.h \ pt-cell.h \ pt-check.h \ + pt-classdef.h \ pt-cmd.h \ pt-colon.h \ pt-const.h \ @@ -393,6 +394,7 @@ pt-cell.cc \ pt-check.cc \ pt-cmd.cc \ + pt-classdef.cc \ pt-colon.cc \ pt-const.cc \ pt-decl.cc \ diff -r aa1f9e479c6e -r 56b8eb7c9c04 src/lex.h --- a/src/lex.h Fri Jul 27 16:02:01 2012 -0400 +++ b/src/lex.h Fri Jul 27 17:10:25 2012 -0400 @@ -52,6 +52,7 @@ extern void prep_lexer_for_script_file (void); extern void prep_lexer_for_function_file (void); +extern void prep_lexer_for_classdef_file (void); // For communication between the lexer and parser. @@ -72,7 +73,8 @@ looking_for_object_index (false), do_comma_insert (false), looking_at_indirect_ref (false), parsed_function_name (), parsing_class_method (false), maybe_classdef_get_set_method (false), - parsing_classdef (false), quote_is_transpose (false), + parsing_classdef (false), parsing_classdef_get_method (false), + parsing_classdef_set_method (false), quote_is_transpose (false), pending_local_variables () { @@ -157,6 +159,12 @@ // TRUE means we are parsing a classdef file bool parsing_classdef; + // TRUE means we are parsing a classdef get.method. + bool parsing_classdef_get_method; + + // TRUE means we are parsing a classdef set.method. + bool parsing_classdef_set_method; + // Return transpose or start a string? bool quote_is_transpose; diff -r aa1f9e479c6e -r 56b8eb7c9c04 src/lex.ll --- a/src/lex.ll Fri Jul 27 16:02:01 2012 -0400 +++ b/src/lex.ll Fri Jul 27 17:10:25 2012 -0400 @@ -34,6 +34,7 @@ %x SCRIPT_FILE_BEGIN %x FUNCTION_FILE_BEGIN +%x CLASSDEF_FILE_BEGIN %{ @@ -373,6 +374,14 @@ COUNT_TOK_AND_RETURN (FUNCTION_FILE); } +. { + LEXER_DEBUG ("."); + + BEGIN (INITIAL); + xunput (yytext[0], yytext); + COUNT_TOK_AND_RETURN (CLASSDEF_FILE); + } + %{ // Help and other command-style functions. %} @@ -756,7 +765,7 @@ { lexer_flags.looking_for_object_index = true; - COUNT_TOK_AND_RETURN (SUPERCLASSREF); + COUNT_TOK_AND_RETURN (id_tok); } } @@ -774,7 +783,7 @@ { lexer_flags.looking_for_object_index = true; - COUNT_TOK_AND_RETURN (METAQUERY); + COUNT_TOK_AND_RETURN (id_tok); } } @@ -3152,37 +3161,40 @@ static int handle_superclass_identifier (void) { - eat_continuation (); + int c = yytext[yyleng-1]; + + std::string meth = strip_trailing_whitespace (yytext); + + int cont_is_spc = eat_continuation (); + + int spc_gobbled = (cont_is_spc || c == ' ' || c == '\t'); + + size_t pos = meth.find ("@"); + std::string cls = meth.substr (pos + 1); + meth = meth.substr (0, pos); std::string pkg; - std::string meth = strip_trailing_whitespace (yytext); - size_t pos = meth.find ("@"); - std::string cls = meth.substr (pos).substr (1); - meth = meth.substr (0, pos - 1); - pos = cls.find ("."); if (pos != std::string::npos) { - pkg = cls.substr (pos).substr (1); - cls = cls.substr (0, pos - 1); + pkg = cls.substr (0, pos); + cls = cls.substr (pos + 1); } int kw_token = (is_keyword_token (meth) || is_keyword_token (cls) || is_keyword_token (pkg)); if (kw_token) { - error ("method, class and package names may not be keywords"); + error ("method, class, and package names may not be keywords"); return LEXICAL_ERROR; } - yylval.tok_val - = new token (meth.empty () ? 0 : &(symbol_table::insert (meth)), - cls.empty () ? 0 : &(symbol_table::insert (cls)), - pkg.empty () ? 0 : &(symbol_table::insert (pkg)), - input_line_number, current_input_column); + yylval.tok_val = new token (meth, pkg, cls, input_line_number, + current_input_column); token_stack.push (yylval.tok_val); - lexer_flags.convert_spaces_to_comma = true; + do_comma_insert_check (); + maybe_unput_comma (spc_gobbled); current_input_column += yyleng; return SUPERCLASSREF; @@ -3191,33 +3203,35 @@ static int handle_meta_identifier (void) { - eat_continuation (); + int c = yytext[yyleng-1]; + + std::string cls = strip_trailing_whitespace (yytext).substr (1); + + int cont_is_spc = eat_continuation (); + + int spc_gobbled = (cont_is_spc || c == ' ' || c == '\t'); std::string pkg; - std::string cls = strip_trailing_whitespace (yytext).substr (1); size_t pos = cls.find ("."); - if (pos != std::string::npos) { - pkg = cls.substr (pos).substr (1); - cls = cls.substr (0, pos - 1); + pkg = cls.substr (0, pos); + cls = cls.substr (pos + 1); } int kw_token = is_keyword_token (cls) || is_keyword_token (pkg); if (kw_token) { - error ("class and package names may not be keywords"); + error ("class and package names may not be keywords"); return LEXICAL_ERROR; } - yylval.tok_val - = new token (cls.empty () ? 0 : &(symbol_table::insert (cls)), - pkg.empty () ? 0 : &(symbol_table::insert (pkg)), - input_line_number, current_input_column); - + yylval.tok_val = new token (pkg, cls, input_line_number, + current_input_column); token_stack.push (yylval.tok_val); - lexer_flags.convert_spaces_to_comma = true; + do_comma_insert_check (); + maybe_unput_comma (spc_gobbled); current_input_column += yyleng; return METAQUERY; @@ -3422,6 +3436,8 @@ // Not initially defining a class with classdef. maybe_classdef_get_set_method = false; parsing_classdef = false; + parsing_classdef_get_method = false; + parsing_classdef_set_method = false; // Not initiallly looking at a function handle. looking_at_function_handle = 0; @@ -3550,6 +3566,12 @@ BEGIN (FUNCTION_FILE_BEGIN); } +void +prep_lexer_for_classdef_file (void) +{ + BEGIN (CLASSDEF_FILE_BEGIN); +} + static void maybe_warn_separator_insert (char sep) { @@ -3722,6 +3744,7 @@ case CLOSE_BRACE: std::cerr << "CLOSE_BRACE\n"; break; case SCRIPT_FILE: std::cerr << "SCRIPT_FILE\n"; break; case FUNCTION_FILE: std::cerr << "FUNCTION_FILE\n"; break; + case CLASSDEF_FILE: std::cerr << "CLASSDEF_FILE\n"; break; case SUPERCLASSREF: std::cerr << "SUPERCLASSREF\n"; break; case METAQUERY: std::cerr << "METAQUERY\n"; break; case GET: std::cerr << "GET\n"; break; @@ -3771,6 +3794,10 @@ std::cerr << "FUNCTION_FILE_BEGIN" << std::endl; break; + case CLASSDEF_FILE_BEGIN: + std::cerr << "CLASSDEF_FILE_BEGIN" << std::endl; + break; + default: std::cerr << "UNKNOWN START STATE!" << std::endl; break; diff -r aa1f9e479c6e -r 56b8eb7c9c04 src/oct-parse.yy --- a/src/oct-parse.yy Fri Jul 27 16:02:01 2012 -0400 +++ b/src/oct-parse.yy Fri Jul 27 17:10:25 2012 -0400 @@ -62,6 +62,7 @@ #include "load-path.h" #include "oct-hist.h" #include "oct-map.h" +#include "ov-classdef.h" #include "ov-fcn-handle.h" #include "ov-usr-fcn.h" #include "ov-null-mat.h" @@ -71,6 +72,7 @@ #include "parse-private.h" #include "pt-all.h" #include "pt-eval.h" +#include "pt-funcall.h" #include "symtab.h" #include "token.h" #include "unwind-prot.h" @@ -152,6 +154,9 @@ // used while reading function files. static symbol_table::scope_id primary_fcn_scope; +// Pointer to the classdef object we just parsed, if any. +static tree_classdef *classdef_object = 0; + // List of autoloads (function -> file mapping). static std::map autoload_map; @@ -356,6 +361,47 @@ append_statement_list (tree_statement_list *list, char sep, tree_statement *stmt, bool warn_missing_semi); +static tree_funcall * +make_superclass_ref (const std::string& method_nm, + const std::string& package_nm, + const std::string& class_nm, + int l, int c); + +static tree_funcall * +make_meta_class_query (const std::string& package_nm, + const std::string& class_nm, + int l, int c); + +static tree_classdef * +make_classdef (token *tok_val, tree_classdef_attribute_list *a, + tree_identifier *id, tree_classdef_superclass_list *sc, + tree_classdef_body *body, token *end_tok, + octave_comment_list *lc); + +static tree_classdef_properties_block * +make_classdef_properties_block (token *tok_val, + tree_classdef_attribute_list *a, + tree_classdef_property_list *plist, + token *end_tok, octave_comment_list *lc); + +static tree_classdef_methods_block * +make_classdef_methods_block (token *tok_val, + tree_classdef_attribute_list *a, + tree_classdef_methods_list *mlist, + token *end_tok, octave_comment_list *lc); + +static tree_classdef_events_block * +make_classdef_events_block (token *tok_val, + tree_classdef_attribute_list *a, + tree_classdef_events_list *elist, + token *end_tok, octave_comment_list *lc); + +static tree_classdef_enum_block * +make_classdef_enum_block (token *tok_val, + tree_classdef_attribute_list *a, + tree_classdef_enum_list *elist, + token *end_tok, octave_comment_list *lc); + // Finish building a statement. template static tree_statement * @@ -400,12 +446,15 @@ // Types for the nonterminals we generate. char sep_type; + token *tok_type; tree *tree_type; tree_matrix *tree_matrix_type; tree_cell *tree_cell_type; tree_expression *tree_expression_type; tree_constant *tree_constant_type; tree_fcn_handle *tree_fcn_handle_type; + tree_funcall *tree_funcall_type; + tree_function_def *tree_function_def_type; tree_anon_fcn_handle *tree_anon_fcn_handle_type; tree_identifier *tree_identifier_type; tree_index_expression *tree_index_expression_type; @@ -425,7 +474,24 @@ tree_statement *tree_statement_type; tree_statement_list *tree_statement_list_type; octave_user_function *octave_user_function_type; - void *dummy_type; + + tree_classdef *tree_classdef_type; + tree_classdef_attribute* tree_classdef_attribute_type; + tree_classdef_attribute_list* tree_classdef_attribute_list_type; + tree_classdef_superclass* tree_classdef_superclass_type; + tree_classdef_superclass_list* tree_classdef_superclass_list_type; + tree_classdef_body* tree_classdef_body_type; + tree_classdef_property* tree_classdef_property_type; + tree_classdef_property_list* tree_classdef_property_list_type; + tree_classdef_properties_block* tree_classdef_properties_block_type; + tree_classdef_methods_list* tree_classdef_methods_list_type; + tree_classdef_methods_block* tree_classdef_methods_block_type; + tree_classdef_event* tree_classdef_event_type; + tree_classdef_events_list* tree_classdef_events_list_type; + tree_classdef_events_block* tree_classdef_events_block_type; + tree_classdef_enum* tree_classdef_enum_type; + tree_classdef_enum_list* tree_classdef_enum_list_type; + tree_classdef_enum_block* tree_classdef_enum_block_type; } // Tokens with line and column information. @@ -452,6 +518,7 @@ %token TRY CATCH %token GLOBAL PERSISTENT %token FCN_HANDLE +%token CLASSDEF %token PROPERTIES METHODS EVENTS ENUMERATION %token METAQUERY %token SUPERCLASSREF @@ -459,13 +526,13 @@ // Other tokens. %token END_OF_INPUT LEXICAL_ERROR -%token FCN SCRIPT_FILE FUNCTION_FILE CLASSDEF +%token FCN SCRIPT_FILE CLASSDEF_FILE FUNCTION_FILE // %token VARARGIN VARARGOUT %token CLOSE_BRACE // Nonterminals we construct. -%type stash_comment function_beg classdef_beg -%type properties_beg methods_beg events_beg enum_beg +%type stash_comment function_beg +%type classdef_beg %type sep_no_nl opt_sep_no_nl sep opt_sep opt_comma %type input %type string constant magic_colon @@ -477,18 +544,19 @@ %type primary_expr oper_expr %type simple_expr colon_expr assign_expr expression %type identifier fcn_name magic_tilde -%type superclass_identifier meta_identifier -%type function1 function2 classdef1 +%type superclass_identifier meta_identifier +%type function1 function2 %type word_list_cmd %type colon_expr1 %type arg_list word_list assign_lhs %type cell_or_matrix_row %type param_list param_list1 param_list2 %type return_list return_list1 -%type superclasses opt_superclasses %type command select_command loop_command -%type jump_command except_command function -%type script_file classdef +%type jump_command except_command +%type function +%type classdef +%type script_file classdef_file %type function_file function_list %type if_command %type elseif_clause else_clause @@ -499,25 +567,26 @@ %type decl2 %type decl1 %type declaration -%type statement function_end classdef_end +%type statement function_end %type simple_list simple_list1 list list1 %type opt_list input1 -// These types need to be specified. -%type attr -%type class_event -%type class_enum -%type class_property -%type properties_list -%type properties_block -%type methods_list -%type methods_block -%type opt_attr_list -%type attr_list -%type events_list -%type events_block -%type enum_list -%type enum_block -%type class_body + +%type attr +%type attr_list opt_attr_list +%type superclass +%type superclass_list opt_superclass_list +%type class_body +%type class_property +%type property_list +%type properties_block +%type methods_list +%type methods_block +%type class_event +%type events_list +%type events_block +%type class_enum +%type enum_list +%type enum_block // Precedence and associativity. %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 @@ -552,6 +621,8 @@ } | function_file { YYACCEPT; } + | classdef_file + { YYACCEPT; } | simple_list parse_error { ABORT_PARSE; } | parse_error @@ -641,11 +712,24 @@ superclass_identifier : SUPERCLASSREF - { $$ = new tree_identifier ($1->line (), $1->column ()); } + { + std::string method_nm = $1->superclass_method_name (); + std::string package_nm = $1->superclass_package_name (); + std::string class_nm = $1->superclass_class_name (); + + $$ = make_superclass_ref (method_nm, package_nm, class_nm, + $1->line (), $1->column ()); + } ; meta_identifier : METAQUERY - { $$ = new tree_identifier ($1->line (), $1->column ()); } + { + std::string package_nm = $1->meta_package_name (); + std::string class_nm = $1->meta_class_name (); + + $$ = make_meta_class_query (package_nm, class_nm, + $1->line (), $1->column ()); + } ; string : DQ_STRING @@ -984,8 +1068,6 @@ { $$ = $1; } | script_file { $$ = $1; } - | classdef - { $$ = $1; } ; // ===================== @@ -1404,12 +1486,14 @@ { lexer_flags.parsed_function_name.top () = true; lexer_flags.maybe_classdef_get_set_method = false; + lexer_flags.parsing_classdef_get_method = true; $$ = $3; } | SET '.' identifier { lexer_flags.parsed_function_name.top () = true; lexer_flags.maybe_classdef_get_set_method = false; + lexer_flags.parsing_classdef_set_method = true; $$ = $3; } ; @@ -1474,161 +1558,211 @@ } ; +// ============= +// Classdef file +// ============= + +classdef_file : CLASSDEF_FILE classdef opt_sep END_OF_INPUT + { + classdef_object = $2; + $$ = 0; + } + ; + // ======== // Classdef // ======== -classdef_beg : CLASSDEF stash_comment +classdef_beg : CLASSDEF { - $$ = 0; + if (! reading_classdef_file) + { + yyerror ("classdef must appear inside a file containing only a class definition"); + YYABORT; + } + lexer_flags.parsing_classdef = true; + $$ = $1; } ; -classdef_end : END +classdef : classdef_beg stash_comment opt_attr_list identifier opt_superclass_list opt_sep class_body opt_sep END { lexer_flags.parsing_classdef = false; - - if (end_token_ok ($1, token::classdef_end)) - $$ = make_end ("endclassdef", $1->line (), $1->column ()); - else - ABORT_PARSE; + $$ = make_classdef ($1, $3, $4, $5, $7, $9, $2); } ; -classdef1 : classdef_beg opt_attr_list identifier opt_superclasses - { $$ = 0; } - ; - -classdef : classdef1 opt_sep class_body opt_sep stash_comment classdef_end - { $$ = 0; } - ; - opt_attr_list : // empty { $$ = 0; } | '(' attr_list ')' - { $$ = 0; } + { $$ = $2; } ; attr_list : attr - { $$ = 0; } + { $$ = new tree_classdef_attribute_list ($1); } | attr_list ',' attr - { $$ = 0; } + { + $1->append ($3); + $$ = $1; + } ; attr : identifier - { $$ = 0; } + { $$ = new tree_classdef_attribute ($1); } | identifier '=' decl_param_init expression - { $$ = 0; } + { + lexer_flags.looking_at_initializer_expression = false; + $$ = new tree_classdef_attribute ($1, $4); + } | EXPR_NOT identifier - { $$ = 0; } + { $$ = new tree_classdef_attribute ($2, false); } ; -opt_superclasses +opt_superclass_list : // empty { $$ = 0; } - | superclasses - { $$ = 0; } + | superclass_list + { $$ = $1; } ; -superclasses : EXPR_LT identifier '.' identifier - { $$ = 0; } - | EXPR_LT identifier - { $$ = 0; } - | superclasses EXPR_AND identifier '.' identifier - { $$ = 0; } - | superclasses EXPR_AND identifier - { $$ = 0; } +superclass_list : EXPR_LT superclass + { $$ = new tree_classdef_superclass_list ($2); } + | superclass_list EXPR_AND superclass + { + $1->append ($3); + $$ = $1; + } + ; + +superclass : identifier + { $$ = new tree_classdef_superclass ($1); } + | identifier '.' identifier + { $$ = new tree_classdef_superclass ($3, $1); } ; class_body : properties_block - { $$ = 0; } + { $$ = new tree_classdef_body ($1); } | methods_block - { $$ = 0; } + { $$ = new tree_classdef_body ($1); } | events_block - { $$ = 0; } + { $$ = new tree_classdef_body ($1); } | enum_block - { $$ = 0; } + { $$ = new tree_classdef_body ($1); } | class_body opt_sep properties_block - { $$ = 0; } + { + $1->append ($3); + $$ = $1; + } | class_body opt_sep methods_block - { $$ = 0; } + { + $1->append ($3); + $$ = $1; + } | class_body opt_sep events_block - { $$ = 0; } + { + $1->append ($3); + $$ = $1; + } | class_body opt_sep enum_block - { $$ = 0; } - ; - -properties_beg : PROPERTIES stash_comment - { $$ = 0; } + { + $1->append ($3); + $$ = $1; + } ; properties_block - : properties_beg opt_attr_list opt_sep properties_list opt_sep END - { $$ = 0; } + : PROPERTIES stash_comment opt_attr_list opt_sep property_list opt_sep END + { + if (! ($$ = make_classdef_properties_block ($1, $3, $5, $7, $2))) + ABORT_PARSE; + } ; -properties_list +property_list : class_property - { $$ = 0; } - | properties_list opt_sep class_property - { $$ = 0; } + { $$ = new tree_classdef_property_list ($1); } + | property_list opt_sep class_property + { + $1->append ($3); + $$ = $1; + } ; class_property : identifier - { $$ = 0; } + { $$ = new tree_classdef_property ($1); } | identifier '=' decl_param_init expression ';' - { $$ = 0; } + { + lexer_flags.looking_at_initializer_expression = false; + $$ = new tree_classdef_property ($1, $4); + } ; -methods_beg : METHODS stash_comment - { $$ = 0; } - ; - -methods_block : methods_beg opt_attr_list opt_sep methods_list opt_sep END - { $$ = 0; } +methods_block : METHODS stash_comment opt_attr_list opt_sep methods_list opt_sep END + { + if (! ($$ = make_classdef_methods_block ($1, $3, $5, $7, $2))) + ABORT_PARSE; + } ; methods_list : function - { $$ = 0; } + { + octave_value fcn; + if ($1) + fcn = $1->function (); + delete $1; + $$ = new tree_classdef_methods_list (fcn); + } | methods_list opt_sep function - { $$ = 0; } + { + octave_value fcn; + if ($3) + fcn = $3->function (); + delete $3; + + $1->append (fcn); + $$ = $1; + } ; -events_beg : EVENTS stash_comment - { $$ = 0; } - ; - -events_block : events_beg opt_attr_list opt_sep events_list opt_sep END - { $$ = 0; } +events_block : EVENTS stash_comment opt_attr_list opt_sep events_list opt_sep END + { + if (! ($$ = make_classdef_events_block ($1, $3, $5, $7, $2))) + ABORT_PARSE; + } ; events_list : class_event - { $$ = 0; } + { $$ = new tree_classdef_events_list ($1); } | events_list opt_sep class_event - { $$ = 0; } + { + $1->append ($3); + $$ = $1; + } ; class_event : identifier - { $$ = 0; } + { $$ = new tree_classdef_event ($1); } ; -enum_beg : ENUMERATION stash_comment - { $$ = 0; } - ; - -enum_block : enum_beg opt_attr_list opt_sep enum_list opt_sep END - { $$ = 0; } +enum_block : ENUMERATION stash_comment opt_attr_list opt_sep enum_list opt_sep END + { + if (! ($$ = make_classdef_enum_block ($1, $3, $5, $7, $2))) + ABORT_PARSE; + } ; enum_list : class_enum - { $$ = 0; } + { $$ = new tree_classdef_enum_list ($1); } | enum_list opt_sep class_enum - { $$ = 0; } + { + $1->append ($3); + $$ = $1; + } ; class_enum : identifier '(' expression ')' - { $$ = 0; } + { $$ = new tree_classdef_enum ($1, $3); } ; // ============= @@ -3268,6 +3402,151 @@ return list; } +static tree_funcall * +make_superclass_ref (const std::string& method_nm, + const std::string& package_nm, + const std::string& class_nm, + int l, int c) +{ + octave_value_list args; + + args(2) = class_nm; + args(1) = package_nm; + args(0) = method_nm; + + octave_value fcn + = symbol_table::find_built_in_function ("__superclass_reference__"); + + return new tree_funcall (fcn, args); +} + +static tree_funcall * +make_meta_class_query (const std::string& package_nm, + const std::string& class_nm, + int l, int c) +{ + octave_value_list args; + + args(1) = class_nm; + args(0) = package_nm; + + octave_value fcn + = symbol_table::find_built_in_function ("__meta_class_query__"); + + return new tree_funcall (fcn, args); +} + +// A CLASSDEF block defines a class that has a constructor and other +// methods, but it is not an executable command. Parsing the block +// makes some changes in the symbol table (inserting the constructor +// and methods, and adding to the list of known objects) and creates +// a parse tree containing meta information about the class. + +static tree_classdef * +make_classdef (token *tok_val, tree_classdef_attribute_list *a, + tree_identifier *id, tree_classdef_superclass_list *sc, + tree_classdef_body *body, token *end_tok, + octave_comment_list *lc) +{ + tree_classdef *retval = 0; + + if (end_token_ok (end_tok, token::classdef_end)) + { + octave_comment_list *tc = octave_comment_buffer::get_comment (); + + int l = tok_val->line (); + int c = tok_val->column (); + + retval = new tree_classdef (a, id, sc, body, lc, tc, l, c); + } + + return retval; +} + +static tree_classdef_properties_block * +make_classdef_properties_block (token *tok_val, + tree_classdef_attribute_list *a, + tree_classdef_property_list *plist, + token *end_tok, octave_comment_list *lc) +{ + tree_classdef_properties_block *retval = 0; + + if (end_token_ok (end_tok, token::properties_end)) + { + octave_comment_list *tc = octave_comment_buffer::get_comment (); + + int l = tok_val->line (); + int c = tok_val->column (); + + retval = new tree_classdef_properties_block (a, plist, lc, tc, l, c); + } + + return retval; +} + +static tree_classdef_methods_block * +make_classdef_methods_block (token *tok_val, + tree_classdef_attribute_list *a, + tree_classdef_methods_list *mlist, + token *end_tok, octave_comment_list *lc) +{ + tree_classdef_methods_block *retval = 0; + + if (end_token_ok (end_tok, token::methods_end)) + { + octave_comment_list *tc = octave_comment_buffer::get_comment (); + + int l = tok_val->line (); + int c = tok_val->column (); + + retval = new tree_classdef_methods_block (a, mlist, lc, tc, l, c); + } + + return retval; +} + +static tree_classdef_events_block * +make_classdef_events_block (token *tok_val, + tree_classdef_attribute_list *a, + tree_classdef_events_list *elist, + token *end_tok, octave_comment_list *lc) +{ + tree_classdef_events_block *retval = 0; + + if (end_token_ok (end_tok, token::events_end)) + { + octave_comment_list *tc = octave_comment_buffer::get_comment (); + + int l = tok_val->line (); + int c = tok_val->column (); + + retval = new tree_classdef_events_block (a, elist, lc, tc, l, c); + } + + return retval; +} + +static tree_classdef_enum_block * +make_classdef_enum_block (token *tok_val, + tree_classdef_attribute_list *a, + tree_classdef_enum_list *elist, + token *end_tok, octave_comment_list *lc) +{ + tree_classdef_enum_block *retval = 0; + + if (end_token_ok (end_tok, token::enumeration_end)) + { + octave_comment_list *tc = octave_comment_buffer::get_comment (); + + int l = tok_val->line (); + int c = tok_val->column (); + + retval = new tree_classdef_enum_block (a, elist, lc, tc, l, c); + } + + return retval; +} + static void safe_fclose (FILE *f) { @@ -3546,11 +3825,7 @@ reading_classdef_file = true; reading_fcn_file = false; - // FIXME -- Should classdef files be handled as - // scripts or separately? Currently, without setting up - // for reading script files, parsing classdef files - // fails. - reading_script_file = true; + reading_script_file = false; } else { @@ -3574,6 +3849,9 @@ frame.protect_var (primary_fcn_ptr); primary_fcn_ptr = 0; + frame.protect_var (classdef_object); + classdef_object = 0; + reset_parser (); // Do this with an unwind-protect cleanup function so that @@ -3587,6 +3865,8 @@ if (reading_script_file) prep_lexer_for_script_file (); + else if (reading_classdef_file) + prep_lexer_for_classdef_file (); else prep_lexer_for_function_file (); @@ -3606,9 +3886,22 @@ fcn_ptr = primary_fcn_ptr; - if (status != 0) - error ("parse error while reading %s file %s", - file_type.c_str (), ff.c_str ()); + if (status == 0) + { + if (reading_classdef_file && classdef_object) + { + // Convert parse tree for classdef object to + // meta.class info (and stash it in the symbol + // table?). Return pointer to constructor? + + octave_value meta_class = classdef_object->make_meta_class (); + } + } + else + { + error ("parse error while reading %s file %s", + file_type.c_str(), ff.c_str ()); + } } else { diff -r aa1f9e479c6e -r 56b8eb7c9c04 src/ov-classdef.cc --- a/src/ov-classdef.cc Fri Jul 27 16:02:01 2012 -0400 +++ b/src/ov-classdef.cc Fri Jul 27 17:10:25 2012 -0400 @@ -31,6 +31,7 @@ #include "ov-classdef.h" #include "ov-fcn-handle.h" #include "ov-typeinfo.h" +#include "pt-classdef.h" static std::map all_classes; static std::map all_packages; @@ -956,6 +957,14 @@ } } +cdef_class +cdef_class::make_meta_class (const tree_classdef* t) +{ + cdef_class retval; + + return retval; +} + octave_value cdef_property::cdef_property_rep::get_value (const cdef_object& obj) { @@ -1370,25 +1379,6 @@ package_meta.install_class (meta_dynproperty, "dynproperty"); } -DEFUN (__meta_get_class__, args, , "") -{ - octave_value retval; - - if (args.length () == 1) - { - std::string cname = args(0).string_value (); - - if (! error_state) - retval = to_ov (lookup_class (cname)); - else - error ("invalid class name, expected a string value"); - } - else - print_usage (); - - return retval; -} - DEFUN (__meta_get_package__, args, , "") { octave_value retval; @@ -1408,6 +1398,55 @@ return retval; } +DEFUN (__superclass_reference__, args, /* nargout */, + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {} __superclass_reference__ ()\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; + + std::cerr << "__superclass_reference__ (" + << args(0).string_value () << ", " + << args(1).string_value () << ", " + << args(2).string_value () << ")" + << std::endl; + + return retval; +} + +DEFUN (__meta_class_query__, args, /* nargout */, + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {} __meta_class_query__ ()\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; + + std::cerr << "__meta_class_query__ (" + << args(0).string_value () << ", " + << args(1).string_value () << ")" + << std::endl; + + if (args.length () == 2) + { + std::string pkg = args(0).string_value (); + std::string cls = args(1).string_value (); + + if (! pkg.empty ()) + cls = pkg + "." + cls; + + if (! error_state) + retval = to_ov (lookup_class (cls)); + else + error ("invalid class name, expected a string value"); + } + else + print_usage (); + + return retval; +} + /* ;;; Local Variables: *** ;;; mode: C++ *** diff -r aa1f9e479c6e -r 56b8eb7c9c04 src/ov-classdef.h --- a/src/ov-classdef.h Fri Jul 27 16:02:01 2012 -0400 +++ b/src/ov-classdef.h Fri Jul 27 17:10:25 2012 -0400 @@ -35,6 +35,8 @@ class cdef_method; class cdef_package; +class tree_classdef; + class cdef_object_rep { @@ -336,6 +338,8 @@ void delete_object (cdef_object obj) { get_rep ()->delete_object (obj); } + static cdef_class make_meta_class (const tree_classdef* t); + private: cdef_class_rep* get_rep (void) { return dynamic_cast (cdef_object::get_rep ()); } diff -r aa1f9e479c6e -r 56b8eb7c9c04 src/ov.cc --- a/src/ov.cc Fri Jul 27 16:02:01 2012 -0400 +++ b/src/ov.cc Fri Jul 27 17:10:25 2012 -0400 @@ -65,6 +65,7 @@ #include "ov-range.h" #include "ov-struct.h" #include "ov-class.h" +#include "ov-classdef.h" #include "ov-oncleanup.h" #include "ov-cs-list.h" #include "ov-colon.h" diff -r aa1f9e479c6e -r 56b8eb7c9c04 src/pt-all.h --- a/src/pt-all.h Fri Jul 27 16:02:01 2012 -0400 +++ b/src/pt-all.h Fri Jul 27 17:10:25 2012 -0400 @@ -30,6 +30,7 @@ #include "pt-binop.h" #include "pt-cbinop.h" #include "pt-check.h" +#include "pt-classdef.h" #include "pt-cmd.h" #include "pt-colon.h" #include "pt-const.h" diff -r aa1f9e479c6e -r 56b8eb7c9c04 src/pt-classdef.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pt-classdef.cc Fri Jul 27 17:10:25 2012 -0400 @@ -0,0 +1,260 @@ +/* + +Copyright (C) 2012 John W. Eaton + +This file is part of Octave. + +Octave is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +Octave is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with Octave; see the file COPYING. If not, see +. + +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "ov-classdef.h" +#include "pt-classdef.h" + +// Classdef attribute + +void +tree_classdef_attribute::accept (tree_walker& tw) +{ + tw.visit_classdef_attribute (*this); +} + +// Classdef attribute_list + +tree_classdef_attribute_list::~tree_classdef_attribute_list (void) +{ + while (! empty ()) + { + iterator p = begin (); + delete *p; + erase (p); + } +} + +void +tree_classdef_attribute_list::accept (tree_walker& tw) +{ + tw.visit_classdef_attribute_list (*this); +} + +// Classdef superclass + +void +tree_classdef_superclass::accept (tree_walker& tw) +{ + tw.visit_classdef_superclass (*this); +} + +// Classdef superclass_list + +tree_classdef_superclass_list::~tree_classdef_superclass_list (void) +{ + while (! empty ()) + { + iterator p = begin (); + delete *p; + erase (p); + } +} + +void +tree_classdef_superclass_list::accept (tree_walker& tw) +{ + tw.visit_classdef_superclass_list (*this); +} + +// Classdef property + +void +tree_classdef_property::accept (tree_walker& tw) +{ + tw.visit_classdef_property (*this); +} + +// Classdef property_list + +tree_classdef_property_list::~tree_classdef_property_list (void) +{ + while (! empty ()) + { + iterator p = begin (); + delete *p; + erase (p); + } +} + +void +tree_classdef_property_list::accept (tree_walker& tw) +{ + tw.visit_classdef_property_list (*this); +} + +// Classdef properties_block + +void +tree_classdef_properties_block::accept (tree_walker& tw) +{ + tw.visit_classdef_properties_block (*this); +} + +// Classdef methods_list + +void +tree_classdef_methods_list::accept (tree_walker& tw) +{ + tw.visit_classdef_methods_list (*this); +} + +// Classdef methods_block + +void +tree_classdef_methods_block::accept (tree_walker& tw) +{ + tw.visit_classdef_methods_block (*this); +} + +// Classdef event + +void +tree_classdef_event::accept (tree_walker& tw) +{ + tw.visit_classdef_event (*this); +} + +// Classdef events_list + +tree_classdef_events_list::~tree_classdef_events_list (void) +{ + while (! empty ()) + { + iterator p = begin (); + delete *p; + erase (p); + } +} + +void +tree_classdef_events_list::accept (tree_walker& tw) +{ + tw.visit_classdef_events_list (*this); +} + +// Classdef events_block + +void +tree_classdef_events_block::accept (tree_walker& tw) +{ + tw.visit_classdef_events_block (*this); +} + +// Classdef enum + +void +tree_classdef_enum::accept (tree_walker& tw) +{ + tw.visit_classdef_enum (*this); +} + +// Classdef enum_list + +tree_classdef_enum_list::~tree_classdef_enum_list (void) +{ + while (! empty ()) + { + iterator p = begin (); + delete *p; + erase (p); + } +} + +void +tree_classdef_enum_list::accept (tree_walker& tw) +{ + tw.visit_classdef_enum_list (*this); +} + +// Classdef enum_block + +void +tree_classdef_enum_block::accept (tree_walker& tw) +{ + tw.visit_classdef_enum_block (*this); +} + +// Classdef body + +tree_classdef_body::~tree_classdef_body (void) +{ + while (! properties_lst.empty ()) + { + properties_list_iterator p = properties_lst.begin (); + delete *p; + properties_lst.erase (p); + } + + while (! methods_lst.empty ()) + { + methods_list_iterator p = methods_lst.begin (); + delete *p; + methods_lst.erase (p); + } + + while (! events_lst.empty ()) + { + events_list_iterator p = events_lst.begin (); + delete *p; + events_lst.erase (p); + } + + while (! enum_lst.empty ()) + { + enum_list_iterator p = enum_lst.begin (); + delete *p; + enum_lst.erase (p); + } +} + +// Classdef + +octave_value +tree_classdef::make_meta_class (void) const +{ + octave_value retval; + cdef_class cls = cdef_class::make_meta_class (this); + + if (cls.ok ()) + retval = to_ov (cls); + + return retval; +} + +tree_classdef * +tree_classdef::dup (symbol_table::scope_id, + symbol_table::context_id) const +{ + // FIXME + return 0; +} + +void +tree_classdef::accept (tree_walker& tw) +{ + std::cerr << "I am super accepting" << std::endl; + // tw.visit_classdef (*this); +} diff -r aa1f9e479c6e -r 56b8eb7c9c04 src/pt-classdef.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pt-classdef.h Fri Jul 27 17:10:25 2012 -0400 @@ -0,0 +1,653 @@ +/* + +Copyright (C) 2012 John W. Eaton + +This file is part of Octave. + +Octave is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +Octave is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with Octave; see the file COPYING. If not, see +. + +*/ + +#if !defined (octave_tree_classdef_h) +#define octave_tree_classdef_h 1 + +class octave_value; + +class tree_walker; + +#include "pt-cmd.h" +#include "pt-exp.h" +#include "pt-id.h" + +#include "base-list.h" + +#include + +class tree_classdef_attribute +{ +public: + + tree_classdef_attribute (tree_identifier *i = 0, tree_expression *e = 0) + : id (i), expr (e), neg (false) { } + + tree_classdef_attribute (tree_identifier *i, bool b) + : id (i), expr (0), neg (b) { } + + ~tree_classdef_attribute (void) + { + delete id; + delete expr; + } + + tree_identifier *ident (void) { return id; } + + tree_expression *expression (void) { return expr; } + + bool negate (void) { return neg; } + + void accept (tree_walker&); + +private: + + tree_identifier *id; + tree_expression *expr; + bool neg; + + // No copying! + + tree_classdef_attribute (const tree_classdef_attribute&); + + tree_classdef_attribute& operator = (const tree_classdef_attribute&); +}; + +class tree_classdef_attribute_list : public octave_base_list +{ +public: + + tree_classdef_attribute_list (void) { } + + tree_classdef_attribute_list (tree_classdef_attribute *a) { append (a); } + + tree_classdef_attribute_list (const octave_base_list& a) + : octave_base_list (a) { } + + ~tree_classdef_attribute_list (void); + + void accept (tree_walker&); + +private: + + // No copying! + + tree_classdef_attribute_list (const tree_classdef_attribute_list&); + + tree_classdef_attribute_list& operator = (const tree_classdef_attribute_list&); +}; + +class tree_classdef_superclass +{ +public: + + tree_classdef_superclass (tree_identifier *i = 0, tree_identifier *p = 0) + : id (i), pkg (p) { } + + ~tree_classdef_superclass (void) + { + delete id; + delete pkg; + } + + tree_identifier *ident (void) { return id; } + + tree_identifier * package (void) { return pkg; } + + void accept (tree_walker&); + +private: + + tree_identifier *id; + tree_identifier *pkg; + + // No copying! + + tree_classdef_superclass (const tree_classdef_superclass&); + + tree_classdef_superclass& operator = (const tree_classdef_superclass&); +}; + +class tree_classdef_superclass_list : public octave_base_list +{ +public: + + tree_classdef_superclass_list (void) { } + + tree_classdef_superclass_list (tree_classdef_superclass *sc) { append (sc); } + + tree_classdef_superclass_list (const octave_base_list& a) + : octave_base_list (a) { } + + ~tree_classdef_superclass_list (void); + + void accept (tree_walker&); + +private: + + // No copying! + + tree_classdef_superclass_list (const tree_classdef_superclass_list&); + + tree_classdef_superclass_list& operator = (const tree_classdef_superclass_list&); +}; + +template +class tree_classdef_element : public tree +{ +public: + + tree_classdef_element (tree_classdef_attribute_list *a, + octave_base_list *elist, + octave_comment_list *lc, octave_comment_list *tc, + int l = -1, int c = -1) + : tree (l, c), attr_list (a), elt_list (elist), + lead_comm (lc), trail_comm (tc) + { } + + ~tree_classdef_element (void) + { + delete attr_list; + delete elt_list; + delete lead_comm; + delete trail_comm; + } + + tree_classdef_attribute_list *attribute_list (void) { return attr_list; } + + octave_base_list *element_list (void) { return elt_list; } + + octave_comment_list *leading_comment (void) { return lead_comm; } + + octave_comment_list *trailing_comment (void) { return trail_comm; } + + void accept (tree_walker&) { } + +private: + + // List of attributes that apply to this class. + tree_classdef_attribute_list *attr_list; + + // The list of objects contained in this block. + octave_base_list *elt_list; + + // Comment preceding the token marking the beginning of the block. + octave_comment_list *lead_comm; + + // Comment preceding END token. + octave_comment_list *trail_comm; + + // No copying! + + tree_classdef_element (const tree_classdef_element&); + + tree_classdef_element& operator = (const tree_classdef_element&); +}; + +class tree_classdef_property +{ +public: + + tree_classdef_property (tree_identifier *i = 0, tree_expression *e = 0) + : id (i), expr (e) { } + + ~tree_classdef_property (void) + { + delete id; + delete expr; + } + + tree_identifier *ident (void) { return id; } + + tree_expression *expression (void) { return expr; } + + void accept (tree_walker&); + +private: + + tree_identifier *id; + tree_expression *expr; + + // No copying! + + tree_classdef_property (const tree_classdef_property&); + + tree_classdef_property& operator = (const tree_classdef_property&); +}; + +class tree_classdef_property_list : public octave_base_list +{ +public: + + tree_classdef_property_list (void) { } + + tree_classdef_property_list (tree_classdef_property* p) { append (p); } + + tree_classdef_property_list (const octave_base_list& a) + : octave_base_list (a) { } + + ~tree_classdef_property_list (void); + + void accept (tree_walker&); + +private: + + // No copying! + + tree_classdef_property_list (const tree_classdef_property_list&); + + tree_classdef_property_list& operator = (const tree_classdef_property_list&); +}; + +class tree_classdef_properties_block + : public tree_classdef_element +{ +public: + + tree_classdef_properties_block (tree_classdef_attribute_list *a, + tree_classdef_property_list *plist, + octave_comment_list *lc, + octave_comment_list *tc, + int l = -1, int c = -1) + : tree_classdef_element (a, plist, lc, tc, l, c) { } + + ~tree_classdef_properties_block (void) { } + + void accept (tree_walker&); + +private: + + // No copying! + + tree_classdef_properties_block (const tree_classdef_properties_block&); + + tree_classdef_properties_block& operator = (const tree_classdef_properties_block&); +}; + +class tree_classdef_methods_list : public octave_base_list +{ +public: + + tree_classdef_methods_list (void) { } + + tree_classdef_methods_list (const octave_value& f) { append (f); } + + tree_classdef_methods_list (const octave_base_list& a) + : octave_base_list (a) { } + + ~tree_classdef_methods_list (void) { } + + void accept (tree_walker&); + +private: + + // No copying! + + tree_classdef_methods_list (const tree_classdef_methods_list&); + + tree_classdef_methods_list& operator = (const tree_classdef_methods_list&); +}; + +class tree_classdef_methods_block : public tree_classdef_element +{ +public: + + tree_classdef_methods_block (tree_classdef_attribute_list *a, + tree_classdef_methods_list *mlist, + octave_comment_list *lc, + octave_comment_list *tc, int l = -1, int c = -1) + : tree_classdef_element (a, mlist, lc, tc, l, c) { } + + ~tree_classdef_methods_block (void) { } + + void accept (tree_walker&); + +private: + + // No copying! + + tree_classdef_methods_block (const tree_classdef_methods_block&); + + tree_classdef_methods_block& operator = (const tree_classdef_methods_block&); +}; + +class tree_classdef_event +{ +public: + + tree_classdef_event (tree_identifier *i = 0) : id (i) { } + + ~tree_classdef_event (void) + { + delete id; + } + + tree_identifier *ident (void) { return id; } + + void accept (tree_walker&); + +private: + + tree_identifier *id; + + // No copying! + + tree_classdef_event (const tree_classdef_event&); + + tree_classdef_event& operator = (const tree_classdef_event&); +}; + +class tree_classdef_events_list : public octave_base_list +{ +public: + + tree_classdef_events_list (void) { } + + tree_classdef_events_list (tree_classdef_event *e) { append (e); } + + tree_classdef_events_list (const octave_base_list& a) + : octave_base_list (a) { } + + ~tree_classdef_events_list (void); + + void accept (tree_walker&); + +private: + + // No copying! + + tree_classdef_events_list (const tree_classdef_events_list&); + + tree_classdef_events_list& operator = (const tree_classdef_events_list&); +}; + +class tree_classdef_events_block + : public tree_classdef_element +{ +public: + + tree_classdef_events_block (tree_classdef_attribute_list *a, + tree_classdef_events_list *elist, + octave_comment_list *lc, + octave_comment_list *tc, int l = -1, int c = -1) + : tree_classdef_element (a, elist, lc, tc, l, c) { } + + ~tree_classdef_events_block (void) { } + + void accept (tree_walker&); + +private: + + // No copying! + + tree_classdef_events_block (const tree_classdef_events_block&); + + tree_classdef_events_block& operator = (const tree_classdef_events_block&); +}; + +class tree_classdef_enum +{ +public: + + tree_classdef_enum (void) : id (0), expr (0) { } + + tree_classdef_enum (tree_identifier *i, tree_expression *e) + : id (i), expr (e) { } + + ~tree_classdef_enum (void) + { + delete id; + delete expr; + } + + tree_identifier *ident (void) { return id; } + + tree_expression *expression (void) { return expr; } + + void accept (tree_walker&); + +private: + + tree_identifier *id; + tree_expression *expr; + + // No copying! + + tree_classdef_enum (const tree_classdef_enum&); + + tree_classdef_enum& operator = (const tree_classdef_enum&); +}; + +class tree_classdef_enum_list : public octave_base_list +{ +public: + + tree_classdef_enum_list (void) { } + + tree_classdef_enum_list (tree_classdef_enum *e) { append (e); } + + tree_classdef_enum_list (const octave_base_list& a) + : octave_base_list (a) { } + + ~tree_classdef_enum_list (void); + + void accept (tree_walker&); + +private: + + // No copying! + + tree_classdef_enum_list (const tree_classdef_enum_list&); + + tree_classdef_enum_list& operator = (const tree_classdef_enum_list&); +}; + +class tree_classdef_enum_block + : public tree_classdef_element +{ +public: + + tree_classdef_enum_block (tree_classdef_attribute_list *a, + tree_classdef_enum_list *elist, + octave_comment_list *lc, + octave_comment_list *tc, int l = -1, int c = -1) + : tree_classdef_element (a, elist, lc, tc, l, c) { } + + ~tree_classdef_enum_block (void) { } + + void accept (tree_walker&); + +private: + + // No copying! + + tree_classdef_enum_block (const tree_classdef_enum_block&); + + tree_classdef_enum_block& operator = (const tree_classdef_enum_block&); +}; + +class tree_classdef_body +{ +public: + + typedef typename std::list::iterator properties_list_iterator; + typedef typename std::list::const_iterator properties_list_const_iterator; + + typedef typename std::list::iterator methods_list_iterator; + typedef typename std::list::const_iterator methods_list_const_iterator; + + typedef typename std::list::iterator events_list_iterator; + typedef typename std::list::const_iterator events_list_const_iterator; + + typedef typename std::list::iterator enum_list_iterator; + typedef typename std::list::const_iterator enum_list_const_iterator; + + tree_classdef_body (void) + : properties_lst (), methods_lst (), events_lst (), enum_lst () { } + + tree_classdef_body (tree_classdef_properties_block *pb) + : properties_lst (), methods_lst (), events_lst (), enum_lst () + { + append (pb); + } + + tree_classdef_body (tree_classdef_methods_block *mb) + : properties_lst (), methods_lst (), events_lst (), enum_lst () + { + append (mb); + } + + tree_classdef_body (tree_classdef_events_block *evb) + : properties_lst (), methods_lst (), events_lst (), enum_lst () + { + append (evb); + } + + tree_classdef_body (tree_classdef_enum_block *enb) + : properties_lst (), methods_lst (), events_lst (), enum_lst () + { + append (enb); + } + + ~tree_classdef_body (void); + + void append (tree_classdef_properties_block *pb) + { + properties_lst.push_back (pb); + } + + void append (tree_classdef_methods_block *mb) + { + methods_lst.push_back (mb); + } + + void append (tree_classdef_events_block *evb) + { + events_lst.push_back (evb); + } + + void append (tree_classdef_enum_block *enb) + { + enum_lst.push_back (enb); + } + + std::list properties_list (void) + { + return properties_lst; + } + + std::list methods_list (void) + { + return methods_lst; + } + + std::list events_list (void) + { + return events_lst; + } + + std::list enum_list (void) + { + return enum_lst; + } + + void accept (tree_walker&); + +private: + + std::list properties_lst; + + std::list methods_lst; + + std::list events_lst; + + std::list enum_lst; + + // No copying! + + tree_classdef_body (const tree_classdef_body&); + + tree_classdef_body& operator = (const tree_classdef_body&); +}; + +// Classdef definition. + +class tree_classdef : public tree_command +{ +public: + + tree_classdef (tree_classdef_attribute_list *a, tree_identifier *i, + tree_classdef_superclass_list *sc, + tree_classdef_body *b, octave_comment_list *lc, + octave_comment_list *tc, int l = -1, int c = -1) + : tree_command (l, c), attr_list (a), id (i), + supclass_list (sc), element_list (b), lead_comm (lc), trail_comm (tc) { } + + ~tree_classdef (void) + { + delete attr_list; + delete id; + delete supclass_list; + delete element_list; + delete lead_comm; + delete trail_comm; + } + + tree_classdef_attribute_list *attribute_list (void) { return attr_list; } + + tree_identifier *ident (void) { return id; } + + tree_classdef_superclass_list *superclass_list (void) { return supclass_list; } + + tree_classdef_body *body (void) { return element_list; } + + octave_comment_list *leading_comment (void) { return lead_comm; } + octave_comment_list *trailing_comment (void) { return trail_comm; } + + octave_value make_meta_class (void) const; + + tree_classdef *dup (symbol_table::scope_id scope, + symbol_table::context_id context) const; + + void accept (tree_walker& tw); + +private: + + tree_classdef_attribute_list *attr_list; + + tree_identifier *id; + + tree_classdef_superclass_list *supclass_list; + + tree_classdef_body *element_list; + + octave_comment_list *lead_comm; + octave_comment_list *trail_comm; + + // No copying! + + tree_classdef (const tree_classdef&); + + tree_classdef& operator = (const tree_classdef&); +}; + +#endif diff -r aa1f9e479c6e -r 56b8eb7c9c04 src/pt-id.h --- a/src/pt-id.h Fri Jul 27 16:02:01 2012 -0400 +++ b/src/pt-id.h Fri Jul 27 17:10:25 2012 -0400 @@ -32,6 +32,7 @@ class tree_walker; +#include "oct-lvalue.h" #include "pt-bp.h" #include "pt-exp.h" #include "symtab.h" diff -r aa1f9e479c6e -r 56b8eb7c9c04 src/pt-walk.h --- a/src/pt-walk.h Fri Jul 27 16:02:01 2012 -0400 +++ b/src/pt-walk.h Fri Jul 27 17:10:25 2012 -0400 @@ -66,6 +66,24 @@ class tree_while_command; class tree_do_until_command; +class tree_classdef_attribute; +class tree_classdef_attribute_list; +class tree_classdef_superclass; +class tree_classdef_superclass_list; +class tree_classdef_property; +class tree_classdef_property_list; +class tree_classdef_properties_block; +class tree_classdef_methods_list; +class tree_classdef_methods_block; +class tree_classdef_event; +class tree_classdef_events_list; +class tree_classdef_events_block; +class tree_classdef_enum; +class tree_classdef_enum_list; +class tree_classdef_enum_block; +class tree_classdef_body; +class tree_classdef; + class tree_walker { @@ -197,6 +215,57 @@ virtual void visit_do_until_command (tree_do_until_command&) = 0; + virtual void + visit_classdef_attribute (tree_classdef_attribute&) { } /* = 0; */ + + virtual void + visit_classdef_attribute_list (tree_classdef_attribute_list&) { } /* = 0; */ + + virtual void + visit_classdef_superclass (tree_classdef_superclass&) { } /* = 0; */ + + virtual void + visit_classdef_superclass_list (tree_classdef_superclass_list&) { } /* = 0; */ + + virtual void + visit_classdef_property (tree_classdef_property&) { } /* = 0; */ + + virtual void + visit_classdef_property_list (tree_classdef_property_list&) { } /* = 0; */ + + virtual void + visit_classdef_properties_block (tree_classdef_properties_block&) { } /* = 0; */ + + virtual void + visit_classdef_methods_list (tree_classdef_methods_list&) { } /* = 0; */ + + virtual void + visit_classdef_methods_block (tree_classdef_methods_block&) { } /* = 0; */ + + virtual void + visit_classdef_event (tree_classdef_event&) { } /* = 0; */ + + virtual void + visit_classdef_events_list (tree_classdef_events_list&) { } /* = 0; */ + + virtual void + visit_classdef_events_block (tree_classdef_events_block&) { } /* = 0; */ + + virtual void + visit_classdef_enum (tree_classdef_enum&) { } /* = 0; */ + + virtual void + visit_classdef_enum_list (tree_classdef_enum_list&) { } /* = 0; */ + + virtual void + visit_classdef_enum_block (tree_classdef_enum_block&) { } /* = 0; */ + + virtual void + visit_classdef_body (tree_classdef_body&) { } /* = 0; */ + + virtual void + visit_classdef (tree_classdef&) { } /* = 0; */ + protected: tree_walker (void) { } diff -r aa1f9e479c6e -r 56b8eb7c9c04 src/token.cc --- a/src/token.cc Fri Jul 27 16:02:01 2012 -0400 +++ b/src/token.cc Fri Jul 27 17:10:25 2012 -0400 @@ -72,32 +72,43 @@ sr = s; } -token::token (symbol_table::symbol_record *cls, - symbol_table::symbol_record *pkg, int l, int c) +token::token (const std::string& pkg, const std::string& cls, int l, int c) { line_num = l; column_num = c; - type_tag = meta_rec_token; - mc.cr = cls; - mc.pr = pkg; + type_tag = meta_name_token; + mc.package_nm = new std::string (pkg); + mc.class_nm = new std::string (cls); } -token::token (symbol_table::symbol_record *mth, - symbol_table::symbol_record *cls, - symbol_table::symbol_record *pkg, int l, int c) +token::token (const std::string& mth, const std::string& pkg, + const std::string& cls, int l, int c) { line_num = l; column_num = c; - type_tag = scls_rec_token; - sc.mr = mth; - sc.cr = cls; - sc.pr = pkg; + type_tag = scls_name_token; + sc.method_nm = new std::string (mth); + sc.package_nm = new std::string (pkg); + sc.class_nm = new std::string (cls); } token::~token (void) { if (type_tag == string_token) delete str; + + if (type_tag == scls_name_token) + { + delete sc.method_nm; + delete sc.package_nm; + delete sc.class_nm; + } + + if (type_tag == meta_name_token) + { + delete mc.package_nm; + delete mc.class_nm; + } } std::string @@ -128,39 +139,39 @@ return sr; } -symbol_table::symbol_record * -token::method_rec (void) +std::string +token::superclass_method_name (void) { - assert (type_tag == scls_rec_token); - return sc.mr; + assert (type_tag == scls_name_token); + return *sc.method_nm; } -symbol_table::symbol_record * -token::class_rec (void) +std::string +token::superclass_package_name (void) { - assert (type_tag == scls_rec_token); - return sc.cr; + assert (type_tag == scls_name_token); + return *sc.package_nm; } -symbol_table::symbol_record * -token::package_rec (void) +std::string +token::superclass_class_name (void) { - assert (type_tag == scls_rec_token); - return sc.pr; + assert (type_tag == scls_name_token); + return *sc.class_nm; } -symbol_table::symbol_record * -token::meta_class_rec (void) +std::string +token::meta_package_name (void) { - assert (type_tag == meta_rec_token); - return mc.cr; + assert (type_tag == meta_name_token); + return *mc.package_nm; } -symbol_table::symbol_record * -token::meta_package_rec (void) +std::string +token::meta_class_name (void) { - assert (type_tag == meta_rec_token); - return mc.pr; + assert (type_tag == meta_name_token); + return *mc.class_nm; } std::string diff -r aa1f9e479c6e -r 56b8eb7c9c04 src/token.h --- a/src/token.h Fri Jul 27 16:02:01 2012 -0400 +++ b/src/token.h Fri Jul 27 17:10:25 2012 -0400 @@ -37,8 +37,8 @@ double_token, ettype_token, sym_rec_token, - scls_rec_token, - meta_rec_token + scls_name_token, + meta_name_token }; enum end_tok_type @@ -65,11 +65,10 @@ int l = -1, int c = -1); token (end_tok_type t, int l = -1, int c = -1); token (symbol_table::symbol_record *s, int l = -1, int c = -1); - token (symbol_table::symbol_record *cls, - symbol_table::symbol_record *pkg, int l = -1, int c = -1); - token (symbol_table::symbol_record *mth, - symbol_table::symbol_record *cls, - symbol_table::symbol_record *pkg, int l = -1, int c = -1); + token (const std::string& pkg, const std::string& cls, + int l = -1, int c = -1); + token (const std::string& mth, const std::string& pkg, + const std::string& cls, int l = -1, int c = -1); ~token (void); @@ -81,12 +80,12 @@ end_tok_type ettype (void); symbol_table::symbol_record *sym_rec (void); - symbol_table::symbol_record *method_rec (void); - symbol_table::symbol_record *class_rec (void); - symbol_table::symbol_record *package_rec (void); + std::string superclass_method_name (void); + std::string superclass_package_name (void); + std::string superclass_class_name (void); - symbol_table::symbol_record *meta_class_rec (void); - symbol_table::symbol_record *meta_package_rec (void); + std::string meta_package_name (void); + std::string meta_class_name (void); std::string text_rep (void); @@ -109,14 +108,14 @@ symbol_table::symbol_record *sr; struct { - symbol_table::symbol_record *mr; - symbol_table::symbol_record *cr; - symbol_table::symbol_record *pr; + std::string *method_nm; + std::string *package_nm; + std::string *class_nm; } sc; struct { - symbol_table::symbol_record *cr; - symbol_table::symbol_record *pr; + std::string *package_nm; + std::string *class_nm; } mc; }; std::string orig_text;