//----------------------------------------------------------------------------- /// @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_parenth.hh" #include "rf_object_ref.ih" #include "rf_word.ih" namespace rfrt { using namespace rftype ; inline Term::Term (unsigned _type) : data1 (_type) { // set_type(_type); } inline Term::Term (unsigned _type, void* _ptr) : data1 (_type), ptr_data2 (_ptr) {} 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; return !is_ref(); } inline bool Term::is_ref () const { // return get_short_type() == type_parenth; return is_instance_of(); } 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 short_type_funcs[type]->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; } template inline C* Term::cast_to () { unsigned t = get_short_type(); if (t == C::reg.get_type()) return reinterpret_cast(this); if (t == type_object) { Object* obj_ptr = static_cast(this)->get_obj_ptr(); if (obj_ptr->get_type() == C::reg.get_type()) return reinterpret_cast(obj_ptr); } return null; } template inline C const& Term::get_object () const { assert(is_instance_of()); return static_cast::Type> const*>(this)-> get_object(); } template inline C* Term::get_obj_ptr () const { assert(is_instance_of()); return static_cast::Type> const*>(this)-> get_obj_ptr(); } template inline bool Term::is_instance_of () const { return short_type_funcs[get_short_type()]->type == Symbol::Type>::get_type(); } inline Term::operator pxx::WString () const { pxx::WString (*to_wstr)(Term const*) = short_type_funcs[get_short_type()]->to_string; if (to_wstr) return (*to_wstr)(this); size_t max_len = 2 * max_int_len + 4; wchar_t* str = static_cast(alloca(max_len * sizeof(wchar_t))); int len = swprintf(str, max_len, L"<%u|%u>", data1, uint_data2); if (-1 == len) FATAL("<%u|%u> is more then %u wide characters", data1, uint_data2, max_len); return pxx::WString(str, len); } inline size_t Term::get_name (wchar_t const** _np) const { size_t (*fp)(Term const*, wchar_t const**) = short_type_funcs[get_short_type()]->get_name; if (fp) return (*fp)(this, _np); return (size_t)-1; } inline int Term::compare (Term const& _t1, Term const& _t2) { unsigned t1 = _t1.get_short_type(); unsigned t2 = _t2.get_short_type(); unsigned type1 = short_type_funcs[t1]->type; unsigned type2 = short_type_funcs[t2]->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[t1]->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__