basix_doc 0.1
/Users/mourrain/Devel/mmx/basix/src/generic_object.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : generic_object.cpp
00004 * DESCRIPTION: User-defined types
00005 * COPYRIGHT  : (C) 2008  Joris van der Hoeven
00006 *******************************************************************************
00007 * This software falls under the GNU general public license and comes WITHOUT
00008 * ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details.
00009 * If you don't have this file, write to the Free Software Foundation, Inc.,
00010 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00011 ******************************************************************************/
00012 
00013 #ifndef __GENERIC_OBJECT_HPP
00014 #define __GENERIC_OBJECT_HPP
00015 #include <basix/glue.hpp>
00016 namespace mmx {
00017 
00018 nat define_user_type (const generic& name);
00019 nat get_user_type (const generic& name);
00020 
00021 /******************************************************************************
00022 * Dynamic user-defined types
00023 ******************************************************************************/
00024 
00025 class generic_object_rep: public generic_rep {
00026 public:
00027   generic rep;
00028   nat id;
00029 
00030 protected:
00031   nat get_type () const { return id; }
00032   bool same_type (const generic& g) const { return type_id (g) == id; }
00033   nat get_symbolic_type () const { return SYMBOLIC_UNSPECIFIED; }
00034   nat get_species_type () const { return SPECIES_DEFAULT; }
00035   nat get_length () const { return 0; }
00036   generic get_child (nat i) const { ERROR ("invalid child"); return 0; }
00037   nat get_hard_hash_value () const { return hard_hash (rep); }
00038   nat get_exact_hash_value () const { return exact_hash (rep); }
00039   nat get_hash_value () const { return hash (rep); }
00040   bool is_hard_eq (const generic& g) const {
00041     if (type (g) != id) return false;
00042     return hard_eq (rep, ((generic_object_rep*) inspect (g)) -> rep); }
00043   bool is_exact_eq (const generic& g) const {
00044     if (type (g) != id) return false;
00045     return exact_eq (rep, ((generic_object_rep*) inspect (g)) -> rep); }
00046   bool is_equal (const generic& g) const {
00047     if (type (g) != id) return false;
00048     return rep == ((generic_object_rep*) inspect (g)) -> rep; }
00049   generic duplicate_me () const {
00050     return as_object (duplicate (rep), id); }
00051   syntactic expression () const {
00052     if (is_alias_type (id))
00053       return flatten (get_alias (as<alias<generic> > (rep)));
00054     else {
00055       //return apply ("object", flatten (rep), flatten (type_name (id))); }
00056       generic r= current_ev->apply (GEN_FLATTEN, as_object (rep, id));
00057       return as<syntactic> (r); } }
00058   generic binary_type () const {
00059     ERROR ("binary type not implemented for user objects"); }
00060   generic binary_disassemble () const {
00061     ERROR ("binary disassemble not implemented for user objects"); }
00062   void binary_write (const port& p) const {
00063     ERROR ("binary write not implemented for user objects"); }
00064   generic make_abstract_vector () const {
00065     ERROR ("invalid abstraction"); }
00066   generic make_concrete_vector (const generic& v) const {
00067     ERROR ("invalid concretization"); }
00068 
00069 public:
00070   generic_object_rep (const generic& rep2, nat id2):
00071     rep (rep2), id (id2) {}
00072 };
00073 
00074 static bool object_equal (const generic& x, const generic& y) {
00075   return x == y; }
00076 static bool object_unequal (const generic& x, const generic& y) {
00077   return x != y; }
00078 static syntactic object_flatten (const generic& x) {
00079   nat id= type (x);
00080   generic rep= as_generic (x, id);
00081   return apply ("object", flatten (rep), flatten (type_name (id))); }
00082 
00083 static generic object_alias (const generic& x) {
00084   nat alias_id= scalar_to_alias (type (x));
00085   return as_object (as<generic> (new_alias<generic> (x)), alias_id); }
00086 static generic object_get_alias (const generic& x) {
00087   nat alias_id= type (x);
00088   return get_alias (as<alias<generic> > (as_generic (x, alias_id))); }
00089 static generic object_set_alias (const generic& x, const generic& y) {
00090   nat alias_id= type (x);
00091   return set_alias (as<alias<generic> > (as_generic (x, alias_id)), y); }
00092 static generic object_specialize_alias (const alias<generic>& x) {
00093   nat alias_id= scalar_to_alias (type (get_alias (x)));
00094   return as_object (as<generic> (x), alias_id); }
00095 static alias<generic> object_generalize_alias (const generic& x) {
00096   nat alias_id= type (x);
00097   return as<alias<generic> > (as_generic (x, alias_id)); }
00098 
00099 /******************************************************************************
00100 * Definition of user types
00101 ******************************************************************************/
00102 
00103 nat
00104 define_user_type (const generic& name) {
00105   nat id= new_type_id ();
00106   nat alias_id= new_alias_type_id (id);
00107   // nat tuple_id= new_tuple_type_id (id);
00108   define_type_sub (name, id);
00109   define_type_sub (gen (GEN_ALIAS_TYPE, name), alias_id);
00110   // define_type_sub (gen (GEN_TUPLE_TYPE, name), tuple_id);
00111 
00112   {
00113     vector<nat> sig= vec<nat> (alias_id, id);
00114     routine r = unary_routine (GEN_ALIAS, object_alias);
00115     routine r2= change_signature (r, sig);
00116     current_ev->overload (GEN_ALIAS, as<generic> (r2), PENALTY_INCLUSION);
00117   }
00118 
00119   {
00120     vector<nat> sig= vec<nat> (id, alias_id);
00121     routine r = unary_routine (GEN_UNALIAS, object_get_alias);
00122     routine r2= change_signature (r, sig);
00123     alias_getter (alias_id, r2);  
00124   }
00125 
00126   {
00127     vector<nat> sig= vec<nat> (id, alias_id, id);
00128     routine r = binary_routine (GEN_UNALIAS, object_set_alias);
00129     routine r2= change_signature (r, sig);
00130     alias_setter (alias_id, r2);  
00131   }
00132 
00133   {
00134     vector<nat> sig= vec<nat> (alias_id, type_id<alias<generic> > ());
00135     routine r = unary_routine (GEN_SPECIALIZE, object_specialize_alias);
00136     routine r2= change_signature (r, sig);
00137     alias_specializer (id, r2);
00138   }
00139 
00140   {
00141     vector<nat> sig= vec<nat> (id, alias_id);
00142     generic cv= gen (GEN_INTO, name, gen (GEN_ALIAS_TYPE, name));
00143     routine r = unary_routine (cv, object_get_alias);
00144     routine r2= change_signature (r, sig);
00145     current_ev->overload (GEN_REWRITE, as<generic> (r2), PENALTY_INCLUSION);
00146   }
00147 
00148   {
00149     vector<nat> sig= vec<nat> (type_id<alias<generic> > (), alias_id);
00150     generic cv= gen (GEN_INTO, gen (GEN_ALIAS_TYPE, GEN_GENERIC_TYPE),
00151                                gen (GEN_ALIAS_TYPE, name));
00152     routine r = unary_routine (cv, object_generalize_alias);
00153     routine r2= change_signature (r, sig);
00154     current_ev->overload (GEN_REWRITE, as<generic> (r2), PENALTY_INCLUSION);
00155   }
00156 
00157   {
00158     vector<nat> sig= vec<nat> (type_id<bool> (), id, id);
00159     routine r = binary_routine (GEN_EQUAL, object_equal);
00160     routine r2= change_signature (r, sig);
00161     current_ev->overload (GEN_EQUAL, as<generic> (r2), PENALTY_INCLUSION);
00162   }
00163 
00164   {
00165     vector<nat> sig= vec<nat> (type_id<bool> (), id, id);
00166     routine r = binary_routine (GEN_UNEQUAL, object_unequal);
00167     routine r2= change_signature (r, sig);
00168     current_ev->overload (GEN_UNEQUAL, as<generic> (r2), PENALTY_INCLUSION);
00169   }
00170 
00171   {
00172     vector<nat> sig= vec<nat> (type_id<syntactic> (), id);
00173     routine r = unary_routine (GEN_FLATTEN, object_flatten);
00174     routine r2= change_signature (r, sig);
00175     current_ev->overload (GEN_FLATTEN, as<generic> (r2), PENALTY_INCLUSION);
00176   }
00177 
00178   return id;
00179 }
00180 
00181 nat
00182 get_user_type (const generic& name) {
00183   nat r= type_id (name);
00184   if (r == 1) {
00185     generic tp= name;
00186     if (is_func (tp, GEN_TUPLE_TYPE, 1)) tp= tp[1];
00187     if (is_func (tp, GEN_ALIAS_TYPE, 1)) tp= tp[1];
00188     if (is_func (tp, GEN_GENERIC_ALIAS_TYPE, 1)) tp= tp[1];
00189     define_user_type (tp);
00190     r= type_id (name);
00191   }
00192   return r;
00193 }
00194 
00195 /******************************************************************************
00196 * Interface
00197 ******************************************************************************/
00198 
00199 generic
00200 as_object (const generic& g, nat tp_id) {
00201   return new generic_object_rep (g, tp_id);
00202 };
00203 
00204 generic
00205 as_object (const generic& g, const generic& tp) {
00206   return new generic_object_rep (g, get_user_type (tp));
00207 };
00208 
00209 generic
00210 as_generic (const generic& g, nat tp_id) {
00211   ASSERT (type (g) == tp_id, "type mismatch");
00212   return ((generic_object_rep*) inspect (g)) -> rep;
00213 };
00214 
00215 generic
00216 as_generic (const generic& g, const generic& tp) {
00217   ASSERT (type (g) == get_user_type (tp), "type mismatch");
00218   return ((generic_object_rep*) inspect (g)) -> rep;
00219 };
00220 
00221 } // namespace mmx
00222 #endif // __GENERIC_OBJECT_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines