//----------------------------------------------------------------------------- /// @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_object.ih" #include "rf_expr.hh" namespace rfrt { using namespace rftype ; inline Term::Term (term_class_t _class, unsigned _type) { set_class(_class); set_type(_type); } inline Term::Term (uint16_t _c) : uint_data2 (_c) { set_class(term_sym); set_type(type_char); } inline Term::Term (Object* _obj) { set_class(term_obj); set_type(_obj->get_type()); new(&uint_data2) Ref(_obj); } inline Term::~Term () { #if 0 if (is_ref()) { // Expr e(this); // e.get_mem_chunk()->dec_ref_count(); MemoryChunk* m = get_mem_chunk(); // // Decrement reference counter and destroy an object if it is zero if (m->dec_ref_count() == 0) { // // Walk through and decrement reference counters on childs // bool f = (data1 & REF_BIT) == 0 ? true : false; Expr::deref_childs( get_first(), (data1 & FLAT_BIT) != 0 ? get_last() : get_first(), m ); // // Deallocate expression holder in memory MemoryChunk::destroy_instance(m); } } #else (this->*dtor_funcs[get_class()])(); #endif } inline Term::Term (Term const& _t) { (this->*ctor_funcs[_t.get_class()])(_t); } 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_ref () const { return get_class() == term_ref; } inline bool Term::is_sym () const { return get_class() == term_sym; } inline bool Term::is_border () const { return data1 == SYM_BORDER; } inline Term* Term::get_first () const { return (Term*)(data1 & PTR_MASK); } inline Term* Term::get_last () const { // return (Term*)(data2 & PTR_MASK); return (Term*)uint_data2; } inline unsigned Term::get_type () const { return data1 >> TYPE_SHIFT; } inline void Term::set_type (unsigned _type) { data1 = (_type << TYPE_SHIFT) | get_class(); } inline term_class_t Term::get_class () const { return (term_class_t)(data1 & CLASS_MASK); } inline void Term::set_class (term_class_t _class) { data1 &= ~(CLASS_MASK); data1 |= _class; } inline MemoryChunk* Term::get_mem_chunk() const { return static_cast(allocator.get_block(get_first())); } #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 { term_class_t cl = get_class(); // // If both terms have the same type... if (cl == _t.get_class()){ // // ...compare them return (this->*eq_funcs[cl])(_t); } else { 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::flat_eq ( Term const* _f1, Term const* _f2, uintptr_t _len ) { for (; _len--; _f1++, _f2++) { // // FIXME: Do not forget to do object comparison for compound symbols if (_f1->get_type() != _f2->get_type() || _f1->uint_data2 != _f2->uint_data2) return false; } return true; } inline Term::Term (Expr const& _expr) : data1 ((uintptr_t)_expr.get_first()), uint_data2 ((uintptr_t)_expr.get_last()) { set_class(term_ref); D(printf("+ term %p from expression %p(%p,%p,%p)\n", this, &_expr, _expr.first, _expr.last, _expr.mem_chunk);) data1 |= (_expr.get_flags() & FLAT_BIT); _expr.get_mem_chunk()->inc_ref_count(); } inline Object& Term::get_object () { if (get_class() == term_obj) { Ref* r1 = (Ref*)(&uint_data2); return *(*r1); } else { FATAL("Term does not contain an object"); } } inline Term::operator pxx::WString () const { return (this->*to_string_funcs[get_class()])(); } } #endif // __rf_term_ih__