//----------------------------------------------------------------------------- /// @file rf_term.ih /// /// Refal+ term inline method implementation // // $Source$ // $Revision$ // $Date$ //----------------------------------------------------------------------------- #ifndef __rf_term_ih__ #define __rf_term_ih__ #include "rf_term.hh" #include "rf_types.ih" #include "rf_expr.hh" #include "rf_object_ref.ih" #include "rf_word.ih" namespace rfrt { using namespace rftype ; inline Term::Term (unsigned _type) { set_type(_type); } #if 0 inline Term::Term (uint16_t _c) : uint_data2 (_c) { set_type(type_char); } #endif inline Term::~Term () { void (*pf)(Term*) = short_type_funcs[get_short_type()]->dtor; if (pf != null) (*pf)(this); } inline Term::Term (Term const& _t) { void (*pf)(Term*, Term const*) = short_type_funcs[_t.get_short_type()]->ctor; if (pf != null) (*pf)(this, &_t); else { data1 = _t.data1; uint_data2 = _t.uint_data2; } } inline Term& Term::operator = (Term const& _t) { if (_t != self) { this->~Term(); new(this) Term(_t); } return self; } inline Expr Term::create_expr (size_t _len, int _align /* = 0 */) { return Expr(_len, _align); } inline Expr Term::create_flat_expr (size_t _len, int _align /* = 0 */) { Expr e(_len, _align); e.flags |= FLAT_BIT; return e; } inline bool Term::is_sym () const { return get_short_type() > type_parenth; } inline bool Term::is_ref () const { return get_short_type() == type_parenth; } inline bool Term::is_border () const { return data1 == SYM_BORDER; } inline unsigned Term::get_short_type () const { return data1; } inline void Term::set_type (unsigned _type) { data1 = _type; } inline unsigned Term::get_type () const { unsigned type = get_short_type(); if (type != type_object) return type; return static_cast(this)->get_obj_ptr()->get_type(); } #if defined(RF_STORE_CHUNK_ORDER_IN_TERM) inline unsigned get_order () const { return Term::ORDER(data1 & ORDER1_MASK, data2 & ORDER2_MASK); } #endif inline bool Term::operator == (Term const& _t) const { if (data1 != _t.data1) return false; if (uint_data2 == _t.uint_data2) return true; bool (*pf)(Term const*, Term const*) = short_type_funcs[get_short_type()]->eq; if (pf && (*pf)(this, &_t)) return true; return false; } inline bool Term::operator != (Term const& _t) const { return !(*this == _t); } inline bool Term::eq ( Term const* _f1, Term const* _l1, Term const* _f2, Term const* _l2 ) { // // First compare term sequences lengths if ((_l1 - _f1) == (_l2 - _f2)) { // // If lengths are equal do per-term comparison for (; _f1 < _l1; _f1++, _f2++) { if (*_f1 != *_f2) return false; } return true; } return false; } inline bool Term::eq ( Term const* _p1, Term const* _p2, uintptr_t _len ) { for (; _len--; _p1++, _p2++) { if (*_p1 != *_p2) return false; } return true; } template inline C* Term::cast_to (unsigned _type) { unsigned t = get_short_type(); if (t == _type) return reinterpret_cast(this); if (t == type_object) { Object* obj_ptr = static_cast(this)->get_obj_ptr(); if (obj_ptr->get_type() == _type) return reinterpret_cast(obj_ptr); } return null; } inline Term::operator pxx::WString () const { return (*(short_type_funcs[get_short_type()]->to_string))(this); } inline int Term::compare (Term const& _t1, Term const& _t2) { unsigned type1 = _t1.get_short_type(); unsigned type2 = _t2.get_short_type(); if (type1 == type_parenth && type2 != type_parenth) return 1; if (type1 != type_parenth && type2 == type_parenth) return -1; if (type1 > type2) return 1; if (type1 < type2) return -1; int (*cmp)(Term const*, Term const*) = short_type_funcs[type1]->compare; if (cmp) return (*cmp)(&_t1, &_t2); if (_t1.uint_data2 > _t2.uint_data2) return 1; if (_t1.uint_data2 < _t2.uint_data2) return -1; return 0; } inline int Term::compare ( Term const* _f1, Term const* _l1, Term const* _f2, Term const* _l2 ) { uintptr_t len1 = _l1 - _f1; uintptr_t len2 = _l2 - _f2; int compare_len = -1; uintptr_t min_len = len1; if (len1 > len2) { compare_len = 1; min_len = len2; } else if (len1 == len2) { compare_len = 0; } for (; min_len; min_len--) { int res = Term::compare(*_f1++, *_f2++); if (res) return res; } return compare_len; } } #endif // __rf_term_ih__