U E D R S I H C RSS
ID
Password
Join
모이가 풍족하면 병아리들은 모이를 놓고 서로 싸우지 않는다. 우리 인류도 마찬가지가 아닐까 ―돈 마키스(美 언론인)

 * 원저자 : Peter Shook ([http]http://lua-users.org/wiki/PeterShook)
  • 간단히 말해서, self.iself:func()을 각각 @i, @func()으로 줄여주는 기능을 추가하는 겁니다.
  • 타이핑 노가다를 덜어주는 쓸만한 기능이라 생각합니다. 청크로딩할때 각각 self. 또는 self:으로 replace해주는거라 실행상의 부하는 없어보입니다. (로딩만 조금 느려지는 거겠죠)
  • lua 5.0.2까지는 위 원저자 링크에 있는 [http]lauxlib.c화일을 덮어쓴다음 컴파일하면 됩니다.

수동으로 패치하기 #

  • 5.1work5, 5.1work6에서 각각 테스트 해봤습니다.
  • 우선 아래 코드를 lua소스중 lauxlib.c의 다음 부분에 삽입합니다.
    /*
    ** {======================================================
    ** Load functions
    ** =======================================================
    */
    (이부분입니다)
    typedef struct LoadF {
    ...
    
    추가 코드 :
    #define BINARY_SIG '\033' /* binary files start with "<esc>Lua" */
    #define MAX_NAME 64
    
    typedef struct LoadX {
      lua_Chunkreader reader;
      void *ud;
      int  state;
      int  nest_count;
      const char *bp;
      const char *ep;
      char *np;
      char name[MAX_NAME];
    } LoadX;
    
    static LoadX *initLoadX (LoadX *lx, lua_Chunkreader reader, void *ud) {
      lx->reader = reader;
      lx->ud = ud;
      lx->state = 1;
      lx->nest_count = 0;
      lx->bp = lx->ep = 0;
      lx->np = lx->name;
      return lx;
    }
    
    static const char *fillX (lua_State *L, LoadX *lx, size_t *size) {
      if (lx->bp >= lx->ep) {
        lx->bp = lx->reader(L, lx->ud, size);  /* get chunk */
        if (lx->bp) lx->ep = lx->bp + *size;
      }
      return lx->bp;
    }
    
    static const char *emptyX (LoadX *lx, size_t *size) {
      if (lx->np > lx->name) {
        *size = lx->np - lx->name;
        lx->np = lx->name;
        return lx->name;
      }
      return NULL;
    }
    
    static const char *scanX (LoadX *lx, const char *bp, const char *sc) {
      const char *s;
      for ( ; bp < lx->ep; bp++)
        for ( s = sc; *s; s++)
          if (*s == *bp) return bp;
      return bp;
    }
    
    #define match(lx, c) (*lx->bp == c)
    #define yield(lx, st, act) { lx->state = st; act; case st: ; }
    #define scanfor(lx, st, sc) case st: \
      if ((lx->bp=scanX(lx, lx->bp, sc)) >= lx->ep) { lx->state = st; break; } else
    #define next(lx, st) \
      if (++lx->bp >= lx->ep) yield(lx, st, break) else
    #define flush(lx, st, sp) \
      if (sp < lx->bp) yield(lx, st, break) else
    #define fill(L, lx, st) \
      ( (lx->bp >= lx->ep) ? fillX(L, lx, size) : lx->bp )
    #define copy(L, lx, size, sp) (*lx->np++ = *lx->bp++, sp=fill(L, lx, size))
    #define skip(L, lx, size, sp) (lx->bp++, sp=fill(L, lx, size))
    
    
    static const char *getX (lua_State *L, void *ud, size_t *size) {
      LoadX *lx = (LoadX *)ud;
      const char *sp;
    
      if ((sp=fill(L, lx, size)) == NULL) return emptyX(lx, size);
    
      switch (lx->state) {
      case 0:
        return lx->reader(L, lx->ud, size);  /* get chunk */
      case 1:
        if (match(lx, BINARY_SIG)) {
          lx->state = 0;
          return sp;
        }
    
    Code:
        scanfor(lx, 2, "#-\'\"[@");
    
        if (match(lx, '#')) {
          flush(lx, 3, sp);
          yield(lx, 4, *size = 2; return "--");
    Comment:
          scanfor(lx, 5, "\n");
          goto Code;
        }
    
        if (match(lx, '-')) {
          next(lx, 6);
          if (!match(lx, '-')) goto Code;
          next(lx, 7);
          if (!match(lx, '[')) goto Comment;
          next(lx, 8);
          if (!match(lx, '[')) goto Comment;
          next(lx, 9);
          lx->nest_count = 0;
          goto LongString;
        }
    
        if (match(lx, '\'')) {
          next(lx, 10);
    sqString:
          scanfor(lx, 11, "\'\\");
          if (match(lx, '\'')) {
            next(lx, 12);
            goto Code;
          }
          if (match(lx, '\\')) {
            next(lx, 13);
            next(lx, 14);
            goto sqString;
          }
          break;  /* impossible? */
        }
    
        if (match(lx, '\"')) {
          next(lx, 15);
    dqString:
          scanfor(lx, 16, "\"\\");
          if (match(lx, '\"')) {
            next(lx, 17);
            goto Code;
          }
          if (match(lx, '\\')) {
            next(lx, 18);
            next(lx, 19);
            goto dqString;
          }
          break;  /* impossible? */
        }
    
        if (match(lx, '[')) {
          next(lx, 20);
          if (!match(lx, '[')) goto Code;
          next(lx, 21);
          lx->nest_count = 0;
    LongString:
          scanfor(lx, 22, "[]");
          if (match(lx, ']')) {
            next(lx, 23);
            if (!match(lx, ']')) goto LongString;
            next(lx, 24);
            if (lx->nest_count == 0) goto Code;
            lx->nest_count--;
            goto LongString;
          }
          if (match(lx, '[')) {
            next(lx, 25);
            if (!match(lx, '[')) goto LongString;
            next(lx, 26);
            lx->nest_count++;
            goto LongString;
          }
          break;  /* impossible? */
        }
    
        if (match(lx, '@')) {
          flush(lx, 27, sp);
          lx->np = lx->name;
          copy(L, lx, size, sp);
          if (sp && isalpha(*sp)) {
            const char *en = &lx->name[MAX_NAME];
            copy(L, lx, size, sp);
            while (sp && lx->np < en && isalnum(*sp)) copy(L, lx, size, sp);
            if (lx->np < en) {
              if    (sp && isspace(*sp) && *sp != '\n') copy(L, lx, size, sp);
              while (sp && isspace(*sp) && *sp != '\n') skip(L, lx, size, sp);
              *lx->name = (sp && (*sp=='(' || *sp=='\'' || *sp=='\"')) ? ':' : '.';
              if (sp && lx->np < en && *sp == '[') {
                copy(L, lx, size, sp);
                if (sp && *sp == '[') *lx->name = ':';
              }
              yield(lx, 28, *size = 4; return "self");
            }
          }
          yield(lx, 29, return emptyX(lx, size));
          goto Code;
        }
      }
    
      *size = lx->bp - sp;
      return sp;
    }
    
  • 그다음 luaL_loadfile 함수부분으로 가서 함수 초반에 다음을 선언합니다.
    LoadX lx;
    
    그런다음 다음 부분을 찾아서,
    ...
    ungetc(c, lf.f);
    status = lua_load(L, getF, &lf, lua_tostring(L, -1));
    readstatus = ferror(lf.f);
    ...
    
    여기서 lua_load부분을 다음과 같이 고칩니다.
    ...
    ungetc(c, lf.f);
    initLoadX(&lx, getF, &lf);
    status = lua_load(L, getX, &lx, lua_tostring(L, -1));
    readstatus = ferror(lf.f);
    ...
    
  • 마찬가지로 luaL_loadbuffer 함수도 같이 바꿔줍니다. LoadX lx; 선언하신다음,
    ...
    return lua_load(L, getX, &lx, name);
    }
    
    이 부분을 다음과 같이 바꿉니다.
    ...
    initLoadX(&lx, getS, &ls);
    return lua_load(L, getX, &lx, name);
    }
    

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2010-10-28 12:42:52
Processing time 0.6204 sec