#ifndef __rf_stack_ih__ #define __rf_stack_ih__ #include "rf_stack.hh" #include "rf_expr.ih" #include "rf_integer.ih" #include "rf_func.ih" namespace rfrt { inline void Stack::push (Expr const& _expr) { if (top > last) FATAL("Stack exhausted"); new (top++) Expr(_expr); } inline void Stack::pop (Expr& _expr) { _expr.~Expr(); new (&_expr) Expr(top++); } inline Expr const* Stack::get () { return top++; } inline Expr* Stack::get_top () { args_num = -1; return top; } inline void Stack::set_top (Expr* _top) { top = _top; } inline void Stack::destroy_results (Expr* _saved_top, size_t _saved_depth) { while (top > _saved_top) { top--; D( printf("destroy_results: %p(%p,%p,%p)\n", top, top->get_first(), top->get_last(), top->get_mem_chunk()); ) top->~Expr(); } depth = _saved_depth; } inline void Stack::destroy_results () { top--; Expr* ress = top - *(reinterpret_cast(top)); Expr* args = ress - *(reinterpret_cast(top) + 1); while (top > ress) (--top)->~Expr(); top = args; dec_depth(); } inline void Stack::cleanup (size_t _saved_depth) { if (trap_stack_on) { trap_stack = get_part(0, depth - _saved_depth); while (depth > _saved_depth) destroy_results(); } else { top = get_upper(depth - _saved_depth); depth = _saved_depth; } } inline void Stack::start_push_mode () { args_num = -1; saved_top = top; } inline void Stack::stop_push_mode () { args_num = top - saved_top; top = saved_top; }; inline void Stack::start_ress_mode () { saved_top = top; } /* * Add to the stack special node -- 3 words: * - number of the results * - number of the arguments * - pointer to the function */ inline void Stack::stop_ress_mode (rftype::Func const* _f) { if (top > last) FATAL("Stack exhausted"); uintptr_t* p = reinterpret_cast(top); *p++ = top - saved_top; *p++ = args_num; *p = reinterpret_cast(_f); top++; inc_depth(); } inline void Stack::start_pop_mode () { top--; top -= *reinterpret_cast(top); } inline void Stack::start_pop_mode (Expr* const __rf_call_saved_top) { top = __rf_call_saved_top; args_num = 0; } inline void Stack::stop_pop_mode () { uintptr_t* p = reinterpret_cast(top); top -= *p + *(p + 1); dec_depth(); } inline bool Stack::is_in_push_mode () const { return args_num == -1; } inline Expr* Stack::get_upper (size_t _offset) const { Expr* node = top; while (_offset--) { node--; uintptr_t* p = reinterpret_cast(node); node -= *p + *(p + 1); } return node; } inline void Stack::up () { top = get_upper(1); dec_depth(); } inline void Stack::inc_depth () { depth++; } inline void Stack::dec_depth () { depth--; } inline size_t Stack::get_depth () const { return depth; } inline rftype::Func* Stack::get_func (size_t _depth) const { uintptr_t* p = reinterpret_cast(get_upper(depth - _depth) - 1); return reinterpret_cast(*(p + 2)); } inline int Stack::get_args (size_t _depth, Expr** _args) const { uintptr_t* p = reinterpret_cast(get_upper(depth - _depth) - 1); *_args = (reinterpret_cast(p) - *p) - *(p + 1); return *(p + 1); } /* * _p is a ponter to special node. * Returns pointer to that node function. */ inline rftype::Func* Stack::getf (Expr const* _p) { return reinterpret_cast( *(reinterpret_cast(_p) + 2)); } /* * _p is a ponter to special node. * Returns number of arguments in corresponding call. */ inline int Stack::getn (Expr const* _p) { return *(reinterpret_cast(_p) + 1); } /* * _p is a ponter to special node. * Returns pointer to the first argument. */ inline Expr const* Stack::geta (Expr const* _p) { return (_p - *reinterpret_cast(_p)) - *(reinterpret_cast(_p) + 1); } /* * _p is a ponter to special node. * Returns pointer to the previous special node. */ inline Expr const* Stack::getup (Expr const* _p) { return geta(_p) - 1; } inline Expr Stack::get_part (size_t _offset, size_t _len) const { size_t depth = get_depth() - _offset; if (!_len) _len = depth; Expr const* p = get_upper(_offset) - 1; Expr e; while (_len--) { int n = getn(p); Expr const* ap = geta(p); Expr e_args; while (n--) e_args = e_args + (*ap++)(); e = e + (Expr::create(depth--) + Expr::create_sym(getf(p)) + e_args)(); p = getup(p); } return e; } /* * For debugging purposes. */ inline void Stack::dump () const { Expr const* p = top - 1; for (int i = depth; i; i--, p = getup(p)) { printf("Node %d:\n", i); Expr const* ap = geta(p); for (int n = getn(p); n; n--, ap++) { printf(" (%p,%p,%p:%u)\n", ap->get_first(), ap->get_last(), ap->get_mem_chunk(), ap->get_mem_chunk() ? ap->get_mem_chunk()->get_ref_count() : 0); } } } inline Expr const& Expr::operator , (Expr const& _expr) const { stack->push(*this); return _expr; } inline Expr const& Expr::operator , (Expr const& _expr) { stack->push(*this); return _expr; } inline Expr& Expr::operator , (Expr& _expr) { if (stack->is_in_push_mode()) stack->push(*this); else stack->pop(*this); return _expr; } inline Result& Expr::operator , (Result& _res) { stack->pop(*this); return _res; } } #endif // __rf_stack_ih__