/*
  이 파일은 ROVM 의 확장 모듈을 작성할 수 있도록 도와주는 헤더 
  파일입니다.
 */

#ifndef _ROVM_ENVLANG_H
#define _ROVM_ENVLANG_H

/*
  다른 헤더에서 정의한 typedef 들과의 충돌을 방지하기 위해서 아래와 같이
  #ifndef 를 사용하게 되었습니다.
*/
#ifndef ROVM_ECLASS_TYPEDEF
typedef struct eclass RvClass;
#endif
#ifndef ROVM_EOBJECT_TYPEDEF
typedef struct eobject RvObject;
#endif
#ifndef ROVM_EVALUE_TYPEDEF
typedef struct rovm_stack RvValue;
#endif

typedef struct emethoddef RvMethodDef;
typedef struct efielddef RvFieldDef;

/**
   Field 모형을 정의한 구조체입니다.
 */
struct efielddef
{
  const char *name;
  const char *type;
};

/**
   Method 의 모형을 정의한 구조체입니다.
 */
struct emethoddef
{
  const char *name;
  const char *type;

  int (*func) (RvObject *cls, RvValue *arg, RvValue *ret);
};

/**
   ObjectRef 에 사용자가 데이타를 설정할 때 사용됩니다.

   @param self  현재 ObjectRef
   @param idx   설정할 사용자 index 번호 (반드시 OBJECT_MAX_USERDATA 보가
                값이 작아야 합니다.
   @param value 설정할 값.
*/
extern int RvSetUserData (RvObject *, int, void *);

/**
   ObjectRef 에 사용자가 설정한 데이타를 얻어올 때, 사용한다.

   (외부 공개 함수)

   @param self  현재 ObjectRef
   @param idx   사용자 데이타의 index 번호
   @return      사용자가 설정한 값을 반환합니다.
*/
extern void *RvGetUserData (RvObject *, int);

/**
   FDS 에 정의되어 있는 field 들을 클래스 CLS 의 하위 field 로 정의한다.

   @param cls   현재 Class 를 정의할 클래스 변수 포인터
   @param fds   Field 가 선언되어 있는 구조체 포인터.
   @return      실행 중 오류가 발생할 경우, -1 을, 그렇지 않을 경우 0 을 반환하게
                된다.
*/
extern int RvDefineFields (RvClass *cls, RvFieldDef *fds);

/**
   CLS 에 MD 를 읽어서 해당 Method 를 정의들을 CLS 내부에 정의한다.

   @param cls   현재 Class 를 정의할 클래스 변수 포인터
   @param md    Method 가 선언되어 있는 변수.
   @return      실행 중 오류가 발생할 경우, -1 을, 그렇지 않을 경우 0 을 반환하게
                된다.
*/
extern int RvDefineMethods (RvClass *, RvMethodDef *);

/**
   ARGS 를 FMT 과 비교하여 해당 변수에 올바른 값을 설정해 주는 역활을 하는
   함수입니다.

   @param args  RvValue 구조체입니다.  이것은 Stack Slot 에 대한 포인터를
                가지게 됩니다.
   @param fmt   해석할 구문입니다.
   @return      성공일 경우 0 을, 그렇지 않을 경우 -1 을 반환한다.
*/
extern int RvParseArg (RvValue *, const char *, ...);

#endif
