Imported from ../lua-4.0.tar.gz.
[lua.git] / src / luac / luac.c
blob8832de62d431caee6c57348b01bbcb827edb1c38
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 */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
11 #include "lparser.h"
12 #include "lstate.h"
13 #include "lzio.h"
14 #include "luac.h"
16 #define OUTPUT "luac.out" /* default output file */
18 static void usage(const char* message, const char* arg);
19 static int doargs(int argc, const char* argv[]);
20 static Proto* load(const char* filename);
21 static FILE* efopen(const char* name, const char* mode);
22 static void strip(Proto* tf);
23 static Proto* combine(Proto** P, int n);
25 lua_State* lua_state=NULL; /* lazy! */
27 static int listing=0; /* list bytecodes? */
28 static int dumping=1; /* dump bytecodes? */
29 static int stripping=0; /* strip debug information? */
30 static int testing=0; /* test integrity? */
31 static const char* output=OUTPUT; /* output file name */
33 #define IS(s) (strcmp(argv[i],s)==0)
35 int main(int argc, const char* argv[])
37 Proto** P,*tf;
38 int i=doargs(argc,argv);
39 argc-=i; argv+=i;
40 if (argc<=0) usage("no input files given",NULL);
41 L=lua_open(0);
42 P=luaM_newvector(L,argc,Proto*);
43 for (i=0; i<argc; i++)
44 P[i]=load(IS("-")? NULL : argv[i]);
45 tf=combine(P,argc);
46 if (dumping) luaU_optchunk(tf);
47 if (listing) luaU_printchunk(tf);
48 if (testing) luaU_testchunk(tf);
49 if (dumping)
51 if (stripping) strip(tf);
52 luaU_dumpchunk(tf,efopen(output,"wb"));
54 return 0;
57 static void usage(const char* message, const char* arg)
59 if (message!=NULL)
61 fprintf(stderr,"luac: "); fprintf(stderr,message,arg); fprintf(stderr,"\n");
63 fprintf(stderr,
64 "usage: luac [options] [filenames]. Available options are:\n"
65 " - process stdin\n"
66 " -l list\n"
67 " -o file output file (default is \"" OUTPUT "\")\n"
68 " -p parse only\n"
69 " -s strip debug information\n"
70 " -t test code integrity\n"
71 " -v show version information\n"
73 exit(1);
76 static int doargs(int argc, const char* argv[])
78 int i;
79 for (i=1; i<argc; i++)
81 if (*argv[i]!='-') /* end of options */
82 break;
83 else if (IS("-")) /* end of options; use stdin */
84 return i;
85 else if (IS("-l")) /* list */
86 listing=1;
87 else if (IS("-o")) /* output file */
89 output=argv[++i];
90 if (output==NULL) usage(NULL,NULL);
92 else if (IS("-p")) /* parse only */
93 dumping=0;
94 else if (IS("-s")) /* strip debug information */
95 stripping=1;
96 else if (IS("-t")) /* test */
98 testing=1;
99 dumping=0;
101 else if (IS("-v")) /* show version */
103 printf("%s %s\n",LUA_VERSION,LUA_COPYRIGHT);
104 if (argc==2) exit(0);
106 else /* unknown option */
107 usage("unrecognized option `%s'",argv[i]);
109 if (i==argc && (listing || testing))
111 dumping=0;
112 argv[--i]=OUTPUT;
114 return i;
117 static Proto* load(const char* filename)
119 Proto* tf;
120 ZIO z;
121 char source[512];
122 FILE* f;
123 int c,undump;
124 if (filename==NULL)
126 f=stdin;
127 filename="(stdin)";
129 else
130 f=efopen(filename,"r");
131 c=ungetc(fgetc(f),f);
132 if (ferror(f))
134 fprintf(stderr,"luac: cannot read from ");
135 perror(filename);
136 exit(1);
138 undump=(c==ID_CHUNK);
139 if (undump && f!=stdin)
141 fclose(f);
142 f=efopen(filename,"rb");
144 sprintf(source,"@%.*s",Sizeof(source)-2,filename);
145 luaZ_Fopen(&z,f,source);
146 tf = undump ? luaU_undump(L,&z) : luaY_parser(L,&z);
147 if (f!=stdin) fclose(f);
148 return tf;
151 static Proto* combine(Proto** P, int n)
153 if (n==1)
154 return P[0];
155 else
157 int i,pc=0;
158 Proto* tf=luaF_newproto(L);
159 tf->source=luaS_new(L,"=(luac)");
160 tf->maxstacksize=1;
161 tf->kproto=P;
162 tf->nkproto=n;
163 tf->ncode=2*n+1;
164 tf->code=luaM_newvector(L,tf->ncode,Instruction);
165 for (i=0; i<n; i++)
167 tf->code[pc++]=CREATE_AB(OP_CLOSURE,i,0);
168 tf->code[pc++]=CREATE_AB(OP_CALL,0,0);
170 tf->code[pc++]=OP_END;
171 return tf;
175 static void strip(Proto* tf)
177 int i,n=tf->nkproto;
178 tf->lineinfo=NULL;
179 tf->nlineinfo=0;
180 tf->source=luaS_new(L,"=(none)");
181 tf->locvars=NULL;
182 tf->nlocvars=0;
183 for (i=0; i<n; i++) strip(tf->kproto[i]);
186 static FILE* efopen(const char* name, const char* mode)
188 FILE* f=fopen(name,mode);
189 if (f==NULL)
191 fprintf(stderr,"luac: cannot open %sput file ",*mode=='r' ? "in" : "out");
192 perror(name);
193 exit(1);
195 return f;
198 void luaU_testchunk(const Proto* Main)
200 UNUSED(Main);
201 fprintf(stderr,"luac: -t not operational in this version\n");
202 exit(1);