[루아1.1] lua.stx 읽기 (5)

2 분 소요

Lua.stx (5)

계속 Lua.stx 파일을 읽겠습니다. 문법 섹션은 지난 글에서 다 읽었고 이제 다시 C 언어 구현입니다. 거의 다 읽었습니다. 느낌상 루아 1.1 소스 코드를 반 정도 읽은 것 같습니다. 그런데 너무 대충 읽은 것 같네요. 그래도 계속 읽으렵니다.

/*
** Search a local name and if find return its index. If do not find return -1
*/
static int lua_localname (Word n)
{
 int i;
 for (i=nlocalvar-1; i >= 0; i--)
  if (n == localvar[i]) return i;	/* local var */
 return -1;		        /* global var */
}

주석이 기능을 충실히 설명했습니다. 코드 자체도 딱히 어렵지 않네요.

/*
** Push a variable given a number. If number is positive, push global variable
** indexed by (number -1). If negative, push local indexed by ABS(number)-1.
** Otherwise, if zero, push indexed variable (record).
*/
static void lua_pushvar (long number)
{ 
 if (number > 0)	/* global var */
 {
  code_byte(PUSHGLOBAL);
  code_word(number-1);
  incr_ntemp();
 }
 else if (number < 0)	/* local var */
 {
  number = (-number) - 1;
  if (number < 10) code_byte(PUSHLOCAL0 + number);
  else
  {
   code_byte(PUSHLOCAL);
   code_byte(number);
  }
  incr_ntemp();
 }
 else
 {
  code_byte(PUSHINDEXED);
  ntemp--;
 }
}

lua_pushvar() 함수의 주석에 루아 내부 구현에서 전역 변수와 지역 변수를 구분하는 방법을 설명합니다. number 파라메터 값이 0보다 크면 전역 변수 작으면 지역 변수입니다.

static void lua_codeadjust (int n)
{
 code_byte(ADJUST);
 code_byte(n + nlocalvar);
}

static void lua_codestore (int i)
{
 if (varbuffer[i] > 0)		/* global var */
 {
  code_byte(STOREGLOBAL);
  code_word(varbuffer[i]-1);
 }
 else if (varbuffer[i] < 0)      /* local var */
 {
  int number = (-varbuffer[i]) - 1;
  if (number < 10) code_byte(STORELOCAL0 + number);
  else
  {
   code_byte(STORELOCAL);
   code_byte(number);
  }
 }
 else				  /* indexed var */
 {
  int j;
  int upper=0;     	/* number of indexed variables upper */
  int param;		/* number of itens until indexed expression */
  for (j=i+1; j <nvarbuffer; j++)
   if (varbuffer[j] == 0) upper++;
  param = upper*2 + i;
  if (param == 0)
   code_byte(STOREINDEXED0);
  else
  {
   code_byte(STOREINDEXED);
   code_byte(param);
  }
 }
}

lua_codeadjust() 함수는 이전 글에서도 한 번 나왔습니다. ADJUST 명령어 의미를 모르기 때문에 나중에 다른 소스 코드를 읽어야 이해 할 수 있는 함수 입니다. lua_codestore() 함수는 절반이 lua_pushvar()와 같은 구현입니다. 왜 있는 함수인지 모르겠군요.

void yyerror (char *s)
{
 static char msg[256];
 sprintf (msg,"%s near \"%s\" at line %d in file \"%s\"",
          s, lua_lasttext (), lua_linenumber, lua_filename());
 lua_error (msg);
 err = 1;
}

int yywrap (void)
{
 return 1;
}


/*
** Parse LUA code and execute global statement.
** Return 0 on success or 1 on error.
*/
int lua_parse (void)
{
 Byte *init = initcode = (Byte *) calloc(GAPCODE, sizeof(Byte));
 maincode = 0; 
 maxmain = GAPCODE;
 if (init == NULL)
 {
  lua_error("not enough memory");
  return 1;
 }
 err = 0;
 if (yyparse () || (err==1)) return 1;
 initcode[maincode++] = HALT;
 init = initcode;
#if LISTING
 PrintCode(init,init+maincode);
#endif
 if (lua_execute (init)) return 1;
 free(init);
 return 0;
}

yyerror() 함수와 yywrap() 함수는 yacc가 호출하는 함수입니다. lua_parse() 파일은 루아 API에서 호출하는 코드 파싱을 시작하는 함수입니다.

여기까지해서 Lua.stx를 다 읽었습니다. 너무 대충 읽은 것은 감이 있습니다만 제 계획대로 라면 앞으로 20번 더 비슷한 코드를 읽을 것이기 때문에 지금은 대충 읽어도 괜찮습니다.

댓글남기기