luac.c
Upload User: kairuinn
Upload Date: 2009-02-07
Package Size: 2922k
Code Size: 5k
Category:

Graph program

Development Platform:

Visual C++

  1. /*
  2. ** $Id: luac.c,v 1.28 2000/11/06 20:06:27 lhf Exp $
  3. ** lua compiler (saves bytecodes to files; also list binary files)
  4. ** See Copyright Notice in lua.h
  5. */
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include "lparser.h"
  10. #include "lstate.h"
  11. #include "lzio.h"
  12. #include "luac.h"
  13. #define OUTPUT "luac.out" /* default output file */
  14. static int usage(const char* message, const char* arg);
  15. static int doargs(int argc, const char* argv[]);
  16. static Proto* load(const char* filename);
  17. static FILE* efopen(const char* name, const char* mode);
  18. static void strip(Proto* tf);
  19. static Proto* combine(Proto** P, int n);
  20. lua_State* lua_state=NULL; /* lazy! */
  21. static int listing = 0; /* list bytecodes? */
  22. static int dumping = 1; /* dump bytecodes? */
  23. static int stripping = 0; /* strip debug information? */
  24. static const char* output=OUTPUT; /* output file name */
  25. #define IS(s) (strcmp(argv[i],s)==0)
  26. int lc_compile(int argc, const char* argv[]) {
  27.   Proto** P,*tf;
  28.   FILE* f;
  29.   int i;
  30.   listing = 0; /* list bytecodes? */
  31.   dumping = 1; /* dump bytecodes? */
  32.   stripping = 0; /* strip debug information? */
  33.   i = doargs(argc,argv);
  34.   if(i < 0)
  35.     return 0;
  36.   argc -= i;
  37.   argv += i;
  38.   if(argc <= 0)
  39.     return usage("no input file given",NULL);
  40.   L = lua_open(0);
  41.   P = luaM_newvector(L,argc,Proto*);
  42.   for(i = 0; i < argc; i++)
  43.     P[i] = load(argv[i]);
  44.   tf = combine(P,argc);
  45.   if(tf == NULL)
  46.     return 1;
  47.   if(dumping) luaU_optchunk(tf);
  48.   if(listing) luaU_printchunk(tf);
  49.   if(dumping) {
  50.     if(stripping)
  51.       strip(tf);
  52.     f = efopen(output,"wb");
  53.     if(f == NULL) return 1;
  54.     luaU_dumpchunk(tf,f);
  55.     fclose(f);
  56.   }
  57.   return 0;
  58. }
  59. static int usage(const char* message, const char* arg) {
  60.   if(message != NULL) {
  61.     sc_printf("luac: ");
  62.     if(arg != NULL)
  63.       sc_printf(message,arg);
  64.     else
  65.       sc_printf(message);
  66.     sc_printf("n");
  67.   }
  68.   sc_printf("usage: luac [options] [filenames].  Available options are:n");
  69.   sc_printf("  -l       listn");
  70.   sc_printf("  -o file  output file (default is "" OUTPUT "")n");
  71.   sc_printf("  -p       parse onlyn");
  72.   sc_printf("  -s       strip debug informationn");
  73.   sc_printf("  -v       show version informationn");
  74.   return -1;
  75. }
  76. static int doargs(int argc, const char* argv[]) {
  77.   int i;
  78.   for(i = 1; i < argc; i++) {
  79.     if(*argv[i] != '-')   /* end of options */
  80.       break;
  81.     else if(IS("-l"))     /* list */
  82.       listing = 1;
  83.     else if(IS("-o"))     /* output file */
  84.     {
  85.       output = argv[++i];
  86.       if(output == NULL)
  87.         return usage(NULL,NULL);
  88.     }
  89.     else if(IS("-p")) /* parse only */
  90.       dumping = 0;
  91.     else if(IS("-s")) /* strip debug information */
  92.       stripping = 1;
  93.     else if(IS("-v")) /* show version */
  94.     {
  95.       sc_printf("%s  %sn",LUA_VERSION,LUA_COPYRIGHT);
  96.       if(argc == 2)
  97.         return -1;
  98.     }
  99.     else /* unknown option */
  100.       return usage("unrecognized option `%s'",argv[i]);
  101.   }
  102.   if(i == argc && listing) {
  103.     dumping = 0;
  104.     argv[--i] = OUTPUT;
  105.   }
  106.   return i;
  107. }
  108. static Proto* load(const char* filename) {
  109.   Proto* tf;
  110.   ZIO z;
  111.   char source[512];
  112.   FILE* f;
  113.   int c,undump;
  114.   if(filename == NULL)
  115.     return NULL;
  116.   else
  117.     f = efopen(filename,"r");
  118.   if(f == NULL)
  119.     return NULL;
  120.   c = ungetc(fgetc(f),f);
  121.   if(ferror(f)) {
  122.     sc_printf("luac: cannot read from %s",filename);
  123.     fclose(f);
  124.     return NULL;
  125.   }
  126.   undump = (c == ID_CHUNK);
  127.   if(undump) {
  128.     fclose(f);
  129.     f = efopen(filename,"rb");
  130.     if(f == NULL)
  131.       return NULL;
  132.   }
  133.   sprintf(source,"@%.*s",Sizeof(source)-2,filename);
  134.   luaZ_Fopen(&z,f,source);
  135.   tf = undump ? luaU_undump(L,&z) : luaY_parser(L,&z);
  136.   fclose(f);
  137.   return tf;
  138. }
  139. static Proto* combine(Proto** P, int n) {
  140.   if (n==1)
  141.     return P[0];
  142.   else {
  143.     int i, pc = 0;
  144.     Proto* tf = luaF_newproto(L);
  145.     tf->source = luaS_new(L,"=(luac)");
  146.     tf->maxstacksize = 1;
  147.     tf->kproto = P;
  148.     tf->nkproto = n;
  149.     tf->ncode = 2*n+1;
  150.     tf->code = luaM_newvector(L,tf->ncode,Instruction);
  151.     for(i = 0; i < n; i++) {
  152.       tf->code[pc++] = CREATE_AB(OP_CLOSURE,i,0);
  153.       tf->code[pc++] = CREATE_AB(OP_CALL,0,0);
  154.     }
  155.     tf->code[pc++]=OP_END;
  156.     return tf;
  157.   }
  158. }
  159. static void strip(Proto* tf) {
  160.   int i, n = tf->nkproto;
  161.   tf->lineinfo = NULL;
  162.   tf->nlineinfo = 0;
  163.   tf->source = luaS_new(L,"=(none)");
  164.   tf->locvars = NULL;
  165.   tf->nlocvars = 0;
  166.   for(i = 0; i < n; i++) strip(tf->kproto[i]);
  167. }
  168. static FILE* efopen(const char* name, const char* mode) {
  169.   FILE* f = fopen(name,mode);
  170.   if(f == NULL) {
  171.     sc_printf("luac: cannot open %sput file ", *mode=='r' ? "in" : "out");
  172.     return NULL;
  173.   }
  174.   return f;
  175. }