/*     
      LIBUSER.H . Magma 1.0 . 1996 . Sylvain HUET

         definitions pour l'utilisateur de la machine SCOL
*/

/* DEFINITIONS DE TYPES ET DE CONSTANTES
  ---------------------------------------
*/

#ifdef __cplusplus
extern "C" {
#endif

#define NIL -1

/* masque pour MMmalloc : tableau d'objets ou buffer quelconque */
#define TYPETAB 1
#define TYPEBUF 0

struct Mmachine
{
  int *tape;     /* pointeur vers la bande       */
  int sizetape;  /* taille de la bande (en mots) */
  int pp;        /* pointeur de pile             */
  int maxpp;     /* valeur max de pp             */
  int topheap;   /* sommet du tas                */
  int sigGC;     /* distance declenchant le GC   */
  int h;         /* position header courant      */
  int err;
};
typedef struct Mmachine *mmachine;

/* definitions des erreurs */
#define MERREND     1
#define MERROK      0
#define MERRMEM    -1
#define MERRTYP    -2
#define MERRRET    -3
#define MERRNUL    -4
#define MERRNF     -5
#define MERRLINK   -6
#define MERRFULL   -7
#define MERRUNKNOWN -8
#define MERRTOOLARGE -9

#define OFFSCBASE    6
#define OFFSCSYS     5
#define OFFSCSERVER  4
#define OFFSCOBJ     3
#define OFFSCRESS    2
#define OFFSCCHAN    1 
#define OFFSCCUR     0

/* GESTION DE LA BANDE MEMOIRE SCOL
  ----------------------------------
*/

/*
   Empilement d'un nouvel objet
        retourne -1 si erreur, 0 si succes.
*/
int MMpush(mmachine m, int val);

/*
   Empilement d'un nouvel objet sans GC : a utiliser avec precaution
        retourne 0
*/
int MMpushNoGC(mmachine m, int val);

/*
   Depile un objet
*/
int MMpull(mmachine m);

/* Lit la valeur du pointeur de pile */
int MMgetPP(mmachine m);

/* Ecrit la valeur du pointeur de pile */
void MMsetPP(mmachine m,int i);

/*
   Lit un etage de la pile, sans le depiler
*/
int MMget(mmachine m,int i);

/*
   Ecrit un etage de la pile, sans le depiler
*/
void MMset(mmachine m,int i,int v);

/*
   Lit une variable globale
*/
int MMgetglobal(mmachine m,int i);

/*
   Ecrit une variable globale
*/
void MMsetglobal(mmachine m,int i,int v);

/*
   Lit un champ de la pile, a partir d'une base donee
*/
int MMgetbase(mmachine m,int b,int i);

/*
   Ecrit un champ de la pile, a partir d'une base donnee
*/
void MMsetbase(mmachine m,int b,int i,int v);

/*
   Lit un champ d'un bloc TAB
*/
int MMfetch(mmachine m,int s,int i);

/*
   Ecrit un champ d'un bloc TAB
*/
void MMstore(mmachine m,int s,int i,int v);

/*
   Recupere un pointeur vers le debut d'un bloc BUF
*/
int* MMstart(mmachine m,int s);

/*
   Donne la taille en "int" d'un bloc BUF ou TAB
*/
int MMsize(mmachine m,int s);

/*
   Donne le type d'un bloc BUF ou TAB -> TYPEBUF ou TYPETAB
*/
int MMtype(mmachine m,int s);

/*
   Recupere un pointeur vers le debut d'une chaine de caracteres
*/
char* MMstartstr(mmachine m,int s);

/*
   Recupere la taille d'une chaine de caracteres
*/
int MMsizestr(mmachine m,int s);

/*
   Regle la taille d'une chaine de caracteres
*/
void MMsetsizestr(mmachine m,int s,int size);

/*
   Fonctions de transfert Objet <-> Int ou Pointer
*/
int ITOO(int i);
int PTOO(int p);
int OTOI(int i);
int OTOP(int p);

/*
   Alloue un bloc dans le tas : la taille est donnee en mots
    le bloc est initialise selon type
    retourne -1 si echec, sinon retourne le pointeur
*/
int MMmalloc(mmachine m, int size, int type);

/*
   Idem Malloc, avec mise a zero du bloc
    retourne -1 si echec, sinon retourne le pointeur
*/
int MMmallocCLR(mmachine m, int size, int type);

/* empilement d'une chaine sous forme de bloc (la chaine ne doit pas etre dans la bande memoire scol */
int Mpushstrbloc(mmachine m,char *buf);

/* empilement d'une chaine sous forme de bloc (la chaine ne doit pas etre dans la bande memoire scol */
int Mpushstrblocn(mmachine m,char *buf,int n);

/* BYTECODE : creation d'un bloc de type TAB en recuperant la taille et les elements dans la pile
 niv 2 : objet A
 niv 1 : objet B
 niv 0 : entier 2
 -> depile les trois arguments et empile le tuple [A B]
*/
int MBdeftab(mmachine m);

/* BYTECODE : concatenation de deux chaines de caracteres en memoire scol
 niv 1 : chaine "xyz"
 niv 0 : chaine "abc"
 -> depile les deux arguments et empile la chaine "xyzabc"
*/
int MBstrcat(mmachine m);

/* INITIALISATION DE LA MACHINE SCOL
  ------------------------------------
*/

#define TYPVAR    -1
#define TYPCONS   -2
#define TYPTYPE   -3
#define TYPFIELD  -4
#define TYPSTRUC  -5
#define TYPCONS0  -6
#define TYPCOM    -7
#define TYPCOMV   -8

/* lecture d'un package en dur
  en 0: liste des packages deja charges
 retourne en 0: nouvelle liste
*/ 
int PKhardpak(mmachine m, char *name,
              int n, char **namefun, int (**fun)(mmachine z)
              , int *nargfun, char **typfun);

/* lecture et linkage d'un package en Magma
  en 0: liste des packages deja charges
 retourne en 0: nouvelle liste
*/ 
int PKloader(mmachine m,char *name,char *simplename);

/* taille de la bande memoire reservee par la machine SCOL
 (donnee en nombre de mots de 4 octets : 16384 -> 64Ko)
*/
extern int ScolMemoryLength;



/* GESTION DES FICHIERS EN SCOL
  ------------------------------
*/
#define SIZESIGN 1024

struct Packdir
{
  char path[SIZESIGN];  /* se termine par '/' */
  int quota;   /* -1: read only, 0: unlimited */
  struct Packdir *next;
};
typedef struct Packdir *packdir;

#define TYPESNONE  0
#define TYPESLOGIC 1

extern packdir Firstpack;

/* trouve un package dans la liste des packdir */
int SPfindfile(packdir p,char *sign,int *size,char *path);

/* ajout d'un fichier : trouve le chemin complet a partir du nom complet et 
  de la taille */
int SPaddfile(packdir p,char *sign,int size,char *path);


/* ACCES AUX NUMEROS DE SOCKET
  ------------------------------
*/

/* lecture du numero de socket associe a un serveur
   (server est un pointeur vers le serveur, avec bit 0 a 1) */
int SCgetsrvsocket(mmachine m, int server);

/* lecture du numero de socket associe a un canal
   (channel est un pointeur vers le canal, avec bit 0 a 1) */
int SCgetsocket(mmachine m, int channel);


/* FONCTIONS UTILES
  ------------------------------
*/

/* decoupage d'une chaine en mots (retourne le nombre de mots) */  
int Mcutting(char *comm, char **argv);


/* DEBUGGAGE
  -----------
*/

/* affichage d'un message dans le log, l'entier est un masque d'affichage, (0 pour non masquable) */
void MMechostr(int i,char *buf,...);
/* definitions des masques de message console */
#define MSKFOO     1
#define MSKRUNTIME 2
#define MSKWARNING 4
#define MSKTRACE   8
#define MSKDEBUG   16

#ifdef __cplusplus
}
#endif
