Mercurial > hg > octave-avbm
changeset 4234:90e44267e8cf
[project @ 2002-12-21 17:15:25 by jwe]
author | jwe |
---|---|
date | Sat, 21 Dec 2002 17:15:25 +0000 |
parents | ccfdb55c8156 |
children | 23bb43fc1184 |
files | src/ChangeLog src/Makefile.in src/defun-int.h src/defun.cc src/defun.h src/lex.h src/lex.l src/mkbuiltins src/mkgendoc src/oct-lvalue.h src/parse.y src/pt-arg-list.cc src/pt-arg-list.h src/pt-idx.cc src/symtab.cc src/symtab.h |
diffstat | 16 files changed, 192 insertions(+), 61 deletions(-) [+] |
line wrap: on
line diff
--- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,10 +1,39 @@ +2002-12-21 John W. Eaton <jwe@bevo.che.wisc.edu> + + * pt-arg-list.cc (indexed_object, indexed_position): + New file-scope static variables. + (tree_argument_list::convert_to_const_vector): New arg, object. + Protect and set indexed_object and indexed_position. + (F__end__): New function. + + * octave-lvalue.h (octave_lvalue::object): New member function. + * pt-idx.cc (make_value_list): New arg, object. Change all + callers. Pass object to convert_to_const_vector. + + * lex.h (lexical_feedback.looking_at_object_index): New data member. + * lex.l (lexical_feedback::init): Initialize it. + (is_keyword): If looking at object index, end is not a keyword. + (handle_identifier): If end is not a keyword, transform it to __end__. + * parse.y (begin_obj_idx): New non-terminal. + (postfix_expr): Use it. + + * defun.cc (install_builtin_function): New arg, can_hide_function. + * defun-int.h: Fix decl. + (DEFCONSTFUN_INTERNAL): New macro. + * defun.h (DEFCONSTFUN): New macro. + * mkbuiltins (XDEFCONSTFUN_INTERNAL): New macro. + * mkgendoc: Likewise. + * Makefile.in (DEFUN_PATTERN): Make it work for DEFCONSTFUN too. + * symtab.h (symbol_record::can_hide_function): New data member. + (symbol_record::symbol_record): Initialize it. + * symtab.cc (symbol_record::variable_reference): Also check + can_hide_function flag. + 2002-12-20 John W. Eaton <jwe@bevo.che.wisc.edu> * DLD-FUNCTIONS/time.cc (extract_tm): Use int_value() instead of casting double_value() to int. - * DLD-FUNCITONS/time.cc () - * ov.cc (octave_value::next_subsref): Arg "skip" is now size_t. * oct-obj.h (octave_value_list::octave_value_list (double),
--- a/src/Makefile.in +++ b/src/Makefile.in @@ -163,7 +163,7 @@ # so we have to repeat ourselves because some stupid egreps don't like # empty elements in alternation patterns. -DEFUN_PATTERN = "^[ \t]*DEF(CMD|UN|UN_DLD|UN_TEXT|UN_MAPPER)[ \t]*\\(" +DEFUN_PATTERN = "^[ \t]*DEF(CONSTFUN|CMD|UN|UN_DLD|UN_TEXT|UN_MAPPER)[ \t]*\\(" DLD_DEF_FILES := $(patsubst %.cc, %.df, $(DLD_XSRC))
--- a/src/defun-int.h +++ b/src/defun-int.h @@ -42,7 +42,8 @@ extern void install_builtin_function (octave_builtin::fcn f, const std::string& name, - const std::string& doc, bool is_text_fcn = false); + const std::string& doc, bool is_text_fcn = false, + bool can_hide_function = true); extern void install_builtin_variable (const std::string& n, const octave_value& v, @@ -107,6 +108,11 @@ XDEFUN_INTERNAL (name, args_name, nargout_name, is_text_fcn, doc) \ END_INSTALL_BUILTIN +#define DEFCONSTFUN_INTERNAL(name, args_name, nargout_name, is_text_fcn, doc) \ + BEGIN_INSTALL_BUILTIN \ + XDEFCONSTFUN_INTERNAL (name, args_name, nargout_name, is_text_fcn, doc) \ + END_INSTALL_BUILTIN + #define DEFUNX_INTERNAL(name, fname, args_name, nargout_name, \ is_text_fcn, doc) \ BEGIN_INSTALL_BUILTIN \ @@ -161,6 +167,9 @@ #define DEFUN_INTERNAL(name, args_name, nargout_name, is_text_fcn, doc) \ DECLARE_FUN (name, args_name, nargout_name) +#define DEFCONSTFUN_INTERNAL(name, args_name, nargout_name, is_text_fcn, doc) \ + DECLARE_FUN (name, args_name, nargout_name) + #define DEFUNX_INTERNAL(name, fname, args_name, nargout_name, \ is_text_fcn, doc) \ DECLARE_FUNX (fname, args_name, nargout_name)
--- a/src/defun.cc +++ b/src/defun.cc @@ -97,7 +97,8 @@ void install_builtin_function (octave_builtin::fcn f, const std::string& name, - const std::string& doc, bool is_text_fcn) + const std::string& doc, bool is_text_fcn, + bool /* can_hide_function -- not yet implemented */) { symbol_record *sym_rec = fbi_sym_tab->lookup (name, true);
--- a/src/defun.h +++ b/src/defun.h @@ -101,6 +101,10 @@ #define DEFUN_TEXT DEFCMD +// This is a function with a name that can't be hidden by a variable. +#define DEFCONSTFUN(name, args_name, nargout_name, doc) \ + DEFCONSTFUN_INTERNAL (name, args_name, nargout_name, true, doc) + // Define a mapper function. // // name is the name of the function, unquoqted.
--- a/src/lex.h +++ b/src/lex.h @@ -162,6 +162,9 @@ // multi-value assignment statement. bool looking_at_matrix_or_assign_lhs; + // TRUE means we're parsing an indexing operation for an object. + bool looking_at_object_index; + // GAG. Stupid kludge so that [[1,2][3,4]] will work. bool do_comma_insert;
--- a/src/lex.l +++ b/src/lex.l @@ -1108,7 +1108,10 @@ break; case end_kw: - yylval.tok_val = new token (token::simple_end, l, c); + if (lexer_flags.looking_at_object_index) + return 0; + else + yylval.tok_val = new token (token::simple_end, l, c); break; case end_try_catch_kw: @@ -2383,7 +2386,11 @@ } } - // Find the token in the symbol table. + // Find the token in the symbol table. Beware the magic + // transformation of the end keyword... + + if (tok == "end") + tok = "__end__"; yylval.tok_val = new token (lookup_identifier (tok), input_line_number, @@ -2538,6 +2545,9 @@ // assignment statement. looking_at_matrix_or_assign_lhs = false; + // Not parsing an object index. + looking_at_object_index = false; + // Next token can be identifier. cant_be_identifier = false;
--- a/src/mkbuiltins +++ b/src/mkbuiltins @@ -42,12 +42,17 @@ #define XDEFUN_INTERNAL(name, args_name, nargout_name, is_text_fcn, doc) \ extern DECLARE_FUN (name, args_name, nargout_name); \ - install_builtin_function (F ## name, #name, doc, is_text_fcn); \ + install_builtin_function (F ## name, #name, doc, is_text_fcn); \ + +#define XDEFCONSTFUN_INTERNAL(name, args_name, nargout_name, \ + is_text_fcn, doc) \ + extern DECLARE_FUN (name, args_name, nargout_name); \ + install_builtin_function (F ## name, #name, doc, is_text_fcn, false); \ #define XDEFUNX_INTERNAL(name, fname, args_name, nargout_name, \ is_text_fcn, doc) \ extern DECLARE_FUNX (fname, args_name, nargout_name); \ - install_builtin_function (fname, name, doc, is_text_fcn); \ + install_builtin_function (fname, name, doc, is_text_fcn); \ #define XDEFALIAS_INTERNAL(alias, name) \ alias_builtin (#alias, #name);
--- a/src/mkgendoc +++ b/src/mkgendoc @@ -24,6 +24,10 @@ #define XDEFUN_INTERNAL(name, args_name, nargout_name, is_text_fcn, doc) \ print_doc_string (#name, doc); +#define XDEFCONSTFUN_INTERNAL(name, args_name, nargout_name, \ + is_text_fcn, doc) \ + print_doc_string (#name, doc); + #define XDEFUNX_INTERNAL(name, fname, args_name, nargout_name, \ is_text_fcn, doc) \ print_doc_string (name, doc);
--- a/src/oct-lvalue.h +++ b/src/oct-lvalue.h @@ -85,6 +85,8 @@ octave_value value (void) { return idx.empty () ? *val : val->subsref (type, idx); } + const octave_value *object (void) const { return val; } + private: octave_value *val;
--- a/src/parse.y +++ b/src/parse.y @@ -705,16 +705,26 @@ { lexer_flags.looking_at_indirect_ref = true; } ; +begin_obj_idx : // empty + { lexer_flags.looking_at_object_index = true; } + ; + postfix_expr : primary_expr { $$ = $1; } - | postfix_expr '(' ')' + | postfix_expr '(' begin_obj_idx ')' { $$ = make_index_expression ($1, 0, '('); } - | postfix_expr '(' arg_list ')' - { $$ = make_index_expression ($1, $3, '('); } - | postfix_expr '{' '}' + | postfix_expr '(' begin_obj_idx arg_list ')' + { + $$ = make_index_expression ($1, $4, '('); + lexer_flags.looking_at_object_index = false; + } + | postfix_expr '{' begin_obj_idx '}' { $$ = make_index_expression ($1, 0, '{'); } - | postfix_expr '{' arg_list '}' - { $$ = make_index_expression ($1, $3, '{'); } + | postfix_expr '{' begin_obj_idx arg_list '}' + { + $$ = make_index_expression ($1, $4, '{'); + lexer_flags.looking_at_object_index = false; + } | postfix_expr PLUS_PLUS { $$ = make_postfix_op (PLUS_PLUS, $1, $2); } | postfix_expr MINUS_MINUS
--- a/src/pt-arg-list.cc +++ b/src/pt-arg-list.cc @@ -33,6 +33,7 @@ #include "str-vec.h" +#include "defun.h" #include "error.h" #include "oct-obj.h" #include "ov.h" @@ -42,6 +43,7 @@ #include "pt-pr-code.h" #include "pt-walk.h" #include "toplev.h" +#include "unwind-prot.h" // Argument lists. @@ -88,9 +90,51 @@ return true; } +static const octave_value *indexed_object = 0; +static int index_position = 0; + +DEFCONSTFUN (__end__, , , + "internal function") +{ + octave_value retval; + + if (indexed_object) + { + switch (index_position) + { + case -1: + // XXX FIXME XXX -- we really want "numel" here. + retval = indexed_object->rows () * indexed_object->columns (); + break; + + case 0: + retval = indexed_object->rows (); + break; + + case 1: + retval = indexed_object->columns (); + break; + + default: + ::error ("__end__: internal error"); + break; + } + } + else + ::error ("__end__: internal error"); + + return retval; +} + octave_value_list -tree_argument_list::convert_to_const_vector (void) +tree_argument_list::convert_to_const_vector (const octave_value *object) { + unwind_protect::begin_frame ("convert_to_const_vector"); + + unwind_protect_ptr (indexed_object); + + indexed_object = object; + int len = length (); // XXX FIXME XXX -- would be nice to know in advance how largs args @@ -105,6 +149,8 @@ int j = 0; for (int k = 0; k < len; k++) { + index_position = (len == 1) ? -1 : k; + tree_expression *elt = *p++; if (elt) @@ -160,6 +206,8 @@ args.resize (j); + unwind_protect::run_frame ("convert_to_const_vector"); + return args; }
--- a/src/pt-arg-list.h +++ b/src/pt-arg-list.h @@ -63,7 +63,7 @@ bool all_elements_are_constant (void) const; - octave_value_list convert_to_const_vector (void); + octave_value_list convert_to_const_vector (const octave_value *object = 0); string_vector get_arg_names (void) const;
--- a/src/pt-idx.cc +++ b/src/pt-idx.cc @@ -148,12 +148,13 @@ } static inline octave_value_list -make_value_list (tree_argument_list *args, const string_vector& arg_nm) +make_value_list (tree_argument_list *args, const string_vector& arg_nm, + const octave_value *object) { octave_value_list retval; if (args) - retval = args->convert_to_const_vector (); + retval = args->convert_to_const_vector (object); if (! error_state) { @@ -274,11 +275,11 @@ switch (type[i]) { case '(': - idx.push_back (make_value_list (*p_args, *p_arg_nm)); + idx.push_back (make_value_list (*p_args, *p_arg_nm, &tmp)); break; case '{': - idx.push_back (make_value_list (*p_args, *p_arg_nm)); + idx.push_back (make_value_list (*p_args, *p_arg_nm, &tmp)); break; case '.': @@ -335,42 +336,44 @@ std::list<string_vector>::iterator p_arg_nm = arg_nm.begin (); std::list<tree_expression *>::iterator p_dyn_field = dyn_field.begin (); - for (int i = 0; i < n; i++) - { - switch (type[i]) - { - case '(': - idx.push_back (make_value_list (*p_args, *p_arg_nm)); - break; - - case '{': - idx.push_back (make_value_list (*p_args, *p_arg_nm)); - break; - - case '.': - { - idx.push_back (octave_value (get_struct_index (p_arg_nm, p_dyn_field))); - - if (error_state) - eval_error (); - } - break; - - default: - panic_impossible (); - } - - if (error_state) - break; - - p_args++; - p_arg_nm++; - p_dyn_field++; - } + retval = expr->lvalue (); if (! error_state) { - retval = expr->lvalue (); + const octave_value *tmp = retval.object (); + + for (int i = 0; i < n; i++) + { + switch (type[i]) + { + case '(': + idx.push_back (make_value_list (*p_args, *p_arg_nm, tmp)); + break; + + case '{': + idx.push_back (make_value_list (*p_args, *p_arg_nm, tmp)); + break; + + case '.': + { + idx.push_back (octave_value (get_struct_index (p_arg_nm, p_dyn_field))); + + if (error_state) + eval_error (); + } + break; + + default: + panic_impossible (); + } + + if (error_state) + break; + + p_args++; + p_arg_nm++; + p_dyn_field++; + } if (! error_state) retval.set_index (type, idx);
--- a/src/symtab.cc +++ b/src/symtab.cc @@ -332,15 +332,14 @@ alias (tmp_sym); } - octave_lvalue symbol_record::variable_reference (void) { - if (Vvariables_can_hide_functions <= 0 + if ((Vvariables_can_hide_functions <= 0 || ! can_hide_function) && (is_function () || (! is_defined () && is_valid_function (nm)))) { - if (Vvariables_can_hide_functions < 0) + if (Vvariables_can_hide_functions < 0 && can_hide_function) warning ("variable `%s' hides function", nm.c_str ()); else {
--- a/src/symtab.h +++ b/src/symtab.h @@ -221,13 +221,16 @@ symbol_record (void) : formal_param (0), linked_to_global (0), tagged_static (0), - nm (), chg_fcn (0), definition (new symbol_def ()), - next_elem (0) { } + can_hide_function (1), nm (), chg_fcn (0), + definition (new symbol_def ()), next_elem (0) { } + + // XXX FIXME XXX -- kluge alert! We obviously need a better way of + // handling allow_shadow! symbol_record (const std::string& n, symbol_record *nxt) : formal_param (0), linked_to_global (0), tagged_static (0), - nm (n), chg_fcn (0), definition (new symbol_def ()), - next_elem (nxt) { } + can_hide_function (n != "__end__"), nm (n), chg_fcn (0), + definition (new symbol_def ()), next_elem (nxt) { } ~symbol_record (void) { } @@ -356,6 +359,7 @@ unsigned int formal_param : 1; unsigned int linked_to_global : 1; unsigned int tagged_static : 1; + unsigned int can_hide_function : 1; std::string nm; change_function chg_fcn;