/*     
      LIBUSER.H . Magma 1.0 . 1996 . Sylvain HUET

         definitions pour l'utilisateur de la machine SCOL
*/

/* DEFINITIONS DE TYPES ET DE CONSTANTES
  ---------------------------------------
*/
// Modification history:
//$ FA(06/06/2001): Add conditional definition of Mmachine struct
//$ FA(10/07/2001): Add conditional inclusion macros #ifndef _KERNEL_H_/#endif
//$ FA(03/08/2001): Add declaration of MMputs() function
//

#ifndef _KERNEL_H_
#define _KERNEL_H_

#include <scolPrerequisites.h>
#include <scolMachine.h>
#include <scolPackDir.h>
#include <scolErrorCodes.h>
#include <scolConstants.h>

#ifdef __cplusplus
extern "C" 
{
#endif

extern struct Mmachine mscol;

/* 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 */
int Mpushstrblocn(mmachine m,char *buf,int l);

/* 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);
int MBstrcatn(mmachine m);

/* 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
  ------------------------------
*/
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,...);
//$ FA(03/08/2001): Echo a string (length is unrestricted)
void MMputs(int i, const char* text);

/* */
void* SCgetExtra(char *funcname);

/* enregistrement d'un nouveau type d'objet */
int OBJregister(int nbrefl,int recrefl,
				int (*destroy)(mmachine m,int handsys,int objm),char *name);

/* determine un numero de type en fonction du nom */
int OBJtypebyname(char *name);


/* obtention d'un nouvel evenement utilisateur */
int OBJgetUserEvent();

/* trouve un objet en fonction du handler systeme (notation int) et du typ (notation int)
 retourne le pointeur ou -1 si introuvable */
int OBJfindTH(mmachine m,int typ,int handsys);

/* trouve un objet en fonction de l'objet magma (notation obj) et du typ (notation int)
 retourne le pointeur ou -1 si introuvable */
int OBJfindTM(mmachine m,int typ,int objm);

/* creation d'un nouvel objet
en 1 : canal
en 0 : objet magma
retourne : 
en 0 : objet inchange
*/
int OBJcreate(mmachine m,int typ,int handsys,int typpere,int handsyspere);

/* definition d'un reflexe
en 2 : objet magma
en 1 : fonction magma
en 0 : argument user
retourne :
en 0 : objet
*/
int OBJaddreflex(mmachine m,int typ, int num);

/* commence le traitement d'un reflexe d'un certain type, avec un certain handler
et un certain numero de reflexe.
retourne :
 0 si OK
 1 si objet non trouve
 autre si erreur RUNTIME
 */
int OBJbeginreflex(mmachine m,int typ,int handsys,int num);

/* appel du reflexe
  nbarg est le nombre d'arguments ajoutes par l'utilisateur */
int OBJcallreflex(mmachine m,int nbarg);

/* destruction d'un objet en fonction de son type et du handler systeme */
int OBJdelTH(mmachine m,int typ,int handsys);

/* destruction d'un objet en fonction de son type et de l'objet magma */
int OBJdelTM(mmachine m,int typ,int q);

/* destruction de tous les objets lies a un canal (notation obj) */
int OBJdelChn(mmachine m,int canal);

/* donne a un canal tous les objets d'un autre */
int OBJchgchannel(mmachine m,int oldchn, int newchn);

/* destruction d'un objet */
int OBJdel(mmachine m,int p,int flag);

int OBJdestroy(mmachine m, int typ,int handsys,int objm,int flag);

/* compte le nombre d'objets d'un certain type */
int OBJcountT(mmachine m,int typ);
/* initialisation de la gestion des objets */
int OBJinit();

#ifdef __cplusplus
}
#endif

#endif // kernel.h
