//
// File: macros.h
// Temporary macros (mostly used by debugger agent)
// F.J. Alberti
//

#ifndef _MACROS_H_
#define _MACROS_H_


#include "base.h"            // future types.h
#include "baselib.h"
#include "mmemory.h"


#define SEPTR                int32
#define SEINT                int32
#define SEWORD               int32

#define _SEPTRBIT            0x00000001
#define _SEBLKTYPEMASK       0x00000001
#define _SEBLKSIZEMASK       0xfffffffe

// SE types conversions
#define SEW2I(w)             ((w)>>1)
#define SEW2P(w)             ((w)>>1)
#define SEI2W(n)             ((n)<<1)
#define SEP2W(p)             ((p)<<1 | _SEPTRBIT)

// Type discrimination
#define SEISNULL(w)          ((w) == NIL)
#define SEISPTR(w)           ((w) & _SEPTRBIT)

// Stack management
#define SEGETSP(m)           ((m)->pp)
#define SESETSP(m, sp)       ((m)->pp = (sp))
#define SEPUSH(m, w)         (MMpush((m), (w)))
#define SEPOP(m)             (MMpull(m))
#define SEGETTOP(m, i)       ((m)->top[(m)->pp+(i)])
#define SESETTOP(m, i, v)    ((m)->top[(m)->pp+(i)] = (v))       
#define SEGET(m, i)          ((m)->top[(i)])
#define SESET(m, i, v)       ((m)->top[(i)] = (v))
#define SEDROP(m, n)         ((m)->pp += (n))
#define SEDUP(m)             SEPUSH(m, SEGETTOP(m, 0))
#define SESWAP(m)            if (1) { SEWORD w = SEGETTOP(m, 0);     \
                                      SESETTOP(m, 0, SEGETTOP(m, 1));\
                                      SESETTOP(m, 1, w); } while (0)

// String management
#define SEPUSHSTR(m, s)      (Mpushstrbloc((m), (s)))

// Block management
#define SETYPEBUFFER         0
#define SETYPETUPLE          1          

#define SEBLKTYPE(m, p)      ((m)->tape[(p)] & _SEBLKTYPEMASK)
#define SEBLKSIZE(m, p)      (((m)->tape[(p)] & _SEBLKSIZEMASK)>>1)
#define SEISTUPLE(m, p)      (SEBLKTYPE((m), (p)) == SETYPETUPLE)
#define SEISBUFFER(m, p)     (SEBLKTYPE((m), (p)) == SETYPEBUFFER)
#define SENEWTUPLE(m)        (MBdeftab(m))
#define SEFETCH(m, p, n)     (MMfetch((m), (p), (n)))
#define SESTORE(m, p, n, v)  (MMstore((m), (p), (n), (v)))
#define SEBEG(m, p)          (MMstart((m), (p)))
#define SESTR(m, p)          (MMstartstr((m), (p)))
#define SESTRLEN(m, p)       (MMsizestr((m), (p)))
#define SECSTR(m, p)         ((char*)SEBEG((m), (p)))      // C-strings (only used internally by Runtime)

// Access to stack roots
#define SEGETROOT(m, n)      (MMgetglobal((m), (n)))
#define SESETROOT(m, n, v)   (MMsetglobal((m), (n), (v)))

#define SECHECK(e)           do { int res = (e); if (res) return res; } while (0)

// List management
#define SEHEAD(m, p)         SEFETCH((m), (p), OFFLVAL)
#define SETAIL(m, p)         SEFETCH((m), (p), OFFLNEXT)
#define SESETHEAD(m, p, v)   SESTORE((m), (p), OFFLVAL, (v))
#define SESETTAIL(m, p, v)   SESTORE((m), (p), OFFLNEXT, (v))


#endif // macros.h