Solve the problem of the previous article, on the code.
The entrance to the C language program is the main function, and the Lua compiler's entry is the main function in the luac.c file.
Let's take a look at the main function:
int main (int argc, const char* argv[]) {proto** p,*tf; int I=doargs (ARGC,ARGV); argc-=i; argv+=i; if (argc<=0) usage ("N o input files given ", NULL); L=lua_open (0); P=luam_newvector (l,argc,proto*); For (i=0, i<argc; i++) p[i]=load (IS ("-")? Null:argv[i]); Tf=combine (P,ARGC); if (dumping) luau_optchunk (TF); if (listing) Luau_printchunk (TF); if (testing) luau_testchunk (TF); if (dumping) {if (stripping) strip (TF); Luau_dumpchunk (Tf,efopen (Output, "WB")); } return 0;}
The program first declares a function prototype of level two pointer P (which is used as an array of pointers to function prototypes), a function prototype of the pointer TF.
A function prototype can simply be thought of as a LUA file equivalent to a compiled thing.
Each LUA file generates a function prototype, and finally, all of the input LUA files are spelled into a function prototype.
Doargs parse into the parameter. The main is the parameter with the underlined. Is the judgment of a series of IS macro calls. The comment for this function is quite clear. The code is as follows:
Static int doargs (int argc, const char* argv[]) { int i; for (i=1; i<argc; i++) { if (*argv[i]!= '-') /* end of options */ break; else if (Is ("-")) /* end of options; use stdin */ return i; else if (Is ("-l")) /* list */ listing=1; else if (Is ("-o")) /* output file */ { output=argv[++i]; if (output== NULL) usage (null,null); } else if (IS ("-P")) /* parse only */ dumping=0; else if (IS ("-S")) /* strip debug information */ stripping=1; else if (IS ("T")) /* Test */ { testing=1; dumping=0; } else if (Is ("-V")) /* show version */ { printf ("%s %s\n", LUA_VERSION, Lua_copyright); if (argc==2) exit (0); } else /* Unknown option */ usage ("unrecognized option '%s '", Argv[i]); } if (i==argc && (listing | | testing)) { dumping=0; argv[--i]=output; } return i;}
The parsed option is saved in the corresponding static variable.
As shown below:
static int listing=0; /* List bytecodes? */static int dumping=1; /* Dump bytecodes? */static int stripping=0; /* Strip debug information? */static int testing=0; /* Test integrity? */static Const char* Output=output; /* Output File name */
The output filename defaults to "Luac.out", and if the user specifies it, the user-specified name is used. It is ("-o") this piece.
If an error occurs, the usage prompt user is invoked. The usage lists the user and meaning of each parameter.
Once the parameters have been parsed, they are treated as input LUA source code files if there are any remaining command-line arguments.
Create a new lua_state, which is the ubiquitous L in Lua.
New function prototype Proto pointer array.
Call load for each command-line argument and convert it to a function prototype. The code is as follows:
For (i=0, i<argc; i++) p[i]=load (IS ("-")? Null:argv[i]);
Merge this array into a function prototype. Tf=combine (P,ARGC);
The bottom of the few if judgments vary depending on the parameter options and operate differently.
The dump code first optimizes the function prototype. if (dumping) luau_optchunk (TF);
Luau_printchunk (TF); Prints the function prototype content.
Luau_dumpchunk:dump function prototype.
These first lists a question, and later on, although the relationship with the main compilation process is not too large.
Back to the question of compilation, how does a LUA file go through the Proto?
Here's a load function, that's the thing to do.
Static proto* load (const char* filename) {proto* tf; Zio Z; Char source[512]; File* F; int c,undump; if (filename==null) {F=stdin; Filename= "(stdin)"; } else F=efopen (filename, "R"); C=ungetc (Fgetc (f), F); if (Ferror (f)) {fprintf (stderr, "luac:cannot read from"); perror (filename); Exit (1); } undump= (C==id_chunk); if (undump && F!=stdin) {fclose (f); F=efopen (filename, "RB"); } sprintf (Source, "@%.*s", Sizeof (source) -2,filename); Luaz_fopen (&z,f,source); tf = Undump? Luau_undump (l,&z): Luay_parser (l,&z); if (F!=stdin) fclose (f); return TF;}
The program declares a Zio variable and reads the source code from it later.
If the file name is empty, read from the standard input, otherwise open the file.
The first character of the file is read first, and if it is id_chunk, then the open file is a LUA bytecode file.
Finally, depending on whether the LUA bytecode file is open, the undump operation or the syntax interpretation operation is determined.
Combine put multiple Proto into a Proto.
One of the things to be aware of is that a function prototype is a Closure. Is what's inside the For loop.
Strip some debugging information to remove.
The content of this article first to here, and so on after a few related knowledge points to say that it is naturally clear.
Look at the current list of issues, as if it's a lot.
----------------------------------------
The problem so far:
> function prototype optimization luau_optchunk
> Print function prototype Luau_printchunk
> Dump function prototype Luau_dumpchunk
> Memory allocation luam_newvector
> What is Zio?
> Grammatical Analysis of Luay_parser
----------------------------------------
Lua4.0 Compiling the entry