#ifndef __PF_STACK__ #define __PF_STACK__ /** @file stack.h @brief Basic stack operations All the pf_stack_ functions perform reference count management. As opposed to pf_list_ and pf_tree_ operations, which work on the list/tree structure only. A stack is treated as a tree (all embedded lists are branches), and all data is owned by the stack. Note that if you create objects that are not referenced on the stacks (return/data/dictionary stacks), you explicitly need to manage them yourself. */ void pf_stack_free(pf_stack_t *s); void pf_stack_clear(pf_stack_t *s); /* forth words. not all the words in forth.c are declared here. if you need more (i.e. for extension modules), this is the place to add declarations. */ pf_error_t pf_stack_drop(pf_stack_t *s); pf_error_t pf_stack_swap(pf_stack_t *s); /* some util stuff */ pf_stack_t *pf_stack_new(void); void pf_stack_free(pf_stack_t *s); void pf_stack_clear(pf_stack_t *s); static inline pf_error_t pf_check_atom(pf_atom_t *s, int n){ while (n--) if (!(s = pf_atom_next(s))) return e_underflow; return e_ok; } /* stack type checking macros */ #define PF_STACK_CHECKN(s, n) if (pf_list_elements(s) < n) return e_underflow #define PF_STACK_CHECK1T(s, t0) if (pf_atom_type(PF_LIST_ATOM_0(s)) != t0) return e_type #define PF_STACK_CHECK2T(s, t0, t1) PF_STACK_CHECK1T(s, t0); if(pf_atom_type(PF_LIST_ATOM_1(s)) != t1) return e_type #define PF_STACK_CHECK3T(s, t0, t1, t2) PF_STACK_CHECK2T(s, t0, t1); if(pf_atom_type(PF_LIST_ATOM_2(s)) != t2) return e_type #define PF_STACK_CHECK4T(s, t0, t1, t2, t3) PF_STACK_CHECK3T(s, t0, t1, t2); if(pf_atom_type(PF_LIST_ATOM_3(s)) != t3) return e_type #define PF_STACK_CHECK1(s, t0) PF_STACK_CHECKN(s, 1); PF_STACK_CHECK1T(s, t0) #define PF_STACK_CHECK2(s, t0, t1) PF_STACK_CHECKN(s, 2); PF_STACK_CHECK2T(s, t0, t1) #define PF_STACK_CHECK3(s, t0, t1, t2) PF_STACK_CHECKN(s, 3); PF_STACK_CHECK3T(s, t0, t1, t2) #define PF_STACK_CHECK4(s, t0, t1, t2, t3) PF_STACK_CHECKN(s, 4); PF_STACK_CHECK4T(s, t0, t1, t2, t3) /* atom pointer checks */ #define PF_ATOM_CHECK_READ(a) if (!a || pf_atom_stale(a)) return e_pointer //#define PF_ATOM_CHECK_WRITE(a) PF_ATOM_CHECK_READ(a); if (!(a->flags & PF_FORTH_ATOM_FLAG_WRITABLE)) return e_access #endif