[루아2.4] func.h func.c

2 분 소요

func.h

함수 관련 처리 코드를 작성한 파일입니다. 헤더 파일에 새로 추가한 자료 구조가 보이네요.

typedef struct LocVar
{
  TaggedString *varname;           /* NULL signals end of scope */
  int       line;
} LocVar;

이름을 봐서는 로컬 변수를 관리하는 자료 구조로 보입니다.

[2.2]
typedef struct TFunc
{
  struct TFunc	*next;
  char		marked;
  int		size;
  Byte		*code;
  int		lineDefined;
  char		*fileName;
} TFunc;

[2.4]
typedef struct TFunc
{
  struct TFunc	*next;
  int		marked;
  int		size;
  Byte		*code;
  int		lineDefined;
  char		*fileName;
  LocVar        *locvars;
} TFunc;

새로 만든 LocVar 포인터를 추가했습니다. 함수 안에서 선언하는 로컬 변수 관리를 더 명확하게 하려고 만든 것으로 보입니다.

func.c

[2.2]
static TFunc *function_root = NULL;

[2.4]
static TFunc *function_root = NULL;
static LocVar *currvars = NULL;
static int numcurrvars = 0;
static int maxcurrvars = 0;

/*
** Initialize TFunc struct
*/
void luaI_initTFunc (TFunc *f)
{
  f->next = NULL;
  f->marked = 0;
  f->size = 0;
  f->code = NULL;
  f->lineDefined = 0;
  f->fileName = NULL;
  f->locvars = NULL;
}

로컬 변수 관리용 버퍼 포인터와 갯수 관리하는 변수들을 추가했습니다. 그리고 TFunc 자료 구조를 초기화하는 luaI_initTFunc() 함수를 새로 작성했습니다. 그런데 저렇게 코딩할꺼면 굳이 함수를 따로 만들 필요가 없습니다. 그냥 memset(f, 0, sizeof(TFunc)); 하면 됩니다.

/*
** Stores information to know that variable has been declared in given line
*/
void luaI_registerlocalvar (TaggedString *varname, int line)
{
  if (numcurrvars >= maxcurrvars)
    maxcurrvars = growvector(&currvars, maxcurrvars, LocVar, "", MAX_WORD);
  currvars[numcurrvars].varname = varname;
  currvars[numcurrvars].line = line;
  numcurrvars++;
}

/*
** Stores information to know that variable has been out of scope in given line
*/
void luaI_unregisterlocalvar (int line)
{
  luaI_registerlocalvar(NULL, line);
}

/*
** Copies "currvars" into a new area and store it in function header.
** The values (varname = NULL, line = -1) signal the end of vector.
*/
void luaI_closelocalvars (TFunc *func)
{
  func->locvars = newvector (numcurrvars+1, LocVar);
  memcpy (func->locvars, currvars, numcurrvars*sizeof(LocVar));
  func->locvars[numcurrvars].varname = NULL;
  func->locvars[numcurrvars].line = -1;
  numcurrvars = 0;  /* prepares for next function */
}

/*
** Look for n-esim local variable at line "line" in function "func".
** Returns NULL if not found.
*/
char *luaI_getlocalname (TFunc *func, int local_number, int line)
{
  int count = 0;
  char *varname = NULL;
  LocVar *lv = func->locvars;
  if (lv == NULL)
    return NULL;
  for (; lv->line != -1 && lv->line < line; lv++)
  {
    if (lv->varname)               /* register */
    {
      if (++count == local_number)
        varname = lv->varname->str;
    }
    else                           /* unregister */
      if (--count < local_number)
        varname = NULL;
  }
  return varname;
}

luaI_registerlocalvar(), luaI_unregisterlocalvar(), luaI_closelocalvars(), luaI_getlocalname() 함수를 새로 만들었습니다. luaI_registerlocalvar() 함수 구현은 그냥 평범한 구현입니다. 그런데 luaI_unregisterlocalvar() 구현은 좀 이해가 안됩니다. line으로 로컬 변수를 찾는 것도 아니고 인덱스를 증가하면서 null 이 추가될 뿐인데, 이게 어떻게 unregister 동작을 한다는 것인지 모르겠습니다. luaI_closelocalvars() 함수는 함수 파싱을 끝내고 로컬 변수 정보를 함수 자료 구조 인스턴스에 복사하고 관리 변수를 초기화합니다. luaI_getlocalname() 함수는 함수에 등록된 로컬 변수 이름을 찾는 함수입니다. 이 함수를 읽고도 luaI_unregisterlocalvar() 함수 구현은 이해를 못하겠네요.

댓글남기기