рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ "рдПрд▓рдПрд▓рд╡реАрдПрдо рдХреЗ рд╕рд╛рде рдПрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ рдмрдирд╛рдирд╛" рдХреЗ рдЕрдзреНрдпрд╛рдп 3 рдореЗрдВ рдЖрдкрдХрд╛ рд╕реНрд╡рд╛рдЧрдд рд╣реИред рдЗрд╕ рдЕрдзреНрдпрд╛рдп рдореЗрдВ, рд╣рдо рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐
рдЕрдзреНрдпрд╛рдп 2 рдореЗрдВ рдирд┐рд░реНрдорд┐рдд AST (Abstract Syntax Tree) рдХреЛ LLVM IR рдореЗрдВ рдХреИрд╕реЗ рдмрджрд▓рд╛ рдЬрд╛рдПред рд╡рд╣ рдЖрдкрдХреЛ LLVM рдХреЗ рдХреБрдЫ рдкрд╣рд▓реБрдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрддрд╛рдПрдЧрд╛, рдФрд░ рдпрд╣ рднреА рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдЧрд╛ рдХрд┐ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдХрд┐рддрдирд╛ рдЖрд╕рд╛рди рд╣реИред рдЖрдк рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рдПрд▓рдПрд▓рд╡реАрдПрдо рдЖрдИрдЖрд░ рдХреЛрдб рдХреЗ рдкреНрд░рддреНрдпрдХреНрд╖ рдирд┐рд░реНрдорд╛рдг рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рд▓реЗрдХреНрд╕рд┐рдХрд▓ рдФрд░ рдкрд╛рд░реНрд╕рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЕрдзрд┐рдХ рдХрд╛рдо рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереАред
рдиреЛрдЯ : рдЗрд╕ рдЕрдзреНрдпрд╛рдп рдХреЗ рдХреЛрдб рдХреЛ LLVM 2.2 рдпрд╛ рдмрд╛рдж рдХреЗ рд╕рдВрд╕реНрдХрд░рдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдПрд▓рдПрд▓рд╡реАрдПрдо 2.1 рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЗ рд╕рд╛рде, рдпрд╣ рдХреЛрдб рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред рдпрд╣ рднреА рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдХрд┐ рдЖрдкрдХреЛ рдЕрдкрдиреЗ рдПрд▓рдПрд▓рд╡реАрдПрдо рд░рд┐рд▓реАрдЬрд╝ рд╕реЗ рдореЗрд▓ рдЦрд╛рдиреЗ рд╡рд╛рд▓реЗ рдЗрд╕ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдХреЗ рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП: рдЖрдк рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рд░рд┐рд▓реАрдЬрд╝ рдХреЗ рд╕рд╛рде рдЖрдиреЗ рд╡рд╛рд▓реЗ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдпрд╛
llvm.org рдкрд░ рд░рд┐рд▓реАрдЬрд╝ рдкреЗрдЬ рдкрд░ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ ред
рд╣рдо рдХреЛрдб рдкреАрдврд╝реА рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИрдВ
LLVM IR рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдХреБрдЫ рд╕рд░рд▓ рд╕реЗрдЯрдЕрдкреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рдПрдПрд╕рдЯреА рд╡рд░реНрдЧ рдХреЗ рд▓рд┐рдП рд╡рд░реНрдЪреБрдЕрд▓ рдХреЛрдб рдЬрдирд░реЗрд╢рди рдореЗрдердб (
Codegen
) рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ:
virtual Value *Codegen() = 0;
};
virtual Value *Codegen();
}; ...
Codegen()
рд╡рд┐рдзрд┐ рдЕрдкрдиреЗ рд╕рднреА рдЖрд╢реНрд░рд┐рддреЛрдВ рдХреЗ рд╕рд╛рде рджрд┐рдП рдЧрдП рдПрдПрд╕рдЯреА рдиреЛрдб рдХреЗ рд▓рд┐рдП рдЖрдИрдЖрд░ рд▓реМрдЯрд╛рдПрдЧреА, рдФрд░ рд╡реЗ рд╕рднреА
LLVM Value
рдСрдмреНрдЬреЗрдХреНрдЯ рд▓реМрдЯрд╛рдПрдВрдЧреЗред
"Value"
рдПрд▓рдПрд▓рд╡реАрдПрдо рдореЗрдВ "
рд╕реНрдЯреЗрдЯрд┐рдХ рд╕рд┐рдВрдЧрд▓ рдЕрд╕рд┐рд╕реНрдореЗрдВрдЯ (
рдПрд╕рдПрд╕рдП )
рд░рдЬрд┐рд╕реНрдЯрд░ " рдпрд╛ "рдПрд╕рдПрд╕рдП рд╡реИрд▓реНрдпреВрдЬрд╝" рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдиреЗ рд╡рд╛рд▓рд╛ рд╡рд░реНрдЧ рд╣реИред рдПрд╕рдПрд╕рдП рдореЗрдВ рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд┐рдВрджреБ рдпрд╣ рд╣реИ рдХрд┐ рдЙрдирдХреЗ рдореВрд▓реНрдп рдХреА рдЧрдгрдирд╛ рд╕рдВрдмрдВрдзрд┐рдд рдЕрдиреБрджреЗрд╢ рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рд░реВрдк рдореЗрдВ рдХреА рдЬрд╛рддреА рд╣реИ рдФрд░ рд╡реЗ рддрдм рддрдХ рдПрдХ рдирдпрд╛ рдореВрд▓реНрдп рдкреНрд░рд╛рдкреНрдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдФрд░ рдпрджрд┐) рдЕрдиреБрджреЗрд╢ рдХреЛ рдлрд┐рд░ рд╕реЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ, SSA рдорд╛рди рдХреЛ "рдмрджрд▓рдиреЗ" рдХрд╛ рдХреЛрдИ рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИред рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП,
рд╕реНрдЯреЗрдЯрд┐рдХ рд╕рд┐рдВрдЧрд▓ рдЕрд╕рд╛рдЗрдирдореЗрдВрдЯ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ
рдкрдврд╝реЗрдВ - рдпреЗ рдЕрд╡рдзрд╛рд░рдгрд╛рдПрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдмрд╣реБрдд рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд▓рдЧрддреА рд╣реИрдВ рдЬреИрд╕реЗ рд╣реА рдЖрдк рдЙрди рдкрд░ рдзреНрдпрд╛рди рджреЗрддреЗ рд╣реИрдВред
рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐
ExprAST
рд╡рд░реНрдЧреЛрдВ рдХреЗ рдкрджрд╛рдиреБрдХреНрд░рдо рдореЗрдВ рдЖрднрд╛рд╕реА рддрд░реАрдХреЛрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рдпрд╣
рд╡рд┐рдЬрд╝рд┐рдЯрд░ рдбрд┐рдЬрд╝рд╛рдЗрди рдкреИрдЯрд░реНрди рдпрд╛ рдХрд┐рд╕реА рдЕрдиреНрдп рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдордЭ рдореЗрдВ рдЖ рд╕рдХрддрд╛ рд╣реИред рдлрд┐рд░, рдЗрд╕ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдореЗрдВ рд╣рдо рдЕрдЪреНрдЫреЗ рд╕реЙрдлреНрдЯрд╡реЗрдпрд░ рдбреЗрд╡рд▓рдкрдореЗрдВрдЯ рдХреЗ рддрд░реАрдХреЛрдВ рдкрд░ рдзреНрдпрд╛рди рдирд╣реАрдВ рджреЗрдВрдЧреЗ: рд╣рдорд╛рд░рд╛ рд▓рдХреНрд╖реНрдп рд╕рд╛рджрдЧреА рд╣реИ - рдФрд░ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рд╡рд░реНрдЪреБрдЕрд▓ рддрд░реАрдХрд╛ рдЬреЛрдбрд╝рдирд╛ рдЖрд╕рд╛рди рд╣реИред
рд╣рдореЗрдВ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рдзрд┐ рдХреА рднреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЬреЛ рдХрд┐ рдкрд╛рд░реНрд╕рд░ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХреА рдЧрдИ рдереАред рд╣рдо рдХреЛрдб рдЬрдирд░реЗрд╢рди рдХреЗ рджреМрд░рд╛рди рдкрд╛рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢реЛрдВ рдХреЗ рд▓рд┐рдП рдЗрд╕ рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЕрдШреЛрд╖рд┐рдд рдорд╛рдкрджрдВрдбреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП):
Value *ErrorV(const char *Str) { Error(Str); return 0; } static Module *TheModule; static IRBuilder<> Builder(getGlobalContext()); static std::map<std::string, Value*> NamedValues;
рдЗрди рд╕реНрдереИрддрд┐рдХ рдЪрд░ рдХреЛрдб рдкреАрдврд╝реА рдХреЗ рджреМрд░рд╛рди рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
TheModule
рдПрдХ LLVM рдХрдВрд╕реНрдЯреНрд░рдХреНрд╢рди рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдХреЛрдб рдХреЗ рдПрдХ рдЯреБрдХрдбрд╝реЗ рдореЗрдВ рд╕рднреА рдлрд╝рдВрдХреНрд╢рди рдФрд░ рд╡реИрд╢реНрд╡рд┐рдХ рдЪрд░ рд╢рд╛рдорд┐рд▓ рд╣реИрдВред рдЬреНрдпрд╛рджрд╛рддрд░ рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдпреЗ рд╢реАрд░реНрд╖-рд╕реНрддрд░реАрдп рд╕рдВрд░рдЪрдирд╛рдПрдВ рд╣реИрдВ рдЬреЛ рдПрд▓рдПрд▓рд╡реАрдПрдо рдЖрдИрдЖрд░ рдирд┐рд╣рд┐рдд рдХреЛрдб рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред
Builder
рдСрдмреНрдЬреЗрдХреНрдЯ рдПрдХ рд╕рд╣рд╛рдпрдХ рд╡рд╕реНрддреБ рд╣реИ рдЬреЛ LLVM рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЛ рдЙрддреНрдкрдиреНрди рдХрд░рдирд╛ рдЖрд╕рд╛рди рдмрдирд╛рддрд╛ рд╣реИред рдХрдХреНрд╖рд╛ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЙрджрд╛рд╣рд░рдг
IRBuilder
IRBuilder
рдирд┐рд░реНрджреЗрд╢ рдбрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд░реНрддрдорд╛рди рд╕реНрдерд╛рди рдХреЛ рдЯреНрд░реИрдХ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдирдП рдирд┐рд░реНрджреЗрд╢ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рддрд░реАрдХреЗ рд╢рд╛рдорд┐рд▓ рдХрд░рддрд╛ рд╣реИред
NamedValues
рдирдХреНрд╢рд╛ рдЗрд╕
NamedValues
рдирдЬрд╝рд░
NamedValues
рд╣реИ рдХрд┐ рд╡рд░реНрддрдорд╛рди рджрд╛рдпрд░реЗ рдореЗрдВ рдХрд┐рди рдореВрд▓реНрдпреЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдФрд░ рдЙрдирдХрд╛ LLVM рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХреНрдпрд╛ рд╣реИред (рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рдпрд╣ рдХреЛрдб рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд░реНрдг рддрд╛рд▓рд┐рдХрд╛ рд╣реИ)ред рдХреИрд▓реАрдбреЛрд╕реНрдХреЛрдк рдореЗрдВ рд╡рд░реНрддрдорд╛рди рд░реВрдк рдореЗрдВ, рдХреЗрд╡рд▓ рдПрдХ рдЪреАрдЬ рдЬрд┐рд╕реЗ рд╕рдВрджрд░реНрднрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рд╡рд╣ рдлрд╝рдВрдХреНрд╢рди рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдЗрд╕ рдирдХреНрд╢реЗ рдореЗрдВ, рдлрд╝рдВрдХреНрд╢рди рдмреЙрдбреА рдХреЗ рд▓рд┐рдП рдХреЛрдб рдмрдирд╛рддреЗ рд╕рдордп, рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рд╕реНрдерд┐рдд рд╣реЛрдВрдЧреЗред
рдпрд╣ рд╕рдм рдЬрд╛рдирддреЗ рд╣реБрдП, рд╣рдо рдХрд┐рд╕реА рднреА рднрд╛рд╡ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдмрдирд╛рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдзреНрдпрд╛рди рджреЗрдВ, рдпрд╣ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐
Builder
"рдХреБрдЫ рднреА" рдореЗрдВ рдХреЛрдб рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЕрднреА рдХреЗ рд▓рд┐рдП, рд╣рдо рдорд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рдкрд╣рд▓реЗ рд╣реА рд╣реЛ рдЪреБрдХрд╛ рд╣реИ, рдФрд░ рд╣рдо рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреЛрдб рдХреЛ рдмрдЪрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░реЗрдВрдЧреЗред
рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЛрдб рдкреАрдврд╝реА
рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдиреЛрдбреНрд╕ рдХреЗ рд▓рд┐рдП рдПрд▓рдПрд▓рд╡реАрдПрдо рдХреЛрдб рдЙрддреНрдкрдиреНрди рдХрд░рдирд╛ рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИ: рд╣рдорд╛рд░реА рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рд╕рднреА рдЪрд╛рд░ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдЯрд┐рдкреНрдкрдгреА рдХреЛрдб рдХреА 45 рд╕реЗ рдХрдо рд▓рд╛рдЗрдиреЗрдВред рдЖрд░рдВрдн рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдЗрдП рд╕рдВрдЦреНрдпрд╛рддреНрдордХ рд╢рд╛рдмреНрджрд┐рдХреЛрдВ рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВ:
Value *NumberExprAST::Codegen() { return ConstantFP::get(getGlobalContext(), APFloat(Val)); }
LLVM IR рдореЗрдВ, рд╕рдВрдЦреНрдпрд╛рддреНрдордХ рд╕реНрдерд┐рд░рд╛рдВрдХ рдХреЛ
ConstantFP
рд╡рд░реНрдЧ рджреНрд╡рд╛рд░рд╛ рджрд░реНрд╢рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ
APFloat
рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдВрдЦреНрдпрд╛рддреНрдордХ рдорд╛рди
APFloat
(
APFloat
рдореЗрдВ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕реНрдерд┐рд░рд╛рдВрдХ рдХреЛ рдордирдорд╛рдиреЗ рдврдВрдЧ рд╕реЗ рд╕рдЯреАрдХ рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдбрд╛рд▓рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд╣реЛрддреА рд╣реИ)ред рдпрд╣ рдХреЛрдб
ConstantFP
рдмрдирд╛рддрд╛ рд╣реИ рдФрд░ рд░рд┐рдЯрд░реНрди рдХрд░рддрд╛ рд╣реИред рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ LLVM IR рдореЗрдВ рд╕рднреА рд╕реНрдерд┐рд░рд╛рдВрдХ рдЕрдиреВрдареЗ (рд╡рд┐рд╢рд┐рд╖реНрдЯ) рдФрд░ рд╕рд╛рдЭрд╛ (рд╕рд╛рдЭрд╛) рд╣реИрдВред рдпрд╣ рдЗрд╕ рдХрд╛рд░рдг рд╕реЗ рд╣реИ рдХрд┐ рдПрдкреАрдЖрдИ
"new foo(..)"
рдпрд╛
"foo::Create(..)"
рдмрдЬрд╛рдп рдореБрд╣рд╛рд╡рд░реЗ
"foo::get(...)"
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред
Value *VariableExprAST::Codegen() {
рдПрд▓рдПрд▓рд╡реАрдПрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп рдкрд░рд┐рд╡рд░реНрддрдиреАрдп рд╕рдВрджрд░реНрдн рднреА рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИрдВред рдХреИрд▓реАрдбреЛрд╕реНрдХреЛрдк рдХреЗ рд╕рд░рд▓ рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ, рд╣рдо рдорд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдЪрд░ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХрд╣реАрдВ рд╕реЗрдЯ рд╣реИ рдФрд░ рдЗрд╕рдХрд╛ рдореВрд▓реНрдп рдЙрдкрд▓рдмреНрдз рд╣реИред рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ, NamedValues тАЛтАЛрдорд╛рдирдЪрд┐рддреНрд░ рдкрд░ рдорд╛рди рдХреЗрд╡рд▓ рдлрд╝рдВрдХреНрд╢рди рддрд░реНрдХ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рдХреЛрдб рдХреЗрд╡рд▓ рдпрд╣ рдЬрд╛рдВрдЪрддрд╛ рд╣реИ рдХрд┐ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╛рдо рдирдХреНрд╢реЗ рдкрд░ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ (рдпрджрд┐ рдирд╣реАрдВ, рддреЛ рдпрд╣ рдПрдХ рдЕрдЬреНрдЮрд╛рдд рдЪрд░ рдХрд╛ рдПрдХ рд▓рд┐рдВрдХ рд╣реИ) рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рдорд╛рди рд▓реМрдЯрд╛рддрд╛ рд╣реИред рдмрд╛рдж рдХреЗ рдЕрдзреНрдпрд╛рдпреЛрдВ рдореЗрдВ, рд╣рдо рд╕реНрдерд╛рдиреАрдп рдЪрд░ рдФрд░ рдкрд╛рд╢ рдХрд╛рдЙрдВрдЯрд░ рдЪрд░ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди рдЬреЛрдбрд╝ рджреЗрдВрдЧреЗред
Value *BinaryExprAST::Codegen() { Value *L = LHS->Codegen(); Value *R = RHS->Codegen(); if (L == 0 || R == 0) return 0; switch (Op) { case '+': return Builder.CreateFAdd(L, R, "addtmp"); case '-': return Builder.CreateFSub(L, R, "subtmp"); case '*': return Builder.CreateFMul(L, R, "multmp"); case '<': L = Builder.CreateFCmpULT(L, R, "cmptmp");
рдмрд╛рдЗрдирд░реА рдСрдкрд░реЗрдЯрд░реЛрдВ рдХреЗ рд╕рд╛рде, рдордЬрд╝рд╛ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИред рдпрд╣рд╛рдВ рдореБрдЦреНрдп рд╡рд┐рдЪрд╛рд░ рдпрд╣ рд╣реИ рдХрд┐ рд╣рдо рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рдмрд╛рдИрдВ рдУрд░ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдХреЛ рдкреБрди: рдЙрддреНрдкрдиреНрди рдХрд░рддреЗ рд╣реИрдВ, рдлрд┐рд░ рджрд╛рдИрдВ рдУрд░ рдХреЗ рд▓рд┐рдП, рдмрд╛рдЗрдирд░реА рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕ рдХреЛрдб рдореЗрдВ, рд╣рдордиреЗ рдПрдХ рдПрд▓рдПрд▓рд╡реАрдПрдо рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдмрд╛рдЗрдирд░реА рдСрдкрд░реЗрдЯрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рд╕рд░рд▓ рд╕реНрд╡рд┐рдЪ рдмрдирд╛рдпрд╛ред
рдЙрдкрд░реЛрдХреНрдд рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, LLVM
Builder
рд╡рд░реНрдЧ рдЕрдВрдд рдореЗрдВ рдЕрдкрдирд╛ рдореВрд▓реНрдп рджрд┐рдЦрд╛рддрд╛ рд╣реИред
IRBuilder
рдкрддрд╛ рд╣реИ рдХрд┐ рдирдП рдмрдирд╛рдП рдЧрдП рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЛ рдХрд╣рд╛рдВ рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░рдирд╛ рд╣реИ, рдФрд░ рдЖрдкрдХреЛ рдЬреЛ рдХреБрдЫ рднреА рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рд╡рд╣ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реЗрдВ рдХрд┐ рдХреМрди рд╕реЗ рдирд┐рд░реНрджреЗрд╢ рдмрдирд╛рдиреЗ рд╣реИрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП,
"CreateFAdd"
), рдЬреЛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
"CreateFAdd"
рдХрд░рддрд╛ рд╣реИ (рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ L рдФрд░ R) рдФрд░, рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ, рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИ рдЙрддреНрдкрдиреНрди рдирд┐рд░реНрджреЗрд╢ рдХреЗ рд▓рд┐рдП рдирд╛рдоред
рдПрд▓рдПрд▓рд╡реАрдПрдо рдореЗрдВ рдПрдХ рдФрд░ рдмрдбрд╝реА рд╡рд┐рд╢реЗрд╖рддрд╛ рдирд╛рдо рдЕрд╕рд╛рдЗрдирдореЗрдВрдЯ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдЙрдкрд░реЛрдХреНрдд рдХрдИ рдмрд╛рд░
"addtmp"
рдЪрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рддреЛ LLVM рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдмрд╛рд░ рдПрдХ рдЕрджреНрд╡рд┐рддреАрдп рд╕рдВрдЦреНрдпрд╛рддреНрдордХ рдкреНрд░рддреНрдпрдп рдкреНрд░рджрд╛рди рдХрд░реЗрдЧрд╛ред рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЗ рд▓рд┐рдП рд╕реНрдерд╛рдиреАрдп рдореВрд▓реНрдп рдирд╛рдо рд╡реИрдХрд▓реНрдкрд┐рдХ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╡реЗ рдЖрдИрдЖрд░ рдбрд┐рдкреНрд╕ рдХреЛ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЖрд╕рд╛рди рдмрдирд╛рддреЗ рд╣реИрдВред
рдПрд▓рдПрд▓рд╡реАрдПрдо рдирд┐рд░реНрджреЗрд╢ рд╕рдЦреНрдд рдирд┐рдпрдореЛрдВ рджреНрд╡рд╛рд░рд╛ рд╕реАрдорд┐рдд
рд╣реИрдВ : рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП,
рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдирд┐рд░реНрджреЗрд╢ рдХреЗ рдмрд╛рдПрдВ рдФрд░ рджрд╛рдПрдВ рдСрдкрд░реЗрдВрдб
рдПрдХ рд╣реА рдкреНрд░рдХрд╛рд░ рдХреЗ рд╣реЛрдиреЗ рдЪрд╛рд╣рд┐рдП рдФрд░ рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдкрд░рд┐рдгрд╛рдо рдХрд╛ рдкреНрд░рдХрд╛рд░ рдСрдкрд░реЗрдВрдб рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЕрдиреБрд░реВрдк рд╣реЛрдЧрд╛ред рдЪреВрдБрдХрд┐ Kaleidoscope рдореЗрдВ рд╕рднреА рдореВрд▓реНрдп рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдВрдЦреНрдпрд╛рдПрдБ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рдЬреЛрдбрд╝, рдШрдЯрд╛рд╡ рдФрд░ рдЧреБрдгрд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдмрд╣реБрдд рд╣реА рд╕рд░рд▓ рдХреЛрдб рдорд┐рд▓рддрд╛ рд╣реИред
рджреВрд╕рд░реА рдУрд░,
fcmp
рд╡рд┐рдирд┐рд░реНрджреЗрд╢ рдХрд╣рддрд╛ рд╣реИ рдХрд┐
fcmp
рдирд┐рд░реНрджреЗрд╢ рд╣рдореЗрд╢рд╛ "i1" (рдПрдХ рд╕рд┐рдВрдЧрд▓-рдмрд┐рдЯ рдкреВрд░реНрдгрд╛рдВрдХ) рдорд╛рди рд▓реМрдЯрд╛рддрд╛ рд╣реИред рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдмрд╣реБрд░реВрдкрджрд░реНрд╢рдХ рдореЗрдВ рд╣рдореЗрдВ 0.0 рдпрд╛ 1.0 рдХреЗ рдорд╛рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо
fcmp
рдХреЛ
fcmp
рд╕рд╛рде
uitofp
ред рдпрд╣ рдирд┐рд░реНрджреЗрд╢ рдПрдХ рдЕрд╣рд╕реНрддрд╛рдХреНрд╖рд░рд┐рдд рдкреВрд░реНрдгрд╛рдВрдХ рдХреЛ рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдлрд╝реНрд▓реЛрдЯрд┐рдВрдЧ рдмрд┐рдВрджреБ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд, рдЕрдЧрд░ рд╣рдо
sitofp
рдЙрдкрдпреЛрдЧ
рдХрд░рддреЗ рд╣реИрдВ , рддреЛ '<' рдСрдкрд░реЗрдЯрд░ рдЗрдирдкреБрдЯ рдорд╛рди рдХреЗ рдЖрдзрд╛рд░ рдкрд░ 0.0 рдФрд░ -1.0 рд▓реМрдЯрд╛рдПрдЧрд╛ред
Value *CallExprAST::Codegen() {
рдХрд┐рд╕реА рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП LLVM рдХреЛрдб рдмрдирд╛рдирд╛ рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИред рдЙрдкрд░реЛрдХреНрдд рдХреЛрдб рдПрд▓рдПрд▓рд╡реАрдПрдо рдореЙрдбреНрдпреВрд▓ рдХреЗ рдкреНрд░рддреАрдХ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдлрд╝рдВрдХреНрд╢рди рдирд╛рдо рдХреА рдЦреЛрдЬ рдХрд░рддрд╛ рд╣реИред рдпрд╛рдж рд░рдЦреЗрдВ рдХрд┐ рдПрд▓рдПрд▓рд╡реАрдПрдо рдореЙрдбреНрдпреВрд▓ рдПрдХ рдХрдВрдЯреЗрдирд░ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╕рднреА рдХрд╛рд░реНрдп рд╢рд╛рдорд┐рд▓ рд╣реИрдВ рдЬрд┐рдирдХрд╛ рдЙрдкрдпреЛрдЧ рд╣рдо рдЬреЗрдЖрдИрдЯреА рд╕рдВрдХрд▓рди рдХреЗ рд▓рд┐рдП рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдкреНрд░рддреНрдпреЗрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдПрдХ рдирд╛рдо рджреЗрддреЗ рд╣реБрдП, рд╣рдо рдлрд╝рдВрдХреНрд╢рди рдирд╛рдореЛрдВ рдХреА рдЦреЛрдЬ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП LLVM рдкреНрд░рддреАрдХ рддрд╛рд▓рд┐рдХрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдлрд╝рдВрдХреНрд╢рди рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рдкрд╛рд╕ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдкреНрд░рддреНрдпреЗрдХ рддрд░реНрдХ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдХреЛ рдкреБрди: рдЙрддреНрдкрдиреНрди рдХрд░рддреЗ рд╣реИрдВ рдФрд░ LLVM рдХреЙрд▓ рдирд┐рд░реНрджреЗрд╢ рдмрдирд╛рддреЗ рд╣реИрдВред рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдПрд▓рдПрд▓рд╡реАрдПрдо рд╕реА рдХреЗ рд░реВрдк рдореЗрдВ рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓рд┐рдВрдЧ рд╕рдореНрдореЗрд▓рдиреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдЖрдкрдХреЛ рдЕрддрд┐рд░рд┐рдХреНрдд рдкреНрд░рдпрд╛рд╕ рдХреЗ рдмрд┐рдирд╛
"sin"
рдФрд░
"cos"
рдЬреИрд╕реЗ рдорд╛рдирдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЗрди рдХреЙрд▓реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
рдпрд╣ рдЪрд╛рд░ рдореБрдЦреНрдп рдкреНрд░рдХрд╛рд░ рдХреА рдмрд╣реБрд░реВрдкрджрд░реНрд╢рдХ рднрд╛рд╖рд╛ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдиреЛрдбреНрд╕ рдХреЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдкреВрд░рд╛ рдХрд░рддрд╛ рд╣реИред рдЖрдк рдЖрдЧреЗ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдХреБрдЫ рдФрд░ рд╡рд┐рдЪрд╛рд░ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрд▓рдПрд▓рд╡реАрдПрдо рднрд╛рд╖рд╛ рдмреНрд░рд╛рдЙрдЬрд╝ рдХрд░рддреЗ рд╕рдордп, рдЖрдкрдХреЛ рдХрдИ рдЕрдиреНрдп рджрд┐рд▓рдЪрд╕реНрдк рдирд┐рд░реНрджреЗрд╢ рдорд┐рд▓реЗрдВрдЧреЗ рдЬреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╣рдорд╛рд░реЗ рдореМрдЬреВрджрд╛ рд╡рд┐рдХрд╛рд╕ рд╕реЗ рдЬреБрдбрд╝рдиреЗ рдореЗрдВ рдЖрд╕рд╛рди рд╣реИрдВред
рдлрдВрдХреНрд╢рди рдХреЛрдб рдЬрдирд░реЗрд╢рди
рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдФрд░ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдЬреЗрдирд░реЗрд╢рди рдХреЛ рдХрдИ рд╡рд┐рд╡рд░рдгреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рдирд╛ рдЪрд╛рд╣рд┐рдП рдЬреЛ рдХреЛрдб рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХреЛ рдмрдирд╛рдиреЗ рд╕реЗ рдЙрдирдХреЗ рдХреЛрдб рдХреЛ рдХрдо рд╕реБрдВрджрд░ рдмрдирд╛рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ рдХреБрдЫ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд┐рдВрджреБрдУрдВ рдХреЛ рдЪрд┐рддреНрд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВред рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдЗрдП рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдХреЗ рд▓рд┐рдП рдХреЛрдб рдкреАрдврд╝реА рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рддреЗ рд╣реИрдВ: рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╢рд░реАрд░ рдФрд░ рдмрд╛рд╣рд░реА рдХрд╛рд░реНрдпреЛрдВ рдХреА рдШреЛрд╖рдгрд╛ рдХреЗ рд▓рд┐рдП рджреЛрдиреЛрдВ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдХреЛрдб рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ:
Function *PrototypeAST::Codegen() {
рдХреБрдЫ рд▓рд╛рдЗрдиреЛрдВ рдореЗрдВ рдпрд╣ рдХреЛрдб рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╢рдХреНрддрд┐ рджрд┐рдЦрд╛рддрд╛ рд╣реИред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдпрд╣ рдлрд╝рдВрдХреНрд╢рди
"Value*"
рдмрдЬрд╛рдп
"Function*"
рджреЗрддрд╛ рд╣реИред рдЪреВрдВрдХрд┐ "рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк" рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдмрд╛рд╣рд░реА рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреА рдмрд╛рдд рдХрд░рддрд╛ рд╣реИ (рдЧрдгрдирд╛ рдХреА рдЧрдИ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рдмрдЬрд╛рдп), рдпрд╣ рдЙрд╕рдХреЗ рд▓рд┐рдП рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдЙрддреНрдкрдиреНрди рдХреЛрдб рдХреЗ рдЕрдиреБрд░реВрдк рдПрд▓рдПрд▓рд╡реАрдПрдо рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИред
"FunctionType::get"
рдХреЙрд▓ рдХрд░рдирд╛ рдПрдХ рдлрд╝рдВрдХреНрд╢рдирдЯрд╛рдЗрдк рдмрдирд╛рддрд╛ рд╣реИ рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдЗрд╕ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЪреВрдВрдХрд┐ рдХреИрд▓рд┐рдбреЛрд╕реНрдХреЛрдк рдореЗрдВ рд╕рднреА рдлрд╝рдВрдХреНрд╢рди рддрд░реНрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдВрдЦреНрдпрд╛ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдкрд╣рд▓реА рдкрдВрдХреНрддрд┐ "рдПрди" рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдВрдЦреНрдпрд╛ рд╕реЗ рдПрд▓рдПрд▓рд╡реАрдПрдо рд╡реЗрдХреНрдЯрд░ рдмрдирд╛рддреА рд╣реИред рдлрд┐рд░,
FunctionType::get
рдЯрд╛рдЗрдк
FunctionType::get
рдореЗрдердб рдХрд╛ рдкреНрд░рдпреЛрдЧ рдПрдХ рдлрдВрдХреНрд╢рди рдЯрд╛рдЗрдк рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬреЛ "N" рдорд╛рдиреНрдп рддрд░реНрдХреЛрдВ рдХреЛ рд▓реЗрддрд╛ рд╣реИ рдФрд░ рдкрд░рд┐рдгрд╛рдо рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рд╡реИрдз рддрд░реНрдХ рджреЗрддрд╛ рд╣реИред рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдПрд▓рдПрд▓рд╡реАрдПрдо рдХреЗ рдкреНрд░рдХрд╛рд░ рд╕реНрдерд┐рд░ рд╣реИрдВ, рд╕реНрдерд┐рд░рд╛рдВрдХ рдХреЗ рд░реВрдк рдореЗрдВ, рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЛ
"new"
рдирд╣реАрдВ рдЪрд╛рд╣рд┐рдП, рд▓реЗрдХрд┐рди
"get"
(рд╢рдмреНрджреЛрдВ рдкрд░ рдореВрд▓ рдирд╛рдЯрдХ рдореЗрдВ: "... рдЗрд╕рд▓рд┐рдП рдЖрдк рдЗрд╕реЗ
"
рдирд╣реАрдВ
"
рдмрдирд╛рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди
"
рдкреНрд░рд╛рдкреНрдд "рдХрд░рддреЗ рд╣реИрдВ)ред ред
рдЕрдВрддрд┐рдо рдкрдВрдХреНрддрд┐ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдмрдирд╛рддреА рд╣реИ рдЬреЛ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рд╕реЗ рдореЗрд▓ рдЦрд╛рддреА рд╣реИред рдпрд╣ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдкреНрд░рдХрд╛рд░, рд╕рдВрдмрдВрдз рдФрд░ рдирд╛рдо рдФрд░ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдХреЗ рд▓рд┐рдП рдореЙрдбреНрдпреВрд▓ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИред "
рдмрд╛рд╣рд░реА рд▓рд┐рдВрдХреЗрдЬ " рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╡рд░реНрддрдорд╛рди рдореЙрдбреНрдпреВрд▓ рдХреЗ рдмрд╛рд╣рд░ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ / рдпрд╛ рдЗрд╕реЗ рдореЙрдбреНрдпреВрд▓ рдХреЗ рдмрд╛рд╣рд░ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
"Name"
рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╛рдо рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ,
"TheModule"
рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдирд╛рдо
"TheModule"
рд╡рд░реНрдг рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдкрдВрдЬреАрдХреГрдд рд╣реИред
рдЬрдм рдирд╛рдо рд╕рдВрдШрд░реНрд╖ рдХреА рдмрд╛рдд рдЖрддреА рд╣реИ, рддреЛ рдореЙрдбреНрдпреВрд▓ рдХреА рдкреНрд░рддреАрдХ рддрд╛рд▓рд┐рдХрд╛ рдкреНрд░рддреАрдХ рддрд╛рд▓рд┐рдХрд╛ рдХреЗ рд╕рдорд╛рди рд╣реА рдХрд╛рд░реНрдп рдХрд░рддреА рд╣реИ: рдпрджрд┐ рдПрдХ рдирдпрд╛ рдлрд╝рдВрдХреНрд╢рди рдПрдХ рдирд╛рдо рдХреЗ рд╕рд╛рде рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдкрд╣рд▓реЗ рдкреНрд░рддреАрдХ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рдерд╛, рддреЛ рдЗрд╕реЗ рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рдЬреЛрдбрд╝рддреЗ рд╕рдордп рдЗрд╕рдХрд╛ рдирд╛рдо рдмрджрд▓ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЙрдкрд░реЛрдХреНрдд рдХреЛрдб рдЗрд╕ рддрдереНрдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдХреНрдпрд╛ рд╕рдорд╛рди рдлрд╝рдВрдХреНрд╢рди рдкрд╣рд▓реЗ рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
рдмрд╣реБрд░реВрдкрджрд░реНрд╢рдХ рдореЗрдВ, рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдкреБрдирд░реНрд╡рд┐рддрд░рдг рджреЛ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдпрджрд┐ рд╣рдо рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рдлрд╝рдВрдХреНрд╢рди рдХреА
extern
рдкрд░рд┐рднрд╛рд╖рд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдЬрдм рддрдХ рдХрд┐ рдЙрдирдХреЗ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдореЗрд▓ рдирд╣реАрдВ рдЦрд╛рддреЗ (рдЪреВрдВрдХрд┐ рд╕рднреА рддрд░реНрдХ рдПрдХ рд╣реА рдкреНрд░рдХрд╛рд░ рдХреЗ рд╣реИрдВ, рд╣рдореЗрдВ рд╕рд┐рд░реНрдл рдпрд╣ рдЬрд╛рдВрдЪрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рддрд░реНрдХреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдореЗрд▓ рдЦрд╛рддреА рд╣реИ)ред рджреВрд╕рд░реА рдмрд╛рдд, рдпрджрд┐ рд╣рдо рдХрд╛рд░реНрдпреЛрдВ рдХреА
extern
рдкрд░рд┐рднрд╛рд╖рд╛ рдФрд░ рдЙрд╕рдХреЗ рдмрд╛рдж рд╢рд░реАрд░ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдкрд╛рд░рд╕реНрдкрд░рд┐рдХ рдкреБрдирд░рд╛рд╡рд░реНрддреА рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╕рдордп рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╣реИред
рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЙрдкрд░реЛрдХреНрдд рдХреЛрдб рдкрд╣рд▓реЗ рдпрд╣ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд╛рдБрдЪ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдлрд╝рдВрдХреНрд╢рди рдирд╛рдореЛрдВ рдХрд╛ рдХреЛрдИ рд╡рд┐рд░реЛрдз рд╣реИ рдпрд╛ рдирд╣реАрдВред рдпрджрд┐ рд╡рд╣рд╛рдБ рд╣реИ, рддреЛ рдпрд╣ рдЕрднреА рдмрдирд╛рдП рдЧрдП рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╣рдЯрд╛ рджреЗрддрд╛ рд╣реИ (
"getFunction"
рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ), рдФрд░ рдлрд┐рд░ рджрд┐рдП рдЧрдП рдирд╛рдо рдХреЗ рд╕рд╛рде рдПрдХ рдореМрдЬреВрджрд╛ рдлрд╝рдВрдХреНрд╢рди рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
"getFunction"
рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдХрд┐ рдПрд▓рдПрд▓рд╡реАрдПрдо рдореЗрдВ рдХрдИ рдПрдкреАрдЖрдИ рдореЗрдВ
"erase"
рдлрд╝реЙрд░реНрдо рдФрд░
"remove"
рдлрд╝реЙрд░реНрдо рджреЛрдиреЛрдВ рд╣реИрдВред
"remove"
рд╡рд┐рдзрд┐ рдЕрдкрдиреЗ рдореВрд▓ рдСрдмреНрдЬреЗрдХреНрдЯ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдореЙрдбреНрдпреВрд▓ рд╕реЗ рдПрдХ рдлрд╝рдВрдХреНрд╢рди) рд╕реЗ рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдЕрд▓рдЧ (рдЕрдирд▓рд┐рдВрдХ) рдХрд░рддреА рд╣реИ рдФрд░ рдЙрд╕реЗ рд╡рд╛рдкрд╕ рдХрд░рддреА рд╣реИред
"erase"
рд╡рд┐рдзрд┐ рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдЕрд▓рдЧ рдХрд░рддреА рд╣реИ (рдЕрдирд▓рд┐рдВрдХ) рдФрд░ рдлрд┐рд░ рдЙрд╕реЗ рд╣рдЯрд╛ рджреЗрддреА рд╣реИред
рдЙрдкрд░реЛрдХреНрдд рддрд░реНрдХ рдХреА рдкреБрд╖реНрдЯрд┐ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдкрд╣рд▓реЗ рдЬрд╛рдВрдЪрддреЗ рд╣реИрдВ рдХрд┐ "рдореМрдЬреВрджрд╛" рдлрд╝рдВрдХреНрд╢рди "рдЦрд╛рд▓реА" рд╣реИред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╢реВрдиреНрдп рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдЗрд╕рдореЗрдВ рдЖрдзрд╛рд░ рдмреНрд▓реЙрдХ рдирд╣реАрдВ рд╣реИрдВ, рдЕрд░реНрдерд╛рддреН рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рд╢рд░реАрд░ред рдпрджрд┐ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдПрдХ рдирд┐рдХрд╛рдп рд╣реИ, рддреЛ рдпрд╣ рдПрдХ рджреЛрд╣рд░рд╛рдпрд╛ рдШреЛрд╖рдгрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП, рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдо рдХреЛрдб рдХреЛ рдЕрд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддреЗ рд╣реИрдВред рдпрджрд┐ рдкрд┐рдЫрд▓рд╛ рдлрд╝рдВрдХреНрд╢рди рдПрдХ
"extern"
рдлрд╝рдВрдХреНрд╢рди рд╣реИ, рддреЛ рд╣рдо рдмрд╕ рд╡рд░реНрддрдорд╛рди рдкрд░рд┐рднрд╛рд╖рд╛ рдореЗрдВ рддрд░реНрдХреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд╕рд╛рде рдЗрд╕рдХреЗ рддрд░реНрдХреЛрдВ рдХреА рддреБрд▓рдирд╛ рдХрд░рддреЗ рд╣реИрдВред рдпрджрд┐ рд╡реЗ рдореЗрд▓ рдирд╣реАрдВ рдЦрд╛рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдПрдХ рддреНрд░реБрдЯрд┐ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддреЗ рд╣реИрдВред
рдлрд╝рдВрдХреНрд╢рди рдлрд╝рдВрдХреНрд╢рди рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдХреЗ рд▓рд┐рдП рдХреЛрдб рдХрд╛ рдЕрдВрддрд┐рдо рднрд╛рдЧ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рддрд░реНрдХреЛрдВ рдХрд╛ рдПрдХ рд▓реВрдк рд╣реИ, рдЬреЛ LLVM рдСрдмреНрдЬреЗрдХреНрдЯ рдирд╛рдо, рд╕рдВрдмрдВрдзрд┐рдд рддрд░реНрдХреЛрдВ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддрд╛ рд╣реИ, рдФрд░
VariableExprAST
AST рдиреЛрдб рджреНрд╡рд╛рд░рд╛ рдмрд╛рдж рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП
NamedValues
рдорд╛рдирдЪрд┐рддреНрд░ рдореЗрдВ рддрд░реНрдХ рджрд░реНрдЬ рдХрд░рддрд╛ рд╣реИред рдлрд┐рд░ рдпрд╣ рдПрдХ рдлрдВрдХреНрд╢рди рдСрдмреНрдЬреЗрдХреНрдЯ рд▓реМрдЯрд╛рддрд╛ рд╣реИред рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рд╣рдо рдкрд░рд╕реНрдкрд░ рд╡рд┐рд░реЛрдзреА рддрд░реНрдХ рдирд╛рдореЛрдВ рдХреА рдЬрд╛рдВрдЪ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП,
"extern Foo (aba)"
)ред рд▓реЗрдХрд┐рди рдпрд╣ рдХрд╛рдлреА рд╕рд░рд▓ рдФрд░ рд╕рд░рд▓ рд░реВрдк рд╕реЗ рдЙрд╕ рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рд╣рдордиреЗ рдКрдкрд░ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдерд╛ред
Function *FunctionAST::Codegen() { NamedValues.clear(); Function *TheFunction = Proto->Codegen(); if (TheFunction == 0) return 0;
рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдкреАрдврд╝реА рдХрд╛рдлреА рд╕рд░рд▓ рд░реВрдк рд╕реЗ рд╢реБрд░реВ рд╣реЛрддреА рд╣реИ: рд╣рдо рд╕рд┐рд░реНрдл рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдХреЛрдб рдкреАрдврд╝реА (
Proto
) рдХрд╣рддреЗ рд╣реИрдВ рдФрд░ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рд╕рдм рдХреБрдЫ рдареАрдХ рд╣реИред рд╣рдо рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП NamedValues тАЛтАЛрдХрд╛рд░реНрдб рдХреЛ рднреА рд╕рд╛рдл рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рд╣рдо рдЬреЛ рдЕрдВрддрд┐рдо рдХрд╛рд░реНрдп рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдЙрд╕рдХрд╛ рдХреБрдЫ рднреА рдирд╣реАрдВ рдмрдЪрд╛ рд╣реИред рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдХреЛрдб рдЙрддреНрдкрдиреНрди рдХрд░рдирд╛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рддреИрдпрд╛рд░ рдПрд▓рдПрд▓рд╡реАрдПрдо рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╡рд╕реНрддреБ рд╣реИ рддрд╛рдХрд┐ рд╣рдо рдЖрдЧреЗ рдмрдврд╝ рд╕рдХреЗрдВред
рдЕрдм рд╣рдо рдмрд┐рд▓реНрдбрд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝реЗрдВрдЧреЗред рдкрд╣рд▓реА рдкрдВрдХреНрддрд┐ рдПрдХ рдирдпрд╛
рдмреЗрд╕ рдмреНрд▓реЙрдХ рдмрдирд╛рддреА рд╣реИ [
en ] (рдЬрд┐рд╕реЗ
"entry"
рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ), рдЬрд┐рд╕реЗ TheFunction рдореЗрдВ рдбрд╛рд▓рд╛ рдЧрдпрд╛ рд╣реИред рджреВрд╕рд░реА рдкрдВрдХреНрддрд┐ рдмрд┐рд▓реНрдбрд░ рдХреЛ рдмрддрд╛рддреА рд╣реИ рдХрд┐ рдирдП рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЛ рдирдИ рдЖрдзрд╛рд░ рдЗрдХрд╛рдИ рдХреЗ рдЕрдВрдд рдореЗрдВ рдбрд╛рд▓рд╛ рдЬрд╛рдПрдЧрд╛ред рдПрд▓рдПрд▓рд╡реАрдПрдо рдореЗрдВ рдмреЗрд╕ рдмреНрд▓реЙрдХ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХрд╛ рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ
рдЬреЛ рдирд┐рдпрдВрддреНрд░рдг рдкреНрд░рд╡рд╛рд╣ рдЧреНрд░рд╛рдл рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛
рд╣реИ ред рдЪреВрдВрдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЕрднреА рддрдХ рдХреЛрдИ рдирд┐рдпрдВрддреНрд░рдг рдкреНрд░рд╡рд╛рд╣ рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдорд╛рд░реЗ рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рдХреЗрд╡рд▓ рдПрдХ рдмреНрд▓реЙрдХ рд╣реЛрдЧрд╛ред рд▓реЗрдХрд┐рди рд╣рдо рдЗрд╕реЗ рдЕрдзреНрдпрд╛рдп 5 :) рдореЗрдВ рдареАрдХ рдХрд░реЗрдВрдЧреЗред
if (Value *RetVal = Body->Codegen()) {
рдПрдХ рдмрд╛рд░ рд╕рдореНрдорд┐рд▓рди рдмрд┐рдВрджреБ рд╕реЗрдЯ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рд░реВрдЯ рдлрд╝рдВрдХреНрд╢рди рдПрдХреНрд╕рдкреНрд░реЗрд╢рди рдХреЗ рд▓рд┐рдП
CodeGen()
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреЛрдб рдЬрдирд░реЗрд╢рди рдХреЛ
CodeGen()
рдХрд░рддреЗ рд╣реИрдВред рдпрджрд┐ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ, рддреЛ рдЗрдирдкреБрдЯ рдмреНрд▓реЙрдХ рдореЗрдВ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдЧрдгрдирд╛ рдХреЛрдб рдЬреЛрдбрд╝реЗрдВ рдФрд░ рдЧрдгрдирд╛ рдХреА рдЬрд╛рдиреЗ рд╡рд╛рд▓реА рдорд╛рди рд▓реМрдЯрд╛рдПрдВред рдлрд┐рд░, рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреА рдЕрдиреБрдкрд╕реНрдерд┐рддрд┐ рдореЗрдВ, рд╣рдо
рдПрд▓рдПрд▓рд╡реАрдПрдо рдирд┐рд░реНрджреЗрд╢ "ret"
рдмрдирд╛рддреЗ рд╣реИрдВ, рдЬреЛ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкреВрд░рд╛ рдХрд░рддрд╛ рд╣реИред рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЗ рдмрд╛рдж, рд╣рдо LLVM рдореЗрдВ рдирд┐рд░реНрдорд┐рдд
"verifyFunction"
рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВред рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХреЛрдб рдкрд░ рд╡рд┐рднрд┐рдиреНрди рд╕реНрдерд┐рд░рддрд╛ рдЬрд╛рдВрдЪ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рд╣рдорд╛рд░реЗ рд╕рдВрдХрд▓рдХ рд╕рдм рдХреБрдЫ рд╕рд╣реА рдХрд░ рд░рд╣реЗ рд╣реИрдВред рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдмрд╣реБрдд рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ: рдпрд╣ рдХрдИ рдХреАрдбрд╝реЗ рдкрдХрдбрд╝ рд╕рдХрддрд╛ рд╣реИред рдЬрдм рдлрд╝рдВрдХреНрд╢рди рд╕рдорд╛рдкреНрдд рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рд╕рддреНрдпрд╛рдкрд┐рдд рд╣реЛрддрд╛ рд╣реИ, рддреЛ рд╣рдо рдЗрд╕реЗ рд╡рд╛рдкрд╕ рдХрд░ рджреЗрддреЗ рд╣реИрдВред
рдпрд╣ рдЫреЛрдЯрд╛ рд╕рд╛ рд╣рд┐рд╕реНрд╕рд╛ рддреНрд░реБрдЯрд┐ рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИред рд╕рд░рд▓рддрд╛ рдХреЗ рд▓рд┐рдП, рд╣рдо
eraseFromParent
рдкрджреНрдзрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдмрдирд╛рдП рдЧрдП рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдЗрд╕ рд╕рд░рд▓ рд╡рд┐рд▓реЛрдкрди рд╕реЗ
eraseFromParent
ред рдпрд╣ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ рдЬреЛ рдкрд╣рд▓реЗ рдЧрд▓рдд рддрд░реАрдХреЗ рд╕реЗ рдЯрд╛рдЗрдк рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛: рдЕрдЧрд░ рд╣рдордиреЗ рдЗрд╕реЗ рдирд╣реАрдВ рд╣рдЯрд╛рдпрд╛, рддреЛ рдпрд╣ рднрд╡рд┐рд╖реНрдп рдХреЗ рдУрд╡рд░рд░рд╛рдЗрдб рдХреЛ рд░реЛрдХрддреЗ рд╣реБрдП, рд╢рд░реАрд░ рдХреЗ рд╕рд╛рде рдкреНрд░рддреАрдХ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рд╣реЛрдЧрд╛ред
рджрд░рдЕрд╕рд▓, рдЗрд╕ рдХреЛрдб рдореЗрдВ рдПрдХ рдмрдЧ рд╣реИред
"PrototypeAST:: Codegen"
рдкрд╣рд▓реЗ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдкреВрд░реНрд╡ рдШреЛрд╖рдгрд╛рдУрдВ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рд╣рдорд╛рд░рд╛ рдХреЛрдб рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЙрдиреНрд╣реЗрдВ рд╣рдЯрд╛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕ рдмрдЧ рдХреЛ рдареАрдХ рдХрд░рдиреЗ рдХреЗ рдХрдИ рддрд░реАрдХреЗ рд╣реИрдВ, рд╕реЛрдЪреЗрдВ рдХрд┐ рдЖрдк рдХреНрдпрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ! рдпрд╣рд╛рдБ рдПрдХ рдЫреЛрдЯрд╛ рд╕рд╛ рдкрд░реАрдХреНрд╖рдг рдорд╛рдорд▓рд╛ рд╣реИ:
extern foo(ab); # o, "foo". def foo(ab) c; # , 'c'. def bar() foo(1, 2); # , "foo"
рдореБрдЦреНрдп рдХрд╛рд░реНрдпрдХреНрд░рдо рдФрд░ рдЕрдВрддрд┐рдо рд╡рд┐рдЪрд╛рд░реЛрдВ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди
рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдЕрдм рддрдХ рдПрд▓рдПрд▓рд╡реАрдПрдо рдХреЛрдб рдкреАрдврд╝реА рдиреЗ рд╣рдореЗрдВ рдереЛрдбрд╝рд╛ рд╕рд╛ рджрд┐рдпрд╛ рд╣реИ, рд╕рд┐рд╡рд╛рдп рдЗрд╕рдХреЗ рдХрд┐ рд╣рдо рджрд┐рд▓рдЪрд╕реНрдк рдЖрдИрдЖрд░ рдХреЙрд▓ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВред рд╣рдорд╛рд░реЗ рдХреЛрдб рдореЗрдВ рдХреЛрдб рдЬреЗрдирд░реЗрд╢рди рдХреЛ "рд╣реИрдВрдбрд▓реЗрдбрд┐рдлрд┐рдирд┐рд╢рди", "рд╣реИрдВрдбрд▓реЗрдХреНрд╕реНрдЯрд░реНрди", рдЗрддреНрдпрд╛рджрд┐ рдХреЛрдб рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдФрд░ рдлрд┐рд░ рдПрд▓рдПрд▓рд╡реАрдПрдо рдЖрдИрдЖрд░ рдХреЛ рдбрдВрдк рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЗрд╕рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рд╣рдо рд╕рд╛рдзрд╛рд░рдг рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП LLVM IR рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:
рддреИрдпрд╛рд░> 4 + 5;
рд╢реАрд░реНрд╖-рд╕реНрддрд░реАрдп рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдкрдврд╝реЗрдВ:
рдкрд░рд┐рднрд╛рд╖рд┐рдд рдбрдмрд▓ @ "" () {
рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐:
рджреЛрд╣рд░рд╛ рджреЛрд╣рд░рд╛ 9.000000e + 00
}
рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдХреИрд╕реЗ рдкрд╛рд░реНрд╕рд░ рдПрдХ рдЕрдирд╛рдо рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рд╢реАрд░реНрд╖-рд╕реНрддрд░реАрдп рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рджреЗрддрд╛ рд╣реИред рдпрд╣ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реЛрдЧрд╛ рдЬрдм рд╣рдо рдЕрдЧрд▓реЗ рдЕрдзреНрдпрд╛рдп рдореЗрдВ JIT рд╕рдорд░реНрдерди рдЬреЛрдбрд╝реЗрдВрдЧреЗред рдпрд╣ рднреА рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдХреЛрдб "рдмрд╣реБрдд рд╣реА рд╢рд╛рдмреНрджрд┐рдХ", "рд╕реАрдзреЗ рддреМрд░ рдкрд░" рдХрд╛ рдЕрдиреБрд╡рд╛рдж рдХрд░рддрд╛ рд╣реИ,
IRBuilder
рджреНрд╡рд╛рд░рд╛ рдмрдирд╛рдП рдЧрдП рд╕реНрдерд┐рд░рд╛рдВрдХ рдХреЗ рд╕рд░рд▓ рддрд╣ рдХреЛ рдЫреЛрдбрд╝рдХрд░ рдХреЛрдИ рдЕрдиреБрдХреВрд▓рди рдирд╣реАрдВ рд╣реИрдВред рд╣рдо рдЕрдЧрд▓реЗ рдЕрдзреНрдпрд╛рдп рдореЗрдВ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЕрдиреБрдХреВрд▓рди рдЬреЛрдбрд╝ рджреЗрдВрдЧреЗред
рддреИрдпрд╛рд░> рдбрд┐рдл рдлреВ (ab) a * a + 2 * a * b + b * b;
рдлрд╝рдВрдХреНрд╢рди рдкрд░рд┐рднрд╛рд╖рд╛ рдкрдврд╝реЗрдВ:
рдбрдмрд▓ @ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВ (рдбрдмрд▓% рдП, рдбрдмрд▓% рдмреА) {
рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐:
% рдорд▓реНрдЯреАрдореНрдк = fmul рдбрдмрд▓% a,% a
% рдорд▓реНрдЯреАрдореНрдк 1 = fmul рдбрдмрд▓ 2.000000e + 00,% a
% рдорд▓реНрдЯреАрдореНрдк 2 = рдПрдлрдПрдордПрд▓ рдбрдмрд▓% рдорд▓реНрдЯреАрдореНрдк 1,% рдмреА
% addtmp = fadd рдбрдмрд▓% рдорд▓реНрдЯреАрдореНрдк,% multmp2
% рдмрд╣реБ = fmul рдбрдмрд▓% b,% b
% addtmp4 = fadd рдбрдмрд▓% addtmp,% multmp3
рджреЛрд╣рд░рд╛% addtmp4
}
рдпрд╣рд╛рдВ рдХреБрдЫ рд╕рд░рд▓ рдЕрдВрдХрдЧрдгрд┐рддреАрдп рдСрдкрд░реЗрд╢рди рджрд┐рдП рдЧрдП рд╣реИрдВред рдПрд▓рдПрд▓рд╡реАрдПрдо
Builder'
рдХреЙрд▓ рдХреЗ рд╣рдбрд╝рддрд╛рд▓реА рд╕рдорд╛рдирддрд╛ рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд╣рдо рдирд┐рд░реНрджреЗрд╢ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░рддреЗ рд╣реИрдВред
рддреИрдпрд╛рд░> рдбрд┐рдл рдмрд╛рд░ (рдП) рдлреВ (рдП, рек.реж) + рдмрд╛рд░ (рейрезрейрей;);
рдлрд╝рдВрдХреНрд╢рди рдкрд░рд┐рднрд╛рд╖рд╛ рдкрдврд╝реЗрдВ:
рдкрд░рд┐рднрд╛рд╖рд┐рдд рдбрдмрд▓ @ рдмрд╛рд░ (рдбрдмрд▓% рдП) {
рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐:
% calltmp = рдХреЙрд▓ рдбрдмрд▓ @foo (рдбрдмрд▓% a, рдбрдмрд▓ 4.000000e + 00)
% calltmp1 = рдХреЙрд▓ рдбрдмрд▓ @ рдмрд╛рд░ (рдбрдмрд▓ 3.133700e + 04)
% addtmp = fadd рдбрдмрд▓% calltmp,% calltmp1
рджреЛрд╣рд░рд╛% addtmp
}
рдпрд╣рд╛рдБ рдХреБрдЫ рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рд╣реИрдВред рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдпрджрд┐ рдЖрдк рдЗрд╕реЗ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ рддреЛ рдпрд╣ рдлрд╝рдВрдХреНрд╢рди рд▓рдВрдмреЗ рд╕рдордп рддрдХ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рднрд╡рд┐рд╖реНрдп рдореЗрдВ, рд╣рдо рд╕рд╢рд░реНрдд рдкреНрд░рд╡рд╛рд╣ рдирд┐рдпрдВрддреНрд░рдг рдЬреЛрдбрд╝ рджреЗрдВрдЧреЗ, рдЬрд┐рд╕рд╕реЗ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЙрдкрдпреЛрдЧреА рд╣реЛ рдЬрд╛рдПрдЧреА :)ред
рддреИрдпрд╛рд░> рдмрд╛рд╣рд░реА рдХреЙрд╢рди (x);
рдмрд╛рд╣рд░реА рдкрдврд╝реЗрдВ:
рдбрдмрд▓ @cos (рдбрдмрд▓) рдШреЛрд╖рд┐рдд рдХрд░реЗрдВ
рддреИрдпрд╛рд░> cos (1.234); рд╢реАрд░реНрд╖-рд╕реНрддрд░реАрдп рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдкрдврд╝реЗрдВ:
рдкрд░рд┐рднрд╛рд╖рд┐рдд рдбрдмрд▓ @ "" () {
рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐:
% calltmp = рдХреЙрд▓ рдбрдмрд▓ @cos (рдбрдмрд▓ 1.234000e + 00)
рджреЛрд╣рд░реЗ% рдХреЙрд▓рдЯреИрдВрдк рдХреЛ рдкреБрдирдГрдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ
}
рдпрд╣рд╛рдВ
extern
рд╣реИ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдлрдВрдХреНрд╢рди
"cos"
рдФрд░ рдЗрд╕рдХреЗ рдХреЙрд▓ рдХреЗ рд▓рд┐рдП
extern
ред
рддреИрдпрд╛рд░> ^ рдбреА
; рдореЙрдбреНрдпреВрд▓ = 'рдореЗрд░рд╛ рд╢рд╛рдВрдд рдЬрд┐рда'
рдкрд░рд┐рднрд╛рд╖рд┐рдд рдбрдмрд▓ @ "" () {
рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐:
% addtmp = fadd double 4.000000e + 00, 5.000000e + 00
рджреЛрд╣рд░рд╛% addtmp
}
рдбрдмрд▓ @ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВ (рдбрдмрд▓% рдП, рдбрдмрд▓% рдмреА) {
рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐:
% рдорд▓реНрдЯреАрдореНрдк = fmul рдбрдмрд▓% a,% a
% рдорд▓реНрдЯреАрдореНрдк 1 = fmul рдбрдмрд▓ 2.000000e + 00,% a
% рдорд▓реНрдЯреАрдореНрдк 2 = рдПрдлрдПрдордПрд▓ рдбрдмрд▓% рдорд▓реНрдЯреАрдореНрдк 1,% рдмреА
% addtmp = fadd рдбрдмрд▓% рдорд▓реНрдЯреАрдореНрдк,% multmp2
% рдмрд╣реБ = fmul рдбрдмрд▓% b,% b
% addtmp4 = fadd рдбрдмрд▓% addtmp,% multmp3
рджреЛрд╣рд░рд╛% addtmp4
}
рдкрд░рд┐рднрд╛рд╖рд┐рдд рдбрдмрд▓ @ рдмрд╛рд░ (рдбрдмрд▓% рдП) {
рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐:
% calltmp = рдХреЙрд▓ рдбрдмрд▓ @foo (рдбрдмрд▓% a, рдбрдмрд▓ 4.000000e + 00)
% calltmp1 = рдХреЙрд▓ рдбрдмрд▓ @ рдмрд╛рд░ (рдбрдмрд▓ 3.133700e + 04)
% addtmp = fadd рдбрдмрд▓% calltmp,% calltmp1
рджреЛрд╣рд░рд╛% addtmp
}
рдбрдмрд▓ @cos (рдбрдмрд▓) рдШреЛрд╖рд┐рдд рдХрд░реЗрдВ
рдкрд░рд┐рднрд╛рд╖рд┐рдд рдбрдмрд▓ @ "" () {
рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐:
% calltmp = рдХреЙрд▓ рдбрдмрд▓ @cos (рдбрдмрд▓ 1.234000e + 00)
рджреЛрд╣рд░рд╛ рджреЛрд╣рд░рд╛ рдХреЙрд▓рдЯреИрдВрдк
}
рд╡рд░реНрддрдорд╛рди рдбреЗрдореЛ рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рдиреЗ рдкрд░, рдПрдХ рдЖрдИрдЖрд░ рдбрдВрдк рдкреВрд░реЗ рдЙрддреНрдкрдиреНрди рдореЙрдбреНрдпреВрд▓ рдХреЗ рд▓рд┐рдП рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рдПрдЧрд╛ред
рдпрд╣рд╛рдВ рдЖрдк рдПрдХ рджреВрд╕рд░реЗ рдХрд╛ рдЬрд┐рдХреНрд░ рдХрд░рддреЗ рд╣реБрдП рд╕рднреА рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рдкреВрд░реА рддрд╕реНрд╡реАрд░ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВредрдпрд╣ рдмрд╣реБрд░реВрдкрджрд░реНрд╢рдХ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдХреЗ рддреАрд╕рд░реЗ рдЕрдзреНрдпрд╛рдп рдХрд╛ рд╕рдорд╛рдкрди рдХрд░рддрд╛ рд╣реИред рдЕрдЧрд▓реЗ рдЕрдзреНрдпрд╛рдп рдореЗрдВ, рд╣рдо JIT рд╕рдорд░реНрдерди рдФрд░ рдЕрдиреБрдХреВрд▓рдХ рдЬреЛрдбрд╝рдиреЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВрдЧреЗ рддрд╛рдХрд┐ рдЖрдк рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреЛрдб рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рд╕рдХреЗрдВ!рдкреВрд░реНрдг рдХреЛрдб рд╕реВрдЪреА
рдпрд╣рд╛рдВ рд╣рдорд╛рд░реЗ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХреА рдПрдХ рдкреВрд░реА рдХреЛрдб рд╕реВрдЪреА рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдПрд▓рдПрд▓рд╡реАрдПрдо рдХреЛрдб рдЬрдирд░реЗрдЯрд░ред рдЪреВрдВрдХрд┐ рд╣рдо LLVM рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рдЙрдиреНрд╣реЗрдВ рдЕрдкрдиреЗ рдХреЛрдб рд╕реЗ рд▓рд┐рдВрдХ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ llvm-config рдЯреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ :#
g++ -g -O3 toy.cpp `llvm-config --cppflags --ldflags --libs core` -o toy
#
./toy
рдФрд░ рдЕрдВрдд рдореЗрдВ, рдХреЛрдб рд╣реА: #include "llvm/DerivedTypes.h" #include "llvm/LLVMContext.h" #include "llvm/Module.h" #include "llvm/Analysis/Verifier.h" #include "llvm/Support/IRBuilder.h" #include <cstdio> #include <string> #include <map> #include <vector> using namespace llvm; //===----------------------------------------------------------------------===// // Lexer ( ) //===----------------------------------------------------------------------===// // [0-255], , // enum Token { tok_eof = -1, // ( ) tok_def = -2, tok_extern = -3, // ( : , ) tok_identifier = -4, tok_number = -5 }; static std::string IdentifierStr; // , tok_identifier static double NumVal; // , tok_number /// gettok - . static int gettok() { static int LastChar = ' '; // . while (isspace(LastChar)) LastChar = getchar(); if (isalpha(LastChar)) { // : [a-zA-Z][a-zA-Z0-9]* IdentifierStr = LastChar; while (isalnum((LastChar = getchar()))) IdentifierStr += LastChar; if (IdentifierStr == "def") return tok_def; if (IdentifierStr == "extern") return tok_extern; return tok_identifier; } if (isdigit(LastChar) || LastChar == '.') { // : [0-9.]+ std::string NumStr; do { NumStr += LastChar; LastChar = getchar(); } while (isdigit(LastChar) || LastChar == '.'); NumVal = strtod(NumStr.c_str(), 0); return tok_number; } if (LastChar == '#') { // do LastChar = getchar(); while (LastChar != EOF && LastChar != '\n' && LastChar != '\r'); if (LastChar != EOF) return gettok(); } // . if (LastChar == EOF) return tok_eof; // ASCII int ThisChar = LastChar; LastChar = getchar(); return ThisChar; } //===----------------------------------------------------------------------===// // Abstract Syntax Tree ( ) //===----------------------------------------------------------------------===// /// ExprAST - . class ExprAST { public: virtual ~ExprAST() {} virtual Value *Codegen() = 0; }; /// NumberExprAST - (, "1.0"). class NumberExprAST : public ExprAST { double Val; public: NumberExprAST(double val) : Val(val) {} virtual Value *Codegen(); }; /// VariableExprAST - (, "a"). class VariableExprAST : public ExprAST { std::string Name; public: VariableExprAST(const std::string &name) : Name(name) {} virtual Value *Codegen(); }; /// BinaryExprAST - . class BinaryExprAST : public ExprAST { char Op; ExprAST *LHS, *RHS; public: BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs) : Op(op), LHS(lhs), RHS(rhs) {} virtual Value *Codegen(); }; /// CallExprAST - . class CallExprAST : public ExprAST { std::string Callee; std::vector<ExprAST*> Args; public: CallExprAST(const std::string &callee, std::vector<ExprAST*> &args) : Callee(callee), Args(args) {} virtual Value *Codegen(); }; /// PrototypeAST - "" , /// (, , /// ). class PrototypeAST { std::string Name; std::vector<std::string> Args; public: PrototypeAST(const std::string &name, const std::vector<std::string> &args) : Name(name), Args(args) {} Function *Codegen(); }; /// FunctionAST - class FunctionAST { PrototypeAST *Proto; ExprAST *Body; public: FunctionAST(PrototypeAST *proto, ExprAST *body) : Proto(proto), Body(body) {} Function *Codegen(); }; //===----------------------------------------------------------------------===// // Parser ( ) //===----------------------------------------------------------------------===// /// CurTok/getNextToken - . CurTok - /// , . getNextToken /// CurTok. static int CurTok; static int getNextToken() { return CurTok = gettok(); } /// BinopPrecedence - static std::map<char, int> BinopPrecedence; /// GetTokPrecedence - . static int GetTokPrecedence() { if (!isascii(CurTok)) return -1; // , . int TokPrec = BinopPrecedence[CurTok]; if (TokPrec <= 0) return -1; return TokPrec; } /// Error* - . ExprAST *Error(const char *Str) { fprintf(stderr, "Error: %s\n", Str);return 0;} PrototypeAST *ErrorP(const char *Str) { Error(Str); return 0; } FunctionAST *ErrorF(const char *Str) { Error(Str); return 0; } static ExprAST *ParseExpression(); /// identifierexpr /// ::= identifier /// ::= identifier '(' expression* ')' static ExprAST *ParseIdentifierExpr() { std::string IdName = IdentifierStr; getNextToken(); // . if (CurTok != '(') // . return new VariableExprAST(IdName); // . getNextToken(); // ( std::vector<ExprAST*> Args; if (CurTok != ')') { while (1) { ExprAST *Arg = ParseExpression(); if (!Arg) return 0; Args.push_back(Arg); if (CurTok == ')') break; if (CurTok != ',') return Error("Expected ')' or ',' in argument list"); getNextToken(); } } // ')'. getNextToken(); return new CallExprAST(IdName, Args); } /// numberexpr ::= number static ExprAST *ParseNumberExpr() { ExprAST *Result = new NumberExprAST(NumVal); getNextToken(); // return Result; } /// parenexpr ::= '(' expression ')' static ExprAST *ParseParenExpr() { getNextToken(); // (. ExprAST *V = ParseExpression(); if (!V) return 0; if (CurTok != ')') return Error("expected ')'"); getNextToken(); // ). return V; } /// primary /// ::= identifierexpr /// ::= numberexpr /// ::= parenexpr static ExprAST *ParsePrimary() { switch (CurTok) { default: return Error("unknown token when expecting an expression"); case tok_identifier: return ParseIdentifierExpr(); case tok_number: return ParseNumberExpr(); case '(': return ParseParenExpr(); } } /// binoprhs /// ::= ('+' primary)* static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) { // , while (1) { int TokPrec = GetTokPrecedence(); // , // , if (TokPrec < ExprPrec) return LHS; // , , . int BinOp = CurTok; getNextToken(); // // ExprAST *RHS = ParsePrimary(); if (!RHS) return 0; // BinOp RHS , RHS, // RHS LHS. int NextPrec = GetTokPrecedence(); if (TokPrec < NextPrec) { RHS = ParseBinOpRHS(TokPrec+1, RHS); if (RHS == 0) return 0; } // LHS/RHS. LHS = new BinaryExprAST(BinOp, LHS, RHS); } } /// expression /// ::= primary binoprhs /// static ExprAST *ParseExpression() { ExprAST *LHS = ParsePrimary(); if (!LHS) return 0; return ParseBinOpRHS(0, LHS); } /// prototype /// ::= id '(' id* ')' static PrototypeAST *ParsePrototype() { if (CurTok != tok_identifier) return ErrorP("Expected function name in prototype"); std::string FnName = IdentifierStr; getNextToken(); if (CurTok != '(') return ErrorP("Expected '(' in prototype"); // . std::vector<std::string> ArgNames; while (getNextToken() == tok_identifier) ArgNames.push_back(IdentifierStr); if (CurTok != ')') return ErrorP("Expected ')' in prototype"); // . getNextToken(); // ')'. return new PrototypeAST(FnName, ArgNames); } /// definition ::= 'def' prototype expression static FunctionAST *ParseDefinition() { getNextToken(); // def. PrototypeAST *Proto = ParsePrototype(); if (Proto == 0) return 0; if (ExprAST *E = ParseExpression()) return new FunctionAST(Proto, E); return 0; } /// toplevelexpr ::= expression static FunctionAST *ParseTopLevelExpr() { if (ExprAST *E = ParseExpression()) { // . PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>()); return new FunctionAST(Proto, E); } return 0; } /// external ::= 'extern' prototype static PrototypeAST *ParseExtern() { getNextToken(); // extern. return ParsePrototype(); } //===----------------------------------------------------------------------===// // Code Generation () //===----------------------------------------------------------------------===// static Module *TheModule; static IRBuilder<> Builder(getGlobalContext()); static std::map<std::string, Value*> NamedValues; Value *ErrorV(const char *Str) { Error(Str); return 0; } Value *NumberExprAST::Codegen() { return ConstantFP::get(getGlobalContext(), APFloat(Val)); } Value *VariableExprAST::Codegen() { // . Value *V = NamedValues[Name]; return V ? V : ErrorV("Unknown variable name"); } Value *BinaryExprAST::Codegen() { Value *L = LHS->Codegen(); Value *R = RHS->Codegen(); if (L == 0 || R == 0) return 0; switch (Op) { case '+': return Builder.CreateFAdd(L, R, "addtmp"); case '-': return Builder.CreateFSub(L, R, "subtmp"); case '*': return Builder.CreateFMul(L, R, "multmp"); case '<': L = Builder.CreateFCmpULT(L, R, "cmptmp"); // 0 1 0.0 1.0 return Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()), "booltmp"); default: return ErrorV("invalid binary operator"); } } Value *CallExprAST::Codegen() { // . Function *CalleeF = TheModule->getFunction(Callee); if (CalleeF == 0) return ErrorV("Unknown function referenced"); // . if (CalleeF->arg_size() != Args.size()) return ErrorV("Incorrect # arguments passed"); std::vector<Value*> ArgsV; for (unsigned i = 0, e = Args.size(); i != e; ++i) { ArgsV.push_back(Args[i]->Codegen()); if (ArgsV.back() == 0) return 0; } return Builder.CreateCall(CalleeF, ArgsV.begin(), ArgsV.end(), "calltmp"); } Function *PrototypeAST::Codegen() { // : double(double,double) .. std::vector<const Type*> Doubles(Args.size(), Type::getDoubleTy(getGlobalContext())); FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()), Doubles, false); Function *F = Function::Create(FT, Function::ExternalLinkage, Name, TheModule); // (F) , 'Name'. // , . if (F->getName() != Name) { // , . F->eraseFromParent(); F = TheModule->getFunction(Name); // (F) , . if (!F->empty()) { ErrorF("redefinition of function"); return 0; } // (F) , . if (F->arg_size() != Args.size()) { ErrorF("redefinition of function with different # args"); return 0; } } // . unsigned Idx = 0; for (Function::arg_iterator AI = F->arg_begin(); Idx != Args.size(); ++AI, ++Idx) { AI->setName(Args[Idx]); // . NamedValues[Args[Idx]] = AI; } return F; } Function *FunctionAST::Codegen() { NamedValues.clear(); Function *TheFunction = Proto->Codegen(); if (TheFunction == 0) return 0; // . BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction); Builder.SetInsertPoint(BB); if (Value *RetVal = Body->Codegen()) { // . Builder.CreateRet(RetVal); // , (). verifyFunction(*TheFunction); return TheFunction; } // , . TheFunction->eraseFromParent(); return 0; } //===----------------------------------------------------------------------===// // Top-Level parsing ( ) JIT //===----------------------------------------------------------------------===// static void HandleDefinition() { if (FunctionAST *F = ParseDefinition()) { if (Function *LF = F->Codegen()) { fprintf(stderr, "Read function definition:"); LF->dump(); } } else { // . getNextToken(); } } static void HandleExtern() { if (PrototypeAST *P = ParseExtern()) { if (Function *F = P->Codegen()) { fprintf(stderr, "Read extern: "); F->dump(); } } else { // . getNextToken(); } } static void HandleTopLevelExpression() { // Evaluate a top-level expression into an anonymous function. if (FunctionAST *F = ParseTopLevelExpr()) { if (Function *LF = F->Codegen()) { fprintf(stderr, "Read top-level expression:"); LF->dump(); } } else { // . getNextToken(); } } /// top ::= definition | external | expression | ';' static void MainLoop() { while (1) { fprintf(stderr, "ready> "); switch (CurTok) { case tok_eof: return; case ';': getNextToken(); break; // . case tok_def: HandleDefinition(); break; case tok_extern: HandleExtern(); break; default: HandleTopLevelExpression(); break; } } } //===----------------------------------------------------------------------===// // "" , // ("extern") . //===----------------------------------------------------------------------===// /// putchard - 0. extern "C" double putchard(double X) { putchar((char)X); return 0; } //===----------------------------------------------------------------------===// // Main driver code ( ) //===----------------------------------------------------------------------===// int main() { LLVMContext &Context = getGlobalContext(); // . // 1 - . BinopPrecedence['<'] = 10; BinopPrecedence['+'] = 20; BinopPrecedence['-'] = 20; BinopPrecedence['*'] = 40; // . fprintf(stderr, "ready> "); getNextToken(); // , . TheModule = new Module("my cool jit", Context); // " ". MainLoop(); // . TheModule->dump(); return 0; }