# HG changeset patch # User Michael Goffioul # Date 1356302586 18000 # Node ID 5861c4bde387f340c30b3db9a01019de13d6cc7a # Parent af9e2ad52943dc99a91c738ca8daa743f26b0722 Move classdef related source files to correct location. diff -r af9e2ad52943 -r 5861c4bde387 libinterp/octave-value/ov-classdef.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libinterp/octave-value/ov-classdef.cc Sun Dec 23 17:43:06 2012 -0500 @@ -0,0 +1,1454 @@ +/* + +Copyright (C) 2012 Michael Goffioul + +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 + +#include "defun.h" +#include "ov-builtin.h" +#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; + +static void +gripe_method_access (const std::string& from, const cdef_method& meth) +{ + error ("%s: method `%s' has %s access and cannot be run in this context", + from.c_str (), meth.get_name ().c_str (), + meth.get_access ().c_str ()); +} + +static void +gripe_property_access (const std::string& from, const cdef_property& prop, + bool is_set = false) +{ + if (is_set) + error ("%s: property `%s' has %s access and cannot be set in this context", + from.c_str (), prop.get_name ().c_str (), + prop.get_set_access ().c_str ()); + else + error ("%s: property `%s' has %s access and cannot be obtained in this context", + from.c_str (), prop.get_name ().c_str (), + prop.get_get_access ().c_str ()); +} + +static octave_value +make_fcn_handle (octave_builtin::fcn ff, const std::string& nm) +{ + octave_value fcn (new octave_builtin (ff, nm)); + + octave_value fcn_handle (new octave_fcn_handle (fcn, nm)); + + return fcn_handle; +} + +inline octave_value_list +execute_ov (octave_value val, const octave_value_list& args, int nargout) +{ + std::list idx (1, args); + + std::string type ("("); + + return val.subsref (type, idx, nargout); +} + +static bool +check_access (const std::string& req, const std::string& acc) +{ + if (req == "private") + return true; + else if (req == "protected") + return (acc != "private"); + else + return (acc == "public"); +} + +static std::string +get_base_name (const std::string& nm) +{ + std::string::size_type pos = nm.find_last_of ('.'); + + if (pos != std::string::npos) + return nm.substr (pos + 1); + + return nm; +} + +static std::string +superclass_access (const std::string& acc) +{ + if (acc == "public") + return acc; + else + return "protected"; +} + +static cdef_class +lookup_class (const std::string& name, bool error_if_not_found = true) +{ + std::map::iterator it = all_classes.find (name); + + if (it == all_classes.end ()) + { + // FIXME: should look into load-path + if (error_if_not_found) + error ("class not found: %s", name.c_str ()); + } + else + { + cdef_class& cls = it->second; + + if (! cls.is_builtin ()) + { + // FIXME: check whether a class reload is needed + } + + if (cls.ok ()) + return cls; + else + all_classes.erase (it); + } + + return cdef_class (); +} + +static Cell +lookup_classes (const Cell& cls_names) +{ + Cell cls (cls_names.numel (), 1); + + for (int i = 0; i < cls_names.numel (); i++) + { + cdef_class c = lookup_class (cls_names(i).string_value ()); + + if (! error_state) + cls(i) = to_ov (c); + else + return Cell (); + } + + return cls; +} + +static bool +is_superclass (const cdef_class& clsa, const cdef_class& clsb, + bool allow_equal = true) +{ + if (allow_equal && clsa == clsb) + return true; + else + { + Cell c = clsb.get ("SuperClasses").cell_value (); + + bool retval = false; + + for (int i = 0; ! retval && i < c.numel (); i++) + { + cdef_class cls = lookup_class (c(i).string_value ()); + + if (! error_state) + retval = is_superclass (clsa, cls, true); + } + + return retval; + } +} + +inline bool +is_strict_superclass (const cdef_class& clsa, const cdef_class& clsb) +{ return is_superclass (clsa, clsb, false); } + +static octave_value_list +class_get_properties (const octave_value_list& args, int /* nargout */) +{ + octave_value_list retval; + + if (args.length () == 1 && args(0).type_name () == "object") + { + cdef_class cls (to_cdef (args(0))); + + retval(0) = cls.get_properties (); + } + + return retval; +} + +static octave_value_list +class_get_methods (const octave_value_list& args, int /* nargout */) +{ + octave_value_list retval; + + if (args.length () == 1 && args(0).type_name () == "object") + { + cdef_class cls (to_cdef (args(0))); + + retval(0) = cls.get_methods (); + } + + return retval; +} + +static octave_value_list +class_get_superclasses (const octave_value_list& args, int /* nargout */) +{ + octave_value_list retval; + + if (args.length () == 1 && args(0).type_name () == "object" + && args(0).class_name () == "meta.class") + { + cdef_class cls (to_cdef (args(0))); + + Cell classes = cls.get ("SuperClasses").cell_value (); + + retval(0) = lookup_classes (classes); + } + + return retval; +} + +static octave_value_list +class_get_inferiorclasses (const octave_value_list& args, int /* nargout */) +{ + octave_value_list retval; + + if (args.length () == 1 && args(0).type_name () == "object" + && args(0).class_name () == "meta.class") + { + cdef_class cls (to_cdef (args(0))); + + Cell classes = cls.get ("InferiorClasses").cell_value (); + + retval(0) = lookup_classes (classes); + } + + return retval; +} + +static octave_value_list +class_fromName (const octave_value_list& args, int /* nargout */) +{ + octave_value_list retval; + + if (args.length () == 1) + { + std::string name = args(0).string_value (); + + if (! error_state) + retval(0) = to_ov (lookup_class (name)); + else + error ("fromName: invalid class name, expected a string value"); + } + else + error ("fromName: invalid number of parameters"); + + return retval; +} + +static octave_value_list +class_fevalStatic (const octave_value_list& args, int nargout) +{ + octave_value_list retval; + + if (args.length () > 1 && args(0).type_name () == "object") + { + cdef_class cls (to_cdef (args(0))); + + if (! error_state) + { + std::string meth_name = args(1).string_value (); + + if (! error_state) + { + cdef_method meth = cls.find_method (meth_name); + + if (meth.ok ()) + { + // FIXME: can the context be something else? + if (meth.check_access ("public")) + { + if (meth.is_static ()) + retval = meth.execute (args.splice (0, 2), nargout); + else + error ("fevalStatic: method `%s' is not static", + meth_name.c_str ()); + } + else + gripe_method_access ("fevalStatic", meth); + } + else + error ("fevalStatic: method not found: %s", + meth_name.c_str ()); + } + else + error ("fevalStatic: invalid method name, expected a string value"); + } + error ("fevalStatic: invalid object, expected a meta.class object"); + } + else + error ("fevalStatic: invalid arguments"); + + return retval; +} + +static octave_value_list +class_getConstant (const octave_value_list& args, int /* nargout */) +{ + octave_value_list retval; + + if (args.length () == 2 && args(0).type_name () == "object" + && args(0).class_name () == "meta.class") + { + cdef_class cls = to_cdef (args(0)); + + if (! error_state) + { + std::string prop_name = args(1).string_value (); + + if (! error_state) + { + cdef_property prop = cls.find_property (prop_name); + + if (prop.ok ()) + { + // FIXME: can the context be something else? + if (prop.check_get_access ("public")) + { + if (prop.is_constant ()) + retval(0) = prop.get_value (); + else + error ("getConstant: property `%s' is not constant", + prop_name.c_str ()); + } + else + gripe_property_access ("getConstant", prop); + } + else + error ("getConstant: property not found: %s", + prop_name.c_str ()); + } + else + error ("getConstant: invalid property name, expected a string value"); + } + else + error ("getConstant: invalid object, expected a meta.class object"); + } + else + error ("getConstant: invalid arguments"); + + return retval; +} + +#define META_CLASS_CMP(OP, CLSA, CLSB, FUN) \ +static octave_value_list \ +class_ ## OP (const octave_value_list& args, int /* nargout */) \ +{ \ + octave_value_list retval; \ +\ + if (args.length () == 2 \ + && args(0).type_name () == "object" && args(1).type_name () == "object" \ + && args(0).class_name () == "meta.class" && args(1).class_name () == "meta.class") \ + { \ + cdef_class clsa = to_cdef (args(0)); \ +\ + cdef_class clsb = to_cdef (args(1)); \ +\ + if (! error_state) \ + retval(0) = FUN (CLSA, CLSB); \ + else \ + error (#OP ": invalid objects, expected meta.class objects"); \ + } \ + else \ + error (#OP ": invalid arguments"); \ +\ + return retval; \ +} + +META_CLASS_CMP (lt, clsb, clsa, is_strict_superclass) +META_CLASS_CMP (le, clsb, clsa, is_superclass) +META_CLASS_CMP (gt, clsa, clsb, is_strict_superclass) +META_CLASS_CMP (ge, clsa, clsb, is_superclass) +META_CLASS_CMP (eq, clsa, clsb, operator==) +META_CLASS_CMP (ne, clsa, clsb, operator!=) + +static octave_value_list +handle_delete (const octave_value_list& /* args */, int /* nargout */) +{ + octave_value_list retval; + + // FIXME: implement this + + return retval; +} + +static cdef_class +make_class (const std::string& name, const std::string& super = std::string()) +{ + cdef_class cls ("meta.class"); + + all_classes[name] = cls; + cls.put ("ConstructOnLoad", false); + cls.put ("ContainingPackage", Matrix ()); + cls.put ("Description", std::string ()); + cls.put ("DetailedDescription", std::string ()); + cls.put ("Events", Cell ()); + cls.put ("Hidden", false); + cls.put ("InferiorClasses", Cell ()); + cls.put ("Methods", Cell ()); + cls.put ("Name", name); + cls.put ("Properties", Cell ()); + cls.put ("Sealed", true); + if (super.empty ()) + cls.put ("SuperClasses", Cell ()); + else + cls.put ("SuperClasses", Cell (octave_value (super))); + + return cls; +} + +static cdef_property +make_property (const cdef_object& cls, const std::string& name, + const octave_value& get_method = Matrix (), + const std::string& get_access = "public", + const octave_value& set_method = Matrix (), + const std::string& set_access = "public") +{ + // FIXME: what about default value? + + cdef_property prop ("meta.property"); + + prop.put ("Name", name); + prop.put ("Description", std::string ()); + prop.put ("DetailedDescription", std::string ()); + prop.put ("Abstract", false); + prop.put ("Constant", false); + prop.put ("GetAccess", get_access); + prop.put ("SetAccess", set_access); + prop.put ("Dependent", false); + prop.put ("Transient", false); + prop.put ("Hidden", false); + prop.put ("GetObservable", false); + prop.put ("SetObservable", false); + prop.put ("GetMethod", get_method); + prop.put ("SetMethod", set_method); + prop.put ("DefiningClass", to_ov (cls)); + + return prop; +} + +inline cdef_property +make_attribute (const cdef_object& cls, const std::string& name) +{ + return make_property (cls, name, Matrix (), "public", Matrix (), "private"); +} + +static cdef_method +make_method (const cdef_object& cls, const std::string& name, const octave_value& fcn, + const std::string& m_access = "public", bool is_static = false) +{ + cdef_method meth ("meta.method"); + + meth.put ("Abstract", false); + meth.put ("Access", m_access); + meth.put ("DefiningClass", to_ov (cls)); + meth.put ("Description", std::string ()); + meth.put ("DetailedDescription", std::string ()); + meth.put ("Hidden", false); + meth.put ("Name", name); + meth.put ("Sealed", true); + meth.put ("Static", is_static); + + meth.set_function (fcn); + + return meth; +} + +inline cdef_method +make_method (const cdef_object& cls, const std::string& name, octave_builtin::fcn ff, + const std::string& m_access = "public", bool is_static = false) +{ + octave_value fcn (new octave_builtin (ff, name)); + + octave_value fcn_handle (new octave_fcn_handle (fcn, name)); + + return make_method (cls, name, fcn_handle, m_access, is_static); +} + +static cdef_package +make_package (const std::string& nm, + const std::string& parent = std::string ()) +{ + cdef_package pack ("meta.package"); + + all_packages[nm] = pack; + pack.put ("Name", nm); + pack.put ("ContainingPackage", to_ov (all_packages[parent])); + + return pack; +} + +DEFINE_OCTAVE_ALLOCATOR (octave_classdef); + +int octave_classdef::t_id (-1); + +const std::string octave_classdef::t_name ("object"); + +void +octave_classdef::register_type (void) +{ + t_id = octave_value_typeinfo::register_type + (octave_classdef::t_name, "", octave_value (new octave_classdef ())); +} + +cdef_class +cdef_object_rep::get_class (void) const +{ + cdef_class cls = lookup_class (class_name ()); + + return cls; +} + +string_vector +cdef_object_rep::map_keys (void) const +{ + cdef_class cls = get_class (); + + if (cls.ok ()) + return cls.get_names (); + + return string_vector (); +} + +octave_value_list +handle_cdef_object::subsref (const std::string& type, + const std::list& idx, + int nargout, int& skip) +{ + skip = 0; + + cdef_class cls = get_class (); + + octave_value_list retval; + + if (! cls.ok ()) + return retval; + + switch (type[0]) + { + case '.': + { + std::string name = (idx.front ())(0).string_value (); + + // FIXME: get the right context; context should also + // be linked to the current executing class (if any) + // such that protected/private methods found in inherited + // classes are correctly resolved. + std::string context = "public"; + + cdef_method meth = cls.find_method (name); + + if (meth.ok ()) + { + if (meth.check_access (context)) + { + int _nargout = (type.length () > 2 ? 1 : nargout); + + octave_value_list args; + + skip = 1; + + if (type.length () > 1 && type[1] == '(') + { + std::list::const_iterator it = idx.begin (); + + args = *++it; + + skip++; + } + + if (meth.is_static ()) + retval = meth.execute (args, _nargout); + else + { + refcount++; + retval = meth.execute (cdef_object (this), args, _nargout); + } + } + else + gripe_method_access ("subsref", meth); + } + + if (skip == 0 && ! error_state) + { + cdef_property prop = cls.find_property (name); + + if (prop.ok ()) + { + if (prop.check_get_access (context)) + { + refcount++; + retval(0) = prop.get_value (cdef_object (this)); + + skip = 1; + } + else + gripe_property_access ("subsref", prop); + } + else + error ("subsref: unknown method or property: %s", name.c_str ()); + } + break; + } + default: + error ("object cannot be indexed with `%c'", type[0]); + break; + } + + return retval; +} + +cdef_method +cdef_class::cdef_class_rep::find_method (const std::string& nm) +{ + method_iterator it = method_map.find (nm); + + if (it == method_map.end ()) + { + // FIXME: look into class directory + } + else + { + cdef_method& meth = it->second; + + // FIXME: check if method reload needed + + if (meth.ok ()) + return meth; + } + + // Look into superclasses + + Cell super_classes = get ("SuperClasses").cell_value (); + + for (int i = 0; i < super_classes.numel (); i++) + { + cdef_class cls = lookup_class (super_classes(i).string_value ()); + + if (! error_state) + { + cdef_method meth = cls.find_method (nm); + + if (meth.ok ()) + return meth; + } + } + + return cdef_method (); +} + +void +cdef_class::cdef_class_rep::install_method (const cdef_method& meth) +{ + method_map[meth.get_name ()] = meth; +} + +void +cdef_class::cdef_class_rep::load_all_methods (void) +{ + // FIXME: re-scan class directory +} + +Cell +cdef_class::cdef_class_rep::get_methods (void) +{ + std::map meths; + + std::map count; + + count["public"] = count["protected"] = count["private"] = 0; + + find_methods (meths, count); + + if (! error_state) + { + Cell c (count["public"] + count["protected"], 1); + + int idx = 0; + + for (std::map::const_iterator it = meths.begin (); + it != meths.end (); ++it) + if (::check_access ("protected", it->second.get_access ())) + c (idx++, 0) = to_ov (it->second); + + return c; + } + + return Cell (); +} + +void +cdef_class::cdef_class_rep::find_methods (std::map& meths, + std::map& count) +{ + load_all_methods (); + + method_const_iterator it; + + for (it = method_map.begin (); it != method_map.end (); ++it) + { + std::string nm = it->second.get_name (); + + if (meths.find (nm) == meths.end ()) + { + std::string acc = it->second.get_access (); + + meths[nm] = it->second; + count[acc]++; + } + } + + // Look into superclasses + + Cell super_classes = get ("SuperClasses").cell_value (); + + for (int i = 0; i < super_classes.numel (); i++) + { + cdef_class cls = lookup_class (super_classes(i).string_value ()); + + if (! error_state) + cls.get_rep ()->find_methods (meths, count); + else + break; + } +} + +cdef_property +cdef_class::cdef_class_rep::find_property (const std::string& nm) +{ + property_iterator it = property_map.find (nm); + + if (it != property_map.end ()) + { + cdef_property& prop = it->second; + + if (prop.ok ()) + return prop; + } + + // Look into superclasses + + Cell super_classes = get ("SuperClasses").cell_value (); + + for (int i = 0; i < super_classes.numel (); i++) + { + cdef_class cls = lookup_class (super_classes(i).string_value ()); + + if (! error_state) + { + cdef_property prop = cls.find_property (nm); + + if (prop.ok ()) + return prop; + } + } + + return cdef_property (); +} + +void +cdef_class::cdef_class_rep::install_property (const cdef_property& prop) +{ + property_map[prop.get_name ()] = prop; +} + +Cell +cdef_class::cdef_class_rep::get_properties (void) +{ + std::map props; + + std::map count; + + count["public"] = count["protected"] = count["private"] = 0; + + find_properties (props, count); + + if (! error_state) + { + Cell c (count["public"] + count["protected"], 1); + + int idx = 0; + + for (std::map::const_iterator it = props.begin (); + it != props.end (); ++it) + if (::check_access ("protected", it->second.get_get_access ())) + c (idx++, 0) = to_ov (it->second); + + return c; + } + + return Cell (); +} + +void +cdef_class::cdef_class_rep::find_properties (std::map& props, + std::map& count) +{ + property_const_iterator it; + + for (it = property_map.begin (); it != property_map.end (); ++it) + { + std::string nm = it->second.get_name (); + + if (props.find (nm) == props.end ()) + { + std::string acc = it->second.get_get_access (); + + props[nm] = it->second; + count[acc]++; + } + } + + // Look into superclasses + + Cell super_classes = get ("SuperClasses").cell_value (); + + for (int i = 0; i < super_classes.numel (); i++) + { + cdef_class cls = lookup_class (super_classes(i).string_value ()); + + if (! error_state) + cls.get_rep ()->find_properties (props, count); + else + break; + } +} + +void +cdef_class::cdef_class_rep::find_names (std::map& names, + std::map& count) +{ + load_all_methods (); + + for (method_const_iterator it = method_map.begin (); + it != method_map.end(); ++it) + { + std::string nm = it->second.get_name (); + + if (names.find (nm) == names.end ()) + { + std::string acc = it->second.get_access (); + + names[nm] = acc; + count[acc]++; + } + } + + for (property_const_iterator it = property_map.begin (); + it != property_map.end (); ++it) + { + std::string nm = it->second.get_name (); + + if (names.find (nm) == names.end ()) + { + std::string acc = it->second.get_get_access (); + + names[nm] = acc; + count[acc]++; + } + } + + // Look into superclasses + + Cell super_classes = get ("SuperClasses").cell_value (); + + for (int i = 0; i < super_classes.numel (); i++) + { + cdef_class cls = lookup_class (super_classes(i).string_value ()); + + if (! error_state) + cls.get_rep ()->find_names (names, count); + else + break; + } +} + +string_vector +cdef_class::cdef_class_rep::get_names (void) +{ + std::map names; + + std::map count; + + count["public"] = count["protected"] = count["private"] = 0; + + find_names (names, count); + + if (! error_state) + { + string_vector v (count["public"]); + + int idx = 0; + for (std::map::const_iterator it = names.begin (); + it != names.end (); ++it) + { + if (it->second == "public") + v[idx++] = it->first; + } + + return v.sort (true); + } + + return string_vector (); +} + +void +cdef_class::cdef_class_rep::delete_object (cdef_object obj) +{ + method_iterator it = method_map.find ("delete"); + + if (it != method_map.end ()) + { + std::string cls_name = obj.class_name (); + + obj.set_class_name (get ("Name").string_value ()); + + it->second.execute (obj, octave_value_list (), 0); + + obj.set_class_name (cls_name); + } + + // FIXME: should we destroy corresponding properties here? + + // Call "delete" in super classes + + Cell super_classes = get ("SuperClasses").cell_value (); + + for (int i = 0; i < super_classes.numel (); i++) + { + cdef_class cls = lookup_class (super_classes(i).string_value ()); + + if (!error_state) + cls.delete_object (obj); + } +} + +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) +{ + // FIXME: should check whether we're already in get accessor method + + octave_value retval; + + octave_value get_fcn = get ("GetMethod"); + + std::string get_access = get ("GetAccess").string_value (); + + if (get_access != "public") + { + // FIXME: should check the current call stack + } + + if (get_fcn.is_empty ()) + retval = obj.get (get ("Name").string_value ()); + else + { + octave_value_list args; + + args(0) = to_ov (obj); + + args = execute_ov (get_fcn, args, 1); + + if (! error_state) + retval = args(0); + } + + return retval; +} + +bool +cdef_property::check_get_access (const std::string& req) const +{ + return ::check_access (req, get_get_access ()); +} + +bool +cdef_property::check_set_access (const std::string& req) const +{ + return ::check_access (req, get_set_access ()); +} + +void +cdef_method::cdef_method_rep::check_method (void) +{ + // FIXME: check whether re-load is needed +} + +octave_value_list +cdef_method::cdef_method_rep::execute (const octave_value_list& args, + int nargout) +{ + octave_value_list retval; + + if (! get ("Abstract").bool_value ()) + { + check_method (); + + if (function.is_defined ()) + { + retval = execute_ov (function, args, nargout); + } + } + else + error ("%s: cannot execute abstract method", + get ("Name").string_value ().c_str ()); + + return retval; +} + +octave_value_list +cdef_method::cdef_method_rep::execute (const cdef_object& obj, + const octave_value_list& args, + int nargout) +{ + octave_value_list retval; + + if (! get ("Abstract").bool_value ()) + { + check_method (); + + octave_value_list new_args; + + if (function.is_defined ()) + { + new_args.resize (args.length () + 1); + + new_args(0) = to_ov (obj); + for (int i = 0; i < args.length (); i++) + new_args(i+1) = args(i); + + retval = execute_ov (function, new_args, nargout); + } + } + else + error ("%s: cannot execute abstract method", + get ("Name").string_value ().c_str ()); + + return retval; +} + +bool +cdef_method::check_access (const std::string& req) const +{ + return ::check_access (req, get_access ()); +} + +static cdef_package +lookup_package (const std::string& name) +{ + std::map::const_iterator it = all_packages.find (name); + + if (it != all_packages.end ()) + { + cdef_package pack = it->second; + + if (pack.ok ()) + return pack; + else + error ("invalid package: %s", name.c_str ()); + } + else + error ("package not found: %s", name.c_str ()); + + return cdef_package (); +} + +static octave_value_list +package_fromName (const octave_value_list& args, int /* nargout */) +{ + octave_value_list retval; + + if (args.length () == 1) + { + std::string name = args(0).string_value (); + + if (! error_state) + retval(0) = to_ov (lookup_package (name)); + else + error ("fromName: invalid package name, expected a string value"); + } + else + error ("fromName: invalid number of parameters"); + + return retval; +} + +static octave_value_list +package_get_classes (const octave_value_list& args, int /* nargout */) +{ + octave_value_list retval (1, Matrix ()); + + if (args.length () == 1 && args(0).type_name () == "object" + && args(0).class_name () == "meta.package") + { + cdef_package pack (to_cdef (args(0))); + + retval(0) = pack.get_classes (); + } + + return retval; +} + +static octave_value_list +package_get_functions (const octave_value_list& args, int /* nargout */) +{ + octave_value_list retval (1, Matrix ()); + + if (args.length () == 0 && args(0).type_name () == "object" + && args(0).class_name () == "meta.package") + { + cdef_package pack (to_cdef (args(0))); + + retval(0) = pack.get_functions (); + } + + return retval; +} + +static octave_value_list +package_get_packages (const octave_value_list& args, int /* nargout */) +{ + octave_value_list retval (1, Matrix ()); + + if (args.length () == 0 && args(0).type_name () == "object" + && args(0).class_name () == "meta.package") + { + cdef_package pack (to_cdef (args(0))); + + retval(0) = pack.get_packages (); + } + + return retval; +} + +void +cdef_package::cdef_package_rep::install_class (const cdef_class& cls, + const std::string& nm) +{ + class_map[nm] = cls; +} + +void +cdef_package::cdef_package_rep::install_function (const octave_value& fcn, + const std::string& nm) +{ + function_map[nm] = fcn; +} + +void +cdef_package::cdef_package_rep::install_package (const cdef_package& pack, + const std::string& nm) +{ + package_map[nm] = pack; +} + +octave_value_list +cdef_package::cdef_package_rep::subsref (const std::string& type, + const std::list& idx, + int nargout, int& skip) +{ + return handle_cdef_object::subsref (type, idx, nargout, skip); +} + +template +Cell +map2Cell (const std::map& m) +{ + Cell retval (1, m.size ()); + int i = 0; + + for (typename std::map::const_iterator it = m.begin (); + it != m.end (); ++it, ++i) + { + retval(i) = to_ov (it->second); + } + + return retval; +} + +Cell +cdef_package::cdef_package_rep::get_classes (void) const +{ return map2Cell (class_map); } + +Cell +cdef_package::cdef_package_rep::get_functions (void) const +{ return map2Cell (function_map); } + +Cell +cdef_package::cdef_package_rep::get_packages (void) const +{ return map2Cell (package_map); } + +octave_value_list +octave_classdef::subsref (const std::string& type, + const std::list& idx, + int nargout) +{ + int skip = 0; + octave_value_list retval; + + // FIXME: should check "subsref" method first + + retval = object.subsref (type, idx, nargout, skip); + + if (! error_state) + { + if (type.length () > skip && idx.size () > skip) + retval = retval(0).next_subsref (nargout, type, idx, skip); + } + + return retval; +} + +void +install_classdef (void) +{ + octave_classdef::register_type (); + + /* meta classes */ + cdef_class handle = make_class ("handle"); + cdef_class meta_class = make_class ("meta.class", "handle"); + cdef_class meta_property = make_class ("meta.property", "handle"); + cdef_class meta_method = make_class ("meta.method", "handle"); + cdef_class meta_event = make_class ("meta.event", "handle"); + cdef_class meta_package = make_class ("meta.package", "handle"); + cdef_class meta_dynproperty = make_class ("meta.dynamicproperty", "handle"); + + /* meta.class properties */ + meta_class.install_property (make_attribute (meta_class, "ConstructOnLoad")); + meta_class.install_property (make_property (meta_class, "ContainingPackage")); + meta_class.install_property (make_property (meta_class, "Description")); + meta_class.install_property (make_property (meta_class, "DetailedDescription")); + meta_class.install_property (make_property (meta_class, "Events")); + meta_class.install_property (make_attribute (meta_class, "Hidden")); + meta_class.install_property + (make_property (meta_class, "InferiorClasses", + make_fcn_handle (class_get_inferiorclasses, "meta.class>get.InferiorClasses"), + "public", Matrix (), "private")); + meta_class.install_property + (make_property (meta_class, "Methods", + make_fcn_handle (class_get_methods, "meta.class>get.Methods"), + "public", Matrix (), "private")); + meta_class.install_property + (make_property (meta_class, "MethodList", + make_fcn_handle (class_get_methods, "meta.class>get.MethodList"), + "public", Matrix (), "private")); + meta_class.install_property (make_attribute (meta_class, "Name")); + meta_class.install_property + (make_property (meta_class, "Properties", + make_fcn_handle (class_get_properties, "meta.class>get.Properties"), + "public", Matrix (), "private")); + meta_class.install_property + (make_property (meta_class, "PropertyList", + make_fcn_handle (class_get_properties, "meta.class>get.PropertyList"), + "public", Matrix (), "private")); + meta_class.install_property (make_attribute (meta_class, "Sealed")); + meta_class.install_property + (make_property (meta_class, "SuperClasses", + make_fcn_handle (class_get_superclasses, "meta.class>get.SuperClasses"), + "public", Matrix (), "private")); + meta_class.install_property + (make_property (meta_class, "SuperClassList", + make_fcn_handle (class_get_superclasses, "meta.class>get.SuperClassList"), + "public", Matrix (), "private")); + /* meta.class methods */ + meta_class.install_method (make_method (meta_class, "fromName", class_fromName, + "public", true)); + meta_class.install_method (make_method (meta_class, "fevalStatic", class_fevalStatic, + "public", false)); + meta_class.install_method (make_method (meta_class, "getConstant", class_getConstant, + "public", false)); + meta_class.install_method (make_method (meta_class, "eq", class_eq)); + meta_class.install_method (make_method (meta_class, "ne", class_ne)); + meta_class.install_method (make_method (meta_class, "lt", class_lt)); + meta_class.install_method (make_method (meta_class, "le", class_le)); + meta_class.install_method (make_method (meta_class, "gt", class_gt)); + meta_class.install_method (make_method (meta_class, "ge", class_ge)); + + /* meta.method properties */ + meta_method.install_property (make_attribute (meta_method, "Abstract")); + meta_method.install_property (make_attribute (meta_method, "Access")); + meta_method.install_property (make_attribute (meta_method, "DefiningClass")); + meta_method.install_property (make_attribute (meta_method, "Description")); + meta_method.install_property (make_attribute (meta_method, "DetailedDescription")); + meta_method.install_property (make_attribute (meta_method, "Hidden")); + meta_method.install_property (make_attribute (meta_method, "Name")); + meta_method.install_property (make_attribute (meta_method, "Sealed")); + meta_method.install_property (make_attribute (meta_method, "Static")); + + /* meta.property properties */ + meta_property.install_property (make_attribute (meta_property, "Name")); + meta_property.install_property (make_attribute (meta_property, "Description")); + meta_property.install_property (make_attribute (meta_property, "DetailedDescription")); + meta_property.install_property (make_attribute (meta_property, "Abstract")); + meta_property.install_property (make_attribute (meta_property, "Constant")); + meta_property.install_property (make_attribute (meta_property, "GetAccess")); + meta_property.install_property (make_attribute (meta_property, "SetAccess")); + meta_property.install_property (make_attribute (meta_property, "Dependent")); + meta_property.install_property (make_attribute (meta_property, "Transient")); + meta_property.install_property (make_attribute (meta_property, "Hidden")); + meta_property.install_property (make_attribute (meta_property, "GetObservable")); + meta_property.install_property (make_attribute (meta_property, "SetObservable")); + meta_property.install_property (make_attribute (meta_property, "GetMethod")); + meta_property.install_property (make_attribute (meta_property, "SetMethod")); + meta_property.install_property (make_attribute (meta_property, "DefiningClass")); + /* meta.property events */ + // FIXME: add events + + /* handle methods */ + handle.install_method (make_method (handle, "delete", handle_delete)); + + /* meta.package properties */ + meta_package.install_property (make_attribute (meta_package, "Name")); + meta_package.install_property (make_property (meta_package, "ContainingPackage")); + meta_package.install_property + (make_property (meta_package, "ClassList", + make_fcn_handle (package_get_classes, "meta.package>get.ClassList"), + "public", Matrix (), "private")); + meta_package.install_property + (make_property (meta_package, "Classes", + make_fcn_handle (package_get_classes, "meta.package>get.Classes"), + "public", Matrix (), "private")); + meta_package.install_property + (make_property (meta_package, "FunctionList", + make_fcn_handle (package_get_functions, "meta.package>get.FunctionList"), + "public", Matrix (), "private")); + meta_package.install_property + (make_property (meta_package, "Functions", + make_fcn_handle (package_get_functions, "meta.package>get.Functions"), + "public", Matrix (), "private")); + meta_package.install_property + (make_property (meta_package, "PackageList", + make_fcn_handle (package_get_packages, "meta.package>get.PackageList"), + "public", Matrix (), "private")); + meta_package.install_property + (make_property (meta_package, "Packages", + make_fcn_handle (package_get_packages, "meta.package>get.Packages"), + "public", Matrix (), "private")); + meta_package.install_method (make_method (meta_package, "fromName", package_fromName, + "public", true)); + + /* create "meta" package */ + cdef_package package_meta = make_package ("meta"); + package_meta.install_class (meta_class, "class"); + package_meta.install_class (meta_property, "property"); + package_meta.install_class (meta_method, "method"); + package_meta.install_class (meta_package, "package"); + package_meta.install_class (meta_event, "event"); + package_meta.install_class (meta_dynproperty, "dynproperty"); +} + +DEFUN (__meta_get_package__, args, , "") +{ + octave_value retval; + + if (args.length () == 1) + { + std::string cname = args(0).string_value (); + + if (! error_state) + retval = to_ov (lookup_package (cname)); + else + error ("invalid package name, expected a string value"); + } + else + print_usage (); + + 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++ *** +;;; End: *** +*/ diff -r af9e2ad52943 -r 5861c4bde387 libinterp/octave-value/ov-classdef.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libinterp/octave-value/ov-classdef.h Sun Dec 23 17:43:06 2012 -0500 @@ -0,0 +1,745 @@ +/* + +Copyright (C) 2012 Michael Goffioul + +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_classdef_h) +#define octave_classdef_h 1 + +#include + +#include "oct-map.h" +#include "oct-refcount.h" +#include "ov-base.h" + +class cdef_object; +class cdef_class; +class cdef_property; +class cdef_method; +class cdef_package; + +class tree_classdef; + +class +cdef_object_rep +{ +public: + friend class cdef_object; + +public: + cdef_object_rep (void) + : refcount (1), cname () { } + + cdef_object_rep (const std::string& nm) + : refcount (1), cname (nm) { } + + virtual ~cdef_object_rep (void) { } + + virtual cdef_class get_class (void) const; + + virtual void set_class (const cdef_object&) + { error ("set_class: invalid object"); } + + virtual cdef_object_rep* clone (void) const + { + error ("clone: invalid object"); + return new cdef_object_rep (); + } + + virtual void put (const std::string&, const octave_value&) + { error ("put: invalid object"); } + + virtual octave_value get (const std::string&) const + { + error ("get: invalid object"); + return octave_value (); + } + + virtual octave_value_list subsref (const std::string&, + const std::list&, + int, int&) + { + error ("subsref: invalid object"); + return octave_value_list (); + } + + virtual string_vector map_keys(void) const; + + virtual bool is_valid (void) const { return false; } + + std::string class_name (void) const { return cname; } + + void set_class_name (const std::string& nm) + { cname = nm; } + +protected: + /* reference count */ + octave_refcount refcount; + + /* class name */ + std::string cname; +}; + +class +cdef_object +{ +public: + /* FIXME: use a null object */ + cdef_object (void) + : rep (new cdef_object_rep ()) { } + + cdef_object (const cdef_object& obj) + : rep (obj.rep) + { + rep->refcount++; + } + + cdef_object (cdef_object_rep *r) + : rep (r) { } + + virtual ~cdef_object (void) + { + if (--rep->refcount == 0) + delete rep; + } + + cdef_object& operator = (const cdef_object& obj) + { + if (rep != obj.rep) + { + if (--rep->refcount == 0) + delete rep; + + rep = obj.rep; + rep->refcount++; + } + + return *this; + } + + cdef_class get_class (void) const; + + void set_class_name (const std::string& nm) + { rep->set_class_name (nm); } + + std::string class_name (void) const + { return rep->class_name (); } + + cdef_object clone (void) const + { return cdef_object (rep->clone ()); } + + void put (const std::string& pname, const octave_value& val) + { rep->put (pname, val); } + + octave_value get (const std::string& pname) const + { return rep->get (pname); } + + octave_value_list subsref (const std::string& type, + const std::list& idx, + int nargout, int& skip) + { return rep->subsref (type, idx, nargout, skip); } + + string_vector map_keys (void) const { return rep->map_keys (); } + + const cdef_object_rep* get_rep (void) const { return rep; } + + bool ok (void) const { return rep->is_valid (); } + +protected: + cdef_object_rep* get_rep (void) { return rep; } + +private: + cdef_object_rep *rep; +}; + +class +handle_cdef_object : public cdef_object_rep +{ +public: + handle_cdef_object (void) + : cdef_object_rep () { } + + handle_cdef_object (const std::string& nm) + : cdef_object_rep (nm) { } + + cdef_object_rep* clone (void) const + { + handle_cdef_object *obj = const_cast (this); + obj->refcount++; + return obj; + } + + void put (const std::string& pname, const octave_value& val) + { map.assign (pname, val); } + + octave_value get (const std::string& pname) const + { + Cell val = map.contents (pname); + + if (val.numel () > 0) + return val(0, 0); + else + { + error ("get: unknown slot: %s", pname.c_str ()); + return octave_value (); + } + } + + octave_value_list subsref (const std::string& type, + const std::list& idx, + int nargout, int& skip); + + bool is_valid (void) const { return true; } + +protected: + Octave_map map; +}; + +class +cdef_class : public cdef_object +{ +private: + + class + cdef_class_rep : public handle_cdef_object + { + public: + cdef_class_rep (const std::string& nm) + : handle_cdef_object (nm) { } + + cdef_method find_method (const std::string& nm); + + void install_method (const cdef_method& meth); + + Cell get_methods (void); + + cdef_property find_property (const std::string& nm); + + void install_property (const cdef_property& prop); + + Cell get_properties (void); + + string_vector get_names (void); + + void set_directory (const std::string& dir) { directory = dir; } + + std::string get_directory (void) const { return directory; } + + void delete_object (cdef_object obj); + + private: + void load_all_methods (void); + + void find_names (std::map& names, + std::map& count); + + void find_properties (std::map& props, + std::map& count); + + void find_methods (std::map& meths, + std::map& count); + + private: + std::string directory; + + std::map method_map; + + std::map property_map; + + typedef std::map::iterator method_iterator; + typedef std::map::const_iterator method_const_iterator; + typedef std::map::iterator property_iterator; + typedef std::map::const_iterator property_const_iterator; + }; + +public: + // Create and invalid class object + cdef_class (void) + : cdef_object () { } + + cdef_class (const std::string& nm) + : cdef_object (new cdef_class_rep (nm)) { } + + cdef_class (const cdef_class& cls) + : cdef_object (cls) { } + + cdef_class (const cdef_object& obj) + : cdef_object (obj) + { + // This should never happen... + if (class_name () != "meta.class") + error ("internal error: invalid assignment from %s to meta.class object", + class_name ().c_str ()); + } + + cdef_class& operator = (const cdef_class& cls) + { + cdef_object::operator= (cls); + + return *this; + } + + cdef_class& operator = (const cdef_object& obj) + { + if (obj.class_name () == "meta.class") + cdef_object::operator= (obj); + else + error ("internal error: invalid assignment from %s to meta.class object", + class_name ().c_str ()); + + return *this; + } + + cdef_method find_method (const std::string& nm); + + void install_method (const cdef_method& meth) + { get_rep ()->install_method (meth); } + + Cell get_methods (void) { return get_rep ()->get_methods (); } + + cdef_property find_property (const std::string& nm); + + void install_property (const cdef_property& prop) + { get_rep ()->install_property (prop); } + + Cell get_properties (void) { return get_rep ()->get_properties (); } + + string_vector get_names (void) { return get_rep ()->get_names (); } + + void set_directory (const std::string& dir) + { get_rep ()->set_directory (dir); } + + std::string get_directory (void) const + { return get_rep ()->get_directory (); } + + std::string get_name (void) const + { return get ("Name").string_value (); } + + bool is_builtin (void) const + { return get_directory ().empty (); } + + 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 ()); } + + const cdef_class_rep* get_rep (void) const + { return dynamic_cast (cdef_object::get_rep ()); } + + friend bool operator == (const cdef_class&, const cdef_class&); + friend bool operator != (const cdef_class&, const cdef_class&); +}; + +inline bool +operator == (const cdef_class& clsa, const cdef_class& clsb) +// FIXME: is this really the right way to check class equality? +{ return (clsa.get_rep () == clsb.get_rep ()); } + +inline bool +operator != (const cdef_class& clsa, const cdef_class& clsb) +{ return ! (clsa == clsb); } + +class +cdef_property : public cdef_object +{ +private: + + class + cdef_property_rep : public handle_cdef_object + { + public: + cdef_property_rep (const std::string& nm) + : handle_cdef_object (nm) { } + + octave_value get_value (void) const { return default_value; } + + octave_value get_value (const cdef_object& obj); + + void set_value (const octave_value& val) { default_value = val; } + + void set_value (const cdef_object& obj, const octave_value& val); + + private: + octave_value default_value; + }; + +public: + cdef_property (void) : cdef_object () { } + + cdef_property (const std::string& nm) + : cdef_object (new cdef_property_rep (nm)) { } + + cdef_property (const cdef_property& prop) + : cdef_object (prop) { } + + cdef_property (const cdef_object& obj) + : cdef_object (obj) + { + // This should never happen... + if (class_name () != "meta.property") + error ("internal error: invalid assignment from %s to meta.property object", + class_name ().c_str ()); + } + + cdef_property& operator = (const cdef_property& prop) + { + cdef_object::operator= (prop); + + return *this; + } + + octave_value get_value (const cdef_object& obj) + { return get_rep ()->get_value (obj); } + + octave_value get_value (void) { return get_rep ()->get_value (); } + + void set_value (const cdef_object& obj, const octave_value& val) + { get_rep ()->set_value (obj, val); } + + void set_value (const octave_value& val) { get_rep ()->set_value (val); } + + std::string get_get_access (void) const + { return get ("GetAccess").string_value (); } + + std::string get_set_access (void) const + { return get ("SetAccess").string_value (); } + + bool check_get_access (const std::string& acc) const; + + bool check_set_access (const std::string& acc) const; + + std::string get_name (void) const + { return get ("Name").string_value (); } + + bool is_constant (void) const + { return get ("Constant").bool_value (); } + +private: + cdef_property_rep* get_rep (void) + { return dynamic_cast (cdef_object::get_rep ()); } + + const cdef_property_rep* get_rep (void) const + { return dynamic_cast (cdef_object::get_rep ()); } +}; + +class +cdef_method : public cdef_object +{ +private: + + class + cdef_method_rep : public handle_cdef_object + { + public: + cdef_method_rep (const std::string& nm) + : handle_cdef_object (nm) { } + + octave_value get_function (void) const { return function; } + + void set_function (const octave_value& fcn) + { function = fcn; } + + octave_value_list execute (const octave_value_list& args, int nargout); + + octave_value_list execute (const cdef_object& obj, + const octave_value_list& args, int nargout); + + private: + void check_method (void); + + private: + octave_value function; + }; + +public: + cdef_method (void) : cdef_object () { } + + cdef_method (const std::string& nm) + : cdef_object (new cdef_method_rep (nm)) { } + + cdef_method (const cdef_property& prop) + : cdef_object (prop) { } + + cdef_method (const cdef_object& obj) + : cdef_object (obj) + { + // This should never happen... + if (class_name () != "meta.method") + error ("internal error: invalid assignment from %s to meta.method object", + class_name ().c_str ()); + } + + cdef_method& operator = (const cdef_method& meth) + { + cdef_object::operator= (meth); + + return *this; + } + + /* normal invokation */ + octave_value_list execute (const octave_value_list& args, int nargout) + { return get_rep ()->execute (args, nargout); } + + /* dot-invokation: object is pushed as 1st argument */ + octave_value_list execute (const cdef_object& obj, + const octave_value_list& args, int nargout) + { return get_rep ()->execute (obj, args, nargout); } + + std::string get_access (void) const + { return get ("Access").string_value (); } + + bool check_access (const std::string& req) const; + + std::string get_name (void) const + { return get ("Name").string_value (); } + + bool is_static (void) const + { return get ("Static").bool_value (); } + + void set_function (const octave_value& fcn) + { get_rep ()->set_function (fcn); } + +private: + cdef_method_rep* get_rep (void) + { return dynamic_cast (cdef_object::get_rep ()); } + + const cdef_method_rep* get_rep (void) const + { return dynamic_cast (cdef_object::get_rep ()); } +}; + +inline cdef_class +cdef_object::get_class (void) const +{ return rep->get_class (); } + +inline cdef_method +cdef_class::find_method (const std::string& nm) +{ return get_rep ()->find_method (nm); } + +inline cdef_property +cdef_class::find_property (const std::string& nm) +{ return get_rep ()->find_property (nm); } + +class +cdef_package : public cdef_object +{ +private: + + class + cdef_package_rep : public handle_cdef_object + { + public: + cdef_package_rep (const std::string& nm) + : handle_cdef_object (nm) { } + + void install_class (const cdef_class& cls, const std::string& nm); + + void install_function (const octave_value& fcn, const std::string& nm); + + void install_package (const cdef_package& pack, const std::string& nm); + + octave_value_list subsref (const std::string& type, + const std::list& idx, + int nargout, int& skip); + + Cell get_classes (void) const; + + Cell get_functions (void) const; + + Cell get_packages (void) const; + + private: + std::map class_map; + std::map function_map; + std::map package_map; + + typedef std::map::iterator class_iterator; + typedef std::map::const_iterator class_const_iterator; + typedef std::map::iterator function_iterator; + typedef std::map::const_iterator function_const_iterator; + typedef std::map::iterator package_iterator; + typedef std::map::const_iterator package_const_iterator; + }; + +public: + cdef_package (void) : cdef_object () { } + + cdef_package (const std::string& nm) + : cdef_object (new cdef_package_rep (nm)) { } + + cdef_package (const cdef_object& obj) + : cdef_object (obj) + { + // This should never happen... + if (class_name () != "meta.package") + error ("internal error: invalid assignment from %s to meta.package object", + class_name ().c_str ()); + } + + cdef_package& operator = (const cdef_package& pack) + { + cdef_object::operator= (pack); + + return *this; + } + + void install_class (const cdef_class& cls, const std::string& nm) + { get_rep ()->install_class (cls, nm); } + + void install_function (const octave_value& fcn, const std::string& nm) + { get_rep ()->install_function (fcn, nm); } + + void install_package (const cdef_package& pack, const std::string& nm) + { get_rep ()->install_package (pack, nm); } + + Cell get_classes (void) const + { return get_rep ()->get_classes (); } + + Cell get_functions (void) const + { return get_rep ()->get_functions (); } + + Cell get_packages (void) const + { return get_rep ()->get_packages (); } + +private: + cdef_package_rep* get_rep (void) + { return dynamic_cast (cdef_object::get_rep ()); } + + const cdef_package_rep* get_rep (void) const + { return dynamic_cast (cdef_object::get_rep ()); } +}; + +class +octave_classdef : public octave_base_value +{ +public: + octave_classdef (void) + : octave_base_value (), object () { } + + octave_classdef (const cdef_object& obj) + : octave_base_value (), object (obj) { } + + octave_classdef (const octave_classdef& obj) + : octave_base_value (obj), object (obj.object) { } + + octave_base_value* clone (void) const + { return new octave_classdef (object.clone ()); } + + octave_base_value* empty_clone (void) const + { return new octave_classdef (); } + + cdef_object get_object (void) const + { return object; } + + bool is_defined (void) const { return true; } + + bool is_map (void) const { return true; } + + bool print_as_scalar (void) const { return true; } + + void print(std::ostream& os, bool pr_as_read_syntax = false) const + { + // FIXME: should call "display" method + print_raw(os, pr_as_read_syntax); + newline(os); + } + + void print_raw(std::ostream& os, bool /* pr_as_read_syntax */ = false) const + { + os << object.class_name () << " object"; + } + + octave_value_list subsref (const std::string& type, + const std::list& idx, int nargout); + + octave_value subsref (const std::string& type, + const std::list& idx) + { + octave_value_list retval = subsref (type, idx, 1); + return (retval.length () > 0 ? retval(0) : octave_value ()); + } + + string_vector map_keys (void) const { return object.map_keys (); } + + dim_vector dims (void) const { return dim_vector (1, 1); } + +private: + cdef_object object; + +private: + DECLARE_OCTAVE_ALLOCATOR + +public: + int type_id (void) const { return t_id; } + std::string type_name (void) const { return t_name; } + std::string class_name (void) const { return object.class_name (); } + + static int static_type_id (void) { return t_id; } + static std::string static_type_name (void) { return t_name; } + static std::string static_class_name (void) { return ""; } + static void register_type (void); + +private: + static int t_id; + + static const std::string t_name; +}; + +inline octave_value +to_ov (const cdef_object& obj) +{ + if (obj.ok ()) + return octave_value (new octave_classdef (obj)); + else + return octave_value (Matrix ()); +} + +inline octave_value +to_ov (const octave_value& ov) +{ return ov; } + +inline cdef_object +to_cdef (const octave_value& val) +{ + if (val.type_name () == "object") + return dynamic_cast (val.internal_rep ())->get_object (); + else + { + warning ("trying to cast non-object into object"); + return cdef_object (); + } +} + +inline cdef_object +to_cdef (const cdef_object& obj) +{ return obj; } + +OCTINTERP_API void install_classdef (void); + +#endif + +/* +;;; Local Variables: *** +;;; mode: C++ *** +;;; End: *** +*/ diff -r af9e2ad52943 -r 5861c4bde387 libinterp/parse-tree/pt-classdef.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libinterp/parse-tree/pt-classdef.cc Sun Dec 23 17:43:06 2012 -0500 @@ -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 af9e2ad52943 -r 5861c4bde387 libinterp/parse-tree/pt-classdef.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libinterp/parse-tree/pt-classdef.h Sun Dec 23 17:43:06 2012 -0500 @@ -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 af9e2ad52943 -r 5861c4bde387 libinterp/parse-tree/pt-funcall.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libinterp/parse-tree/pt-funcall.cc Sun Dec 23 17:43:06 2012 -0500 @@ -0,0 +1,83 @@ +/* + +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-fcn.h" +#include "pt-funcall.h" +#include "pt-walk.h" + +// Function call objects. + +void +tree_funcall::print (std::ostream& os, bool pr_as_read_syntax, + bool pr_orig_text) +{ + print_raw (os, pr_as_read_syntax, pr_orig_text); +} + +void +tree_funcall::print_raw (std::ostream& os, bool pr_as_read_syntax, + bool pr_orig_text) +{ + if (pr_orig_text) + { + os << original_text (); + } + else + { + octave_function *fp = fcn.function_value (); + std::string nm = fp ? fp->name () : std::string (""); + + os << nm << " ("; + + octave_idx_type len = args.length (); + for (octave_idx_type i = 0; i < len; i++) + { + args(i).print_raw (os, pr_as_read_syntax); + + if (i < len - 1) + os << ", "; + } + + os << ")"; + } +} + +tree_funcall * +tree_funcall::dup (symbol_table::scope_id, + symbol_table::context_id context) const +{ + tree_funcall *new_fc = new tree_funcall (fcn, args, line (), column ()); + + new_fc->copy_base (*new_fc); + + return new_fc; +} + +void +tree_funcall::accept (tree_walker& tw) +{ + tw.visit_funcall (*this); +} diff -r af9e2ad52943 -r 5861c4bde387 libinterp/parse-tree/pt-funcall.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libinterp/parse-tree/pt-funcall.h Sun Dec 23 17:43:06 2012 -0500 @@ -0,0 +1,101 @@ +/* + +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_funcall_h) +#define octave_tree_funcall_h 1 + +#include "ov.h" +#include "oct-obj.h" +#include "parse.h" +#include "pt-exp.h" + +// Function call. This class only represents function calls that have +// known functions (most useful for calls to built-in functions that +// are generated by the parser) and fixed argument lists, known at +// compile time. + +class +tree_funcall : public tree_expression +{ +public: + + tree_funcall (const octave_value& f, const octave_value_list& a, + int l = -1, int c = -1) + : tree_expression (l, c), fcn (f), args (a) + { + if (! fcn.is_function ()) + error ("tree_funcall: invalid function"); + } + + ~tree_funcall (void) { } + + bool has_magic_end (void) const { return false; } + + void print (std::ostream& os, bool pr_as_read_syntax = false, + bool pr_orig_txt = true); + + void print_raw (std::ostream& os, bool pr_as_read_syntax = false, + bool pr_orig_txt = true); + + tree_funcall *dup (symbol_table::scope_id, + symbol_table::context_id context) const; + + octave_value rvalue1 (int nargout) + { + octave_value retval; + + const octave_value_list tmp = rvalue (nargout); + + if (! tmp.empty ()) + retval = tmp(0); + + return retval; + } + + octave_value_list rvalue (int nargout) + { + return feval (fcn.function_value (), args, nargout); + } + + octave_value function (void) const { return fcn; } + + octave_value_list arguments (void) const { return args; } + + void accept (tree_walker& tw); + +private: + + // Function to call. Error if not a valid function at time of + // construction. + octave_value fcn; + + // Argument list. + octave_value_list args; + + // No copying! + + tree_funcall (const tree_funcall&); + + tree_funcall& operator = (const tree_funcall&); +}; + +#endif diff -r af9e2ad52943 -r 5861c4bde387 src/octave-value/ov-classdef.cc --- a/src/octave-value/ov-classdef.cc Sun Dec 23 13:19:40 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1454 +0,0 @@ -/* - -Copyright (C) 2012 Michael Goffioul - -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 - -#include "defun.h" -#include "ov-builtin.h" -#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; - -static void -gripe_method_access (const std::string& from, const cdef_method& meth) -{ - error ("%s: method `%s' has %s access and cannot be run in this context", - from.c_str (), meth.get_name ().c_str (), - meth.get_access ().c_str ()); -} - -static void -gripe_property_access (const std::string& from, const cdef_property& prop, - bool is_set = false) -{ - if (is_set) - error ("%s: property `%s' has %s access and cannot be set in this context", - from.c_str (), prop.get_name ().c_str (), - prop.get_set_access ().c_str ()); - else - error ("%s: property `%s' has %s access and cannot be obtained in this context", - from.c_str (), prop.get_name ().c_str (), - prop.get_get_access ().c_str ()); -} - -static octave_value -make_fcn_handle (octave_builtin::fcn ff, const std::string& nm) -{ - octave_value fcn (new octave_builtin (ff, nm)); - - octave_value fcn_handle (new octave_fcn_handle (fcn, nm)); - - return fcn_handle; -} - -inline octave_value_list -execute_ov (octave_value val, const octave_value_list& args, int nargout) -{ - std::list idx (1, args); - - std::string type ("("); - - return val.subsref (type, idx, nargout); -} - -static bool -check_access (const std::string& req, const std::string& acc) -{ - if (req == "private") - return true; - else if (req == "protected") - return (acc != "private"); - else - return (acc == "public"); -} - -static std::string -get_base_name (const std::string& nm) -{ - std::string::size_type pos = nm.find_last_of ('.'); - - if (pos != std::string::npos) - return nm.substr (pos + 1); - - return nm; -} - -static std::string -superclass_access (const std::string& acc) -{ - if (acc == "public") - return acc; - else - return "protected"; -} - -static cdef_class -lookup_class (const std::string& name, bool error_if_not_found = true) -{ - std::map::iterator it = all_classes.find (name); - - if (it == all_classes.end ()) - { - // FIXME: should look into load-path - if (error_if_not_found) - error ("class not found: %s", name.c_str ()); - } - else - { - cdef_class& cls = it->second; - - if (! cls.is_builtin ()) - { - // FIXME: check whether a class reload is needed - } - - if (cls.ok ()) - return cls; - else - all_classes.erase (it); - } - - return cdef_class (); -} - -static Cell -lookup_classes (const Cell& cls_names) -{ - Cell cls (cls_names.numel (), 1); - - for (int i = 0; i < cls_names.numel (); i++) - { - cdef_class c = lookup_class (cls_names(i).string_value ()); - - if (! error_state) - cls(i) = to_ov (c); - else - return Cell (); - } - - return cls; -} - -static bool -is_superclass (const cdef_class& clsa, const cdef_class& clsb, - bool allow_equal = true) -{ - if (allow_equal && clsa == clsb) - return true; - else - { - Cell c = clsb.get ("SuperClasses").cell_value (); - - bool retval = false; - - for (int i = 0; ! retval && i < c.numel (); i++) - { - cdef_class cls = lookup_class (c(i).string_value ()); - - if (! error_state) - retval = is_superclass (clsa, cls, true); - } - - return retval; - } -} - -inline bool -is_strict_superclass (const cdef_class& clsa, const cdef_class& clsb) -{ return is_superclass (clsa, clsb, false); } - -static octave_value_list -class_get_properties (const octave_value_list& args, int /* nargout */) -{ - octave_value_list retval; - - if (args.length () == 1 && args(0).type_name () == "object") - { - cdef_class cls (to_cdef (args(0))); - - retval(0) = cls.get_properties (); - } - - return retval; -} - -static octave_value_list -class_get_methods (const octave_value_list& args, int /* nargout */) -{ - octave_value_list retval; - - if (args.length () == 1 && args(0).type_name () == "object") - { - cdef_class cls (to_cdef (args(0))); - - retval(0) = cls.get_methods (); - } - - return retval; -} - -static octave_value_list -class_get_superclasses (const octave_value_list& args, int /* nargout */) -{ - octave_value_list retval; - - if (args.length () == 1 && args(0).type_name () == "object" - && args(0).class_name () == "meta.class") - { - cdef_class cls (to_cdef (args(0))); - - Cell classes = cls.get ("SuperClasses").cell_value (); - - retval(0) = lookup_classes (classes); - } - - return retval; -} - -static octave_value_list -class_get_inferiorclasses (const octave_value_list& args, int /* nargout */) -{ - octave_value_list retval; - - if (args.length () == 1 && args(0).type_name () == "object" - && args(0).class_name () == "meta.class") - { - cdef_class cls (to_cdef (args(0))); - - Cell classes = cls.get ("InferiorClasses").cell_value (); - - retval(0) = lookup_classes (classes); - } - - return retval; -} - -static octave_value_list -class_fromName (const octave_value_list& args, int /* nargout */) -{ - octave_value_list retval; - - if (args.length () == 1) - { - std::string name = args(0).string_value (); - - if (! error_state) - retval(0) = to_ov (lookup_class (name)); - else - error ("fromName: invalid class name, expected a string value"); - } - else - error ("fromName: invalid number of parameters"); - - return retval; -} - -static octave_value_list -class_fevalStatic (const octave_value_list& args, int nargout) -{ - octave_value_list retval; - - if (args.length () > 1 && args(0).type_name () == "object") - { - cdef_class cls (to_cdef (args(0))); - - if (! error_state) - { - std::string meth_name = args(1).string_value (); - - if (! error_state) - { - cdef_method meth = cls.find_method (meth_name); - - if (meth.ok ()) - { - // FIXME: can the context be something else? - if (meth.check_access ("public")) - { - if (meth.is_static ()) - retval = meth.execute (args.splice (0, 2), nargout); - else - error ("fevalStatic: method `%s' is not static", - meth_name.c_str ()); - } - else - gripe_method_access ("fevalStatic", meth); - } - else - error ("fevalStatic: method not found: %s", - meth_name.c_str ()); - } - else - error ("fevalStatic: invalid method name, expected a string value"); - } - error ("fevalStatic: invalid object, expected a meta.class object"); - } - else - error ("fevalStatic: invalid arguments"); - - return retval; -} - -static octave_value_list -class_getConstant (const octave_value_list& args, int /* nargout */) -{ - octave_value_list retval; - - if (args.length () == 2 && args(0).type_name () == "object" - && args(0).class_name () == "meta.class") - { - cdef_class cls = to_cdef (args(0)); - - if (! error_state) - { - std::string prop_name = args(1).string_value (); - - if (! error_state) - { - cdef_property prop = cls.find_property (prop_name); - - if (prop.ok ()) - { - // FIXME: can the context be something else? - if (prop.check_get_access ("public")) - { - if (prop.is_constant ()) - retval(0) = prop.get_value (); - else - error ("getConstant: property `%s' is not constant", - prop_name.c_str ()); - } - else - gripe_property_access ("getConstant", prop); - } - else - error ("getConstant: property not found: %s", - prop_name.c_str ()); - } - else - error ("getConstant: invalid property name, expected a string value"); - } - else - error ("getConstant: invalid object, expected a meta.class object"); - } - else - error ("getConstant: invalid arguments"); - - return retval; -} - -#define META_CLASS_CMP(OP, CLSA, CLSB, FUN) \ -static octave_value_list \ -class_ ## OP (const octave_value_list& args, int /* nargout */) \ -{ \ - octave_value_list retval; \ -\ - if (args.length () == 2 \ - && args(0).type_name () == "object" && args(1).type_name () == "object" \ - && args(0).class_name () == "meta.class" && args(1).class_name () == "meta.class") \ - { \ - cdef_class clsa = to_cdef (args(0)); \ -\ - cdef_class clsb = to_cdef (args(1)); \ -\ - if (! error_state) \ - retval(0) = FUN (CLSA, CLSB); \ - else \ - error (#OP ": invalid objects, expected meta.class objects"); \ - } \ - else \ - error (#OP ": invalid arguments"); \ -\ - return retval; \ -} - -META_CLASS_CMP (lt, clsb, clsa, is_strict_superclass) -META_CLASS_CMP (le, clsb, clsa, is_superclass) -META_CLASS_CMP (gt, clsa, clsb, is_strict_superclass) -META_CLASS_CMP (ge, clsa, clsb, is_superclass) -META_CLASS_CMP (eq, clsa, clsb, operator==) -META_CLASS_CMP (ne, clsa, clsb, operator!=) - -static octave_value_list -handle_delete (const octave_value_list& /* args */, int /* nargout */) -{ - octave_value_list retval; - - // FIXME: implement this - - return retval; -} - -static cdef_class -make_class (const std::string& name, const std::string& super = std::string()) -{ - cdef_class cls ("meta.class"); - - all_classes[name] = cls; - cls.put ("ConstructOnLoad", false); - cls.put ("ContainingPackage", Matrix ()); - cls.put ("Description", std::string ()); - cls.put ("DetailedDescription", std::string ()); - cls.put ("Events", Cell ()); - cls.put ("Hidden", false); - cls.put ("InferiorClasses", Cell ()); - cls.put ("Methods", Cell ()); - cls.put ("Name", name); - cls.put ("Properties", Cell ()); - cls.put ("Sealed", true); - if (super.empty ()) - cls.put ("SuperClasses", Cell ()); - else - cls.put ("SuperClasses", Cell (octave_value (super))); - - return cls; -} - -static cdef_property -make_property (const cdef_object& cls, const std::string& name, - const octave_value& get_method = Matrix (), - const std::string& get_access = "public", - const octave_value& set_method = Matrix (), - const std::string& set_access = "public") -{ - // FIXME: what about default value? - - cdef_property prop ("meta.property"); - - prop.put ("Name", name); - prop.put ("Description", std::string ()); - prop.put ("DetailedDescription", std::string ()); - prop.put ("Abstract", false); - prop.put ("Constant", false); - prop.put ("GetAccess", get_access); - prop.put ("SetAccess", set_access); - prop.put ("Dependent", false); - prop.put ("Transient", false); - prop.put ("Hidden", false); - prop.put ("GetObservable", false); - prop.put ("SetObservable", false); - prop.put ("GetMethod", get_method); - prop.put ("SetMethod", set_method); - prop.put ("DefiningClass", to_ov (cls)); - - return prop; -} - -inline cdef_property -make_attribute (const cdef_object& cls, const std::string& name) -{ - return make_property (cls, name, Matrix (), "public", Matrix (), "private"); -} - -static cdef_method -make_method (const cdef_object& cls, const std::string& name, const octave_value& fcn, - const std::string& m_access = "public", bool is_static = false) -{ - cdef_method meth ("meta.method"); - - meth.put ("Abstract", false); - meth.put ("Access", m_access); - meth.put ("DefiningClass", to_ov (cls)); - meth.put ("Description", std::string ()); - meth.put ("DetailedDescription", std::string ()); - meth.put ("Hidden", false); - meth.put ("Name", name); - meth.put ("Sealed", true); - meth.put ("Static", is_static); - - meth.set_function (fcn); - - return meth; -} - -inline cdef_method -make_method (const cdef_object& cls, const std::string& name, octave_builtin::fcn ff, - const std::string& m_access = "public", bool is_static = false) -{ - octave_value fcn (new octave_builtin (ff, name)); - - octave_value fcn_handle (new octave_fcn_handle (fcn, name)); - - return make_method (cls, name, fcn_handle, m_access, is_static); -} - -static cdef_package -make_package (const std::string& nm, - const std::string& parent = std::string ()) -{ - cdef_package pack ("meta.package"); - - all_packages[nm] = pack; - pack.put ("Name", nm); - pack.put ("ContainingPackage", to_ov (all_packages[parent])); - - return pack; -} - -DEFINE_OCTAVE_ALLOCATOR (octave_classdef); - -int octave_classdef::t_id (-1); - -const std::string octave_classdef::t_name ("object"); - -void -octave_classdef::register_type (void) -{ - t_id = octave_value_typeinfo::register_type - (octave_classdef::t_name, "", octave_value (new octave_classdef ())); -} - -cdef_class -cdef_object_rep::get_class (void) const -{ - cdef_class cls = lookup_class (class_name ()); - - return cls; -} - -string_vector -cdef_object_rep::map_keys (void) const -{ - cdef_class cls = get_class (); - - if (cls.ok ()) - return cls.get_names (); - - return string_vector (); -} - -octave_value_list -handle_cdef_object::subsref (const std::string& type, - const std::list& idx, - int nargout, int& skip) -{ - skip = 0; - - cdef_class cls = get_class (); - - octave_value_list retval; - - if (! cls.ok ()) - return retval; - - switch (type[0]) - { - case '.': - { - std::string name = (idx.front ())(0).string_value (); - - // FIXME: get the right context; context should also - // be linked to the current executing class (if any) - // such that protected/private methods found in inherited - // classes are correctly resolved. - std::string context = "public"; - - cdef_method meth = cls.find_method (name); - - if (meth.ok ()) - { - if (meth.check_access (context)) - { - int _nargout = (type.length () > 2 ? 1 : nargout); - - octave_value_list args; - - skip = 1; - - if (type.length () > 1 && type[1] == '(') - { - std::list::const_iterator it = idx.begin (); - - args = *++it; - - skip++; - } - - if (meth.is_static ()) - retval = meth.execute (args, _nargout); - else - { - refcount++; - retval = meth.execute (cdef_object (this), args, _nargout); - } - } - else - gripe_method_access ("subsref", meth); - } - - if (skip == 0 && ! error_state) - { - cdef_property prop = cls.find_property (name); - - if (prop.ok ()) - { - if (prop.check_get_access (context)) - { - refcount++; - retval(0) = prop.get_value (cdef_object (this)); - - skip = 1; - } - else - gripe_property_access ("subsref", prop); - } - else - error ("subsref: unknown method or property: %s", name.c_str ()); - } - break; - } - default: - error ("object cannot be indexed with `%c'", type[0]); - break; - } - - return retval; -} - -cdef_method -cdef_class::cdef_class_rep::find_method (const std::string& nm) -{ - method_iterator it = method_map.find (nm); - - if (it == method_map.end ()) - { - // FIXME: look into class directory - } - else - { - cdef_method& meth = it->second; - - // FIXME: check if method reload needed - - if (meth.ok ()) - return meth; - } - - // Look into superclasses - - Cell super_classes = get ("SuperClasses").cell_value (); - - for (int i = 0; i < super_classes.numel (); i++) - { - cdef_class cls = lookup_class (super_classes(i).string_value ()); - - if (! error_state) - { - cdef_method meth = cls.find_method (nm); - - if (meth.ok ()) - return meth; - } - } - - return cdef_method (); -} - -void -cdef_class::cdef_class_rep::install_method (const cdef_method& meth) -{ - method_map[meth.get_name ()] = meth; -} - -void -cdef_class::cdef_class_rep::load_all_methods (void) -{ - // FIXME: re-scan class directory -} - -Cell -cdef_class::cdef_class_rep::get_methods (void) -{ - std::map meths; - - std::map count; - - count["public"] = count["protected"] = count["private"] = 0; - - find_methods (meths, count); - - if (! error_state) - { - Cell c (count["public"] + count["protected"], 1); - - int idx = 0; - - for (std::map::const_iterator it = meths.begin (); - it != meths.end (); ++it) - if (::check_access ("protected", it->second.get_access ())) - c (idx++, 0) = to_ov (it->second); - - return c; - } - - return Cell (); -} - -void -cdef_class::cdef_class_rep::find_methods (std::map& meths, - std::map& count) -{ - load_all_methods (); - - method_const_iterator it; - - for (it = method_map.begin (); it != method_map.end (); ++it) - { - std::string nm = it->second.get_name (); - - if (meths.find (nm) == meths.end ()) - { - std::string acc = it->second.get_access (); - - meths[nm] = it->second; - count[acc]++; - } - } - - // Look into superclasses - - Cell super_classes = get ("SuperClasses").cell_value (); - - for (int i = 0; i < super_classes.numel (); i++) - { - cdef_class cls = lookup_class (super_classes(i).string_value ()); - - if (! error_state) - cls.get_rep ()->find_methods (meths, count); - else - break; - } -} - -cdef_property -cdef_class::cdef_class_rep::find_property (const std::string& nm) -{ - property_iterator it = property_map.find (nm); - - if (it != property_map.end ()) - { - cdef_property& prop = it->second; - - if (prop.ok ()) - return prop; - } - - // Look into superclasses - - Cell super_classes = get ("SuperClasses").cell_value (); - - for (int i = 0; i < super_classes.numel (); i++) - { - cdef_class cls = lookup_class (super_classes(i).string_value ()); - - if (! error_state) - { - cdef_property prop = cls.find_property (nm); - - if (prop.ok ()) - return prop; - } - } - - return cdef_property (); -} - -void -cdef_class::cdef_class_rep::install_property (const cdef_property& prop) -{ - property_map[prop.get_name ()] = prop; -} - -Cell -cdef_class::cdef_class_rep::get_properties (void) -{ - std::map props; - - std::map count; - - count["public"] = count["protected"] = count["private"] = 0; - - find_properties (props, count); - - if (! error_state) - { - Cell c (count["public"] + count["protected"], 1); - - int idx = 0; - - for (std::map::const_iterator it = props.begin (); - it != props.end (); ++it) - if (::check_access ("protected", it->second.get_get_access ())) - c (idx++, 0) = to_ov (it->second); - - return c; - } - - return Cell (); -} - -void -cdef_class::cdef_class_rep::find_properties (std::map& props, - std::map& count) -{ - property_const_iterator it; - - for (it = property_map.begin (); it != property_map.end (); ++it) - { - std::string nm = it->second.get_name (); - - if (props.find (nm) == props.end ()) - { - std::string acc = it->second.get_get_access (); - - props[nm] = it->second; - count[acc]++; - } - } - - // Look into superclasses - - Cell super_classes = get ("SuperClasses").cell_value (); - - for (int i = 0; i < super_classes.numel (); i++) - { - cdef_class cls = lookup_class (super_classes(i).string_value ()); - - if (! error_state) - cls.get_rep ()->find_properties (props, count); - else - break; - } -} - -void -cdef_class::cdef_class_rep::find_names (std::map& names, - std::map& count) -{ - load_all_methods (); - - for (method_const_iterator it = method_map.begin (); - it != method_map.end(); ++it) - { - std::string nm = it->second.get_name (); - - if (names.find (nm) == names.end ()) - { - std::string acc = it->second.get_access (); - - names[nm] = acc; - count[acc]++; - } - } - - for (property_const_iterator it = property_map.begin (); - it != property_map.end (); ++it) - { - std::string nm = it->second.get_name (); - - if (names.find (nm) == names.end ()) - { - std::string acc = it->second.get_get_access (); - - names[nm] = acc; - count[acc]++; - } - } - - // Look into superclasses - - Cell super_classes = get ("SuperClasses").cell_value (); - - for (int i = 0; i < super_classes.numel (); i++) - { - cdef_class cls = lookup_class (super_classes(i).string_value ()); - - if (! error_state) - cls.get_rep ()->find_names (names, count); - else - break; - } -} - -string_vector -cdef_class::cdef_class_rep::get_names (void) -{ - std::map names; - - std::map count; - - count["public"] = count["protected"] = count["private"] = 0; - - find_names (names, count); - - if (! error_state) - { - string_vector v (count["public"]); - - int idx = 0; - for (std::map::const_iterator it = names.begin (); - it != names.end (); ++it) - { - if (it->second == "public") - v[idx++] = it->first; - } - - return v.sort (true); - } - - return string_vector (); -} - -void -cdef_class::cdef_class_rep::delete_object (cdef_object obj) -{ - method_iterator it = method_map.find ("delete"); - - if (it != method_map.end ()) - { - std::string cls_name = obj.class_name (); - - obj.set_class_name (get ("Name").string_value ()); - - it->second.execute (obj, octave_value_list (), 0); - - obj.set_class_name (cls_name); - } - - // FIXME: should we destroy corresponding properties here? - - // Call "delete" in super classes - - Cell super_classes = get ("SuperClasses").cell_value (); - - for (int i = 0; i < super_classes.numel (); i++) - { - cdef_class cls = lookup_class (super_classes(i).string_value ()); - - if (!error_state) - cls.delete_object (obj); - } -} - -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) -{ - // FIXME: should check whether we're already in get accessor method - - octave_value retval; - - octave_value get_fcn = get ("GetMethod"); - - std::string get_access = get ("GetAccess").string_value (); - - if (get_access != "public") - { - // FIXME: should check the current call stack - } - - if (get_fcn.is_empty ()) - retval = obj.get (get ("Name").string_value ()); - else - { - octave_value_list args; - - args(0) = to_ov (obj); - - args = execute_ov (get_fcn, args, 1); - - if (! error_state) - retval = args(0); - } - - return retval; -} - -bool -cdef_property::check_get_access (const std::string& req) const -{ - return ::check_access (req, get_get_access ()); -} - -bool -cdef_property::check_set_access (const std::string& req) const -{ - return ::check_access (req, get_set_access ()); -} - -void -cdef_method::cdef_method_rep::check_method (void) -{ - // FIXME: check whether re-load is needed -} - -octave_value_list -cdef_method::cdef_method_rep::execute (const octave_value_list& args, - int nargout) -{ - octave_value_list retval; - - if (! get ("Abstract").bool_value ()) - { - check_method (); - - if (function.is_defined ()) - { - retval = execute_ov (function, args, nargout); - } - } - else - error ("%s: cannot execute abstract method", - get ("Name").string_value ().c_str ()); - - return retval; -} - -octave_value_list -cdef_method::cdef_method_rep::execute (const cdef_object& obj, - const octave_value_list& args, - int nargout) -{ - octave_value_list retval; - - if (! get ("Abstract").bool_value ()) - { - check_method (); - - octave_value_list new_args; - - if (function.is_defined ()) - { - new_args.resize (args.length () + 1); - - new_args(0) = to_ov (obj); - for (int i = 0; i < args.length (); i++) - new_args(i+1) = args(i); - - retval = execute_ov (function, new_args, nargout); - } - } - else - error ("%s: cannot execute abstract method", - get ("Name").string_value ().c_str ()); - - return retval; -} - -bool -cdef_method::check_access (const std::string& req) const -{ - return ::check_access (req, get_access ()); -} - -static cdef_package -lookup_package (const std::string& name) -{ - std::map::const_iterator it = all_packages.find (name); - - if (it != all_packages.end ()) - { - cdef_package pack = it->second; - - if (pack.ok ()) - return pack; - else - error ("invalid package: %s", name.c_str ()); - } - else - error ("package not found: %s", name.c_str ()); - - return cdef_package (); -} - -static octave_value_list -package_fromName (const octave_value_list& args, int /* nargout */) -{ - octave_value_list retval; - - if (args.length () == 1) - { - std::string name = args(0).string_value (); - - if (! error_state) - retval(0) = to_ov (lookup_package (name)); - else - error ("fromName: invalid package name, expected a string value"); - } - else - error ("fromName: invalid number of parameters"); - - return retval; -} - -static octave_value_list -package_get_classes (const octave_value_list& args, int /* nargout */) -{ - octave_value_list retval (1, Matrix ()); - - if (args.length () == 1 && args(0).type_name () == "object" - && args(0).class_name () == "meta.package") - { - cdef_package pack (to_cdef (args(0))); - - retval(0) = pack.get_classes (); - } - - return retval; -} - -static octave_value_list -package_get_functions (const octave_value_list& args, int /* nargout */) -{ - octave_value_list retval (1, Matrix ()); - - if (args.length () == 0 && args(0).type_name () == "object" - && args(0).class_name () == "meta.package") - { - cdef_package pack (to_cdef (args(0))); - - retval(0) = pack.get_functions (); - } - - return retval; -} - -static octave_value_list -package_get_packages (const octave_value_list& args, int /* nargout */) -{ - octave_value_list retval (1, Matrix ()); - - if (args.length () == 0 && args(0).type_name () == "object" - && args(0).class_name () == "meta.package") - { - cdef_package pack (to_cdef (args(0))); - - retval(0) = pack.get_packages (); - } - - return retval; -} - -void -cdef_package::cdef_package_rep::install_class (const cdef_class& cls, - const std::string& nm) -{ - class_map[nm] = cls; -} - -void -cdef_package::cdef_package_rep::install_function (const octave_value& fcn, - const std::string& nm) -{ - function_map[nm] = fcn; -} - -void -cdef_package::cdef_package_rep::install_package (const cdef_package& pack, - const std::string& nm) -{ - package_map[nm] = pack; -} - -octave_value_list -cdef_package::cdef_package_rep::subsref (const std::string& type, - const std::list& idx, - int nargout, int& skip) -{ - return handle_cdef_object::subsref (type, idx, nargout, skip); -} - -template -Cell -map2Cell (const std::map& m) -{ - Cell retval (1, m.size ()); - int i = 0; - - for (typename std::map::const_iterator it = m.begin (); - it != m.end (); ++it, ++i) - { - retval(i) = to_ov (it->second); - } - - return retval; -} - -Cell -cdef_package::cdef_package_rep::get_classes (void) const -{ return map2Cell (class_map); } - -Cell -cdef_package::cdef_package_rep::get_functions (void) const -{ return map2Cell (function_map); } - -Cell -cdef_package::cdef_package_rep::get_packages (void) const -{ return map2Cell (package_map); } - -octave_value_list -octave_classdef::subsref (const std::string& type, - const std::list& idx, - int nargout) -{ - int skip = 0; - octave_value_list retval; - - // FIXME: should check "subsref" method first - - retval = object.subsref (type, idx, nargout, skip); - - if (! error_state) - { - if (type.length () > skip && idx.size () > skip) - retval = retval(0).next_subsref (nargout, type, idx, skip); - } - - return retval; -} - -void -install_classdef (void) -{ - octave_classdef::register_type (); - - /* meta classes */ - cdef_class handle = make_class ("handle"); - cdef_class meta_class = make_class ("meta.class", "handle"); - cdef_class meta_property = make_class ("meta.property", "handle"); - cdef_class meta_method = make_class ("meta.method", "handle"); - cdef_class meta_event = make_class ("meta.event", "handle"); - cdef_class meta_package = make_class ("meta.package", "handle"); - cdef_class meta_dynproperty = make_class ("meta.dynamicproperty", "handle"); - - /* meta.class properties */ - meta_class.install_property (make_attribute (meta_class, "ConstructOnLoad")); - meta_class.install_property (make_property (meta_class, "ContainingPackage")); - meta_class.install_property (make_property (meta_class, "Description")); - meta_class.install_property (make_property (meta_class, "DetailedDescription")); - meta_class.install_property (make_property (meta_class, "Events")); - meta_class.install_property (make_attribute (meta_class, "Hidden")); - meta_class.install_property - (make_property (meta_class, "InferiorClasses", - make_fcn_handle (class_get_inferiorclasses, "meta.class>get.InferiorClasses"), - "public", Matrix (), "private")); - meta_class.install_property - (make_property (meta_class, "Methods", - make_fcn_handle (class_get_methods, "meta.class>get.Methods"), - "public", Matrix (), "private")); - meta_class.install_property - (make_property (meta_class, "MethodList", - make_fcn_handle (class_get_methods, "meta.class>get.MethodList"), - "public", Matrix (), "private")); - meta_class.install_property (make_attribute (meta_class, "Name")); - meta_class.install_property - (make_property (meta_class, "Properties", - make_fcn_handle (class_get_properties, "meta.class>get.Properties"), - "public", Matrix (), "private")); - meta_class.install_property - (make_property (meta_class, "PropertyList", - make_fcn_handle (class_get_properties, "meta.class>get.PropertyList"), - "public", Matrix (), "private")); - meta_class.install_property (make_attribute (meta_class, "Sealed")); - meta_class.install_property - (make_property (meta_class, "SuperClasses", - make_fcn_handle (class_get_superclasses, "meta.class>get.SuperClasses"), - "public", Matrix (), "private")); - meta_class.install_property - (make_property (meta_class, "SuperClassList", - make_fcn_handle (class_get_superclasses, "meta.class>get.SuperClassList"), - "public", Matrix (), "private")); - /* meta.class methods */ - meta_class.install_method (make_method (meta_class, "fromName", class_fromName, - "public", true)); - meta_class.install_method (make_method (meta_class, "fevalStatic", class_fevalStatic, - "public", false)); - meta_class.install_method (make_method (meta_class, "getConstant", class_getConstant, - "public", false)); - meta_class.install_method (make_method (meta_class, "eq", class_eq)); - meta_class.install_method (make_method (meta_class, "ne", class_ne)); - meta_class.install_method (make_method (meta_class, "lt", class_lt)); - meta_class.install_method (make_method (meta_class, "le", class_le)); - meta_class.install_method (make_method (meta_class, "gt", class_gt)); - meta_class.install_method (make_method (meta_class, "ge", class_ge)); - - /* meta.method properties */ - meta_method.install_property (make_attribute (meta_method, "Abstract")); - meta_method.install_property (make_attribute (meta_method, "Access")); - meta_method.install_property (make_attribute (meta_method, "DefiningClass")); - meta_method.install_property (make_attribute (meta_method, "Description")); - meta_method.install_property (make_attribute (meta_method, "DetailedDescription")); - meta_method.install_property (make_attribute (meta_method, "Hidden")); - meta_method.install_property (make_attribute (meta_method, "Name")); - meta_method.install_property (make_attribute (meta_method, "Sealed")); - meta_method.install_property (make_attribute (meta_method, "Static")); - - /* meta.property properties */ - meta_property.install_property (make_attribute (meta_property, "Name")); - meta_property.install_property (make_attribute (meta_property, "Description")); - meta_property.install_property (make_attribute (meta_property, "DetailedDescription")); - meta_property.install_property (make_attribute (meta_property, "Abstract")); - meta_property.install_property (make_attribute (meta_property, "Constant")); - meta_property.install_property (make_attribute (meta_property, "GetAccess")); - meta_property.install_property (make_attribute (meta_property, "SetAccess")); - meta_property.install_property (make_attribute (meta_property, "Dependent")); - meta_property.install_property (make_attribute (meta_property, "Transient")); - meta_property.install_property (make_attribute (meta_property, "Hidden")); - meta_property.install_property (make_attribute (meta_property, "GetObservable")); - meta_property.install_property (make_attribute (meta_property, "SetObservable")); - meta_property.install_property (make_attribute (meta_property, "GetMethod")); - meta_property.install_property (make_attribute (meta_property, "SetMethod")); - meta_property.install_property (make_attribute (meta_property, "DefiningClass")); - /* meta.property events */ - // FIXME: add events - - /* handle methods */ - handle.install_method (make_method (handle, "delete", handle_delete)); - - /* meta.package properties */ - meta_package.install_property (make_attribute (meta_package, "Name")); - meta_package.install_property (make_property (meta_package, "ContainingPackage")); - meta_package.install_property - (make_property (meta_package, "ClassList", - make_fcn_handle (package_get_classes, "meta.package>get.ClassList"), - "public", Matrix (), "private")); - meta_package.install_property - (make_property (meta_package, "Classes", - make_fcn_handle (package_get_classes, "meta.package>get.Classes"), - "public", Matrix (), "private")); - meta_package.install_property - (make_property (meta_package, "FunctionList", - make_fcn_handle (package_get_functions, "meta.package>get.FunctionList"), - "public", Matrix (), "private")); - meta_package.install_property - (make_property (meta_package, "Functions", - make_fcn_handle (package_get_functions, "meta.package>get.Functions"), - "public", Matrix (), "private")); - meta_package.install_property - (make_property (meta_package, "PackageList", - make_fcn_handle (package_get_packages, "meta.package>get.PackageList"), - "public", Matrix (), "private")); - meta_package.install_property - (make_property (meta_package, "Packages", - make_fcn_handle (package_get_packages, "meta.package>get.Packages"), - "public", Matrix (), "private")); - meta_package.install_method (make_method (meta_package, "fromName", package_fromName, - "public", true)); - - /* create "meta" package */ - cdef_package package_meta = make_package ("meta"); - package_meta.install_class (meta_class, "class"); - package_meta.install_class (meta_property, "property"); - package_meta.install_class (meta_method, "method"); - package_meta.install_class (meta_package, "package"); - package_meta.install_class (meta_event, "event"); - package_meta.install_class (meta_dynproperty, "dynproperty"); -} - -DEFUN (__meta_get_package__, args, , "") -{ - octave_value retval; - - if (args.length () == 1) - { - std::string cname = args(0).string_value (); - - if (! error_state) - retval = to_ov (lookup_package (cname)); - else - error ("invalid package name, expected a string value"); - } - else - print_usage (); - - 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++ *** -;;; End: *** -*/ diff -r af9e2ad52943 -r 5861c4bde387 src/octave-value/ov-classdef.h --- a/src/octave-value/ov-classdef.h Sun Dec 23 13:19:40 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,745 +0,0 @@ -/* - -Copyright (C) 2012 Michael Goffioul - -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_classdef_h) -#define octave_classdef_h 1 - -#include - -#include "oct-map.h" -#include "oct-refcount.h" -#include "ov-base.h" - -class cdef_object; -class cdef_class; -class cdef_property; -class cdef_method; -class cdef_package; - -class tree_classdef; - -class -cdef_object_rep -{ -public: - friend class cdef_object; - -public: - cdef_object_rep (void) - : refcount (1), cname () { } - - cdef_object_rep (const std::string& nm) - : refcount (1), cname (nm) { } - - virtual ~cdef_object_rep (void) { } - - virtual cdef_class get_class (void) const; - - virtual void set_class (const cdef_object&) - { error ("set_class: invalid object"); } - - virtual cdef_object_rep* clone (void) const - { - error ("clone: invalid object"); - return new cdef_object_rep (); - } - - virtual void put (const std::string&, const octave_value&) - { error ("put: invalid object"); } - - virtual octave_value get (const std::string&) const - { - error ("get: invalid object"); - return octave_value (); - } - - virtual octave_value_list subsref (const std::string&, - const std::list&, - int, int&) - { - error ("subsref: invalid object"); - return octave_value_list (); - } - - virtual string_vector map_keys(void) const; - - virtual bool is_valid (void) const { return false; } - - std::string class_name (void) const { return cname; } - - void set_class_name (const std::string& nm) - { cname = nm; } - -protected: - /* reference count */ - octave_refcount refcount; - - /* class name */ - std::string cname; -}; - -class -cdef_object -{ -public: - /* FIXME: use a null object */ - cdef_object (void) - : rep (new cdef_object_rep ()) { } - - cdef_object (const cdef_object& obj) - : rep (obj.rep) - { - rep->refcount++; - } - - cdef_object (cdef_object_rep *r) - : rep (r) { } - - virtual ~cdef_object (void) - { - if (--rep->refcount == 0) - delete rep; - } - - cdef_object& operator = (const cdef_object& obj) - { - if (rep != obj.rep) - { - if (--rep->refcount == 0) - delete rep; - - rep = obj.rep; - rep->refcount++; - } - - return *this; - } - - cdef_class get_class (void) const; - - void set_class_name (const std::string& nm) - { rep->set_class_name (nm); } - - std::string class_name (void) const - { return rep->class_name (); } - - cdef_object clone (void) const - { return cdef_object (rep->clone ()); } - - void put (const std::string& pname, const octave_value& val) - { rep->put (pname, val); } - - octave_value get (const std::string& pname) const - { return rep->get (pname); } - - octave_value_list subsref (const std::string& type, - const std::list& idx, - int nargout, int& skip) - { return rep->subsref (type, idx, nargout, skip); } - - string_vector map_keys (void) const { return rep->map_keys (); } - - const cdef_object_rep* get_rep (void) const { return rep; } - - bool ok (void) const { return rep->is_valid (); } - -protected: - cdef_object_rep* get_rep (void) { return rep; } - -private: - cdef_object_rep *rep; -}; - -class -handle_cdef_object : public cdef_object_rep -{ -public: - handle_cdef_object (void) - : cdef_object_rep () { } - - handle_cdef_object (const std::string& nm) - : cdef_object_rep (nm) { } - - cdef_object_rep* clone (void) const - { - handle_cdef_object *obj = const_cast (this); - obj->refcount++; - return obj; - } - - void put (const std::string& pname, const octave_value& val) - { map.assign (pname, val); } - - octave_value get (const std::string& pname) const - { - Cell val = map.contents (pname); - - if (val.numel () > 0) - return val(0, 0); - else - { - error ("get: unknown slot: %s", pname.c_str ()); - return octave_value (); - } - } - - octave_value_list subsref (const std::string& type, - const std::list& idx, - int nargout, int& skip); - - bool is_valid (void) const { return true; } - -protected: - Octave_map map; -}; - -class -cdef_class : public cdef_object -{ -private: - - class - cdef_class_rep : public handle_cdef_object - { - public: - cdef_class_rep (const std::string& nm) - : handle_cdef_object (nm) { } - - cdef_method find_method (const std::string& nm); - - void install_method (const cdef_method& meth); - - Cell get_methods (void); - - cdef_property find_property (const std::string& nm); - - void install_property (const cdef_property& prop); - - Cell get_properties (void); - - string_vector get_names (void); - - void set_directory (const std::string& dir) { directory = dir; } - - std::string get_directory (void) const { return directory; } - - void delete_object (cdef_object obj); - - private: - void load_all_methods (void); - - void find_names (std::map& names, - std::map& count); - - void find_properties (std::map& props, - std::map& count); - - void find_methods (std::map& meths, - std::map& count); - - private: - std::string directory; - - std::map method_map; - - std::map property_map; - - typedef std::map::iterator method_iterator; - typedef std::map::const_iterator method_const_iterator; - typedef std::map::iterator property_iterator; - typedef std::map::const_iterator property_const_iterator; - }; - -public: - // Create and invalid class object - cdef_class (void) - : cdef_object () { } - - cdef_class (const std::string& nm) - : cdef_object (new cdef_class_rep (nm)) { } - - cdef_class (const cdef_class& cls) - : cdef_object (cls) { } - - cdef_class (const cdef_object& obj) - : cdef_object (obj) - { - // This should never happen... - if (class_name () != "meta.class") - error ("internal error: invalid assignment from %s to meta.class object", - class_name ().c_str ()); - } - - cdef_class& operator = (const cdef_class& cls) - { - cdef_object::operator= (cls); - - return *this; - } - - cdef_class& operator = (const cdef_object& obj) - { - if (obj.class_name () == "meta.class") - cdef_object::operator= (obj); - else - error ("internal error: invalid assignment from %s to meta.class object", - class_name ().c_str ()); - - return *this; - } - - cdef_method find_method (const std::string& nm); - - void install_method (const cdef_method& meth) - { get_rep ()->install_method (meth); } - - Cell get_methods (void) { return get_rep ()->get_methods (); } - - cdef_property find_property (const std::string& nm); - - void install_property (const cdef_property& prop) - { get_rep ()->install_property (prop); } - - Cell get_properties (void) { return get_rep ()->get_properties (); } - - string_vector get_names (void) { return get_rep ()->get_names (); } - - void set_directory (const std::string& dir) - { get_rep ()->set_directory (dir); } - - std::string get_directory (void) const - { return get_rep ()->get_directory (); } - - std::string get_name (void) const - { return get ("Name").string_value (); } - - bool is_builtin (void) const - { return get_directory ().empty (); } - - 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 ()); } - - const cdef_class_rep* get_rep (void) const - { return dynamic_cast (cdef_object::get_rep ()); } - - friend bool operator == (const cdef_class&, const cdef_class&); - friend bool operator != (const cdef_class&, const cdef_class&); -}; - -inline bool -operator == (const cdef_class& clsa, const cdef_class& clsb) -// FIXME: is this really the right way to check class equality? -{ return (clsa.get_rep () == clsb.get_rep ()); } - -inline bool -operator != (const cdef_class& clsa, const cdef_class& clsb) -{ return ! (clsa == clsb); } - -class -cdef_property : public cdef_object -{ -private: - - class - cdef_property_rep : public handle_cdef_object - { - public: - cdef_property_rep (const std::string& nm) - : handle_cdef_object (nm) { } - - octave_value get_value (void) const { return default_value; } - - octave_value get_value (const cdef_object& obj); - - void set_value (const octave_value& val) { default_value = val; } - - void set_value (const cdef_object& obj, const octave_value& val); - - private: - octave_value default_value; - }; - -public: - cdef_property (void) : cdef_object () { } - - cdef_property (const std::string& nm) - : cdef_object (new cdef_property_rep (nm)) { } - - cdef_property (const cdef_property& prop) - : cdef_object (prop) { } - - cdef_property (const cdef_object& obj) - : cdef_object (obj) - { - // This should never happen... - if (class_name () != "meta.property") - error ("internal error: invalid assignment from %s to meta.property object", - class_name ().c_str ()); - } - - cdef_property& operator = (const cdef_property& prop) - { - cdef_object::operator= (prop); - - return *this; - } - - octave_value get_value (const cdef_object& obj) - { return get_rep ()->get_value (obj); } - - octave_value get_value (void) { return get_rep ()->get_value (); } - - void set_value (const cdef_object& obj, const octave_value& val) - { get_rep ()->set_value (obj, val); } - - void set_value (const octave_value& val) { get_rep ()->set_value (val); } - - std::string get_get_access (void) const - { return get ("GetAccess").string_value (); } - - std::string get_set_access (void) const - { return get ("SetAccess").string_value (); } - - bool check_get_access (const std::string& acc) const; - - bool check_set_access (const std::string& acc) const; - - std::string get_name (void) const - { return get ("Name").string_value (); } - - bool is_constant (void) const - { return get ("Constant").bool_value (); } - -private: - cdef_property_rep* get_rep (void) - { return dynamic_cast (cdef_object::get_rep ()); } - - const cdef_property_rep* get_rep (void) const - { return dynamic_cast (cdef_object::get_rep ()); } -}; - -class -cdef_method : public cdef_object -{ -private: - - class - cdef_method_rep : public handle_cdef_object - { - public: - cdef_method_rep (const std::string& nm) - : handle_cdef_object (nm) { } - - octave_value get_function (void) const { return function; } - - void set_function (const octave_value& fcn) - { function = fcn; } - - octave_value_list execute (const octave_value_list& args, int nargout); - - octave_value_list execute (const cdef_object& obj, - const octave_value_list& args, int nargout); - - private: - void check_method (void); - - private: - octave_value function; - }; - -public: - cdef_method (void) : cdef_object () { } - - cdef_method (const std::string& nm) - : cdef_object (new cdef_method_rep (nm)) { } - - cdef_method (const cdef_property& prop) - : cdef_object (prop) { } - - cdef_method (const cdef_object& obj) - : cdef_object (obj) - { - // This should never happen... - if (class_name () != "meta.method") - error ("internal error: invalid assignment from %s to meta.method object", - class_name ().c_str ()); - } - - cdef_method& operator = (const cdef_method& meth) - { - cdef_object::operator= (meth); - - return *this; - } - - /* normal invokation */ - octave_value_list execute (const octave_value_list& args, int nargout) - { return get_rep ()->execute (args, nargout); } - - /* dot-invokation: object is pushed as 1st argument */ - octave_value_list execute (const cdef_object& obj, - const octave_value_list& args, int nargout) - { return get_rep ()->execute (obj, args, nargout); } - - std::string get_access (void) const - { return get ("Access").string_value (); } - - bool check_access (const std::string& req) const; - - std::string get_name (void) const - { return get ("Name").string_value (); } - - bool is_static (void) const - { return get ("Static").bool_value (); } - - void set_function (const octave_value& fcn) - { get_rep ()->set_function (fcn); } - -private: - cdef_method_rep* get_rep (void) - { return dynamic_cast (cdef_object::get_rep ()); } - - const cdef_method_rep* get_rep (void) const - { return dynamic_cast (cdef_object::get_rep ()); } -}; - -inline cdef_class -cdef_object::get_class (void) const -{ return rep->get_class (); } - -inline cdef_method -cdef_class::find_method (const std::string& nm) -{ return get_rep ()->find_method (nm); } - -inline cdef_property -cdef_class::find_property (const std::string& nm) -{ return get_rep ()->find_property (nm); } - -class -cdef_package : public cdef_object -{ -private: - - class - cdef_package_rep : public handle_cdef_object - { - public: - cdef_package_rep (const std::string& nm) - : handle_cdef_object (nm) { } - - void install_class (const cdef_class& cls, const std::string& nm); - - void install_function (const octave_value& fcn, const std::string& nm); - - void install_package (const cdef_package& pack, const std::string& nm); - - octave_value_list subsref (const std::string& type, - const std::list& idx, - int nargout, int& skip); - - Cell get_classes (void) const; - - Cell get_functions (void) const; - - Cell get_packages (void) const; - - private: - std::map class_map; - std::map function_map; - std::map package_map; - - typedef std::map::iterator class_iterator; - typedef std::map::const_iterator class_const_iterator; - typedef std::map::iterator function_iterator; - typedef std::map::const_iterator function_const_iterator; - typedef std::map::iterator package_iterator; - typedef std::map::const_iterator package_const_iterator; - }; - -public: - cdef_package (void) : cdef_object () { } - - cdef_package (const std::string& nm) - : cdef_object (new cdef_package_rep (nm)) { } - - cdef_package (const cdef_object& obj) - : cdef_object (obj) - { - // This should never happen... - if (class_name () != "meta.package") - error ("internal error: invalid assignment from %s to meta.package object", - class_name ().c_str ()); - } - - cdef_package& operator = (const cdef_package& pack) - { - cdef_object::operator= (pack); - - return *this; - } - - void install_class (const cdef_class& cls, const std::string& nm) - { get_rep ()->install_class (cls, nm); } - - void install_function (const octave_value& fcn, const std::string& nm) - { get_rep ()->install_function (fcn, nm); } - - void install_package (const cdef_package& pack, const std::string& nm) - { get_rep ()->install_package (pack, nm); } - - Cell get_classes (void) const - { return get_rep ()->get_classes (); } - - Cell get_functions (void) const - { return get_rep ()->get_functions (); } - - Cell get_packages (void) const - { return get_rep ()->get_packages (); } - -private: - cdef_package_rep* get_rep (void) - { return dynamic_cast (cdef_object::get_rep ()); } - - const cdef_package_rep* get_rep (void) const - { return dynamic_cast (cdef_object::get_rep ()); } -}; - -class -octave_classdef : public octave_base_value -{ -public: - octave_classdef (void) - : octave_base_value (), object () { } - - octave_classdef (const cdef_object& obj) - : octave_base_value (), object (obj) { } - - octave_classdef (const octave_classdef& obj) - : octave_base_value (obj), object (obj.object) { } - - octave_base_value* clone (void) const - { return new octave_classdef (object.clone ()); } - - octave_base_value* empty_clone (void) const - { return new octave_classdef (); } - - cdef_object get_object (void) const - { return object; } - - bool is_defined (void) const { return true; } - - bool is_map (void) const { return true; } - - bool print_as_scalar (void) const { return true; } - - void print(std::ostream& os, bool pr_as_read_syntax = false) const - { - // FIXME: should call "display" method - print_raw(os, pr_as_read_syntax); - newline(os); - } - - void print_raw(std::ostream& os, bool /* pr_as_read_syntax */ = false) const - { - os << object.class_name () << " object"; - } - - octave_value_list subsref (const std::string& type, - const std::list& idx, int nargout); - - octave_value subsref (const std::string& type, - const std::list& idx) - { - octave_value_list retval = subsref (type, idx, 1); - return (retval.length () > 0 ? retval(0) : octave_value ()); - } - - string_vector map_keys (void) const { return object.map_keys (); } - - dim_vector dims (void) const { return dim_vector (1, 1); } - -private: - cdef_object object; - -private: - DECLARE_OCTAVE_ALLOCATOR - -public: - int type_id (void) const { return t_id; } - std::string type_name (void) const { return t_name; } - std::string class_name (void) const { return object.class_name (); } - - static int static_type_id (void) { return t_id; } - static std::string static_type_name (void) { return t_name; } - static std::string static_class_name (void) { return ""; } - static void register_type (void); - -private: - static int t_id; - - static const std::string t_name; -}; - -inline octave_value -to_ov (const cdef_object& obj) -{ - if (obj.ok ()) - return octave_value (new octave_classdef (obj)); - else - return octave_value (Matrix ()); -} - -inline octave_value -to_ov (const octave_value& ov) -{ return ov; } - -inline cdef_object -to_cdef (const octave_value& val) -{ - if (val.type_name () == "object") - return dynamic_cast (val.internal_rep ())->get_object (); - else - { - warning ("trying to cast non-object into object"); - return cdef_object (); - } -} - -inline cdef_object -to_cdef (const cdef_object& obj) -{ return obj; } - -OCTINTERP_API void install_classdef (void); - -#endif - -/* -;;; Local Variables: *** -;;; mode: C++ *** -;;; End: *** -*/ diff -r af9e2ad52943 -r 5861c4bde387 src/parse-tree/pt-classdef.cc --- a/src/parse-tree/pt-classdef.cc Sun Dec 23 13:19:40 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,260 +0,0 @@ -/* - -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 af9e2ad52943 -r 5861c4bde387 src/parse-tree/pt-classdef.h --- a/src/parse-tree/pt-classdef.h Sun Dec 23 13:19:40 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,653 +0,0 @@ -/* - -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 af9e2ad52943 -r 5861c4bde387 src/parse-tree/pt-funcall.cc --- a/src/parse-tree/pt-funcall.cc Sun Dec 23 13:19:40 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,83 +0,0 @@ -/* - -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-fcn.h" -#include "pt-funcall.h" -#include "pt-walk.h" - -// Function call objects. - -void -tree_funcall::print (std::ostream& os, bool pr_as_read_syntax, - bool pr_orig_text) -{ - print_raw (os, pr_as_read_syntax, pr_orig_text); -} - -void -tree_funcall::print_raw (std::ostream& os, bool pr_as_read_syntax, - bool pr_orig_text) -{ - if (pr_orig_text) - { - os << original_text (); - } - else - { - octave_function *fp = fcn.function_value (); - std::string nm = fp ? fp->name () : std::string (""); - - os << nm << " ("; - - octave_idx_type len = args.length (); - for (octave_idx_type i = 0; i < len; i++) - { - args(i).print_raw (os, pr_as_read_syntax); - - if (i < len - 1) - os << ", "; - } - - os << ")"; - } -} - -tree_funcall * -tree_funcall::dup (symbol_table::scope_id, - symbol_table::context_id context) const -{ - tree_funcall *new_fc = new tree_funcall (fcn, args, line (), column ()); - - new_fc->copy_base (*new_fc); - - return new_fc; -} - -void -tree_funcall::accept (tree_walker& tw) -{ - tw.visit_funcall (*this); -} diff -r af9e2ad52943 -r 5861c4bde387 src/parse-tree/pt-funcall.h --- a/src/parse-tree/pt-funcall.h Sun Dec 23 13:19:40 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,101 +0,0 @@ -/* - -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_funcall_h) -#define octave_tree_funcall_h 1 - -#include "ov.h" -#include "oct-obj.h" -#include "parse.h" -#include "pt-exp.h" - -// Function call. This class only represents function calls that have -// known functions (most useful for calls to built-in functions that -// are generated by the parser) and fixed argument lists, known at -// compile time. - -class -tree_funcall : public tree_expression -{ -public: - - tree_funcall (const octave_value& f, const octave_value_list& a, - int l = -1, int c = -1) - : tree_expression (l, c), fcn (f), args (a) - { - if (! fcn.is_function ()) - error ("tree_funcall: invalid function"); - } - - ~tree_funcall (void) { } - - bool has_magic_end (void) const { return false; } - - void print (std::ostream& os, bool pr_as_read_syntax = false, - bool pr_orig_txt = true); - - void print_raw (std::ostream& os, bool pr_as_read_syntax = false, - bool pr_orig_txt = true); - - tree_funcall *dup (symbol_table::scope_id, - symbol_table::context_id context) const; - - octave_value rvalue1 (int nargout) - { - octave_value retval; - - const octave_value_list tmp = rvalue (nargout); - - if (! tmp.empty ()) - retval = tmp(0); - - return retval; - } - - octave_value_list rvalue (int nargout) - { - return feval (fcn.function_value (), args, nargout); - } - - octave_value function (void) const { return fcn; } - - octave_value_list arguments (void) const { return args; } - - void accept (tree_walker& tw); - -private: - - // Function to call. Error if not a valid function at time of - // construction. - octave_value fcn; - - // Argument list. - octave_value_list args; - - // No copying! - - tree_funcall (const tree_funcall&); - - tree_funcall& operator = (const tree_funcall&); -}; - -#endif