IronPython Source Profiling Series (1): IronPython compiler

Source: Internet
Author: User

Since IronPython officially released, because of the love of the Python language driven, and I want to understand the programming language compiler, parser and other programs are how the principle, how to operate, so I started the IronPython source code of the learning process. But the code has been watching for some time, before looking at some implementation details, the result is more confused. Now I find that I need to change my strategy, because we understand that a system always starts with the way it is used, and if you go directly to the underlying workings, you may get lost in the code ocean. So I also prepare to take the top-down analysis method, pick soft persimmon pinch, from the simple, macro-start. As for the specific implementation details, you can study it slowly and further.

OK, the one I caught today looks like a soft persimmon:

Ironpython/hosting/pythoncompiler.cs

First, let's take a look at the main class in this file: Pythoncompiler (Python compiler)

In this class, there is a bunch of properties that do not have to go to the tube, which means that the compiler will output the type of the file (DLL or EXE), the output path, the reference to which Assembly AH and so on.

Heading straight to the topic, we see the Compile () method, which is responsible for compiling the master control method.
This method is not difficult to understand, I read it again, the following comments:

/// <summary>
///Compile
/// </summary>
Public voidCompile () {
stringFullPath=Path.GetFullPath (outputassembly);
stringOutDir=Path.getdirectoryname (FullPath);
stringFileName=Path.getfilename (outputassembly);

//Accept pool for Python compiler
Pythoncompilersink Sink= NewPythoncompilersink (Compilersink);

//Assembly Generator
Assemblygen= NewAssemblygen (
Path.getfilenamewithoutextension (outputassembly),
OutDir, FileName, IncludeDebugInformation, Statictypes, executable, machine
);

//whether to set entry points (entry point)
    BOOLEntrypointset= false;

//Set the default primary file (for non-DLL output file types)
    if(Mainfile== NULL &&Sourcefiles.count== 1 &&Targetkind!=PEFileKinds.Dll) {
Mainfile=sourcefiles[0];
}

//compile each source file in turn
    foreach (stringsourcefileinchsourceFiles) {
//whether to produce the Main method
        BOOLCreatemainmethod=sourcefile==Mainfile;
//Each source code file is compiled into a single module
Compilepythonmodule (sourcefile, Sink, Createmainmethod);

if(sink. Errors> 0) return;

if(Createmainmethod) {
Entrypointset= true;
}
}

//Add all the resource files to the assembly in turn
    if(Resourcefiles!= NULL) {
foreach(Resourcefile RFinchresourcefiles) {
Assemblygen.addresourcefile (RF. Name, RF. File, RF. Publicresource?ResourceAttributes.Public:ResourceAttributes.Private);
}
}

//for non-DLL target files, an entry point must be required
    if(Targetkind!=PEFileKinds.Dll&& !Entrypointset) {
Sink. Adderror ("", string. Format ("need an entry point for target kind {0}", Targetkind), String.Empty, Codespan.empty,-1, Severity.error);
}

//the assembly that eventually produces the output
Assemblygen.dump ();
}

In this code, the Pythoncompiler class itself is called to the Private Method Compilepythonmodule () to complete the function of the compilation module. Let's take a look at what this method does:

//compiling the module
Private voidCompilepythonmodule (stringFileName, Pythoncompilersink sink,BOOLCreatemain) {
//set the current source file to be compiled
Assemblygen.setpythonsourcefile (fileName);
//creating a compiler environment object
Compilercontext Context= NewCompilercontext (fileName, sink);
//Creating analyzers
Parser P=Parser.fromfile (State, context);
//Call the parser parsing method and get a statement object (the statement should be a nested concept that takes advantage of the combined pattern, which represents a large statement in the entire file)
Statement Body=P.parsefileinput ();

if(sink. Errors> 0) return;

//Create a global suite?? It is possible to refer to globals () as the Dictionary object. Pending analysis ...
//What the Binder is doing here is still to be researched.
globalsuite GS=Compiler.Ast.Binder.Bind (body, context);
stringModuleName=Getmodulefromfilename (fileName);
//Here you see Typegen, the class representing a type generator
//TG points to a module type (in IronPython, each module is generated as a corresponding class. )
Typegen TG=Outputgenerator.generatemoduletype (ModuleName, Assemblygen);
//__init__ method of compiling module?? (guessing)
CodeGen Init=Compilemoduleinit (Context, GS, TG, modulename);

//If you need to create the Main method, create the
    if(Createmain) {
//Lenovo in front of a CodeGen example, observe the call statement can be thought of, the method of the generator is
//CodeGen, and the type of generator is Typegen
CodeGen Main=Outputgenerator.generatemoduleentrypoint (TG, init, modulename, referencedassemblies);
//notice here that the CodeGen code generator contains an important attribute that represents this method
//the MethodInfo of the reflected information, which can be called by this method.
Assemblygen.setentrypoint (Main. MethodInfo, Targetkind);
}

//because the module class is not an ordinary class, you need to add a special tag to it (Attribute)
Assemblygen.addpythonmoduleattribute (TG, modulename);
//the resulting type of action is complete
TG. Finishtype ();
}

In the above two methods, we see that there are several important classes that will be the key clues that we'll proceed to analyze below:

Parser: Analyzer
Statement: statement
Globalsuite:globals ()??
Typegen: Type generator
CodeGen: Code generator (code to generate the method)

In another private method Compilemoduleunit, the main is to do some module import work, the code is easy to understand, here is not detailed analysis.

Now look back, in Ironpython/hosting/pythoncompiler.cs this file, there are still two classes left to mention:
Resourcefile: Represents a related property of a resource file.
Pythoncompilersink: The Accepted pool of Pythoncompiler compilation results is literally understood. As to how it works, let's leave it behind for analysis.

So far, we have generally seen the workflow of the IronPython compiler, starting with a series of source code files, resource files, and other configuration properties, through Parser, various Generator operations, eventually reaching Assemblygenerator's The Dump () method, which outputs the compiled result assembly.

The above code analysis inevitably has the error, still needs to continue to dig and comb.



Source: http://www.cnblogs.com/RChen/archive/2006/10/09/ipysrcstudy1.html

IronPython Source Profiling Series (1): IronPython compiler

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.