Mercurial > octave
changeset 22893:5ff6716cf157
allow dispatch types to be declared for built-in functions
* mk-builtins.pl, gendoc.pl: Handle "classes: NAME ..." info in DEFUN
macros.
* defun-int.h, defun.cc (install_builtin_dispatch): New function.
symtab.h (symbol_tableinstall_built_in_dispatch,
symbol_table::fcn_info::install_built_in_dispatch,
symbol_table::fcn_info::fcn_info_rep::install_built_in_dispatch):
New functions.
* svd.cc (Fsvd): Add "classes: double single" tag prior to doc: comment.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 14 Dec 2016 14:59:27 -0500 |
parents | 5521b8a271ae |
children | 0ab9eecbb165 |
files | build-aux/mk-builtins.pl libinterp/corefcn/defun-int.h libinterp/corefcn/defun.cc libinterp/corefcn/svd.cc libinterp/corefcn/symtab.h libinterp/gendoc.pl |
diffstat | 6 files changed, 102 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/build-aux/mk-builtins.pl Wed Dec 14 13:27:08 2016 -0500 +++ b/build-aux/mk-builtins.pl Wed Dec 14 14:59:27 2016 -0500 @@ -178,28 +178,30 @@ $name = ""; $alias = ""; - while (<$fh>) + %dispatch_map = (); + + while ($line = <$fh>) { - if (/^ *DEFUN *\( *([^ ,]*) *,.*$/) + if ($line =~ /^ *DEFUN *\( *([^ ,]*) *,.*$/) { $type = "fun"; $fname = "F$1"; $name = "$1"; } - elsif (/^ *DEFUNX *\( *"([^"]*)" *, *([^ ,]*) *,.*$/) + elsif ($line =~ /^ *DEFUNX *\( *"([^"]*)" *, *([^ ,]*) *,.*$/) { $type = "fun"; $fname = "$2"; $name = "$1"; } - elsif (/^ *DEFCONSTFUN *\( *([^ ,]*) *,.*$/) + elsif ($line =~ /^ *DEFCONSTFUN *\( *([^ ,]*) *,.*$/) { $type = "fun"; $fname = "F$1"; $name = "$1"; $const = 1; } - elsif (/^ *DEFALIAS *\( *([^ ,]*) *, *([^ )]*) *\).*$/) + elsif ($line =~ /^ *DEFALIAS *\( *([^ ,]*) *, *([^ )]*) *\).*$/) { $type = "alias"; $alias = "$1"; @@ -207,13 +209,13 @@ } elsif ($defun_dld_are_built_in) { - if (/^ *DEFUN_DLD *\( *([^ ,]*) *,.*$/) + if ($line =~ /^ *DEFUN_DLD *\( *([^ ,]*) *,.*$/) { $type = "fun"; $fname = "F$1"; $name = "$1"; } - elsif (/^ *DEFUNX_DLD *\( *"([^"]*)" *, *([^ ,]*) *,.*$/) + elsif ($line =~ /^ *DEFUNX_DLD *\( *"([^"]*)" *, *([^ ,]*) *,.*$/) { $type = "fun"; $fname = "$2"; @@ -223,6 +225,15 @@ if ($type eq "fun") { + if (($line = <$fh>) =~ /^ *classes:/) + { + $line =~ s/\s*classes:\s*//; + $line =~ s/\s*$//; + @classes = split (/\s+/, $line); + + $dispatch_map{$name} = [@classes]; + } + ## We use the name appended to the "external-doc" tag to find ## the docstring for aliases to this function. @@ -244,11 +255,34 @@ { print " alias_builtin (\"$alias\", \"$name\");\n"; + ## Preserve dispatch info (if any) that we have for the + ## original function. + + @classes = @{$dispatch_map{$name}}; + + if (@classes) + { + $dispatch_map{$alias} = [@classes]; + } + $type = ""; $name = ""; $alias = ""; } } + + foreach $fcn (keys %dispatch_map) + { + print "\n"; + + @classes = @{$dispatch_map{$fcn}}; + + foreach $class (@classes) + { + print " install_builtin_dispatch (\"$fcn\", \"$class\");\n"; + } + } + print "}\n"; }
--- a/libinterp/corefcn/defun-int.h Wed Dec 14 13:27:08 2016 -0500 +++ b/libinterp/corefcn/defun-int.h Wed Dec 14 14:59:27 2016 -0500 @@ -57,6 +57,9 @@ extern OCTINTERP_API void alias_builtin (const std::string& alias, const std::string& name); +extern OCTINTERP_API void +install_builtin_dispatch (const std::string& name, const std::string& klass); + // Gets the shlib of the currently executing DLD function, if any. extern OCTINTERP_API octave::dynamic_library get_current_shlib (void);
--- a/libinterp/corefcn/defun.cc Wed Dec 14 13:27:08 2016 -0500 +++ b/libinterp/corefcn/defun.cc Wed Dec 14 14:59:27 2016 -0500 @@ -124,6 +124,12 @@ symbol_table::alias_built_in_function (alias, name); } +void +install_builtin_dispatch (const std::string& name, const std::string& klass) +{ + symbol_table::install_built_in_dispatch (name, klass); +} + octave::dynamic_library get_current_shlib (void) {
--- a/libinterp/corefcn/svd.cc Wed Dec 14 13:27:08 2016 -0500 +++ b/libinterp/corefcn/svd.cc Wed Dec 14 14:59:27 2016 -0500 @@ -66,6 +66,7 @@ } DEFUN (svd, args, nargout, + classes: double single doc: /* -*- texinfo -*- @deftypefn {} {@var{s} =} svd (@var{A}) @deftypefnx {} {[@var{U}, @var{S}, @var{V}] =} svd (@var{A})
--- a/libinterp/corefcn/symtab.h Wed Dec 14 13:27:08 2016 -0500 +++ b/libinterp/corefcn/symtab.h Wed Dec 14 14:59:27 2016 -0500 @@ -853,6 +853,21 @@ built_in_function = f; } + void install_built_in_dispatch (const std::string& klass) + { + if (built_in_function.is_defined ()) + { + if (class_methods.find (klass) != class_methods.end ()) + warning ("install_built_in_dispatch: '%s' already defined for class '%s'", + name.c_str (), klass.c_str ()); + else + class_methods[klass] = built_in_function; + } + else + error ("install_built_in_dispatch: '%s' is not a built-in function", + name.c_str ()); + } + template <typename T> void clear_map (std::map<T, octave_value>& map, bool force = false) @@ -1080,6 +1095,11 @@ rep->install_built_in_function (f); } + void install_built_in_dispatch (const std::string& klass) + { + rep->install_built_in_dispatch (klass); + } + void clear (bool force = false) { rep->clear (force); } void clear_user_function (bool force = false) @@ -1789,6 +1809,21 @@ panic ("alias: '%s' is undefined", name.c_str ()); } + static void install_built_in_dispatch (const std::string& name, + const std::string& klass) + { + fcn_table_iterator p = fcn_table.find (name); + + if (p != fcn_table.end ()) + { + fcn_info& finfo = p->second; + + finfo.install_built_in_dispatch (klass); + } + else + error ("install_built_in_dispatch: '%s' is undefined", name.c_str ()); + } + static void push_context (scope_id scope = xcurrent_scope) { if (scope == xglobal_scope || scope == xtop_scope)
--- a/libinterp/gendoc.pl Wed Dec 14 13:27:08 2016 -0500 +++ b/libinterp/gendoc.pl Wed Dec 14 14:59:27 2016 -0500 @@ -46,15 +46,23 @@ @func_list = (); @docstr = (); - LINE: while (<SRC_FH>) + LINE: while (my $line = <SRC_FH>) { - if (/^\s*DEF(?:CONSTFUN|UN|UN_DLD|UNX|UNX_DLD)\s*\(/) + if ($line =~ /^\s*DEF(?:CONSTFUN|UN|UN_DLD|UNX|UNX_DLD)\s*\(/) { - ($func) = /\("?(\w+)"?,/; + ($func) = $line =~ /\("?(\w+)"?,/; unless ($func) { die "Unable to parse $src_fname at line $.\n" } push (@func_list, $func); - if (<SRC_FH> =~ m#\s*doc:\s+\Q/*\E\s+\Q-*- texinfo -*-\E\s*$#) + ## Skip optional line that declares list of classes that this + ## function accepts. + $line = <SRC_FH>; + if ($line =~ m#\s*classes:#) + { + $line = <SRC_FH>; + } + + if ($line =~ m#\s*doc:\s+\Q/*\E\s+\Q-*- texinfo -*-\E\s*$#) { $str = "-*- texinfo -*-\n"; $reading_docstring = 1; @@ -67,15 +75,15 @@ } elsif ($reading_docstring) { - if (/^.*\s+\*\/\s*\)\s*$/) + if ($line =~ /^.*\s+\*\/\s*\)\s*$/) { - s#\s+\*/\s*\)\s*$##; - push (@docstr, $str . $_); + $line =~ s#\s+\*/\s*\)\s*$##; + push (@docstr, $str . $line); $reading_docstring = 0; } else { - $str .= $_; + $str .= $line; } } }