{"id":345671,"date":"2023-02-19T21:03:31","date_gmt":"2023-02-19T21:03:31","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=345671"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=345671","title":{"rendered":"<span>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0441\u0432\u043e\u0439 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u044f\u0437\u044b\u043a \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c LLVM. \u0427\u0430\u0441\u0442\u044c 3: \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0441\u0442\u0430\u0442\u044c\u044f\u0445 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u043b\u0435\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0438 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u044b, \u0430 \u0442\u0430\u043a \u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437 \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u0443\u0447\u0435\u0431\u043d\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430, \u0447\u0442\u043e \u0434\u0430\u043b\u043e \u043d\u0430\u043c \u043e\u0441\u043d\u043e\u0432\u0443. \u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u043c \u043d\u0430\u0447\u0430\u0442\u043e\u0435 \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u043a\u043e\u0434\u0430 \u0434\u043b\u044f LLVM IR.<\/p>\n<h3>LLVM<\/h3>\n<p>LLVM \u044d\u0442\u043e \u043d\u0430\u0431\u043e\u0440 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u043e\u0432 \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u044b \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u043e\u0432 \u0434\u043b\u044f \u043b\u044e\u0431\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u0431\u044d\u043a\u0435\u043d\u0434\u043e\u0432 \u0434\u043b\u044f \u043b\u044e\u0431\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u043d\u0430\u0431\u043e\u0440\u0430 \u043a\u043e\u043c\u0430\u043d\u0434. LLVM \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d \u0432\u043e\u043a\u0440\u0443\u0433 \u044f\u0437\u044b\u043a\u043e-\u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0433\u043e \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f (LLVM IR), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043b\u0443\u0436\u0438\u0442 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u043e\u0440\u0442\u0430\u0442\u0438\u0432\u043d\u043e\u0433\u043e, \u0432\u044b\u0441\u043e\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430 \u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0439.<\/p>\n<p>\u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 LLVM \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u043c\u043e\u0434\u0443\u043b\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0435\u0434\u0438\u043d\u0438\u0446\u0430\u043c\u0438 \u0442\u0440\u0430\u043d\u0441\u043b\u044f\u0446\u0438\u0438 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b. \u041a\u0430\u0436\u0434\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432. \u041c\u043e\u0434\u0443\u043b\u0438 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u044b \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043b\u0438\u043d\u043a\u043e\u0432\u0449\u0438\u043a\u0430 LLVM.<\/p>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f \u0441\u0430\u043c\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 (\u0435\u0435 \u0438\u043c\u044f, \u0442\u0438\u043f\u044b \u0435\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432, \u0442\u0438\u043f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u0440\u0443\u0433\u0438\u0435 \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0447\u0430\u0441\u0442\u0438, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a \u0441\u043f\u043e\u0441\u043e\u0431 \u043b\u0438\u043d\u043a\u043e\u0432\u043a\u0438, \u0435\u0435 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u044c, \u0441\u043f\u043e\u0441\u043e\u0431 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0438 \u0434\u0440.), \u0430 \u0442\u0430\u043a\u0436\u0435 \u0435\u0435 \u0442\u0435\u043b\u0430, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0431\u0430\u0437\u043e\u0432\u044b\u0445 \u0431\u043b\u043e\u043a\u043e\u0432.<\/p>\n<p>\u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u0431\u043b\u043e\u043a \u2014 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 (\u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439), \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0431\u0440\u0430\u0437\u0443\u044e\u0442 \u043b\u043e\u0433\u0438\u043a\u0443 \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0430. \u041b\u044e\u0431\u043e\u0439 \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u0431\u043b\u043e\u043a \u0434\u043e\u043b\u0436\u0435\u043d \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0442\u044c\u0441\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0435\u0439 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u0442\u043e\u0440\u043e\u043c (\u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u0438\u043b\u0438 \u0431\u0435\u0437\u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434, \u0432\u043e\u0437\u0432\u0440\u0430\u0442 \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u0434\u0440.).<\/p>\n<p>\u0421\u0438\u0441\u0442\u0435\u043c\u0430 \u0442\u0438\u043f\u043e\u0432 LLVM \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0442\u0438\u043f\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u0435\u043b\u044f\u0442\u0441\u044f \u043d\u0430 (\u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435 \u0442\u0438\u043f\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0430\u0448\u0435\u0433\u043e \u0443\u0447\u0435\u0431\u043d\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430):<\/p>\n<ol>\n<li>\n<p>\u0426\u0435\u043b\u044b\u0435 \u0447\u0438\u0441\u043b\u0430 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u043e\u0439 \u0440\u0430\u0437\u0440\u044f\u0434\u043d\u043e\u0441\u0442\u0438 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 i1, i8, i32, i64);<\/p>\n<\/li>\n<li>\n<p>\u0427\u0438\u0441\u043b\u0430 \u0441 \u043f\u043b\u0430\u0432\u0430\u044e\u0449\u0435\u0439 \u0442\u043e\u0447\u043a\u043e\u0439 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 float, double);<\/p>\n<\/li>\n<li>\n<p>void;<\/p>\n<\/li>\n<li>\n<p>\u0423\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 i64*);<\/p>\n<\/li>\n<li>\n<p>\u041c\u0430\u0441\u0441\u0438\u0432\u044b (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 [20 x i32]);<\/p>\n<\/li>\n<li>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 { i32, double, i64 });<\/p>\n<\/li>\n<li>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u0438 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 i32 (i32, double)).<\/p>\n<\/li>\n<\/ol>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c LLVM IR \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043e\u043d \u0437\u0430\u043f\u0438\u0441\u0430\u043d \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 SSA (Static Single Assignment), \u043f\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0443 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437. \u0427\u0442\u043e \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u0430\u043d\u0430\u043b\u0438\u0437 \u043f\u043e\u0442\u043e\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<p>\u041d\u043e \u0442\u0430\u043a\u0430\u044f \u0444\u043e\u0440\u043c\u0430 \u043d\u0430\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f, \u0435\u0441\u043b\u0438 \u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435 \u0435\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f, \u0434\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f phi, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0442\u043e\u0433\u043e, \u0438\u0437 \u043a\u0430\u043a\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0430 \u0431\u044b\u043b \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u0432 \u0431\u043b\u043e\u043a \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0443\u044e \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e phi. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code>Loop:       ; Infinite loop that counts from 0 on up...   %indvar = phi i32 [ 0, %LoopHeader ], [ %nextindvar, %Loop ]   %nextindvar = add i32 %indvar, 1   br label %Loop<\/code><\/pre>\n<p>\u0411\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043f\u0440\u043e LLVM IR \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0432 [1], \u0430 \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0432\u0441\u0435 \u044d\u0442\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u0432 [2].<\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u044f\u0437\u044b\u043a\u0430 (\u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c JIT, \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 \u043f\u043e\u043b\u043d\u043e\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c \u043a\u043e\u0434\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043d\u0430 <a href=\"https:\/\/github.com\/dc-sinpo\/simple\/tree\/part01\" rel=\"noopener noreferrer nofollow\">github<\/a>, \u043b\u0438\u0431\u043e \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0432 [3]).<\/p>\n<h3>\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0442\u0438\u043f\u043e\u0432<\/h3>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0447\u0442\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u043e\u0441\u044c \u0432 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0438 \u0442\u0438\u043f\u0430 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430:<\/p>\n<pre><code class=\"cpp\">struct TypeAST {     \/\/\/ \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0442\u0438\u043f LLVM \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0439 \u0432\u0435\u0442\u043a\u0438 \u0434\u0435\u0440\u0435\u0432\u0430   virtual llvm::Type* getType() = 0;     llvm::Type* ThisType; \/\/\/&lt; \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0442\u0438\u043f LLVM };<\/code><\/pre>\n<p>\u0421\u0430\u043c\u0430 \u0436\u0435 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0434\u043b\u044f \u0432\u0435\u0442\u043e\u043a \u0434\u0435\u0440\u0435\u0432\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0442\u043d\u043e\u0441\u044f\u0442\u0441\u044f \u043a \u0442\u0438\u043f\u0430\u043c \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u0430\u044f, \u043d\u0443\u0436\u043d\u043e \u0432\u0441\u0435\u0433\u043e \u0441\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0442\u0438\u043f \u044f\u0437\u044b\u043a\u0430 \u043a \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e\u043c\u0443 \u0442\u0438\u043f\u0443 \u0432 LLVM:<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">Type* BuiltinTypeAST::getType() {   static Type* builtinTypes[] = {     Type::getVoidTy(getGlobalContext()),     Type::getInt1Ty(getGlobalContext()),     Type::getInt32Ty(getGlobalContext()),     Type::getDoubleTy(getGlobalContext()),     Type::getInt8Ty(getGlobalContext()),     Type::getInt8PtrTy(getGlobalContext())   };    if (ThisType) {     return ThisType;   }    return ThisType = builtinTypes[TypeKind]; }  Type* FuncTypeAST::getType() {   \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0442\u0438\u043f \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437   if (ThisType) {     return ThisType;   }    \/\/ \u0415\u0441\u043b\u0438 ReturnType \u043d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d, \u0442\u043e \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \"void\"   Type* returnType = (ReturnType ? ReturnType->getType() :      Type::getVoidTy(getGlobalContext()));    if (Params.empty()) {     \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0431\u0435\u0437 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432     return ThisType = FunctionType::get(returnType, false);   }      std::vector&lt; Type* > params;    \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432   for (ParameterList::iterator it = Params.begin(),      end = Params.end(); it != end; ++it) {     params.push_back((*it)->Param->getType());   }    \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0442\u0438\u043f \u0434\u043b\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438   return ThisType = FunctionType::get(returnType, params, false); }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h3>\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439<\/h3>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439:<\/p>\n<pre><code class=\"cpp\">struct ExprAST {    \/\/\/ \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043e \u0432 \u043b\u0435\u0432\u043e\u0439    \/\/\/ \u0447\u0430\u0441\u0442\u0438 \"=\"   virtual llvm::Value *getLValue(SLContext &amp;Context);    \/\/\/ \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043e \u0432 \u043f\u0440\u0430\u0432\u043e\u0439   \/\/\/ \u0447\u0430\u0441\u0442\u0438 \"=\"   virtual llvm::Value *getRValue(SLContext &amp;Context) = 0;  };<\/code><\/pre>\n<p>\u0417\u0430\u0447\u0435\u043c \u043d\u0443\u0436\u043d\u044b \u0434\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f lvalue \u0438 rvalue? \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f<\/p>\n<pre><code class=\"cpp\">i<\/code><\/pre>\n<p>rvalue \u044d\u0442\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439, \u0430 lvalue \u0431\u0443\u0434\u0435\u0442 \u0430\u0434\u0440\u0435\u0441 \u044d\u0442\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0432 \u043f\u0430\u043c\u044f\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0430 \u0434\u043b\u044f \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043e\u0447\u0435\u043d\u044c \u0447\u0430\u0441\u0442\u043e:<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">\/\/\/ \u0421\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u0434\u043b\u044f \u0446\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u043e\u0439 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b ConstantInt* getConstInt(uint64_t value) {   return ConstantInt::get(Type::getInt32Ty(getGlobalContext()),                           value, true); }  \/\/\/ \u041a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0438\u043f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432 \"bool\" \/\/\/ \\param[in] val \u2014 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u0438 \/\/\/ \\param[in] type \u2014 \u0442\u0438\u043f \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \/\/\/ \\param[in] builder \u2014 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 LLVM IR Value* promoteToBool(Value* val,                      TypeAST* type,                      IRBuilder&lt; >&amp; builder) {   if (type == BuiltinTypeAST::get(TypeAST::TI_Bool)) {     \/\/ \u042d\u0442\u043e \u0443\u0436\u0435 \"bool\"     return val;   }    if (type->isInt()) {     \/\/ \u0414\u043b\u044f \u0446\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0441 0     return builder.CreateICmpNE(val,                                 ConstantInt::get(                                   type->getType(),                                   0)                                );   } else {     assert(type->isFloat());     \/\/ \u0414\u043b\u044f \u0447\u0438\u0441\u043b\u0430 \u0441 \u043f\u043b\u0430\u0432\u0430\u044e\u0449\u0435\u0439 \u0442\u043e\u0447\u043a\u043e\u0439 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0441 0.0     return builder.CreateFCmpUNE(val, ConstantFP::get(       Type::getDoubleTy(getGlobalContext()), 0.0));   } } \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0441\u0430\u043c\u0438\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439: Value* ExprAST::getLValue(SLContext&amp; ) {   assert(0 &amp;&amp; \"\");   return nullptr; }  Value* IntExprAST::getRValue(SLContext&amp; ) {   \/\/ \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0446\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u0443\u044e \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0443 \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0441 \u043d\u0443\u0436\u043d\u044b\u043c    \/\/ \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c   return ConstantInt::get(ExprType->getType(), Val, true); }  Value* FloatExprAST::getRValue(SLContext&amp; ) {   \/\/ \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0443 \u0434\u043b\u044f \u0447\u0438\u0441\u043b\u0430 \u0441 \u043f\u043b\u0430\u0432\u0430\u044e\u0449\u0435\u0439 \u0442\u043e\u0447\u043a\u043e\u0439 \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0441    \/\/ \u043d\u0443\u0436\u043d\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c   return ConstantFP::get(ExprType->getType(), Val); }  Value* IdExprAST::getLValue(SLContext&amp; Context) {   \/\/ \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0430\u0434\u0440\u0435\u0441 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 (\u0441\u0430\u043c \u0430\u0434\u0440\u0435\u0441 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 SymbolAST,    \/\/ \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u0441\u044b\u043b\u0430\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f)   return ThisSym->getValue(Context); }  Value* IdExprAST::getRValue(SLContext&amp; Context) {   if (isa&lt;FuncDeclAST>(ThisSym)) {     \/\/ \u041e\u0441\u043e\u0431\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0434\u043b\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0439     return ThisSym->getValue(Context);   }    \/\/ \u0414\u043b\u044f \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u043d\u0443\u0436\u043d\u043e \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \"load\"   return Context.TheBuilder->CreateLoad(     ExprType->getType(),     ThisSym->getValue(Context),      StringRef(Val->Id, Val->Length)   ); }  Value* CastExprAST::getRValue(SLContext&amp; Context) {   \/\/ \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u044d\u0442\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \u0446\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0439 \u0442\u0438\u043f   if (ExprType->isInt()) {     if (Val->ExprType->isBool()) {       \/\/ \u0415\u0441\u043b\u0438 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u0442\u0438\u043f \"bool\", \u0442\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u044f\u0435\u043c 0       return Context.TheBuilder->CreateZExt(         Val->getRValue(Context),          ExprType->getType()       );     }      assert(Val->ExprType->isFloat());     \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \"float\" \u0432 \"int\"     return Context.TheBuilder->CreateFPToSI(       Val->getRValue(Context),        ExprType->getType()     );   }    if (ExprType->isBool()) {     \/\/ \u0414\u043b\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432 \"bool\"     return promoteToBool(Val->getRValue(Context), Val->ExprType,        *Context.TheBuilder);   } else if (Val->ExprType->isInt()) {     \/\/ \u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \"int\" \u0432 \"float\"      return Context.TheBuilder->CreateSIToFP(       Val->getRValue(Context),        ExprType->getType()     );   } else if (Val->ExprType->isBool()) {     \/\/ \u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \"bool\" \u0432 \"float\"     return Context.TheBuilder->CreateUIToFP(       Val->getRValue(Context),       ExprType->getType()     );   }    assert(0 &amp;&amp; \"should never be reached\");   return nullptr; }  Value* UnaryExprAST::getRValue(SLContext&amp; Context) {   assert(0 &amp;&amp; \"Should never happen\");   return nullptr; }  Value* BinaryExprAST::getRValue(SLContext&amp; Context) {   \/\/ \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0432\u0441\u0435 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0435 \u0441\u043b\u0443\u0447\u0430\u0438    \/\/ =   if (Op == tok::Assign) {          \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u043f\u0440\u0430\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f     Value* right = RightExpr->getRValue(Context);     \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0430\u0434\u0440\u0435\u0441 \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435     Value* res = LeftExpr->getLValue(Context);      \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \"store\"     Context.TheBuilder->CreateStore(right, res);     return right;   }    \/\/ ,   if (Op == tok::Comma) {     \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u043b\u0435\u0432\u043e\u0433\u043e \u0438 \u043f\u0440\u0430\u0432\u043e\u0433\u043e \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430     LeftExpr->getRValue(Context);     Value* rhs = RightExpr->getRValue(Context);     \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043f\u0440\u0430\u0432\u044b\u0439 \u043e\u043f\u0435\u0440\u0430\u043d\u0434     return rhs;   }    \/\/ \u041f\u043e\u0441\u0442\u0444\u0438\u043a\u0441\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 ++ \u0438 --   if (Op == tok::PlusPlus || Op == tok::MinusMinus) {     \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0430\u0434\u0440\u0435\u0441 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439, \u0430 \u0442\u0430\u043a \u0436\u0435 \u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435     Value* var = LeftExpr->getLValue(Context);     Value* val = LeftExpr->getRValue(Context);      if (Op == tok::PlusPlus) {       \/\/ \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0446\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u0443\u044e \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0443 1 \u0438 \u043f\u0440\u0438\u0431\u0430\u0432\u0438\u0442\u044c \u0435\u0435 \u043a        \/\/ \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u043e\u043c\u0443 \u0440\u0430\u043d\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e       Value* tmp = getConstInt(1);       tmp = Context.TheBuilder->CreateAdd(val, tmp, \"inctmp\");       \/\/ \u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043d\u043e\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0441\u0442\u0430\u0440\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435       Context.TheBuilder->CreateStore(tmp, var);       return val;     } else {       \/\/ \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0446\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u0443\u044e \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0443 -1 \u0438 \u043f\u0440\u0438\u0431\u0430\u0432\u0438\u0442\u044c \u0435\u0435 \u043a        \/\/ \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u043e\u043c\u0443 \u0440\u0430\u043d\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e       Value* tmp = getConstInt(~0ULL);       tmp = Context.TheBuilder->CreateAdd(val, tmp, \"dectmp\");       \/\/ \u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043d\u043e\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0441\u0442\u0430\u0440\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435       Context.TheBuilder->CreateStore(tmp, var);       return val;     }   }    \/\/ ||   if (Op == tok::LogOr) {     \/\/ \u041f\u0441\u0435\u0432\u0434\u043e\u043a\u043e\u0434 \u0434\u043b\u044f \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430 ||      \/\/if (bool result = (left != 0))     \/\/  return result;     \/\/else     \/\/  return (right != 0);      \/\/ \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u043b\u0435\u0432\u043e\u0433\u043e \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430     Value* lhs = LeftExpr->getRValue(Context);     \/\/ \u041f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \"bool\"     lhs = promoteToBool(lhs, LeftExpr->ExprType,                          *Context.TheBuilder);      \/\/ \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0431\u043b\u043e\u043a\u0438 \u0434\u043b\u044f \u0432\u0435\u0442\u043a\u0438 \"false\" \u0438 \"result\" (\u043a\u0443\u0434\u0430 \u0431\u0443\u0434\u0435\u0442      \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b)     BasicBlock* condBB = Context.TheBuilder->GetInsertBlock();     BasicBlock* resultBB = BasicBlock::Create(       getGlobalContext(),       \"result\"     );     BasicBlock* falseBB = BasicBlock::Create(       getGlobalContext(),       \"false\"     );      \/\/ \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043a \"result\" \u0438\u043b\u0438 \"false\" \u0432      \/\/ \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0438\u0441\u0442\u0438\u043d\u043d\u043e\u0441\u0442\u0438 \u043b\u0435\u0432\u043e\u0433\u043e \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430     Context.TheBuilder->CreateCondBr(lhs, resultBB, falseBB);      \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0431\u043b\u043e\u043a \"false\" \u043a \u0444\u0443\u043d\u043a\u0446\u0438\u0438 (\u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434)      \/\/ \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u043d\u0435\u0435     Context.TheFunction->getBasicBlockList().push_back(falseBB);     Context.TheBuilder->SetInsertPoint(falseBB);     \/\/ \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u043f\u0440\u0430\u0432\u043e\u0433\u043e \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430     Value* rhs = RightExpr->getRValue(Context);     \/\/ \u041e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0431\u043b\u043e\u043a \"false\", \u0442.\u00a0\u043a. \u043a\u043e\u0434 \u0434\u043b\u044f \u043f\u0440\u0430\u0432\u043e\u0433\u043e \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430 \u043c\u043e\u0433      \/\/ \u0435\u0435 \u0441\u043c\u0435\u043d\u0438\u0442\u044c     falseBB = Context.TheBuilder->GetInsertBlock();     \/\/ \u041f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \"bool\"     rhs = promoteToBool(       rhs,       RightExpr->ExprType,       *Context.TheBuilder     );     \/\/ \u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c \u0431\u0435\u0437\u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043a \"result\"     Context.TheBuilder->CreateBr(resultBB);      \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0431\u043b\u043e\u043a \"result\" \u043a \u0444\u0443\u043d\u043a\u0446\u0438\u0438 (\u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434)     \/\/ \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u043d\u0435\u0435     Context.TheFunction->getBasicBlockList().push_back(resultBB);     Context.TheBuilder->SetInsertPoint(resultBB);      \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c PHI \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432      \/\/ \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u043e\u0433\u043e \u043a\u0430\u043a\u0430\u044f \u0432\u0435\u0442\u043a\u0430 \u0431\u044b\u043b\u0430 \u0432\u044b\u0431\u0440\u0430\u043d\u0430 \u043f\u0440\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435     \/\/ \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u044f     PHINode* PN = Context.TheBuilder->CreatePHI(       Type::getInt1Ty(getGlobalContext()),       2     );      PN->addIncoming(lhs, condBB);     PN->addIncoming(rhs, falseBB);      return PN;   }    \/\/ &amp;&amp;   if (Op == tok::LogAnd) {     \/\/ \u041f\u0441\u0435\u0432\u0434\u043e\u043a\u043e\u0434 \u0434\u043b\u044f \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430 &amp;&amp;      \/\/if (left != 0 &amp;&amp; right != 0)     \/\/    return true;     \/\/else     \/\/  return false;      \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u043b\u0435\u0432\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430     Value* lhs = LeftExpr->getRValue(Context);     \/\/ \u041f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \"bool\"     lhs = promoteToBool(       lhs,       LeftExpr->ExprType,       *Context.TheBuilder     );      \/\/ \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0431\u043b\u043e\u043a\u0438 \u0434\u043b\u044f \u0432\u0435\u0442\u043a\u0438 \"true\" \u0438 \"result\" (\u043a\u0443\u0434\u0430 \u0431\u0443\u0434\u0435\u0442      \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b)     BasicBlock* condBB = Context.TheBuilder->GetInsertBlock();     BasicBlock* resultBB = BasicBlock::Create(       getGlobalContext(),       \"result\"     );     BasicBlock* trueBB = BasicBlock::Create(       getGlobalContext(),       \"true\"     );      \/\/ \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043a \"true\" \u0438\u043b\u0438 \"result\" \u0432      \/\/ \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0438\u0441\u0442\u0438\u043d\u043d\u043e\u0441\u0442\u0438 \u043b\u0435\u0432\u043e\u0433\u043e \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430     Context.TheBuilder->CreateCondBr(lhs, trueBB, resultBB);      \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0431\u043b\u043e\u043a \"true\" \u043a \u0444\u0443\u043d\u043a\u0446\u0438\u0438 (\u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434)      \/\/ \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u043d\u0435\u0435     Context.TheFunction->getBasicBlockList().push_back(trueBB);     Context.TheBuilder->SetInsertPoint(trueBB);     \/\/ \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u043f\u0440\u0430\u0432\u043e\u0433\u043e \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430     Value* rhs = RightExpr->getRValue(Context);     \/\/ \u041e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0431\u043b\u043e\u043a \"true\", \u0442.\u00a0\u043a. \u043a\u043e\u0434 \u0434\u043b\u044f \u043f\u0440\u0430\u0432\u043e\u0433\u043e \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430 \u043c\u043e\u0433      \/\/ \u0435\u0435 \u0441\u043c\u0435\u043d\u0438\u0442\u044c     trueBB = Context.TheBuilder->GetInsertBlock();     \/\/ \u041f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \"bool\"     rhs = promoteToBool(       rhs,       RightExpr->ExprType,       *Context.TheBuilder     );     \/\/ \u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c \u0431\u0435\u0437\u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043a \"result\"     Context.TheBuilder->CreateBr(resultBB);      \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0431\u043b\u043e\u043a \"result\" \u043a \u0444\u0443\u043d\u043a\u0446\u0438\u0438 (\u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c      \/\/ \u043a\u043e\u0434) \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u043d\u0435\u0435     Context.TheFunction->getBasicBlockList().push_back(resultBB);     Context.TheBuilder->SetInsertPoint(resultBB);      \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c PHI \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432      \/\/ \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u043e\u0433\u043e \u043a\u0430\u043a\u0430\u044f \u0432\u0435\u0442\u043a\u0430 \u0431\u044b\u043b\u0430 \u0432\u044b\u0431\u0440\u0430\u043d\u0430 \u043f\u0440\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435      \/\/ \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u044f     PHINode* PN = Context.TheBuilder->CreatePHI(       Type::getInt1Ty(getGlobalContext()),       2     );      PN->addIncoming(lhs, condBB);     PN->addIncoming(rhs, trueBB);      return PN;   }    \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u043e\u0431\u043e\u0438\u0445 \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u043e\u0432   Value* lhs = LeftExpr->getRValue(Context);   Value* rhs = RightExpr->getRValue(Context);    \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0442\u0438\u043f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u044d\u0442\u043e \"int\"   if (LeftExpr->ExprType == BuiltinTypeAST::get(TypeAST::TI_Int)) {     \/\/ \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0441 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0435\u0439     switch (Op) {       case tok::Plus:         return Context.TheBuilder->CreateAdd(lhs, rhs, \"addtmp\");       case tok::Minus:         return Context.TheBuilder->CreateSub(lhs, rhs, \"subtmp\");       case tok::Mul:         return Context.TheBuilder->CreateMul(lhs, rhs, \"multmp\");       case tok::Div:         return Context.TheBuilder->CreateSDiv(lhs, rhs, \"divtmp\");       case tok::Mod:         return Context.TheBuilder->CreateSRem(lhs, rhs, \"remtmp\");       case tok::BitOr:         return Context.TheBuilder->CreateOr(lhs, rhs, \"ortmp\");       case tok::BitAnd:         return Context.TheBuilder->CreateAnd(lhs, rhs, \"andtmp\");       case tok::BitXor:         return Context.TheBuilder->CreateXor(lhs, rhs, \"xortmp\");       case tok::LShift:         return Context.TheBuilder->CreateShl(lhs, rhs, \"shltmp\");       case tok::RShift:         return Context.TheBuilder->CreateAShr(lhs, rhs, \"shrtmp\");       case tok::Less:         return Context.TheBuilder->CreateICmpSLT(lhs, rhs, \"cmptmp\");       case tok::Greater:         return Context.TheBuilder->CreateICmpSGT(lhs, rhs, \"cmptmp\");       case tok::LessEqual:         return Context.TheBuilder->CreateICmpSLE(lhs, rhs, \"cmptmp\");       case tok::GreaterEqual:         return Context.TheBuilder->CreateICmpSGE(lhs, rhs, \"cmptmp\");       case tok::Equal:         return Context.TheBuilder->CreateICmpEQ(lhs, rhs, \"cmptmp\");       case tok::NotEqual:         return Context.TheBuilder->CreateICmpNE(lhs, rhs, \"cmptmp\");       default:         assert(0 &amp;&amp; \"Invalid integral binary operator\");         return nullptr;     }   }      \/\/ \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0441 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0435\u0439   switch (Op) {     case tok::Plus:       return Context.TheBuilder->CreateFAdd(lhs, rhs, \"addtmp\");     case tok::Minus:       return Context.TheBuilder->CreateFSub(lhs, rhs, \"subtmp\");     case tok::Mul:       return Context.TheBuilder->CreateFMul(lhs, rhs, \"multmp\");     case tok::Div:       return Context.TheBuilder->CreateFDiv(lhs, rhs, \"divtmp\");     case tok::Mod:       return Context.TheBuilder->CreateFRem(lhs, rhs, \"remtmp\");     case tok::Less:       return Context.TheBuilder->CreateFCmpULT(lhs, rhs, \"cmptmp\");     case tok::Greater:       return Context.TheBuilder->CreateFCmpUGT(lhs, rhs, \"cmptmp\");     case tok::LessEqual:       return Context.TheBuilder->CreateFCmpULE(lhs, rhs, \"cmptmp\");     case tok::GreaterEqual:       return Context.TheBuilder->CreateFCmpUGE(lhs, rhs, \"cmptmp\");     case tok::Equal:       return Context.TheBuilder->CreateFCmpUEQ(lhs, rhs, \"cmptmp\");     case tok::NotEqual:       return Context.TheBuilder->CreateFCmpUNE(lhs, rhs, \"cmptmp\");     default:       assert(0 &amp;&amp; \"Invalid floating point binary operator\");       return nullptr;   } }  \/\/\/ \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0442\u0435\u0440\u043d\u0430\u0440\u043d\u043e\u0433\u043e \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430 (\u0432 \u043e\u0442\u043b\u0438\u0447\u0438\u0438 \u043e\u0442 \"if\"  \/\/\/ \u0434\u0430\u043d\u043d\u044b\u0439 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438 \u043c\u043e\u0436\u0435\u0442  \/\/\/ \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d \u0432 \u0434\u0440\u0443\u0433\u0438\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u0445) \/\/\/ \\param[in] Context - \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \/\/\/ \\param[in] Cond \u2014 \u0443\u0441\u043b\u043e\u0432\u043d\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \/\/\/ \\param[in] IfExpr \u2014 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u0435\u0441\u043b\u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0438\u0441\u0442\u0438\u043d\u043d\u043e \/\/\/ \\param[in] ElseExpr \u2014 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u0435\u0441\u043b\u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u043b\u043e\u0436\u043d\u043e \/\/\/ \\param[in] isLValue - true \u2014 \u0435\u0441\u043b\u0438 \u043d\u0443\u0436\u0435\u043d \u0430\u0434\u0440\u0435\u0441 (\u0438\u043b\u0438 lvalue) Value* generateCondExpr(   SLContext&amp; Context,   ExprAST* Cond,   ExprAST* IfExpr,    ExprAST* ElseExpr,   bool isLValue) {   \/\/ \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0443\u0441\u043b\u043e\u0432\u0438\u044f   Value* cond = Cond->getRValue(Context);   \/\/ \u041f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \"bool\"   cond = promoteToBool(cond, Cond->ExprType, *Context.TheBuilder);    \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0431\u043b\u043e\u043a\u0438 \u0434\u043b\u044f \u0432\u0435\u0442\u043e\u043a \"then\", \"else\" \u0438 \"ifcont\"   BasicBlock* thenBB = BasicBlock::Create(     getGlobalContext(),     \"then\",      Context.TheFunction   );   BasicBlock* elseBB = BasicBlock::Create(     getGlobalContext(),      \"else\"   );   BasicBlock* mergeBB = BasicBlock::Create(     getGlobalContext(),      \"ifcont\"   );    \/\/ \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 \"then\" \u0438\u043b\u0438 \"else\", \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438   \/\/ \u043e\u0442 \u0438\u0441\u0442\u0438\u043d\u043d\u043e\u0441\u0442\u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u044f   Context.TheBuilder->CreateCondBr(cond, thenBB, elseBB);   \/\/ Set insert point to a then branch   Context.TheBuilder->SetInsertPoint(thenBB);    \/\/ \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0432\u0435\u0442\u043a\u0438 \"then\"   Value* thenValue;      \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c lvalue \u0438\u043b\u0438 rvalue   if (isLValue) {     thenValue = IfExpr->getLValue(Context);   } else {     thenValue = IfExpr->getRValue(Context);   }    \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0431\u0435\u0437\u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 \"ifcont\" \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0431\u043b\u043e\u043a    \/\/ \"then\", \u0442.\u00a0\u043a. \u043e\u043d \u043c\u043e\u0433 \u0441\u043c\u0435\u043d\u0438\u0442\u044c\u0441\u044f   Context.TheBuilder->CreateBr(mergeBB);   thenBB = Context.TheBuilder->GetInsertBlock();    \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0431\u043b\u043e\u043a \"else\" \u043a \u0444\u0443\u043d\u043a\u0446\u0438\u0438 (\u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434)    \/\/ \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u043d\u0435\u0435   Context.TheFunction->getBasicBlockList().push_back(elseBB);   Context.TheBuilder->SetInsertPoint(elseBB);    Value* elseValue;      \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c lvalue \u0438\u043b\u0438 rvalue   if (isLValue) {     elseValue = ElseExpr->getLValue(Context);   } else {     elseValue = ElseExpr->getRValue(Context);   }    \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0431\u0435\u0437\u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 \"ifcont\" \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0431\u043b\u043e\u043a    \/\/ \"else\", \u0442.\u00a0\u043a. \u043e\u043d \u043c\u043e\u0433 \u0441\u043c\u0435\u043d\u0438\u0442\u044c\u0441\u044f   Context.TheBuilder->CreateBr(mergeBB);   elseBB = Context.TheBuilder->GetInsertBlock();    \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0431\u0435\u0437\u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 \"ifcont\" \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0431\u043b\u043e\u043a    \/\/ \"else\", \u0442.\u00a0\u043a. \u043e\u043d \u043c\u043e\u0433 \u0441\u043c\u0435\u043d\u0438\u0442\u044c\u0441\u044f   Context.TheFunction->getBasicBlockList().push_back(mergeBB);   Context.TheBuilder->SetInsertPoint(mergeBB);    \/\/ \u0415\u0441\u043b\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438\u043c\u0435\u0435\u0442 \u0442\u0438\u043f \"void\", \u0442\u043e \u043c\u044b \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0438\u0447\u0435\u0433\u043e   \/\/ \u043d\u0435 \u0434\u0435\u043b\u0430\u0435\u043c   if (!IfExpr->ExprType || IfExpr->ExprType->isVoid()) {     return nullptr;   }    \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c PHI \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432    \/\/ \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u043e\u0433\u043e \u043a\u0430\u043a\u0430\u044f \u0432\u0435\u0442\u043a\u0430 \u0431\u044b\u043b\u0430 \u0432\u044b\u0431\u0440\u0430\u043d\u0430 \u043f\u0440\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435   \/\/ \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u044f   PHINode* PN;      if (isLValue) {     \/\/ \u0414\u043b\u044f lvalue \u0442\u0438\u043f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u043c     PN = Context.TheBuilder->CreatePHI(       PointerType::get(IfExpr->ExprType->getType(), 0),       2     );   } else {     PN = Context.TheBuilder->CreatePHI(       IfExpr->ExprType->getType(),       2     );   }    PN->addIncoming(thenValue, thenBB);   PN->addIncoming(elseValue, elseBB);      return PN; }  Value* CondExprAST::getLValue(SLContext&amp; Context) {   return generateCondExpr(Context, Cond, IfExpr, ElseExpr, true); }  Value* CondExprAST::getRValue(SLContext&amp; Context) {   return generateCondExpr(Context, Cond, IfExpr, ElseExpr, false); }  Value* CallExprAST::getRValue(SLContext&amp; Context) {   Value* callee = nullptr;   std::vector&lt; Value* > args;   ExprList::iterator it = Args.begin();    assert(isa&lt;FuncDeclAST>(CallFunc));   FuncDeclAST* funcDecl = (FuncDeclAST*)CallFunc;   Type* funcRawType = CallFunc->getType()->getType();   assert(isa&lt;FunctionType>(funcRawType));   FunctionType* funcType = static_cast&lt;FunctionType*>(funcRawType);    \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0430\u0434\u0440\u0435\u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u0438   callee = CallFunc->getValue(Context);    \/\/ \u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438    \/\/ \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0438\u0445 \u043a \u0441\u043f\u0438\u0441\u043a\u0443 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438   for (ExprList::iterator end = Args.end(); it != end; ++it) {     Value* v = (*it)->getRValue(Context);     args.push_back(v);   }      \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0432\u044b\u0437\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438   return Context.TheBuilder->CreateCall(funcType, callee, args); }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h3>\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439<\/h3>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439:<\/p>\n<pre><code class=\"cpp\">struct StmtAST {    \/\/\/ \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438   virtual llvm::Value* generateCode(SLContext&amp; Context);  };  struct BlockStmtAST : StmtAST {    \/\/\/ \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438   llvm::Value* generateCode(SLContext&amp; Context);    \/\/\/ \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u0438\u043d\u0442\u0441\u0440\u0443\u043a\u0446\u0438\u0439   \/\/\/ \\param[in] Context - \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442   \/\/\/ \\param[in] it \u2014 \u043d\u0430\u0447\u0430\u043b\u043e   \/\/\/ \\param[in] end \u2014 \u043a\u043e\u043d\u0435\u0446   \/\/\/ \\note \u0412\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0431\u043b\u043e\u043a\u0430, \u043d\u0443\u0436\u043d\u0430   \/\/\/  \u0442.\u00a0\u043a. \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u043d\u0443\u0436\u0434\u0430\u044e\u0442\u0441\u044f \u0432 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435   \/\/\/  (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b \u0438 \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b)    llvm::Value* generatePartialCode(SLContext&amp; Context, StmtList::iterator it,      StmtList::iterator end);  };<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u044f\u0437\u044b\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c, \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0441\u043b\u043e\u0436\u043d\u044b\u0439 \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0445 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439, \u0442\u043e \u043f\u0440\u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0438\u043d\u044f\u0442\u044c \u0440\u0435\u0448\u0435\u043d\u0438\u0435, \u043a\u0430\u043a \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a \u0447\u0442\u043e \u0431\u044b \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0431\u044b\u043b\u0430 \u0441 \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u043f\u0440\u043e\u0441\u0442\u043e\u0439, \u0430 \u0441 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0439. \u042d\u0442\u043e \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e, \u0435\u0441\u043b\u0438 \u044f\u0437\u044b\u043a \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u041e\u041e\u041f. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0435\u0441\u043b\u0438 \u0432\u0437\u044f\u0442\u044c \u044f\u0437\u044b\u043a \u0421++, \u0442\u043e \u0435\u0441\u043b\u0438 \u043c\u044b \u0433\u0434\u0435-\u0442\u043e \u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435 \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u043a\u043b\u0430\u0441\u0441\u0430, \u0443 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0435\u0441\u0442\u044c \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440, \u0442\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0434\u043e\u043b\u0436\u0435\u043d \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432\u044b\u0437\u043e\u0432 \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430 \u0434\u043b\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0432\u043e \u0432\u0441\u0435\u0445 \u043c\u0435\u0441\u0442\u0430\u0445, \u0433\u0434\u0435 \u0434\u0430\u043d\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0432\u044b\u0445\u043e\u0434\u0438\u0442 \u0438\u0437 \u0441\u0432\u043e\u0435\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438 (\u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u044d\u0442\u043e\u0442 \u043a\u0435\u0439\u0441 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0432 \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0447\u0430\u0441\u0442\u0435\u0439 \u0441\u0435\u0440\u0438\u0438, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u043a\u043b\u0430\u0441\u0441\u043e\u0432).<\/p>\n<p>\u0414\u043b\u044f \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0445 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443:<\/p>\n<pre><code class=\"cpp\">struct LandingPadAST {    \/\/\/ \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438   llvm::Value* getReturnValue();       \/\/\/ \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 (\u043d\u0443\u0434\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c getReturnValue)   llvm::Value* ReturnValue;    llvm::BasicBlock* BreakLoc; \/\/\/&lt; \u0431\u043b\u043e\u043a \u0434\u043b\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 \u043f\u043e \"break\"   llvm::BasicBlock* ContinueLoc; \/\/\/&lt; \u0431\u043b\u043e\u043a \u0434\u043b\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 \u043f\u043e \"continue\"   llvm::BasicBlock* ReturnLoc; \/\/\/&lt; \u0431\u043b\u043e\u043a \u0434\u043b\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 \u043f\u043e \"return\"   \/\/\/ \u0431\u043b\u043e\u043a \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0442\u0435\u0447\u0435\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438   llvm::BasicBlock* FallthroughLoc; }; <\/code><\/pre>\n<p>\u0412\u043e \u0432\u0440\u0435\u043c\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0442\u0435\u043b\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u043e\u043c\u0443 \u043f\u043e\u0434\u0445\u043e\u0434\u0443, \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u0442\u0438\u043f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0433\u043e \u0435\u0439 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043e\u0442\u043b\u0438\u0447\u0435\u043d \u043e\u0442 &#171;void&#187;, \u0442\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u044d\u0442\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0430 \u0432\u043e \u0432\u0441\u0435\u0445 \u043c\u0435\u0441\u0442\u0430\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f &#171;return&#187; \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0432 \u044d\u0442\u0443 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 \u0438 \u0434\u0435\u043b\u0430\u0442\u044c \u0431\u0435\u0437\u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 \u0431\u043b\u043e\u043a \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u0436\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 (clang \u043f\u0440\u0438\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u0430\u043a\u043e\u0433\u043e \u0436\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0430). \u0422\u0435 \u043a\u0442\u043e \u043f\u0438\u0441\u0430\u043b\u0438 \u043d\u0430 C, \u043c\u043e\u0433\u043b\u0438 \u0432\u0438\u0434\u0435\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434, \u043a\u043e\u0433\u0434\u0430 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0431\u044b\u043b\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 (\u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0434\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440\u043e\u0432, \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0431\u043b\u043e\u043a\u043e\u0432 \u043f\u0430\u043c\u044f\u0442\u0438 \u0438 \u0442.\u00a0\u043f.), \u0442\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e \u0431\u044b \u043d\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u043e\u0447\u0438\u0441\u0442\u043a\u0443 \u0432\u0441\u0435\u0445 \u044d\u0442\u0438\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u043c\u0435\u0441\u0442\u0435 \u0441 &#171;return&#187;, \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u043b\u0441\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0431\u043b\u043e\u043a \u0441 \u043c\u0435\u0442\u043a\u043e\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u043d\u0438\u043c\u0430\u043b\u0441\u044f \u043e\u0447\u0438\u0441\u0442\u043a\u043e\u0439 \u0432\u0441\u0435\u0445 \u044d\u0442\u0438\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e &#171;goto&#187; \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u043b\u043e\u0441\u044c \u043d\u0430 \u044d\u0442\u0443 \u043c\u0435\u0442\u043a\u0443.<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043f\u0440\u0438 \u0434\u0430\u043d\u043d\u043e\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u0435, \u0444\u0443\u043d\u043a\u0446\u0438\u044f main \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 C \u0438\u043c\u0435\u044e\u0449\u0430\u044f \u0432\u0438\u0434:<\/p>\n<pre><code class=\"cpp\">int main() {   for (int i = 0; i &lt; 10; ++i) {     if (i == 5) {       break;     }        if (i == 2) {       continue;     }        if (i == 7) {       return 1;     }        printf(\"%d\", i);   }    return 0; }<\/code><\/pre>\n<p>\u043c\u043e\u0433\u043b\u0430 \u0431\u044b \u0431\u044b\u0442\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0430 \u0432 \u0432\u0438\u0434\u0435:<\/p>\n<pre><code class=\"cpp\">int main() {   int result;   {     int i = 0; loopcond:     if (i &lt; 10) {       goto loopbody;     } else {       goto loopend;     } loopbody:     if (i == 5) {       goto loopend;     }     if (i == 2) {       goto postbody;     }     if (i == 7) {       result = 1;       goto return_point;     }     printf(\"%d\", i); postbody:     ++i;     goto loopcond; loopend:   }   result = 0; return_point:   return result; }<\/code><\/pre>\n<p><strong>\u0417\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u0435:<\/strong> \u0412 \u043a\u043e\u0434\u0435 \u043d\u0438\u0436\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u044b \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0443\u0431\u0440\u0430\u0442\u044c \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0431\u043b\u043e\u043a\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u0432\u044b\u0437\u0432\u0430\u043d\u044b. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043f\u0440\u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 \u0432\u0435\u0442\u0432\u043b\u0435\u043d\u0438\u044f \u0438\u043b\u0438 \u0446\u0438\u043a\u043b\u043e\u0432, \u0447\u0430\u0441\u0442\u044c \u043a\u043e\u0434\u0430 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0443\u0431\u0440\u0430\u043d\u0430, \u0435\u0441\u043b\u0438 \u0438\u0441\u0442\u0438\u043d\u043d\u043e\u0441\u0442\u044c \u0438\u043b\u0438 \u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 (\u041e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0441\u0442\u044b\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0432\u0438\u0434\u0430 1, \u043d\u043e \u043d\u0435 1 + 2. \u0427\u0442\u043e \u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c\u0438 \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438, \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u043d\u044b\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430).<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e:<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">Value* StmtAST::generateCode(SLContext&amp; Context) {   assert(0 &amp;&amp; \"StmtAST::generateCode should never be reached\");   return nullptr; }  Value* ExprStmtAST::generateCode(SLContext&amp; Context) {   if (Expr) {     \/\/ \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f     return Expr->getRValue(Context);   }      return nullptr; }  llvm::Value* BlockStmtAST::generatePartialCode(SLContext&amp; Context,    StmtList::iterator it, StmtList::iterator end) {   \/\/ \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0431\u043b\u043e\u043a\u0438 \"break\", \"continue\" \u0438 \"return\" \u0434\u043b\u044f    \/\/ LandingPadAST \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0431\u043b\u043e\u043a\u0430 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0430   LandingPadAST* parent = LandingPad->Prev;   LandingPad->BreakLoc = parent->BreakLoc;   LandingPad->ContinueLoc = parent->ContinueLoc;   LandingPad->ReturnLoc = parent->ReturnLoc;    \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u0431\u043b\u043e\u043a FallthroughLoc (\u044d\u0442\u043e\u0442 \u0431\u043b\u043e\u043a \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c    \/\/ \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d \u0432 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f\u0445, \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0442\u043e\u0447\u043a\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430    \/\/ (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f \u0432\u044b\u0445\u043e\u0434\u0430 \u0438\u0437 \u0446\u0438\u043a\u043b\u0430))   LandingPad->FallthroughLoc = BasicBlock::Create(     getGlobalContext(),     \"block\"   );    \/\/ \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439   for (; it != end; ++it) {     \/\/ \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c FallthroughLoc (\u0442.\u00a0\u043a. \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0435\u0433\u043e      \/\/ \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u0430\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u0435\u0433\u043e \u043e\u0431\u043d\u0443\u043b\u0438\u0442\u044c)     BasicBlock* fallthroughBB = LandingPad->FallthroughLoc;     lastFallThrough = LandingPad->FallthroughLoc;      \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438     (*it)->generateCode(Context);      \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0431\u044b\u043b\u0430 \u043b\u0438 FallthroughLoc \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0430 \u0432\u043e \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0439      \/\/ \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0438\u043b\u0438 \u043d\u0435\u0442     if (!LandingPad->FallthroughLoc) {       \/\/ \u0411\u044b\u043b\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0439 \u0431\u043b\u043e\u043a \u0432 \u043a\u043e\u043d\u0435\u0446 \u0444\u0443\u043d\u043a\u0446\u0438\u0438,        \/\/ \u043a\u0430\u043a \u0435\u0435 \u0447\u0430\u0441\u0442\u044c \u0438 \u0437\u0430\u0434\u0430\u0442\u044c \u0435\u0433\u043e \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0442\u043e\u0447\u043a\u0438 \u0434\u043b\u044f \u0432\u0441\u0442\u0430\u0432\u043a\u0438       \/\/ \u043d\u043e\u0432\u043e\u0433\u043e \u043a\u043e\u0434\u0430       Context.TheFunction->getBasicBlockList().push_back(         fallthroughBB       );       Context.TheBuilder->SetInsertPoint(fallthroughBB);        \/\/ \u0417\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0432 FallthroughLoc \u043d\u043e\u0432\u044b\u0439 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u0431\u043b\u043e\u043a, \u0434\u043b\u044f        \/\/ \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432\u043e \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f\u0445       LandingPad->FallthroughLoc = BasicBlock::Create(         getGlobalContext(),         \"block\"       );     }   }    \/\/ \u0414\u0435\u043b\u0430\u0435\u043c \u043f\u043e\u0434\u0441\u0447\u0435\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \"break\" \"continue\" \u0438 \"return\"    \/\/ \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0431\u043b\u043e\u043a\u0435 (\u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0441\u0442\u0430\u0442\u044c\u044f\u0445 \u0431\u0443\u0434\u0435\u0442    \/\/ \u044f\u0441\u043d\u043e \u0437\u0430\u0447\u0435\u043c \u043e\u043d\u0438 \u043d\u0443\u0436\u043d\u044b)   parent->Breaks += LandingPad->Breaks;   parent->Continues += LandingPad->Continues;   parent->Returns += LandingPad->Returns;    \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0431\u043b\u043e\u043a \u0438\u043c\u0435\u0435\u0442 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0431\u043b\u043e\u043a\u0430   \/\/ (\u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u0438\u043b\u0438 \u0431\u0435\u0437\u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434)   if (!Context.TheBuilder->GetInsertBlock()->getTerminator()) {     \/\/ \u041d\u0435\u0442. \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043d\u0430 FallthroughLoc      \/\/ \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0430 \u0438 \u043f\u043e\u043c\u0435\u0447\u0430\u0435\u043c, \u0435\u0435 \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043d\u0443\u044e      \/\/ (\u043f\u0443\u0442\u0435\u043c \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u0438\u044f nullptr)     Context.TheBuilder->CreateBr(parent->FallthroughLoc);     parent->FallthroughLoc = nullptr;          \/\/ \u0415\u0441\u043b\u0438 FallthroughLoc, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u0434\u043b\u044f \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445      \/\/ \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 \u043d\u0435 \u0431\u044b\u043b\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0430, \u0442\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c \u0435\u0435 \u043e\u0447\u0438\u0441\u0442\u043a\u0443     if (!LandingPad->FallthroughLoc->hasNUsesOrMore(1)) {       delete LandingPad->FallthroughLoc;     }   \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e  FallthroughLoc \u0431\u044b\u043b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d \u0432\u043e \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445    \/\/ \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f\u0445   } else if (LandingPad->FallthroughLoc->hasNUsesOrMore(1)) {     \/\/ \u0411\u044b\u043b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d, \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0435\u0433\u043e \u0432 \u043a\u043e\u043d\u0435\u0446 \u0444\u0443\u043d\u043a\u0446\u0438\u0438,      \/\/ \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0435\u0433\u043e \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043c\u0435\u0441\u0442\u0430 \u0432\u0441\u0442\u0430\u0432\u043a\u0438 \u043d\u043e\u0432\u043e\u0433\u043e \u043a\u043e\u0434\u0430, \u0430      \/\/ \u0442\u0430\u043a\u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0431\u0435\u0437\u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 FallthroughLoc     \/\/ \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0430, \u0430 \u0442\u0430\u043a \u0436\u0435 \u043f\u043e\u043c\u0435\u0447\u0430\u0435\u043c \u0435\u0433\u043e \u043a\u0430\u043a      \/\/ \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043d\u0443\u044e (\u043f\u0443\u0442\u0435\u043c \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u0438\u044f nullptr)     Context.TheFunction->getBasicBlockList().push_back(       LandingPad->FallthroughLoc     );     Context.TheBuilder->SetInsertPoint(LandingPad->FallthroughLoc);     Context.TheBuilder->CreateBr(parent->FallthroughLoc);     parent->FallthroughLoc = nullptr;   } else {     \/\/ \u041d\u0435\u0442. \u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c \u0435\u0435 \u043e\u0447\u0438\u0441\u0442\u043a\u0443     delete LandingPad->FallthroughLoc;   }    return nullptr; }  Value* BlockStmtAST::generateCode(SLContext&amp; Context) {   return generatePartialCode(Context, Body.begin(), Body.end()); }  Value* DeclStmtAST::generateCode(SLContext&amp; Context) {   \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f   for (SymbolList::iterator it = Decls.begin(), end = Decls.end();     it != end; ++it) {     (*it)->generateCode(Context);   }    return nullptr; }  Value* LandingPadAST::getReturnValue() {   LandingPadAST* prev = this;    \/\/ \u0418\u0449\u0435\u043c LandingPadAST \u0441\u0430\u043c\u043e\u0433\u043e \u0432\u0435\u0440\u0445\u043d\u0435\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f (\u0431\u043b\u043e\u043a \u0442\u0435\u043b\u0430 \u0441\u0430\u043c\u043e\u0439    \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u0438)   while (prev->Prev) {     prev = prev->Prev;   }    \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c (\u0430\u0434\u0440\u0435\u0441 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439) \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438   return prev->ReturnValue; }  Value* BreakStmtAST::generateCode(SLContext&amp; Context) {   \/\/ \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0431\u0435\u0437\u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 \u043c\u0435\u0442\u043a\u0443 \"break\" \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0446\u0438\u043a\u043b\u0430   Context.TheBuilder->CreateBr(BreakLoc->BreakLoc);   return nullptr; }  Value* ContinueStmtAST::generateCode(SLContext&amp; Context) {   \/\/ \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0431\u0435\u0437\u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 \u043c\u0435\u0442\u043a\u0443 \"continue\" \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0446\u0438\u043a\u043b\u0430   Context.TheBuilder->CreateBr(ContinueLoc->ContinueLoc);   return nullptr; }  Value* ReturnStmtAST::generateCode(SLContext&amp; Context) {   \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435   if (Expr) {     \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0441 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c     Value* retVal = Expr->getRValue(Context);     \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \"store\" \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0433\u043e      \/\/ \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439, \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f     \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u0438     Context.TheBuilder->CreateStore(       retVal,       ReturnLoc->getReturnValue()     );     \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0431\u0435\u0437\u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 \u043c\u0435\u0442\u043a\u0443 \u0441 \u0432\u044b\u0445\u043e\u0434\u043e\u043c \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0438     Context.TheBuilder->CreateBr(ReturnLoc->ReturnLoc);     return nullptr;   }    \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0431\u0435\u0437\u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 \u043c\u0435\u0442\u043a\u0443 \u0441 \u0432\u044b\u0445\u043e\u0434\u043e\u043c \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0438   Context.TheBuilder->CreateBr(ReturnLoc->ReturnLoc);   return nullptr; }  Value* WhileStmtAST::generateCode(SLContext&amp; Context) {   LandingPadAST* prev = LandingPad->Prev;   LandingPad->ReturnLoc = prev->ReturnLoc;    \/\/ \u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u0434\u043b\u044f \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430, \u0435\u0441\u043b\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u044f    \/\/ \u0446\u0438\u043a\u043b\u0430 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 (\u043d\u043e \u043c\u044b \u043d\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c    \/\/ \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u043d\u044b\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0432\u0438\u0434\u0430 1 + 2, \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u043c   \/\/ \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432\u0438\u0434\u0430 1)   if (Cond->isConst()) {     \/\/ \u0415\u0441\u043b\u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \"false\", \u0442\u043e \u043d\u0435 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434     \/\/ \u0432\u043e\u043e\u0431\u0449\u0435     if (!Cond->isTrue()) {       return nullptr;     }      \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0435 \u0431\u043b\u043e\u043a\u0438 \u0434\u043b\u044f \u0442\u0435\u043b\u0430 \u0446\u0438\u043a\u043b\u0430 \u0438 \u0432\u044b\u0445\u043e\u0434\u0430 \u0438\u0437 \u0446\u0438\u043a\u043b\u0430, \u0438      \/\/ \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0438\u0445 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043c\u0435\u0442\u043e\u043a \u0434\u043b\u044f \"break\" \u0438 \"continue\"     BasicBlock* bodyBB =      LandingPad->ContinueLoc = BasicBlock::Create(       getGlobalContext(),       \"loopbody\",       Context.TheFunction     );     BasicBlock* endBB = LandingPad->BreakLoc = BasicBlock::Create(       getGlobalContext(),        \"loopend\"     );      if (PostExpr) {       \/\/ \u0414\u043b\u044f \u0446\u0438\u043a\u043b\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u044b\u043b\u0438 \u0441\u0434\u0435\u043b\u0430\u043d\u044b \u0438\u0437 \u0446\u0438\u043a\u043b\u0430 \"for\" \u0438 \u0443        \/\/ \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0435\u0441\u0442\u044c \u0431\u043b\u043e\u043a \u0434\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0446\u0438\u043a\u043b\u043e\u0432, \u043d\u0430\u043c       \/\/ \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u0431\u043b\u043e\u043a \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0438 \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b        \/\/ \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0435\u0433\u043e \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043c\u0435\u0442\u043a\u0438 \"continue\"       LandingPad->ContinueLoc = BasicBlock::Create(         getGlobalContext(),         \"postbody\"       );     }      \/\/ \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0431\u0435\u0437\u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 \u0442\u0435\u043b\u043e \u0446\u0438\u043a\u043b\u0430 \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c      \/\/ \u0434\u0430\u043d\u043d\u044b\u0439 \u0431\u043b\u043e\u043a \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0442\u043e\u0447\u043a\u0438 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430     Context.TheBuilder->CreateBr(bodyBB);     Context.TheBuilder->SetInsertPoint(bodyBB);      \/\/ \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0442\u043e\u0447\u043a\u0443 \u0434\u043b\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 \u0438\u0437 \u0446\u0438\u043a\u043b\u0430 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442      \/\/ \u0442\u043e\u0433\u043e, \u0435\u0441\u0442\u044c \u043b\u0438 \u0431\u043b\u043e\u043a \u0434\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0446\u0438\u043a\u043b\u0430 \u0438\u043b\u0438 \u043d\u0435\u0442     if (PostExpr) {       LandingPad->FallthroughLoc = LandingPad->ContinueLoc;     } else {       LandingPad->FallthroughLoc = bodyBB;     }      \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434 \u0442\u0435\u043b\u0430 \u0446\u0438\u043a\u043b\u0430     Body->generateCode(Context);      \/\/ \u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0434\u043b\u044f \u0446\u0438\u043a\u043b\u043e\u0432 \"for\" \u0441 \u0431\u043b\u043e\u043a\u043e\u043c      \/\/ \u0434\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0446\u0438\u043a\u043b\u0430     if (PostExpr) {       \/\/ \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0431\u043b\u043e\u043a \u0432 \u043a\u043e\u043d\u0435\u0446 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0435\u0433\u043e \u0432        \/\/ \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0442\u043e\u0447\u043a\u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430       Context.TheFunction->getBasicBlockList().push_back(         LandingPad->ContinueLoc       );       Context.TheBuilder->SetInsertPoint(LandingPad->ContinueLoc);        \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0446\u0438\u043a\u043b\u0430       PostExpr->getRValue(Context);       \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0431\u0435\u0437\u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 \u0442\u0435\u043b\u043e \u0446\u0438\u043a\u043b\u0430       Context.TheBuilder->CreateBr(bodyBB);     }      \/\/ \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0431\u043b\u043e\u043a \u0434\u043b\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 \u0438\u0437 \u0446\u0438\u043a\u043b\u0430 \u0432 \u043a\u043e\u043d\u0435\u0446 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438      \/\/ \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0435\u0433\u043e \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0442\u043e\u0447\u043a\u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430     Context.TheFunction->getBasicBlockList().push_back(endBB);     Context.TheBuilder->SetInsertPoint(endBB);     prev->Returns += LandingPad->Returns;      \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0431\u0435\u0437\u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 \u0442\u043e\u0447\u043a\u0443 \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e      \/\/ \u0431\u043b\u043e\u043a\u0430 \u0438 \u043f\u043e\u043c\u0435\u0447\u0430\u0435\u043c \u0435\u0435 \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043d\u0443\u044e (\u043f\u0443\u0442\u0435\u043c \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u0438\u044f     \/\/ nullptr)     Context.TheBuilder->CreateBr(prev->FallthroughLoc);     prev->FallthroughLoc = nullptr;      return nullptr;   }      \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0435 \u0431\u043b\u043e\u043a\u0438 \u0434\u043b\u044f \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u0446\u0438\u043a\u043b\u0430, \u0435\u0433\u043e \u0442\u0435\u043b\u0430 \u0438 \u0432\u044b\u0445\u043e\u0434\u0430 \u0438\u0437    \/\/ \u043d\u0435\u0433\u043e, \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0438\u0445 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043c\u0435\u0442\u043e\u043a \u0434\u043b\u044f \"break\"    \/\/ \u0438 \"continue\"   BasicBlock* condBB = LandingPad->ContinueLoc = BasicBlock::Create(     getGlobalContext(),      \"loopcond\",     Context.TheFunction   );   BasicBlock* bodyBB = BasicBlock::Create(     getGlobalContext(),      \"loopbody\"   );   BasicBlock* endBB = LandingPad->BreakLoc = BasicBlock::Create(     getGlobalContext(),     \"loopend\"   );    if (PostExpr) {     \/\/ \u0414\u043b\u044f \u0446\u0438\u043a\u043b\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u044b\u043b\u0438 \u0441\u0434\u0435\u043b\u0430\u043d\u044b \u0438\u0437 \u0446\u0438\u043a\u043b\u0430 \"for\" \u0438 \u0443 \u043a\u043e\u0442\u043e\u0440\u044b\u0445      \/\/ \u0435\u0441\u0442\u044c \u0431\u043b\u043e\u043a \u0434\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0446\u0438\u043a\u043b\u043e\u0432, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c     \/\/ \u043d\u043e\u0432\u044b\u0439 \u0431\u043b\u043e\u043a \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0438 \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0435\u0433\u043e \u0432      \/\/ \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043c\u0435\u0442\u043a\u0438 \"continue\"     LandingPad->ContinueLoc = BasicBlock::Create(       getGlobalContext(),       \"postbody\"     );   }    \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0431\u0435\u0437\u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 \u0431\u043b\u043e\u043a \u0441 \u0443\u0441\u043b\u043e\u0432\u0438\u0435\u043c \u0446\u0438\u043a\u043b\u0430 \u0438    \/\/ \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0435\u0433\u043e \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0442\u043e\u0447\u043a\u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430   Context.TheBuilder->CreateBr(condBB);   Context.TheBuilder->SetInsertPoint(condBB);    \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u0446\u0438\u043a\u043b\u0430   Value* cond = Cond->getRValue(Context);   \/\/ \u041f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \"bool\"   cond = promoteToBool(cond, Cond->ExprType, *Context.TheBuilder);   \/\/ \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 \u0442\u0435\u043b\u043e \u0446\u0438\u043a\u043b\u0430 \u0438\u043b\u0438 \u043d\u0430 \u0432\u044b\u0445\u043e\u0434 \u0438\u0437 \u0446\u0438\u043a\u043b\u0430    \/\/ \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0438\u0441\u0442\u0438\u043d\u043d\u043e\u0441\u0442\u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u0446\u0438\u043a\u043b\u0430   Context.TheBuilder->CreateCondBr(cond, bodyBB, endBB);    \/\/ \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0431\u0435\u0437\u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 \u0442\u0435\u043b\u043e \u0446\u0438\u043a\u043b\u0430 \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0439   \/\/ \u0431\u043b\u043e\u043a \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0442\u043e\u0447\u043a\u0438 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430   Context.TheFunction->getBasicBlockList().push_back(bodyBB);   Context.TheBuilder->SetInsertPoint(bodyBB);    \/\/ \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0442\u043e\u0447\u043a\u0443 \u0434\u043b\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 \u0438\u0437 \u0446\u0438\u043a\u043b\u0430 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442   \/\/ \u0442\u043e\u0433\u043e, \u0435\u0441\u0442\u044c \u043b\u0438 \u0431\u043b\u043e\u043a \u0434\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0446\u0438\u043a\u043b\u0430 \u0438\u043b\u0438 \u043d\u0435\u0442   if (PostExpr) {     LandingPad->FallthroughLoc = LandingPad->ContinueLoc;   } else {     LandingPad->FallthroughLoc = condBB;   }    \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434 \u0442\u0435\u043b\u0430 \u0446\u0438\u043a\u043b\u0430   Body->generateCode(Context);    \/\/ \u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0434\u043b\u044f \u0446\u0438\u043a\u043b\u043e\u0432 \"for\" \u0441 \u0431\u043b\u043e\u043a\u043e\u043c    \/\/ \u0434\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0446\u0438\u043a\u043b\u0430   if (PostExpr) {     \/\/ \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0431\u043b\u043e\u043a \u0432 \u043a\u043e\u043d\u0435\u0446 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0435\u0433\u043e \u0432      \/\/ \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0442\u043e\u0447\u043a\u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430     Context.TheFunction->getBasicBlockList().push_back(       LandingPad->ContinueLoc     );     Context.TheBuilder->SetInsertPoint(LandingPad->ContinueLoc);      \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0446\u0438\u043a\u043b\u0430     PostExpr->getRValue(Context);     \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0431\u0435\u0437\u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0446\u0438\u043a\u043b\u0430     Context.TheBuilder->CreateBr(condBB);   }    \/\/ \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0431\u043b\u043e\u043a \u0434\u043b\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 \u0438\u0437 \u0446\u0438\u043a\u043b\u0430 \u0432 \u043a\u043e\u043d\u0435\u0446 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438    \/\/ \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0435\u0433\u043e \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0442\u043e\u0447\u043a\u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430   Context.TheFunction->getBasicBlockList().push_back(endBB);   Context.TheBuilder->SetInsertPoint(endBB);   prev->Returns += LandingPad->Returns;    \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0431\u0435\u0437\u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 \u0442\u043e\u0447\u043a\u0443 \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e    \/\/ \u0431\u043b\u043e\u043a\u0430 \u0438 \u043f\u043e\u043c\u0435\u0447\u0430\u0435\u043c \u0435\u0435 \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043d\u0443\u044e (\u043f\u0443\u0442\u0435\u043c \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u0438\u044f    \/\/ nullptr)   Context.TheBuilder->CreateBr(prev->FallthroughLoc);   prev->FallthroughLoc = nullptr;    return nullptr; }  llvm::Value* ForStmtAST::generateCode(SLContext&amp; Context) {   assert(0 &amp;&amp; \"ForStmtAST::semantic should never be reached\");   return nullptr; }  llvm::Value* IfStmtAST::generateCode(SLContext&amp; Context) {   \/\/ \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0431\u043b\u043e\u043a\u0438 \"break\", \"continue\" \u0438 \"return\" \u0434\u043b\u044f    \/\/ LandingPadAST \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0431\u043b\u043e\u043a\u0430 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0430   LandingPadAST* prev = LandingPad->Prev;   LandingPad->ReturnLoc = prev->ReturnLoc;   LandingPad->FallthroughLoc = prev->FallthroughLoc;   LandingPad->ContinueLoc = prev->ContinueLoc;   LandingPad->BreakLoc = prev->BreakLoc;    \/\/ \u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u0434\u043b\u044f \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430, \u0435\u0441\u043b\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u044f    \/\/ \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 (\u043d\u043e \u043c\u044b \u043d\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435   \/\/ \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u043d\u044b\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0432\u0438\u0434\u0430 1 + 2, \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e   \/\/ \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432\u0438\u0434\u0430 1)   if (Cond->isConst()) {     \/\/ \u0415\u0441\u043b\u0438 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438\u0441\u0442\u0438\u043d\u043d\u043e     if (Cond->isTrue()) {       \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u0432\u0435\u0442\u043a\u0438 \"then\"       ThenBody->generateCode(Context);        \/\/ \u0414\u0435\u043b\u0430\u0435\u043c \u043f\u043e\u0434\u0441\u0447\u0435\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \"break\" \"continue\" \u0438 \"return\"        \/\/ \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0431\u043b\u043e\u043a\u0435 (\u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0441\u0442\u0430\u0442\u044c\u044f\u0445 \u0431\u0443\u0434\u0435\u0442       \/\/ \u044f\u0441\u043d\u043e \u0437\u0430\u0447\u0435\u043c \u043e\u043d\u0438 \u043d\u0443\u0436\u043d\u044b)       prev->Returns += LandingPad->Returns;       prev->Breaks += LandingPad->Breaks;       prev->Continues += LandingPad->Continues;        if (!Context.TheBuilder->GetInsertBlock()->getTerminator()) {         \/\/ \u0415\u0441\u043b\u0438 \u0435\u0449\u0435 \u043d\u0435\u0442 \u0443\u0441\u043b\u043e\u0432\u043d\u043e\u0433\u043e \u0438\u043b\u0438 \u0431\u0435\u0437\u0443\u0441\u043b\u043e\u0432\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430, \u0442\u043e          \/\/ \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0431\u0435\u0437\u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 \u0442\u043e\u0447\u043a\u0443 \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430          \/\/ \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0430 \u0438 \u043f\u043e\u043c\u0435\u0447\u0430\u0435\u043c \u0435\u0435 \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043d\u0443\u044e          \/\/ (\u043f\u0443\u0442\u0435\u043c \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u0438\u044f nullptr)         Context.TheBuilder->CreateBr(prev->FallthroughLoc);         prev->FallthroughLoc = nullptr;       }        return nullptr;     }            \/\/ \u0415\u0441\u043b\u0438 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043b\u043e\u0436\u043d\u043e \u0438 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0432\u0435\u0442\u043a\u0430 \"else\"     if (ElseBody) {       \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u0432\u0435\u0442\u043a\u0438 \"else\"       ElseBody->generateCode(Context);        \/\/ \u0414\u0435\u043b\u0430\u0435\u043c \u043f\u043e\u0434\u0441\u0447\u0435\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \"break\" \"continue\" \u0438 \"return\"        \/\/ \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0431\u043b\u043e\u043a\u0435 (\u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0441\u0442\u0430\u0442\u044c\u044f\u0445 \u0431\u0443\u0434\u0435\u0442       \/\/ \u044f\u0441\u043d\u043e \u0437\u0430\u0447\u0435\u043c \u043e\u043d\u0438 \u043d\u0443\u0436\u043d\u044b)       prev->Returns += LandingPad->Returns;       prev->Breaks += LandingPad->Breaks;       prev->Continues += LandingPad->Continues;        if (!Context.TheBuilder->GetInsertBlock()->getTerminator()) {         \/\/ \u0415\u0441\u043b\u0438 \u0435\u0449\u0435 \u043d\u0435\u0442 \u0443\u0441\u043b\u043e\u0432\u043d\u043e\u0433\u043e \u0438\u043b\u0438 \u0431\u0435\u0437\u0443\u0441\u043b\u043e\u0432\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430, \u0442\u043e         \/\/ \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0431\u0435\u0437\u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 \u0442\u043e\u0447\u043a\u0443 \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430          \/\/ \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0430 \u0438 \u043f\u043e\u043c\u0435\u0447\u0430\u0435\u043c \u0435\u0435 \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043d\u0443\u044e         \/\/ (\u043f\u0443\u0442\u0435\u043c \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u0438\u044f nullptr)         Context.TheBuilder->CreateBr(prev->FallthroughLoc);         prev->FallthroughLoc = nullptr;       }     }      return nullptr;   }       \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u0443\u0441\u043b\u043e\u0432\u043d\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f   Value* cond = Cond->getRValue(Context);   \/\/ \u041f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \"bool\"   cond = promoteToBool(cond, Cond->ExprType, *Context.TheBuilder);    \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0431\u043b\u043e\u043a \u0434\u043b\u044f \u0432\u0435\u0442\u043e\u043a \"then\" \u0438 \u0431\u043b\u043e\u043a\u0430 \u0437\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0435\u0439 \u0432\u0435\u0442\u0432\u043b\u0435\u043d\u0438\u044f   BasicBlock* thenBB = BasicBlock::Create(     getGlobalContext(),     \"thenpart\",      Context.TheFunction   );   BasicBlock* elseBB = nullptr;   BasicBlock* endBB = BasicBlock::Create(     getGlobalContext(),     \"ifcont\"   );    \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0432\u0435\u0442\u043a\u0438 \"else\"   if (ElseBody) {     \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0431\u043b\u043e\u043a \u0434\u043b\u044f \u0432\u0435\u0442\u043a\u0438 \"else\"     elseBB = BasicBlock::Create(getGlobalContext(), \"elsepart\");     \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 \"then\" \u0438\u043b\u0438 \"else\" \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438      \/\/ \u043e\u0442 \u0438\u0441\u0442\u0438\u043d\u043d\u043e\u0441\u0442\u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u044f     Context.TheBuilder->CreateCondBr(cond, thenBB, elseBB);   } else {     \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 \"then\" \u0438\u043b\u0438 \u0431\u043b\u043e\u043a \u0437\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0435\u0439      \/\/ \u0432\u0435\u0442\u0432\u043b\u0435\u043d\u0438\u044f \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0438\u0441\u0442\u0438\u043d\u043d\u043e\u0441\u0442\u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u044f     Context.TheBuilder->CreateCondBr(cond, thenBB, endBB);   }    \/\/ \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0442\u043e\u0447\u043a\u0443 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u043d\u0430 \u0431\u043b\u043e\u043a \"then\"   Context.TheBuilder->SetInsertPoint(thenBB);      \/\/ \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0442\u043e\u0447\u043a\u0443 \u0434\u043b\u044f FallthroughLoc   LandingPad->FallthroughLoc = endBB;    \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u0432\u0435\u0442\u0432\u0438 \"then\"   ThenBody->generateCode(Context);    \/\/ \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0442\u043e\u0447\u043a\u0443 \u0434\u043b\u044f FallthroughLoc (\u0442.\u00a0\u043a. \u043e\u043d\u0430 \u043c\u043e\u0433\u043b\u0430 \u0431\u044b\u0442\u044c    \/\/ \u043e\u0431\u043d\u0443\u043b\u0435\u043d\u0430 \u043f\u0440\u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0432\u0435\u0442\u043a\u0438 \"then\")   LandingPad->FallthroughLoc = endBB;    \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0432\u0435\u0442\u043a\u0438 \"else\"   if (ElseBody) {     \/\/ \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0431\u043b\u043e\u043a \"else\" \u0432 \u043a\u043e\u043d\u0435\u0446 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0435\u0433\u043e \u0432      \/\/ \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0442\u043e\u0447\u043a\u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430     Context.TheFunction->getBasicBlockList().push_back(elseBB);     Context.TheBuilder->SetInsertPoint(elseBB);      \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u0432\u0435\u0442\u0432\u0438 \"else\"     ElseBody->generateCode(Context);   }    \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0431\u044b\u043b \u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d \u0431\u043b\u043e\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u0434\u043b\u044f    \/\/ \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u043e\u0441\u043b\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0432\u0435\u0442\u0432\u043b\u0435\u043d\u0438\u044f   if (endBB->hasNUsesOrMore(1)) {     \/\/ \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0439 \u0431\u043b\u043e\u043a \u0432 \u043a\u043e\u043d\u0435\u0446 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0435\u0433\u043e \u0432      \/\/ \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0442\u043e\u0447\u043a\u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430     Context.TheFunction->getBasicBlockList().push_back(endBB);     Context.TheBuilder->SetInsertPoint(endBB);      \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0431\u0435\u0437\u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 \u0442\u043e\u0447\u043a\u0443 \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e      \/\/ \u0431\u043b\u043e\u043a\u0430 \u0438 \u043f\u043e\u043c\u0435\u0447\u0430\u0435\u043c \u0435\u0435 \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043d\u0443\u044e (\u043f\u0443\u0442\u0435\u043c \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u0438\u044f     \/\/ nullptr)     Context.TheBuilder->CreateBr(prev->FallthroughLoc);     prev->FallthroughLoc = nullptr;   } else {     \/\/ \u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c \u043e\u0447\u0438\u0441\u0442\u043a\u0443     delete endBB;   }    \/\/ \u0414\u0435\u043b\u0430\u0435\u043c \u043f\u043e\u0434\u0441\u0447\u0435\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \"break\" \"continue\" \u0438 \"return\"    \/\/ \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0431\u043b\u043e\u043a\u0435 (\u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0441\u0442\u0430\u0442\u044c\u044f\u0445 \u0431\u0443\u0434\u0435\u0442   \/\/ \u044f\u0441\u043d\u043e \u0437\u0430\u0447\u0435\u043c \u043e\u043d\u0438 \u043d\u0443\u0436\u043d\u044b)   prev->Returns += LandingPad->Returns;   prev->Breaks += LandingPad->Breaks;   prev->Continues += LandingPad->Continues;    return nullptr; }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h3>\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0439<\/h3>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0439:<\/p>\n<pre><code class=\"cpp\">struct SymbolAST {    \/\/\/ \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0438\u043c\u0432\u043e\u043b\u0430 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439)   virtual llvm::Value *getValue(SLContext &amp;Context);    \/\/\/ \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0441\u0438\u043c\u0432\u043e\u043b\u0430 (\u0442\u0435\u043b\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u043e\u0432 \u0438 \u0442.\u00a0\u043f.)   virtual llvm::Value *generateCode(SLContext &amp;Context);  }; <\/code><\/pre>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u0430\u043c\u0443 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0439:<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">Value* SymbolAST::getValue(SLContext&amp; ) {   assert(0 &amp;&amp; \"SymbolAST::getValue should never be reached\");   return nullptr; }  Value* SymbolAST::generateCode(SLContext&amp; Context) {   assert(0 &amp;&amp; \"SymbolAST::generateCode should never be reached\");   return nullptr; }  Value* VarDeclAST::generateCode(SLContext&amp; Context) {   assert(SemaState >= 5);   \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0430\u0434\u0440\u0435\u0441 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 (\u0442.\u00a0\u043a. \u043f\u0430\u043c\u044f\u0442\u044c \u043f\u043e\u0434 \u0441\u0430\u043c\u0443 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e    \/\/ \u0443\u0436\u0435 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u043b\u0430 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0430 \u0440\u0430\u043d\u0435\u0435 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u0434\u043b\u044f   \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u0438)   Value* val = getValue(Context);     \/\/ \u0415\u0441\u043b\u0438 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0435\u0435    \/\/ \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438   if (Val) {     \/\/ \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u044e\u0449\u0435\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f     Value* init = Val->getRValue(Context);      \/\/ \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \"store\"     return Context.TheBuilder->CreateStore(init, val);   }    return val; }  Value* VarDeclAST::getValue(SLContext&amp; Context) {   \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437   if (CodeValue) {     return CodeValue;   }    \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \"alloca\" \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439   CodeValue = Context.TheBuilder->CreateAlloca(     ThisType->getType(),     0,     StringRef(Id->Id, Id->Length)   );   return CodeValue; }  llvm::Value* ParameterSymbolAST::getValue(SLContext&amp; Context) {   \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437   if (Param->CodeValue) {     return Param->CodeValue;   }    \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \"alloca\" \u0434\u043b\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438   Param->CodeValue = Context.TheBuilder->CreateAlloca(     Param->Param->getType(),     0U   );   return Param->CodeValue; }  llvm::Value* ParameterSymbolAST::generateCode(SLContext&amp; Context) {   assert(SemaState >= 5);   \/\/ \u041c\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0430\u0434\u0440\u0435\u0441 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439, \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u0438    \/\/ \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0431\u0443\u0434\u0435\u0442 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043e \u0432  FuncDeclAST   return getValue(Context); }  Value* FuncDeclAST::getValue(SLContext&amp; Context) {   \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437   if (CodeValue) {     return CodeValue;   }    SmallString&lt; 128 > str;   raw_svector_ostream output(str);    \/\/ \u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u0438\u043c\u0435\u043d\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 (\u0434\u043b\u044f \"main\" \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c    \/\/ \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430)   if (!(Id->Length == 4 &amp;&amp; memcmp(Id->Id, \"main\", 4) == 0)) {     \/\/ \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0434\u0435\u043a\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0438\u043c\u0435\u043d\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438     output &lt;&lt; \"_P\" &lt;&lt; Id->Length &lt;&lt; StringRef(Id->Id, Id->Length);     ThisType->toMangleBuffer(output);   } else {     output &lt;&lt; \"main\";   }    \/\/ \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0441 \u0432\u043d\u0435\u0448\u043d\u0438\u043c \u0432\u0438\u0434\u043e\u043c \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u043e\u0441\u0442\u0438 \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e    \/\/ \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f   CodeValue = Function::Create((FunctionType*)ThisType->getType(),      Function::ExternalLinkage, output.str(), nullptr);   Context.TheModule->getFunctionList().push_back(CodeValue);    return CodeValue; }  Value* FuncDeclAST::generateCode(SLContext&amp; Context) {   if (Compiled) {     return CodeValue;   }    assert(SemaState >= 5);   \/\/ \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 (\u0435\u0435 \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f)   getValue(Context);    BasicBlock* oldBlock = Context.TheBuilder->GetInsertBlock();    Function::arg_iterator AI = CodeValue->arg_begin();   ParameterList::iterator PI =      ((FuncTypeAST*)ThisType)->Params.begin();   ParameterList::iterator PE =      ((FuncTypeAST*)ThisType)->Params.end();    \/\/ \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0431\u043b\u043e\u043a \"entry\" \u0434\u043b\u044f \u0442\u0435\u043b\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0435\u0433\u043e \u0432    \/\/ \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0442\u043e\u0447\u043a\u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430   BasicBlock* BB = BasicBlock::Create(     getGlobalContext(),      \"entry\",      CodeValue   );   Context.TheBuilder->SetInsertPoint(BB);    \/\/ \u0412\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u0438 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445   for (std::vector&lt; SymbolAST* >::iterator it = FuncVars.begin(),      end = FuncVars.end(); it != end; ++it) {     (*it)->getValue(Context);   }    \/\/ \u041f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432   for ( ; PI != PE; ++PI, ++AI) {     ParameterAST* p = *PI;      \/\/ \u041d\u0430\u043c \u0432\u0430\u0436\u043d\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b     if (p->Id) {       \/\/ \u0423\u043a\u0430\u0437\u0430\u043d\u0438\u0435 \u0438\u043c\u0435\u043d\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430       AI->setName(StringRef(p->Id->Id, p->Id->Length));       \/\/ \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \"alloca\", \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e       if (!p->CodeValue) {         p->CodeValue = Context.TheBuilder->CreateAlloca(           p->Param->getType(),           0U         );       }       \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \"store\" \u0434\u043b\u044f \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f        \/\/ \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e       \/\/ \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u0443\u044e \u043f\u043e\u0434 \u044d\u0442\u043e\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440       Context.TheBuilder->CreateStore(AI, p->CodeValue);     }   }    \/\/ \u0415\u0441\u043b\u0438 \u0442\u0438\u043f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \"void\",   \/\/ \u0442\u043e \u0432\u044b\u0434\u0435\u043b\u044f\u0435\u043c \u043f\u0430\u043c\u044f\u0442\u044c \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c   \/\/ \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438   if (!ReturnType->isVoid()) {     LandingPad->ReturnValue = Context.TheBuilder->CreateAlloca(       ReturnType->getType(),       0U,       \"return.value\"     );   }    \/\/ \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0431\u043b\u043e\u043a \u0434\u043b\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0435\u0433\u043e \u0432    \/\/ \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 FallthroughLoc   LandingPad->ReturnLoc = BasicBlock::Create(     getGlobalContext(),     \"return.block\"   );   LandingPad->FallthroughLoc = LandingPad->ReturnLoc;    Function* oldFunction = Context.TheFunction;   Context.TheFunction = CodeValue;    \/\/ \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0442\u0435\u043b\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438   Body->generateCode(Context);     Context.TheFunction = oldFunction;    \/\/ \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 \u0431\u043b\u043e\u043a \u0432\u044b\u0445\u043e\u0434\u0430 \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0435\u0441\u043b\u0438    \/\/ \u043e\u043d \u0435\u0449\u0435 \u043d\u0435 \u0431\u044b\u043b \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d   if (!Context.TheBuilder->GetInsertBlock()->getTerminator()) {     Context.TheBuilder->CreateBr(LandingPad->ReturnLoc);   }    \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0431\u043b\u043e\u043a \u0434\u043b\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432 \u043a\u043e\u043d\u0435\u0446 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438    \/\/ \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0435\u0433\u043e \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0442\u043e\u0447\u043a\u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430   CodeValue->getBasicBlockList().push_back(LandingPad->ReturnLoc);   Context.TheBuilder->SetInsertPoint(LandingPad->ReturnLoc);      if (!ReturnType->isVoid()) {     \/\/ \u0422\u0438\u043f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043d\u0435 \"void\". \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e      \/\/ \"load\" \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f     Value* ret = Context.TheBuilder->CreateLoad(       ReturnType->getType(),       LandingPad->ReturnValue     );     \/\/ \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0438     Context.TheBuilder->CreateRet(ret);   } else {     \/\/ \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \"void\"     Context.TheBuilder->CreateRetVoid();   }    \/\/ \u0412\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0442\u043e\u0447\u043a\u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 (\u0435\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u043e)   if (oldBlock) {     Context.TheBuilder->SetInsertPoint(oldBlock);   }    \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043a\u043e\u0434\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f (\u0435\u0441\u043b\u0438 \u043e\u043d\u0430 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0430)   verifyFunction(*CodeValue, &amp;llvm::errs());      Compiled = true;    return CodeValue; }  void ModuleDeclAST::generateCode() {   SLContext&amp; Context = getSLContext();      \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0439   for (SymbolList::iterator it = Members.begin(),     end = Members.end(); it != end; ++it) {     (*it)->generateCode(Context);   }    \/\/ \u041f\u0435\u0447\u0430\u0442\u044c \u043a\u043e\u0434\u0430 \u043c\u043e\u0434\u0443\u043b\u044f \u043d\u0430 \u043a\u043e\u043d\u0441\u043e\u043b\u044c   Context.TheModule->dump();    if (!OutputFilename.empty()) {     std::error_code errorInfo;     raw_fd_ostream fd(OutputFilename.c_str(), errorInfo);      if (errorInfo) {       llvm::errs()         &lt;&lt; \"Can't write to \\\"\"         &lt;&lt; OutputFilename.c_str()         &lt;&lt; \"\\\" file\\n\";     }      \/\/ \u041f\u0435\u0447\u0430\u0442\u044c \u043a\u043e\u0434\u0430 \u043c\u043e\u0434\u0443\u043b\u044f \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u0444\u0430\u0439\u043b, \u0435\u0441\u043b\u0438 \u043e\u043d \u0431\u044b\u043b \u0437\u0430\u0434\u0430\u043d     Context.TheModule->print(fd, 0);   }    \/\/ \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0430\u0434\u0440\u0435\u0441 JIT \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \"main\", \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c    \/\/ \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f   MainPtr = (double (*)())(intptr_t)getJITMain(); }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h3>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h3>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u043a\u043e\u0434\u0430 \u0434\u043b\u044f LLVM IR, \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u0438 LLVM \u0438 LLVM IR. \u0422\u0430\u043a \u0436\u0435 \u0431\u044b\u043b\u0438 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u044b \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u043a\u043e\u0434\u0430 \u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0430 \u0438\u0445 \u043e\u0441\u043d\u043e\u0432\u0435.<\/p>\n<p>\u041f\u043e\u043b\u043d\u044b\u0439 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u043d\u0430 <a href=\"https:\/\/github.com\/dc-sinpo\/simple\/tree\/part01\" rel=\"noopener noreferrer nofollow\">github<\/a>. \u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0441\u0442\u0430\u0442\u044c\u044f\u0445 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u043d\u0430\u0448\u0435\u0433\u043e \u0443\u0447\u0435\u0431\u043d\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430 \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0431\u043e\u043b\u0435\u0435 \u0432\u044b\u0441\u043e\u043a\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a:<\/p>\n<ol>\n<li>\n<p>\u0423\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438 \u0438 \u043c\u0430\u0441\u0441\u0438\u0432\u044b;<\/p>\n<\/li>\n<li>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0438 \u043a\u043b\u0430\u0441\u0441\u044b;<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u043a\u043b\u0430\u0441\u0441\u0430;<\/p>\n<\/li>\n<li>\n<p>\u0410 \u0442\u0430\u043a \u0436\u0435 \u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0437\u043a\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u0439.<\/p>\n<\/li>\n<\/ol>\n<h3>\u041f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0441\u0441\u044b\u043b\u043a\u0438<\/h3>\n<ol>\n<li>\n<p><a href=\"https:\/\/llvm.org\/docs\/LangRef.html\" rel=\"noopener noreferrer nofollow\">https:\/\/llvm.org\/docs\/LangRef.html<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/llvm.org\/docs\/tutorial\/MyFirstLanguageFrontend\/index.html\" rel=\"noopener noreferrer nofollow\">https:\/\/llvm.org\/docs\/tutorial\/MyFirstLanguageFrontend\/index.html<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/llvm.org\/docs\/tutorial\/BuildingAJIT1.html\" rel=\"noopener noreferrer nofollow\">https:\/\/llvm.org\/docs\/tutorial\/BuildingAJIT1.html<\/a><\/p>\n<\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/div>\n<p> <!----> <!----><\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/717886\/\"> https:\/\/habr.com\/ru\/post\/717886\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0441\u0442\u0430\u0442\u044c\u044f\u0445 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u043b\u0435\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0438 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u044b, \u0430 \u0442\u0430\u043a \u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437 \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u0443\u0447\u0435\u0431\u043d\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430, \u0447\u0442\u043e \u0434\u0430\u043b\u043e \u043d\u0430\u043c \u043e\u0441\u043d\u043e\u0432\u0443. \u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u043c \u043d\u0430\u0447\u0430\u0442\u043e\u0435 \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u043a\u043e\u0434\u0430 \u0434\u043b\u044f LLVM IR.<\/p>\n<h3>LLVM<\/h3>\n<p>LLVM \u044d\u0442\u043e \u043d\u0430\u0431\u043e\u0440 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u043e\u0432 \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u044b \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u043e\u0432 \u0434\u043b\u044f \u043b\u044e\u0431\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u0431\u044d\u043a\u0435\u043d\u0434\u043e\u0432 \u0434\u043b\u044f \u043b\u044e\u0431\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u043d\u0430\u0431\u043e\u0440\u0430 \u043a\u043e\u043c\u0430\u043d\u0434. LLVM \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d \u0432\u043e\u043a\u0440\u0443\u0433 \u044f\u0437\u044b\u043a\u043e-\u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0433\u043e \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f (LLVM IR), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043b\u0443\u0436\u0438\u0442 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u043e\u0440\u0442\u0430\u0442\u0438\u0432\u043d\u043e\u0433\u043e, \u0432\u044b\u0441\u043e\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430 \u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0439.<\/p>\n<p>\u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 LLVM \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u043c\u043e\u0434\u0443\u043b\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0435\u0434\u0438\u043d\u0438\u0446\u0430\u043c\u0438 \u0442\u0440\u0430\u043d\u0441\u043b\u044f\u0446\u0438\u0438 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b. \u041a\u0430\u0436\u0434\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432. \u041c\u043e\u0434\u0443\u043b\u0438 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u044b \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043b\u0438\u043d\u043a\u043e\u0432\u0449\u0438\u043a\u0430 LLVM.<\/p>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f \u0441\u0430\u043c\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 (\u0435\u0435 \u0438\u043c\u044f, \u0442\u0438\u043f\u044b \u0435\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432, \u0442\u0438\u043f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u0440\u0443\u0433\u0438\u0435 \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0447\u0430\u0441\u0442\u0438, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a \u0441\u043f\u043e\u0441\u043e\u0431 \u043b\u0438\u043d\u043a\u043e\u0432\u043a\u0438, \u0435\u0435 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u044c, \u0441\u043f\u043e\u0441\u043e\u0431 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0438 \u0434\u0440.), \u0430 \u0442\u0430\u043a\u0436\u0435 \u0435\u0435 \u0442\u0435\u043b\u0430, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0431\u0430\u0437\u043e\u0432\u044b\u0445 \u0431\u043b\u043e\u043a\u043e\u0432.<\/p>\n<p>\u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u0431\u043b\u043e\u043a \u2014 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 (\u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439), \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0431\u0440\u0430\u0437\u0443\u044e\u0442 \u043b\u043e\u0433\u0438\u043a\u0443 \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0430. \u041b\u044e\u0431\u043e\u0439 \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u0431\u043b\u043e\u043a \u0434\u043e\u043b\u0436\u0435\u043d \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0442\u044c\u0441\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0435\u0439 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u0442\u043e\u0440\u043e\u043c (\u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u0438\u043b\u0438 \u0431\u0435\u0437\u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434, \u0432\u043e\u0437\u0432\u0440\u0430\u0442 \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u0434\u0440.).<\/p>\n<p>\u0421\u0438\u0441\u0442\u0435\u043c\u0430 \u0442\u0438\u043f\u043e\u0432 LLVM \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0442\u0438\u043f\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u0435\u043b\u044f\u0442\u0441\u044f \u043d\u0430 (\u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435 \u0442\u0438\u043f\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0430\u0448\u0435\u0433\u043e \u0443\u0447\u0435\u0431\u043d\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430):<\/p>\n<ol>\n<li>\n<p>\u0426\u0435\u043b\u044b\u0435 \u0447\u0438\u0441\u043b\u0430 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u043e\u0439 \u0440\u0430\u0437\u0440\u044f\u0434\u043d\u043e\u0441\u0442\u0438 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 i1, i8, i32, i64);<\/p>\n<\/li>\n<li>\n<p>\u0427\u0438\u0441\u043b\u0430 \u0441 \u043f\u043b\u0430\u0432\u0430\u044e\u0449\u0435\u0439 \u0442\u043e\u0447\u043a\u043e\u0439 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 float, double);<\/p>\n<\/li>\n<li>\n<p>void;<\/p>\n<\/li>\n<li>\n<p>\u0423\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 i64*);<\/p>\n<\/li>\n<li>\n<p>\u041c\u0430\u0441\u0441\u0438\u0432\u044b (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 [20 x i32]);<\/p>\n<\/li>\n<li>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 { i32, double, i64 });<\/p>\n<\/li>\n<li>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u0438 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 i32 (i32, double)).<\/p>\n<\/li>\n<\/ol>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c LLVM IR \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043e\u043d \u0437\u0430\u043f\u0438\u0441\u0430\u043d \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 SSA (Static Single Assignment), \u043f\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0443 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437. \u0427\u0442\u043e \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u0430\u043d\u0430\u043b\u0438\u0437 \u043f\u043e\u0442\u043e\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<p>\u041d\u043e \u0442\u0430\u043a\u0430\u044f \u0444\u043e\u0440\u043c\u0430 \u043d\u0430\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f, \u0435\u0441\u043b\u0438 \u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435 \u0435\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f, \u0434\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f phi, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0442\u043e\u0433\u043e, \u0438\u0437 \u043a\u0430\u043a\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0430 \u0431\u044b\u043b \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u0432 \u0431\u043b\u043e\u043a \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0443\u044e \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e phi. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code>Loop:       ; Infinite loop that counts from 0 on up...   %indvar = phi i32 [ 0, %LoopHeader ], [ %nextindvar, %Loop ]   %nextindvar = add i32 %indvar, 1   br label %Loop<\/code><\/pre>\n<p>\u0411\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043f\u0440\u043e LLVM IR \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0432 [1], \u0430 \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0432\u0441\u0435 \u044d\u0442\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u0432 [2].<\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u044f\u0437\u044b\u043a\u0430 (\u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c JIT, \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 \u043f\u043e\u043b\u043d\u043e\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c \u043a\u043e\u0434\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043d\u0430 <a href=\"https:\/\/github.com\/dc-sinpo\/simple\/tree\/part01\" rel=\"noopener noreferrer nofollow\">github<\/a>, \u043b\u0438\u0431\u043e \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0432 [3]).<\/p>\n<h3>\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0442\u0438\u043f\u043e\u0432<\/h3>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0447\u0442\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u043e\u0441\u044c \u0432 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0438 \u0442\u0438\u043f\u0430 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430:<\/p>\n<pre><code class=\"cpp\">struct TypeAST {     \/\/\/ \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0442\u0438\u043f LLVM \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0439 \u0432\u0435\u0442\u043a\u0438 \u0434\u0435\u0440\u0435\u0432\u0430   virtual llvm::Type* getType() = 0;     llvm::Type* ThisType; \/\/\/&lt; \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0442\u0438\u043f LLVM };<\/code><\/pre>\n<p>\u0421\u0430\u043c\u0430 \u0436\u0435 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0434\u043b\u044f \u0432\u0435\u0442\u043e\u043a \u0434\u0435\u0440\u0435\u0432\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0442\u043d\u043e\u0441\u044f\u0442\u0441\u044f \u043a \u0442\u0438\u043f\u0430\u043c \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u0430\u044f, \u043d\u0443\u0436\u043d\u043e \u0432\u0441\u0435\u0433\u043e \u0441\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0442\u0438\u043f \u044f\u0437\u044b\u043a\u0430 \u043a \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e\u043c\u0443 \u0442\u0438\u043f\u0443 \u0432 LLVM:<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">Type* BuiltinTypeAST::getType() {   static Type* builtinTypes[] = {     Type::getVoidTy(getGlobalContext()),     Type::getInt1Ty(getGlobalContext()),     Type::getInt32Ty(getGlobalContext()),     Type::getDoubleTy(getGlobalContext()),     Type::getInt8Ty(getGlobalContext()),     Type::getInt8PtrTy(getGlobalContext())   };    if (ThisType) {     return ThisType;   }    return ThisType = builtinTypes[TypeKind]; }  Type* FuncTypeAST::getType() {   \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0442\u0438\u043f \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437   if (ThisType) {     return ThisType;   }    \/\/ \u0415\u0441\u043b\u0438 ReturnType \u043d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d, \u0442\u043e \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \"void\"   Type* returnType = (ReturnType ? ReturnType->getType() :      Type::getVoidTy(getGlobalContext()));    if (Params.empty()) {     \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0431\u0435\u0437 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432     return ThisType = FunctionType::get(returnType, false);   }      std::vector&lt; Type* > params;    \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432   for (ParameterList::iterator it = Params.begin(),      end = Params.end(); it != end; ++it) {     params.push_back((*it)->Param->getType());   }    \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0442\u0438\u043f \u0434\u043b\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438   return ThisType = FunctionType::get(returnType, params, false); }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h3>\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439<\/h3>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439:<\/p>\n<pre><code class=\"cpp\">struct ExprAST {    \/\/\/ \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043e \u0432 \u043b\u0435\u0432\u043e\u0439    \/\/\/ \u0447\u0430\u0441\u0442\u0438 \"=\"   virtual llvm::Value *getLValue(SLContext &amp;Context);    \/\/\/ \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043e \u0432 \u043f\u0440\u0430\u0432\u043e\u0439   \/\/\/ \u0447\u0430\u0441\u0442\u0438 \"=\"   virtual llvm::Value *getRValue(SLContext &amp;Context) = 0;  };<\/code><\/pre>\n<p>\u0417\u0430\u0447\u0435\u043c \u043d\u0443\u0436\u043d\u044b \u0434\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f lvalue \u0438 rvalue? \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f<\/p>\n<pre><code class=\"cpp\">i<\/code><\/pre>\n<p>rvalue \u044d\u0442\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439, \u0430 lvalue \u0431\u0443\u0434\u0435\u0442 \u0430\u0434\u0440\u0435\u0441 \u044d\u0442\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0432 \u043f\u0430\u043c\u044f\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0430 \u0434\u043b\u044f \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043e\u0447\u0435\u043d\u044c \u0447\u0430\u0441\u0442\u043e:<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">\/\/\/ \u0421\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u0434\u043b\u044f \u0446\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u043e\u0439 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b ConstantInt* getConstInt(uint64_t value) {   return ConstantInt::get(Type::getInt32Ty(getGlobalContext()),                           value, true); }  \/\/\/ \u041a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0438\u043f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432 \"bool\" \/\/\/ \\param[in] val \u2014 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u0438 \/\/\/ \\param[in] type \u2014 \u0442\u0438\u043f \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \/\/\/ \\param[in] builder \u2014 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 LLVM IR Value* promoteToBool(Value* val,                      TypeAST* type,                      IRBuilder&lt; >&amp; builder) {   if (type == BuiltinTypeAST::get(TypeAST::TI_Bool)) {     \/\/ \u042d\u0442\u043e \u0443\u0436\u0435 \"bool\"     return val;   }    if (type->isInt()) {     \/\/ \u0414\u043b\u044f \u0446\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0441 0     return builder.CreateICmpNE(val,                                 ConstantInt::get(                                   type->getType(),                                   0)                                );   } else {     assert(type->isFloat());     \/\/ \u0414\u043b\u044f \u0447\u0438\u0441\u043b\u0430 \u0441 \u043f\u043b\u0430\u0432\u0430\u044e\u0449\u0435\u0439 \u0442\u043e\u0447\u043a\u043e\u0439 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0441 0.0     return builder.CreateFCmpUNE(val, ConstantFP::get(       Type::getDoubleTy(getGlobalContext()), 0.0));   } } \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0441\u0430\u043c\u0438\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439: Value* ExprAST::getLValue(SLContext&amp; ) {   assert(0 &amp;&amp; \"\");   return nullptr; }  Value* IntExprAST::getRValue(SLContext&amp; ) {   \/\/ \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0446\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u0443\u044e \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0443 \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0441 \u043d\u0443\u0436\u043d\u044b\u043c    \/\/ \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c   return ConstantInt::get(ExprType->getType(), Val, true); }  Value* FloatExprAST::getRValue(SLContext&amp; ) {   \/\/ \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0443 \u0434\u043b\u044f \u0447\u0438\u0441\u043b\u0430 \u0441 \u043f\u043b\u0430\u0432\u0430\u044e\u0449\u0435\u0439 \u0442\u043e\u0447\u043a\u043e\u0439 \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0441    \/\/ \u043d\u0443\u0436\u043d\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c   return ConstantFP::get(ExprType->getType(), Val); }  Value* IdExprAST::getLValue(SLContext&amp; Context) {   \/\/ \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0430\u0434\u0440\u0435\u0441 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 (\u0441\u0430\u043c \u0430\u0434\u0440\u0435\u0441 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 SymbolAST,    \/\/ \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u0441\u044b\u043b\u0430\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f)   return ThisSym->getValue(Context); }  Value* IdExprAST::getRValue(SLContext&amp; Context) {   if (isa&lt;FuncDeclAST>(ThisSym)) {     \/\/ \u041e\u0441\u043e\u0431\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0434\u043b\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0439     return ThisSym->getValue(Context);   }    \/\/ \u0414\u043b\u044f \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u043d\u0443\u0436\u043d\u043e \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \"load\"   return Context.TheBuilder->CreateLoad(     ExprType->getType(),     ThisSym->getValue(Context),      StringRef(Val->Id, Val->Length)   ); }  Value* CastExprAST::getRValue(SLContext&amp; Context) {   \/\/ \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u044d\u0442\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \u0446\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0439 \u0442\u0438\u043f   if (ExprType->isInt()) {     if (Val->ExprType->isBool()) {       \/\/ \u0415\u0441\u043b\u0438 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u0442\u0438\u043f \"bool\", \u0442\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u044f\u0435\u043c 0       return Context.TheBuilder->CreateZExt(         Val->getRValue(Context),          ExprType->getType()       );     }      assert(Val->ExprType->isFloat());     \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \"float\" \u0432 \"int\"     return Context.TheBuilder->CreateFPToSI(       Val->getRValue(Context),        ExprType->getType()     );   }    if (ExprType->isBool()) {     \/\/ \u0414\u043b\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432 \"bool\"     return promoteToBool(Val->getRValue(Context), Val->ExprType,        *Context.TheBuilder);   } else if (Val->ExprType->isInt()) {     \/\/ \u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \"int\" \u0432 \"float\"      return Context.TheBuilder->CreateSIToFP(       Val->getRValue(Context),        ExprType->getType()     );   } else if (Val->ExprType->isBool()) {     \/\/ \u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \"bool\" \u0432 \"float\"     return Context.TheBuilder->CreateUIToFP(       Val->getRValue(Context),       ExprType->getType()     );   }    assert(0 &amp;&amp; \"should never be reached\");   return nullptr; }  Value* UnaryExprAST::getRValue(SLContext&amp; Context) {   assert(0 &amp;&amp; \"Should never happen\");   return nullptr; }  Value* BinaryExprAST::getRValue(SLContext&amp; Context) {   \/\/ \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0432\u0441\u0435 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0435 \u0441\u043b\u0443\u0447\u0430\u0438    \/\/ =   if (Op == tok::Assign) {          \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u043f\u0440\u0430\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f     Value* right = RightExpr->getRValue(Context);     \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0430\u0434\u0440\u0435\u0441 \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435     Value* res = LeftExpr->getLValue(Context);      \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \"store\"     Context.TheBuilder->CreateStore(right, res);     return right;   }    \/\/ ,   if (Op == tok::Comma) {     \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u043b\u0435\u0432\u043e\u0433\u043e \u0438 \u043f\u0440\u0430\u0432\u043e\u0433\u043e \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430     LeftExpr->getRValue(Context);     Value* rhs = RightExpr->getRValue(Context);     \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043f\u0440\u0430\u0432\u044b\u0439 \u043e\u043f\u0435\u0440\u0430\u043d\u0434     return rhs;   }    \/\/ \u041f\u043e\u0441\u0442\u0444\u0438\u043a\u0441\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 ++ \u0438 --   if (Op == tok::PlusPlus || Op == tok::MinusMinus) {     \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0430\u0434\u0440\u0435\u0441 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439, \u0430 \u0442\u0430\u043a \u0436\u0435 \u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435     Value* var = LeftExpr->getLValue(Context);     Value* val = LeftExpr->getRValue(Context);      if (Op == tok::PlusPlus) {       \/\/ \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0446\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u0443\u044e \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0443 1 \u0438 \u043f\u0440\u0438\u0431\u0430\u0432\u0438\u0442\u044c \u0435\u0435 \u043a        \/\/ \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u043e\u043c\u0443<\/code><\/pre>\n<\/div>\n<\/details>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-345671","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/345671","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=345671"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/345671\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=345671"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=345671"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=345671"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}