{"id":354434,"date":"2024-05-20T22:48:24","date_gmt":"2024-05-20T22:48:24","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=354434"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=354434","title":{"rendered":"<span>\u041f\u0435\u0440\u0435\u0441\u0442\u0430\u0451\u043c \u0431\u043e\u044f\u0442\u044c\u0441\u044f \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0431\u0430\u0439\u0442-\u043a\u043e\u0434<\/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>\u041c\u043d\u043e\u0433\u0438\u0435, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0434\u0443\u043c\u0430\u044e\u0442, \u0447\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u0431\u0430\u0439\u0442-\u043a\u043e\u0434\u043e\u043c Java (\u0431\u0443\u0434\u044c \u0442\u043e \u0447\u0442\u0435\u043d\u0438\u0435 \u0438\u043b\u0438, \u0442\u0435\u043c \u0431\u043e\u043b\u0435\u0435, \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f) \u2014 \u044d\u0442\u043e \u043a\u0430\u043a\u0430\u044f-\u0442\u043e \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u0430\u044f \u043c\u0430\u0433\u0438\u044f, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c \u0441 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u043a\u0440\u0443\u0442\u044b\u043c \u043e\u043f\u044b\u0442\u043e\u043c. \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435, \u044f \u0441\u0447\u0438\u0442\u0430\u044e \u0442\u0430\u043a\u0443\u044e \u0442\u043e\u0447\u043a\u0443 \u0437\u0440\u0435\u043d\u0438\u044f \u043e\u0448\u0438\u0431\u043e\u0447\u043d\u043e\u0439. JVM \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u0430 \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043f\u0440\u043e\u0449\u0435, \u0447\u0435\u043c CPU; \u043e\u043d\u0430 \u043e\u043f\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0442\u0430\u043a\u0438\u043c\u0438 \u0432\u044b\u0441\u043e\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u043c\u0438 \u043f\u043e\u043d\u044f\u0442\u0438\u044f\u043c\u0438 \u043a\u0430\u043a \u043a\u043b\u0430\u0441\u0441\u044b, \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u044b, \u043c\u0435\u0442\u043e\u0434\u044b, \u0430 \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043b\u043e\u043f\u0430\u0442\u0438\u0442 \u0431\u0430\u0439\u0442\u044b \u0432 \u043f\u0430\u043c\u044f\u0442\u0438. \u0412 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 CPU, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043b\u0435\u0433\u043a\u043e \u0443\u0440\u043e\u043d\u0438\u0442\u044c \u043a\u0440\u0438\u0432\u043e \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u043c\u0430\u0448\u0438\u043d\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c, JVM \u0437\u0430\u0431\u043e\u0442\u043b\u0438\u0432\u043e \u043e\u0442\u0432\u0435\u0440\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u0442 \u043b\u044e\u0431\u043e\u0439 \u0431\u0430\u0439\u0442-\u043a\u043e\u0434 \u0438 \u0432 \u043e\u0431\u0449\u0435\u043c \u043d\u0435 \u0434\u0430\u0441\u0442 \u0432\u044b\u0441\u0442\u0440\u0435\u043b\u0438\u0442\u044c \u0432 \u043d\u043e\u0433\u0443.<\/p>\n<p>\u041d\u043e \u0441 \u0447\u0435\u0433\u043e \u043d\u0430\u0447\u0430\u0442\u044c \u043f\u043e\u0433\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u0432 \u0431\u0430\u0439\u0442-\u043a\u043e\u0434\u043d\u0443\u044e \u043c\u0430\u0433\u0438\u044e? \u0412 \u0441\u0435\u0442\u0438 \u0435\u0441\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u043e\u0432 \u043f\u043e \u044d\u0442\u043e\u043c\u0443 \u0432\u043e\u043f\u0440\u043e\u0441\u0443. \u041a\u0430\u043a \u043c\u043d\u0435 \u043a\u0430\u0436\u0435\u0442\u0441\u044f, \u043e\u043d\u0438 \u043b\u0438\u0431\u043e \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043f\u0440\u043e\u0441\u0442\u044b\u0435 \u0441\u043b\u0443\u0447\u0430\u0438, \u043e\u0442 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0435\u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u043a\u0430\u043a \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0447\u0435\u043c\u0443-\u0442\u043e \u0431\u043e\u043b\u0435\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u043c\u0443, \u043b\u0438\u0431\u043e \u043e\u0447\u0435\u043d\u044c \u043e\u0441\u043d\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0438 \u0442\u0440\u0435\u0431\u0443\u044e\u0442 \u0432\u043d\u0438\u043a\u0430\u0442\u044c \u0432 \u0442\u0435\u043e\u0440\u0438\u044e, \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u0446\u0435\u043b\u0438\u043a\u043e\u043c \u043a\u0430\u0440\u0442\u0438\u043d\u0443 \u0432 \u0433\u043e\u043b\u043e\u0432\u0435 \u043f\u043e \u043a\u0443\u0441\u043e\u0447\u043a\u0430\u043c. \u042f \u0445\u043e\u0442\u0435\u043b \u0431\u044b \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0432\u043d\u0435\u0441\u0442\u0438 \u0441\u0432\u043e\u0439 \u0432\u043a\u043b\u0430\u0434 \u0432 \u044d\u0442\u0443 \u0442\u0435\u043c\u0443 \u2014 \u043d\u0430\u0434\u0435\u044e\u0441\u044c, \u0443 \u043c\u0435\u043d\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0431\u043e\u0440\u043e\u0442\u044c \u043f\u0435\u0440\u0432\u044b\u0439 \u0441\u0442\u0440\u0430\u0445 \u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0445\u043e\u0436\u0435\u0435 \u043d\u0430 \u0440\u0435\u0430\u043b\u0438\u0441\u0442\u0438\u0447\u043d\u044b\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439 \u0431\u0435\u0437 \u043e\u0441\u043e\u0431\u043e\u0433\u043e \u0432\u043d\u0438\u043a\u0430\u043d\u0438\u044f \u0432 \u0442\u0435\u043e\u0440\u0438\u044e \u043d\u0430 \u043f\u0435\u0440\u0432\u043e\u043c \u044d\u0442\u0430\u043f\u0435.<\/p>\n<p>\u0412\u0435\u0441\u044c \u043f\u0440\u0438\u0432\u0435\u0434\u0451\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0432 <a href=\"https:\/\/github.com\/konsoletyper\/exprbc\/tree\/9630c3d8fb3bd507b6a6d0201ba84baa9000bff1\" rel=\"noopener noreferrer nofollow\">\u043c\u043e\u0451\u043c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/a>.<\/p>\n<h2>\u0417\u0430\u0434\u0430\u0447\u0430<\/h2>\n<p>\u042f \u0432\u0434\u043e\u0445\u043d\u043e\u0432\u0438\u043b\u0441\u044f \u043a\u043d\u0438\u0433\u043e\u0439 \u0411\u044c\u0451\u0440\u043d\u0430 \u0421\u0442\u0440\u0430\u0443\u0441\u0442\u0440\u0443\u043f\u0430, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043b\u0435\u0442 20 \u043d\u0430\u0437\u0430\u0434 \u0438\u0437\u0443\u0447\u0430\u043b C++. \u0412 \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 \u043f\u0435\u0440\u0432\u044b\u0445 \u0433\u043b\u0430\u0432 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u0434\u043b\u044f \u0432\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u0432 \u044f\u0437\u044b\u043a \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u0430\u043b\u044c\u043a\u0443\u043b\u044f\u0442\u043e\u0440 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439. \u042f \u0436\u0435 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043d\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0442\u044c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0430 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0431\u0430\u0439\u0442-\u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0418\u0442\u0430\u043a, \u0444\u043e\u0440\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u043a\u0430: \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043d\u0430 \u0432\u0445\u043e\u0434 \u0441\u0442\u0440\u043e\u043a\u0443 \u0441 \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u043c\u0438 \u0438 \u0432\u044b\u0434\u0430\u0451\u0442 \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0442\u0430\u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430:<\/p>\n<pre><code class=\"java\">public interface Expression {   double evaluate(Function&lt;String, Double> inputs); }<\/code><\/pre>\n<p>\u0412\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432 \u0441\u043f\u0438\u0441\u043a\u0435 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u044b \u0442\u043e\u0447\u043a\u043e\u0439 \u0441 \u0437\u0430\u043f\u044f\u0442\u043e\u0439 (<code>;<\/code>), \u043c\u0435\u0442\u043e\u0434 <code>evaluate<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0438\u0437 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439. \u0412\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u0442\u0430\u043a:<\/p>\n<ol>\n<li>\n<p>\u0427\u0438\u0441\u043b\u043e (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>2<\/code>, <code>42<\/code>, <code>3.14<\/code>) \u2014 \u044d\u0442\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435.<\/p>\n<\/li>\n<li>\n<p>\u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>foo<\/code>, <code>pi<\/code>, <code>myVar_1<\/code>) \u2014 \u044d\u0442\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435. \u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e-\u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0432\u044b\u0437\u043e\u0432\u0430 <code>inputs.apply(id)<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u0415\u0441\u043b\u0438 A \u0438 B \u2014 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0442\u043e A + B, A &#8212; B, A * B, A \/ B, -A, (A) \u2014 \u0442\u0430\u043a \u0436\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>\u0415\u0441\u043b\u0438 A \u2014 \u044d\u0442\u043e \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440, \u0438 B \u2014 \u044d\u0442\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u0442\u043e A = B \u2014 \u0442\u0430\u043a \u0436\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435<\/p>\n<\/li>\n<\/ol>\n<h2>\u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043b\u0430\u0441\u0441<\/h2>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u043a\u043b\u0430\u0441\u0441\u0430, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0435\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 <code>Expression<\/code>. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u043d\u0430\u0447\u0430\u043b\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 <a href=\"https:\/\/asm.ow2.io\/\" rel=\"noopener noreferrer nofollow\">ASM<\/a> (\u043a\u0441\u0442\u0430\u0442\u0438, \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u043f\u043e \u043d\u0435\u0439 \u2014 \u044d\u0442\u043e \u043e\u0442\u043b\u0438\u0447\u043d\u044b\u0439 \u043c\u0430\u043d\u0443\u0430\u043b \u0435\u0449\u0451 \u0438 \u043f\u043e \u0431\u0430\u0439\u0442-\u043a\u043e\u0434\u0443). \u0412 Gradle \u044d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code class=\"java\">dependencies {   implementation \"org.ow2.asm:asm:9.5\"   implementation \"org.ow2.asm:asm-util:9.5\" }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0437\u0430\u0433\u043e\u0442\u043e\u0432\u043a\u0443 \u043d\u0430\u0448\u0435\u0433\u043e \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0430:<\/p>\n<pre><code class=\"java\">public class ClassGenerator {   \/\/ \u0418\u043c\u044f \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430. \u0412 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043b\u044e\u0431\u044b\u043c.   public static final String CLASS_NAME = ClassGenerator.class.getName()        + \"$Generated\";      \/\/ \u0418\u043c\u044f \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430, \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u0445 JVM.   \/\/ \u0412 JVM \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u0435\u043b\u044f \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \/ \u0432\u043c\u0435\u0441\u0442\u043e .   private static final String CLASS_INTERNAL_NAME =        CLASS_NAME.replace('.', '\/');    public byte[] generate(String expr) {     \/\/ \u0422\u043e\u0447\u043a\u0430 \u0432\u0445\u043e\u0434\u0430 \u0432 ASM - ClassWriter.      \/\/ \u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043e\u043d \u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0431\u0430\u0439\u0442-\u043a\u043e\u0434.       var cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES          | ClassWriter.COMPUTE_MAXS);          \/\/ \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u044b\u0432\u043e\u0434 \u0434\u0438\u0437\u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0431\u0430\u0439\u0442-\u043a\u043e\u0434\u0430 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c     ClassVisitor cv = cw;     if (Boolean.getBoolean(\"konsoletyper.exprbc.log\")) {       cv = new TraceClassVisitor(cv, new PrintWriter(System.out));     }      \/\/ \u0421\u043e\u0437\u0434\u0430\u0451\u043c \u043a\u043b\u0430\u0441\u0441     cv.visit(       Opcodes.V11,         \/\/ \u0412\u0435\u0440\u0441\u0438\u044f JVM       Opcodes.ACC_PUBLIC,  \/\/ \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b (public)       CLASS_INTERNAL_NAME, \/\/ \u0438\u043c\u044f \u043a\u043b\u0430\u0441\u0441\u0430 (\u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u0445 JVM)       null,                \/\/ generic \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0430, \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u043d\u0430       Type.getInternalName(Object.class),         \/\/ \u0438\u043c\u044f \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430         \/\/ \u0432 Java \u043c\u043e\u0436\u043d\u043e \u043d\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c extends Object,         \/\/ \u043e\u0434\u043d\u0430\u043a\u043e \u0432 JVM \u043d\u0443\u0436\u043d\u043e \u0432\u0441\u0451 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u044f\u0432\u043d\u043e         \/\/ \u0438 \u043f\u0440\u0435\u0434\u0435\u043b\u044c\u043d\u043e \u0441\u043a\u0440\u0443\u043f\u0443\u043b\u0451\u0437\u043d\u043e       new String[] { Type.getInternalName(Expression.class) }         \/\/ \u0438\u043c\u0435\u043d\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c\u044b\u0445 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u0432     );      \/\/ \u0421\u043e\u0437\u0434\u0430\u0451\u043c \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440     \/\/ \u0412 Java \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u0435\u043d,     \/\/ \u043e\u0434\u043d\u0430\u043a\u043e \u0432 JVM \u043d\u0443\u0436\u043d\u043e \u0432\u0441\u0451 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u044f\u0432\u043d\u043e     generateEmptyConstructor(cv);          \/\/ \u0421\u043e\u0437\u0434\u0430\u0451\u043c \u043c\u0435\u0442\u043e\u0434 evaluate     generateWorkerMethod(cv, expr);      \/\/ \u0417\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u043b\u0430\u0441\u0441\u0430 \u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0431\u0430\u0439\u0442-\u043a\u043e\u0434     cv.visitEnd();     return cw.toByteArray();   } }<\/code><\/pre>\n<p>\u041f\u043e\u044f\u0441\u043d\u044e \u043f\u0430\u0440\u0443 \u043c\u043e\u043c\u0435\u043d\u0442\u043e\u0432.<\/p>\n<p>\u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u043c \u043d\u0435\u043a\u0438\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 <code>ClassWriter<\/code>. \u0412\u043e\u0442 \u0437\u0430\u0447\u0435\u043c \u044d\u0442\u043e \u043d\u0443\u0436\u043d\u043e. \u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0432 \u0431\u0430\u0439\u0442-\u043a\u043e\u0434\u0435 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u043c\u0435\u0440 \u0441\u0442\u0435\u043a\u0430 \u043c\u0435\u0442\u043e\u0434\u0430 \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u043b\u043e\u0442\u043e\u0432 \u043f\u043e\u0434 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435. \u0422\u0430\u043a \u0436\u0435 \u0441 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043f\u043e\u0440 \u0441\u0442\u0430\u043b\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0444\u0440\u0435\u0439\u043c\u0430\u0445 \u2014 \u0442\u0438\u043f\u0430\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u043d\u0430 \u0441\u0442\u0435\u043a\u0435 \u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0442\u043e\u0447\u043a\u0430\u0445 \u0431\u0430\u0439\u0442-\u043a\u043e\u0434\u0430, \u044d\u0442\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0443\u0441\u043a\u043e\u0440\u0438\u0442\u044c JIT-\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044e (\u0432 \u0434\u0430\u0432\u043d\u0438\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u0430 \u0444\u0440\u0435\u0439\u043c\u044b \u0431\u044b\u043b\u0438 \u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u043c\u0438). \u0421\u0443\u0440\u043e\u0432\u044b\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0449\u0438\u043a\u0438 \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e \u0432\u0441\u044e \u044d\u0442\u0443 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0442 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e, \u043d\u043e \u0438 \u0432 \u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0446\u0435\u043b\u044f\u0445, \u0438 \u0432\u043e \u043c\u043d\u043e\u0433\u0438\u0445 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0437\u0430\u0434\u0430\u0447\u0430\u0445 \u043f\u0440\u043e\u0449\u0435 \u043f\u043e\u0440\u0443\u0447\u0438\u0442\u044c \u044d\u0442\u0443 \u0437\u0430\u0434\u0430\u0447\u0443 ASM.<\/p>\n<p>\u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445, \u0434\u043b\u044f \u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u0438 \u0443\u0434\u043e\u0431\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0440\u0430\u0441\u043f\u0435\u0447\u0430\u0442\u043a\u0443 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0431\u0430\u0439\u0442-\u043a\u043e\u0434\u0430. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0439 <code>ClassVisitor<\/code>. \u0422\u0443\u0442 \u043d\u0430\u0434\u043e \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0440\u043e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 ASM. \u0412 \u043d\u0451\u043c \u0447\u0442\u0435\u043d\u0438\u0435 \u0438 \u0437\u0430\u043f\u0438\u0441\u044c \u0431\u0430\u0439\u0442-\u043a\u043e\u0434\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u044f\u0442\u0441\u044f <code>ClassVisitor<\/code>-\u0430\u043c\u0438 (\u0430 \u0442\u0430\u043a \u0436\u0435 <code>MethodVisitor<\/code>, <code>FieldVisitor<\/code> \u0438 \u0442.\u0434.). \u041f\u0440\u0438 \u0447\u0442\u0435\u043d\u0438\u0438 \u043a\u043b\u0430\u0441\u0441\u0430 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0451\u043c <code>ClassReader<\/code> \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u043c \u0442\u0443\u0434\u0430 <code>ClassVisitor<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043e\u0442 <code>ClassReader<\/code>-\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434. <code>ClassWriter<\/code> \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u0435\u0442\u0441\u044f \u043e\u0442 <code>ClassVisitor<\/code> \u0438 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043a\u043b\u0430\u0441\u0441\u0430 \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0432\u0441\u0451 \u0442\u0435 \u0436\u0435 \u043c\u0435\u0442\u043e\u0434\u044b, \u0447\u0442\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>ClassReader<\/code> \u043f\u0440\u0438 \u0447\u0442\u0435\u043d\u0438\u0438. \u0422\u0430\u043a \u043c\u043e\u0436\u043d\u043e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441\u044b, \u0432\u0441\u0442\u0430\u0432\u0438\u0432 \u043c\u0435\u0436\u0434\u0443 reader-\u043e\u043c \u0438 writer-\u043e\u043c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443, \u043e\u0434\u043d\u0430\u043a\u043e \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043c\u044b \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043b\u0430\u0441\u0441 \u0438\u0437 \u0432\u043e\u0437\u0434\u0443\u0445\u0430, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430\u043c\u0438 \u0442\u0430\u043a\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u0441\u043e\u0441\u0442\u0430\u0432\u0435 ASM \u0435\u0441\u0442\u044c <code>TraceClassVisitor<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0441\u0435 \u0432\u044b\u0437\u043e\u0432\u044b \u0432\u044b\u0432\u043e\u0434\u0438\u0442 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c, \u0447\u0435\u043c \u043c\u044b \u0438 \u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f, \u0437\u0430\u0432\u0435\u0440\u043d\u0443\u0432 \u0432 \u043d\u0435\u0433\u043e \u043d\u0430\u0448 <code>ClassWriter<\/code>.<\/p>\n<p>\u0418\u0442\u0430\u043a, \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u043f\u0443\u0441\u0442\u043e\u0433\u043e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430:<\/p>\n<pre><code class=\"java\">private void generateEmptyConstructor(ClassVisitor cv) {   \/\/ \u0421\u043e\u0437\u0434\u0430\u0451\u043c \u043c\u0435\u0442\u043e\u0434   var mv = cv.visitMethod(     Opcodes.ACC_PUBLIC,   \/\/ \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b     \"&lt;init>\",             \/\/ \u0438\u043c\u044f \u043c\u0435\u0442\u043e\u0434\u0430     Type.getMethodDescriptor(Type.VOID_TYPE),       \/\/ \u0434\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440 \u043c\u0435\u0442\u043e\u0434\u0430 - \u0442\u0438\u043f\u044b \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f     null,                 \/\/ \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0430 generic \u043c\u0435\u0442\u043e\u0434\u0430                           \/\/ (\u0434\u043b\u044f \u043d\u0430\u0441 \u043d\u0435 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e)     null                  \/\/ \u0432\u044b\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c\u044b\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f   );   mv.visitCode();    \/\/ \u041a\u043b\u0430\u0434\u0451\u043c \u043d\u0430 \u0441\u0442\u0435\u043a \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u0443\u044e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e 0    \/\/ (\u0432\u0441\u0435\u0433\u0434\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 this \u0434\u043b\u044f \u043d\u0435 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432)   mv.visitVarInsn(Opcodes.ALOAD, 0);      \/\/ \u0412\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u043c\u0435\u0442\u043e\u0434 Object.&lt;init>, \u0442.\u0435. \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440   \/\/ \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430   \/\/ (\u0430\u043d\u0430\u043b\u043e\u0433 super() \u0432 Java - \u043c\u044b \u0436\u0435 \u043f\u043e\u043c\u043d\u0438\u043c, \u0447\u0442\u043e \u0432 \u0431\u0430\u0439\u0442-\u043a\u043e\u0434\u0435   \/\/ \u0432\u0441\u0451 \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u044f\u0432\u043d\u043e)   mv.visitMethodInsn(     Opcodes.INVOKESPECIAL,     Type.getInternalName(Object.class),       \/\/ \u0443 \u043a\u0430\u043a\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u043c\u0435\u0442\u043e\u0434 -       \/\/ \u0434\u0430, \u0432 \u0431\u0430\u0439\u0442-\u043a\u043e\u0434\u0435 \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u043d\u0430\u0441\u0442\u043e\u043b\u044c\u043a\u043e       \/\/ \u0441\u043a\u0440\u0443\u043f\u0443\u043b\u0451\u0437\u043d\u044b\u043c     \"&lt;init>\",     Type.getMethodDescriptor(Type.VOID_TYPE),       \/\/ \u0434\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430     false  \/\/ \u0432\u044b\u0437\u043e\u0432 *\u043d\u0435* \u0443 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430   );      \/\/ \u042f\u0432\u043d\u043e \u043f\u0438\u0448\u0435\u043c return (\u0445\u043e\u0442\u044f \u0432 Java \u043e\u043d \u0438 \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u0435\u043d)   mv.visitInsn(Opcodes.RETURN);    \/\/ \u0422\u0443\u0442 \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0440\u0430\u0437\u043c\u0435\u0440 \u0441\u0442\u0435\u043a\u0430 \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u043b\u043e\u0442\u043e\u0432    \/\/ \u043f\u043e\u0434 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435, \u043f\u0440\u043e \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043b\u043e\u0441\u044c   \/\/ \u0432\u044b\u0448\u0435. \u041c\u044b \u043f\u043e\u043f\u0440\u043e\u0441\u0438\u043b\u0438 ASM \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0442\u044c \u0438\u0445 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438,   \/\/ \u043d\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c visitMaxs \u043c\u044b \u043e\u0431\u044f\u0437\u0430\u043d\u044b, \u043f\u0435\u0440\u0435\u0434\u0430\u0432 \u0438\u043c 0   mv.visitMaxs(0, 0);   mv.visitEnd(); }<\/code><\/pre>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0432 JVM \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0435 \u0442\u0430\u043a \u0436\u0435 \u043a\u0430\u043a \u043a\u043b\u0430\u0441\u0441 (\u043a\u0430\u043a \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0432 Java), \u0430 \u0438\u043c\u0435\u0435\u0442 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0435 \u0438\u043c\u044f <code>&lt;init><\/code>. \u0414\u043b\u044f \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0434\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440 \u2014 \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 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432. JVM \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u0434\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440\u043e\u0432, \u0432 \u0438 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0434\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440 \u0438\u043c\u0435\u0435\u0442 \u0432\u0438\u0434 <code>()V<\/code>. \u041e\u0434\u043d\u0430\u043a\u043e, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043f\u0440\u043e\u0441\u0438\u0442\u044c ASM \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440 \u0437\u0430 \u043d\u0430\u0441.<\/p>\n<p>JVM \u2014 \u044d\u0442\u043e \u0441\u0442\u0435\u043a\u043e\u0432\u0430\u044f \u043c\u0430\u0448\u0438\u043d\u0430. \u041b\u044e\u0431\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0431\u0435\u0440\u0451\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0441\u043e \u0441\u0442\u0435\u043a\u0430, \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442 \u043d\u0430\u0434 \u043d\u0438\u043c\u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0438 \u043a\u043b\u0430\u0434\u0451\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043d\u0430 \u0441\u0442\u0435\u043a. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0430\u0440\u0438\u0444\u043c\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b IADD, ISUB \u0438 \u043f\u0440\u043e\u0447\u0438\u0435, \u0441\u043d\u0438\u043c\u0430\u044e\u0442 \u0441 \u0432\u0435\u0440\u0448\u0438\u043d\u044b \u0441\u0442\u0435\u043a\u0430 \u0434\u0432\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438 \u043a\u043b\u0430\u0434\u0443\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0430 \u0432\u0435\u0440\u0448\u0438\u043d\u0443 \u0441\u0442\u0435\u043a\u0430. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u043d\u0435 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 \u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 INVOKESPECIAL \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u044c (receiver) \u043c\u0435\u0442\u043e\u0434\u0430, \u0442.\u0435. \u0442\u043e, \u0447\u0442\u043e \u0441\u0442\u043e\u0438\u0442 \u0441\u043b\u0435\u0432\u0430 \u043e\u0442 \u0442\u043e\u0447\u043a\u0438 (\u0445\u043e\u0442\u044f \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 c <code>super()<\/code> \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u0441 \u0442\u043e\u0447\u043a\u043e\u0439 \u043d\u0435 \u043f\u0440\u0435\u0434\u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043d).<\/p>\n<p>\u041a\u0441\u0442\u0430\u0442\u0438, \u043e\u0431 INVOKESPECIAL. \u0415\u0441\u0442\u044c \u0442\u0440\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u0430 \u043c\u0435\u0442\u043e\u0434\u0430: INVOKESPECIAL, INVOKEVIRTUAL \u0438 INVOKEINTERFACE. INVOKESPECIAL \u2014 \u044d\u0442\u043e \u0432\u044b\u0437\u043e\u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u0441 \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439, \u0442.\u0435. \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0438\u0441\u043a\u0430\u0442\u044c \u0432 \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0435. \u0412 \u043f\u0440\u043e\u0442\u0438\u0432\u043e\u0432\u0435\u0441 INVOKEVIRTUAL, \u043a\u043e\u0433\u0434\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043d\u0443\u0436\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0438\u0441\u043a\u0430\u0442\u044c \u0432 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u0435. \u0422\u0430\u043a\u043e\u0435 \u0431\u044b\u0432\u0430\u0435\u0442 \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445: \u0432\u044b\u0437\u043e\u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430, \u0432\u044b\u0437\u043e\u0432 super-\u043c\u0435\u0442\u043e\u0434\u0430, \u0432\u044b\u0437\u043e\u0432 \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430.<\/p>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u043c\u0435\u0442\u043e\u0434\u0430 <code>evaluate<\/code>:<\/p>\n<pre><code class=\"java\">private void generateWorkerMethod(ClassVisitor cv, String expr) {   var mv = cv.visitMethod(       Opcodes.ACC_PUBLIC,       \"evaluate\",       Type.getMethodDescriptor(Type.DOUBLE_TYPE,            Type.getType(Function.class)),        null, null   );   mv.visitCode();    var generator = new CodeGenerator(mv);   var lexer = new Lexer(expr);   var parser = new Parser(lexer, generator);   parser.parse();   mv.visitInsn(Opcodes.DRETURN);    mv.visitMaxs(0, 0);   mv.visitEnd(); }<\/code><\/pre>\n<p>\u0432\u0441\u044e \u043e\u0441\u043d\u043e\u0432\u043d\u0443\u044e \u0440\u0430\u0431\u043e\u0442\u0443 \u0434\u0435\u043b\u0430\u0435\u0442 \u043a\u043b\u0430\u0441\u0441 <code>CodeGenerator<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 <code>Parser<\/code>. \u0412 \u043a\u043e\u043d\u0446\u0435 \u0441\u0432\u043e\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u044b <code>CodeGenerator<\/code> \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043e\u0434\u043d\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043d\u0430 \u0441\u0442\u0435\u043a\u0435 \u2014 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u0415\u0433\u043e \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f DRETURN.<\/p>\n<h2>\u041f\u0438\u0448\u0435\u043c \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u0431\u0430\u0439\u0442-\u043a\u043e\u0434\u0430 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439<\/h2>\n<p>\u041f\u0430\u0440\u0441\u0435\u0440 \u043e\u0442\u0434\u0430\u0451\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u043e \u0432\u043d\u0435\u0448\u043d\u0438\u0439 \u043c\u0438\u0440 \u0447\u0435\u0440\u0435\u0437 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441:<\/p>\n<pre><code class=\"java\">public interface ParserConsumer {   void number(double value);   void identifier(String id);   void assignment(String id);   void add();   void subtract();   void multiply();   void divide();   void negate();   void statement(); }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 \u0432\u043d\u0430\u0447\u0430\u043b\u0435 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u044f\u0435\u0442 \u043e \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0435 \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u043e\u0432, \u0430 \u0437\u0430\u0442\u0435\u043c \u2014 \u043e \u0441\u0430\u043c\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f <code>2 + 3<\/code> \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0431\u0443\u0434\u0435\u0442 \u0442\u0430\u043a\u043e\u0439:<\/p>\n<ol>\n<li>\n<p><code>number(2)<\/code><\/p>\n<\/li>\n<li>\n<p><code>number(3)<\/code><\/p>\n<\/li>\n<li>\n<p><code>add()<\/code><\/p>\n<\/li>\n<\/ol>\n<p>\u041d\u0430\u0448 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u044d\u0442\u043e\u0442 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441:<\/p>\n<pre><code class=\"java\">public class CodeGenerator implements ParserConsumer {   private final MethodVisitor mv;    public CodeGenerator(MethodVisitor mv) {     this.mv = mv;   } }<\/code><\/pre>\n<p>\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0447\u0438\u0441\u043b\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"java\">@Override public void number(double value) {   mv.visitLdcInsn(value); }<\/code><\/pre>\n<p>\u0418\u043c\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 LDC \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a &#171;load constant&#187;. \u0414\u0443\u043c\u0430\u044e, \u0442\u0443\u0442 \u0432\u0441\u0451 \u043f\u043e\u043d\u044f\u0442\u043d\u043e. \u041d\u0435 \u043c\u0435\u043d\u0435\u0435 \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439:<\/p>\n<pre><code class=\"java\">@Override public void add() {   mv.visitInsn(Opcodes.DADD); } @Override public void subtract() {   mv.visitInsn(Opcodes.DSUB); } @Override public void multiply() {   mv.visitInsn(Opcodes.DMUL); } @Override public void divide() {   mv.visitInsn(Opcodes.DDIV); } @Override public void negate() {   mv.visitInsn(Opcodes.DNEG); }<\/code><\/pre>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u0435\u0449\u0451 \u043e\u0434\u043d\u043e\u0439 \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0435\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <code>statement<\/code>, \u043e\u0442\u0434\u0435\u043b\u044f\u044e\u0449\u0435\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0434\u0440\u0443\u0433 \u043e\u0442 \u0434\u0440\u0443\u0433\u0430:<\/p>\n<pre><code class=\"java\">@Override public void statement() {   mv.visitInsn(Opcodes.POP2); }<\/code><\/pre>\n<p>\u041e\u043d\u0430 \u0441\u043d\u0438\u043c\u0430\u0435\u0442 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0441\u043e \u0441\u0442\u0435\u043a\u0430. \u0421\u043c\u044b\u0441\u043b \u0432 \u044d\u0442\u043e\u043c \u0432\u043e\u0442 \u043a\u0430\u043a\u043e\u0439: \u043a\u0430\u0436\u0434\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u0430 \u0441\u0442\u0435\u043a\u0435 \u043e\u0434\u043d\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u2014 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u041e\u0434\u043d\u0430\u043a\u043e, \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u041e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u043d\u0438\u044f\u043c\u0438, \u0438\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u041f\u043e\u0447\u0435\u043c\u0443 \u0436\u0435 POP2? \u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0432 JVM \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0442\u0438\u043f\u0430 long \u0438 double \u0437\u0430\u043d\u0438\u043c\u0430\u044e\u0442 \u043f\u043e \u0434\u0432\u0430 &#171;\u0441\u043b\u043e\u0442\u0430&#187; \u0432 \u0441\u0442\u0435\u043a\u0435 \u0438 \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432\u043e\u0437\u044c\u043c\u0451\u043c\u0441\u044f \u0437\u0430 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435. \u0413\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u0438\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"java\">private final Map&lt;String, Integer> variables = new HashMap&lt;>(); private int lastVariableIndex = 2;  @Override public void assignment(String id) {   var index = variables.computeIfAbsent(id, k -> introduceVariable());   \/\/ \u041f\u0438\u0448\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u043e \u0441\u0442\u0435\u043a\u0430 \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u0443\u044e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e   mv.visitVarInsn(Opcodes.DSTORE, index);   \/\/ \u0427\u0438\u0442\u0430\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0432 \u0441\u0442\u0435\u043a   mv.visitVarInsn(Opcodes.DLOAD, index); }  private int introduceVariable() {   var result = lastVariableIndex;   lastVariableIndex += 2;   return result; }<\/code><\/pre>\n<p>\u0422.\u0435. \u0432\u044b\u0434\u0435\u043b\u044f\u0435\u043c \u043f\u043e \u0434\u0432\u0430 \u0441\u043b\u043e\u0442\u0430 \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u043d\u043e\u0432\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0438 \u043f\u0438\u0448\u0435\u043c \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u0443\u044e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u043e \u0441\u0442\u0435\u043a\u0430, \u0430 \u0437\u0430\u0442\u0435\u043c \u0441\u043d\u043e\u0432\u0430 \u043a\u043b\u0430\u0434\u0451\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043d\u0430 \u0441\u0442\u0435\u043a \u2014 \u044d\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0443 \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u0438\u044f \u0432 C\/C++, \u0442.\u0435. \u043e\u043d\u043e \u0442\u043e\u0436\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c, \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u043d\u043e\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439.<\/p>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0447\u0442\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439:<\/p>\n<pre><code class=\"java\">@Override public void identifier(String id) {   var index = variables.computeIfAbsent(id, k -> {     var newIndex = introduceVariable();     \/\/ \u0415\u0441\u043b\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0435\u0449\u0451 \u043d\u0435 \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043b\u0430\u0441\u044c, \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f     \/\/ \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0435\u0451 \u0438\u0437 inputs     getAndCacheVariable(newIndex, k);     return newIndex;   });   mv.visitVarInsn(Opcodes.DLOAD, index); }  private void getAndCacheVariable(int index, String id) {   \/\/ \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0441 \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u043c 1 - \u044d\u0442\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 inputs   mv.visitVarInsn(Opcodes.ALOAD, 1);   mv.visitLdcInsn(id);   mv.visitMethodInsn(     Opcodes.INVOKEINTERFACE,     \/\/ \u043d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0435\u043c \u044f\u0432\u043d\u043e \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0438\u043f receiver-\u0430 - Function     Type.getInternalName(Function.class),     \"apply\",     \/\/ erasure \u0432 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0438. \u041f\u043e\u0441\u043b\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u043e\u0442 generics     \/\/ \u043d\u0435 \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0438 \u0441\u043b\u0435\u0434\u0430. \u0422\u0435\u043f\u0435\u0440\u044c \u043b\u044e\u0431\u0430\u044f Function&lt;T,R>     \/\/ \"\u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f\" \u0432 Function&lt;Object,Object>     Type.getMethodDescriptor(Type.getType(Object.class),         Type.getType(Object.class)),     true     );    \/\/ \u0415\u0441\u043b\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 null - \u043a\u0438\u0434\u0430\u0435\u043c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435   var continueLabel = new Label();   \/\/ \u0434\u0443\u0431\u043b\u0438\u0440\u0443\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043d\u0430 \u0441\u0442\u0435\u043a\u0435, \u0442.\u043a. \u0432\u043d\u0430\u0447\u0430\u043b\u0435 \u043f\u0435\u0440\u0432\u0443\u044e \u043a\u043e\u043f\u0438\u044e    \/\/ \u043f\u043e\u0433\u043b\u043e\u0449\u0430\u0435\u0442 IFNONNULL, \u0430 \u0432\u0442\u043e\u0440\u0443\u044e - \u043b\u043e\u0433\u0438\u043a\u0430 \u043d\u0438\u0436\u0435   mv.visitInsn(Opcodes.DUP);   mv.visitJumpInsn(Opcodes.IFNONNULL, continueLabel);   reportUndefinedVariable(id);    mv.visitLabel(continueLabel);   \/\/ erasure \u0432 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0438 - \u0442\u0438\u043f \u0443 \u043d\u0430\u0441 \u0441\u0442\u0451\u0440\u0441\u044f,   \/\/ \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u0432\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u044f\u0432\u043d\u044b\u0439 cast \u043a DOUBLE   mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(Double.class));   \/\/ \u0442\u0430\u043a \u0436\u0435 \u0441 \u043f\u0440\u0438\u0441\u0443\u0449\u0435\u0439 JVM \u0441\u043a\u0440\u0443\u043f\u0443\u043b\u0451\u0437\u043d\u043e\u0441\u0442\u044c\u044e \u0434\u0435\u043b\u0430\u0435\u043c \u044f\u0432\u043d\u044b\u0439 unboxing   mv.visitMethodInsn(     Opcodes.INVOKEVIRTUAL,     Type.getInternalName(Double.class),     \"doubleValue\",     Type.getMethodDescriptor(Type.DOUBLE_TYPE),     false   );   mv.visitVarInsn(Opcodes.DSTORE, index); }<\/code><\/pre>\n<p>\u043b\u043e\u0433\u0438\u043a\u0430 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0431\u0430\u0439\u0442-\u043a\u043e\u0434\u0430 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043f\u0441\u0435\u0432\u0434\u043e\u043a\u043e\u0434\u043e\u043c:<\/p>\n<pre><code class=\"java\">Object value = inputs.apply(\"varName\"); if (value == null) {   throw new ExecutionException(\"Undefined variable varName\"); } double varName = ((Double) value).doubleValue();<\/code><\/pre>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0432\u044b\u0431\u0440\u043e\u0441 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f:<\/p>\n<pre><code class=\"java\">private void reportUndefinedVariable(String id) {   \/\/ \u0412 JVM \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0432\u044b\u0437\u043e\u0432\u0430 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430.   \/\/ \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u0432\u043d\u0430\u0447\u0430\u043b\u0435 \u043d\u0430\u0434\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0443\u0441\u0442\u043e\u0439 \u043e\u0431\u044a\u0435\u043a\u0442,   \/\/ \u0410 \u043f\u043e\u0442\u043e\u043c \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043d\u0435\u0433\u043e \u043c\u0435\u0442\u043e\u0434 &lt;init>   mv.visitTypeInsn(Opcodes.NEW,        Type.getInternalName(ExecutionException.class));   \/\/ \u041f\u0435\u0440\u0432\u044b\u0439 \u0440\u0430\u0437 \u043d\u0430\u0448\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u0442\u0441\u044f \u0432 &lt;init>   \/\/ \u0412\u0442\u043e\u0440\u043e\u0439 \u0440\u0430\u0437 - \u0432 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e ATHROW   mv.visitInsn(Opcodes.DUP);   mv.visitLdcInsn(\"Undefined variable \" + id);   mv.visitMethodInsn(     Opcodes.INVOKESPECIAL,      Type.getInternalName(ExecutionException.class),     \"&lt;init>\",     Type.getMethodDescriptor(Type.VOID_TYPE,         Type.getType(String.class)),     false   );   mv.visitInsn(Opcodes.ATHROW); }<\/code><\/pre>\n<h2>\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u043a\u043b\u0430\u0441\u0441 \u0432 \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0435<\/h2>\n<p>\u0412 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435, \u043d\u0430\u0448 \u043a\u043e\u0434 \u0443\u0436\u0435 \u0443\u043c\u0435\u0435\u0442 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0431\u0430\u0439\u0442-\u043a\u043e\u0434, \u043e\u0434\u043d\u0430\u043a\u043e \u0447\u0442\u043e \u0441 \u043d\u0438\u043c \u0434\u0435\u043b\u0430\u0442\u044c? \u041c\u043e\u0436\u043d\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0435\u0433\u043e \u043d\u0430 \u0434\u0438\u0441\u043a \u0432 \u0444\u0430\u0439\u043b \u0441 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435\u043c class \u0438 \u043b\u0438\u043d\u043a\u043e\u0432\u0430\u0442\u044c \u043a \u043a\u043e\u0434\u0443. \u041e\u0434\u043d\u0430\u043a\u043e, \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0441\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u0443\u0442\u0438\u043b\u0438\u0442\u044b \u043d\u0435\u0432\u044b\u0441\u043e\u043a\u0430. \u0418\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0435\u0435 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0435\u0433\u043e \u0442\u0443\u0442 \u0436\u0435, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0441\u0442\u0430\u0440\u044b\u0439 \u0434\u043e\u0431\u0440\u044b\u0439 reflection:<\/p>\n<pre><code class=\"java\">public class Compiler {   private final ClassLoader classLoader;    public Compiler(ClassLoader classLoader) {     this.classLoader = classLoader;   }    public Expression compile(String expr) {     var bytecode = new ClassGenerator().generate(expr);     var loader = new ProvidedBytecodeClassLoader(classLoader, bytecode);     Class&lt;?> cls;     try {       cls = Class.forName(ClassGenerator.CLASS_NAME, false, loader);     } catch (ClassNotFoundException e) {       throw new RuntimeException(e);     }     try {       return (Expression) cls.getConstructor().newInstance();     } catch (InstantiationException          | IllegalAccessException          | NoSuchMethodException          | InvocationTargetException e) {       throw new RuntimeException(e);     }   } }<\/code><\/pre>\n<p>\u0421\u0435\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u0438\u043d\u0433\u0440\u0435\u0434\u0438\u0435\u043d\u0442 \u0437\u0434\u0435\u0441\u044c:<\/p>\n<pre><code class=\"java\">public class ProvidedBytecodeClassLoader extends ClassLoader {   private final byte[] bytecode;    public ProvidedBytecodeClassLoader(ClassLoader parent, byte[] bytecode) {     super(parent);     this.bytecode = bytecode;   }    @Override   protected Class&lt;?> findClass(String name) throws ClassNotFoundException {     if (!name.equals(ClassGenerator.CLASS_NAME)) {       return super.findClass(name);     }     return defineClass(ClassGenerator.CLASS_NAME, bytecode, 0, bytecode.length);   } }<\/code><\/pre>\n<p>\u041f\u0443\u0441\u0442\u044c \u0432\u0430\u0441 \u043d\u0435 \u0441\u043c\u0443\u0449\u0430\u0435\u0442 \u0442\u043e, \u0447\u0442\u043e \u043a\u043b\u0430\u0441\u0441 \u0432\u0441\u0435\u0433\u0434\u0430 \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u043f\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u0438\u043c\u0435\u043d\u0438. \u0412 JVM \u0438\u043c\u044f \u043a\u043b\u0430\u0441\u0441\u0430 \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u043d\u043e \u0431\u044b\u0442\u044c \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u043c, \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u043f\u0430\u0440\u0430 (\u0438\u043c\u044f \u043a\u043b\u0430\u0441\u0441\u0430, ClassLoader). \u041a\u0430\u0436\u0434\u043e\u0435 \u043d\u043e\u0432\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043e \u0447\u0435\u0440\u0435\u0437 \u043d\u043e\u0432\u044b\u0439 ClassLoader, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0443 \u043d\u0430\u0441 \u043d\u0435 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0435\u0442.<\/p>\n<h2>\u041f\u0438\u0448\u0435\u043c \u043f\u0430\u0440\u0441\u0435\u0440<\/h2>\n<p>\u0417\u0434\u0435\u0441\u044c \u043d\u0435\u0442 \u043d\u0438\u0447\u0435\u0433\u043e \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0433\u043e \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u0438\u043c\u0435\u043d\u043d\u043e \u043d\u0430\u0448\u0435\u0439 \u0437\u0430\u0434\u0430\u0447\u0438. \u0420\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432 \u043f\u043e \u0442\u043e\u043c\u0443, \u043a\u0430\u043a \u044d\u0442\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c, \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043c\u043d\u043e\u0433\u043e. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043a\u043e\u0434 \u0441 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0434\u043e\u043c\u0430\u0448\u043d\u0435\u0433\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u0440\u0430\u0437\u0434\u0435\u043b \u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0430\u0440\u0441\u0435\u0440 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e.<\/p>\n<p>\u0418\u0442\u0430\u043a, \u043e\u0431\u044b\u0447\u043d\u043e \u043f\u0430\u0440\u0441\u0435\u0440 \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u044e\u0442 \u043d\u0430 \u043b\u0435\u043a\u0441\u0435\u0440 \u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043f\u0430\u0440\u0441\u0435\u0440. \u041b\u0435\u043a\u0441\u0435\u0440 \u0440\u0430\u0437\u0431\u0438\u0432\u0430\u0435\u0442 \u043f\u043e\u0442\u043e\u043a \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u043d\u0430 \u043b\u0435\u043a\u0441\u0435\u043c\u044b. \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043f\u0438\u0441\u043e\u043a \u043b\u0435\u043a\u0441\u0435\u043c \u043d\u0430\u0448\u0435\u0433\u043e \u044f\u0437\u044b\u043a\u0430:<\/p>\n<pre><code class=\"java\">public enum Token {   NUMBER,   PLUS,   MINUS,   STAR,   SLASH,   LEFT_BRACE,   RIGHT_BRACE,   SEMICOLON,   ASSIGNMENT,   IDENTIFIER,   EOF }<\/code><\/pre>\n<p>\u0438 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0441\u0430\u043c \u043b\u0435\u043a\u0441\u0435\u0440:<\/p>\n<pre><code class=\"java\">public class Lexer {   private final CharSequence inputString;   private int position;   private Token token;   private int tokenPosition;   private double number;   private String identifier;    public Lexer(CharSequence inputString) {     this.inputString = inputString;   }    public void next() {     if (token == Token.EOF) {       return;     }     skipWhitespace();     identifier = null;     number = 0;     tokenPosition = position;     if (position == inputString.length()) {       token = Token.EOF;       return;     }      var c = inputString.charAt(position);     switch (c) {       case '+':         simpleToken(Token.PLUS);         break;       case '-':         simpleToken(Token.MINUS);         break;       case '*':         simpleToken(Token.STAR);         break;       case '\/':         simpleToken(Token.SLASH);         break;       case '(':         simpleToken(Token.LEFT_BRACE);         break;       case ')':         simpleToken(Token.RIGHT_BRACE);         break;       case '=':         simpleToken(Token.ASSIGNMENT);         break;       case ';':         simpleToken(Token.SEMICOLON);         break;       default:         if (isIdentifierStart(c)) {           parseIdentifier();         } else if (isDigit(c)) {           parseNumber();         } else {           error(\"Unexpected character\");         }         break;     }   }    private void simpleToken(Token token) {     this.token = token;     ++position;   }    private void skipWhitespace() {     while (position &lt; inputString.length()          &amp;&amp; Character.isWhitespace(inputString.charAt(position))) {       ++position;     }   }    private void parseIdentifier() {     token = Token.IDENTIFIER;     tokenPosition = position;     while (position &lt; inputString.length()          &amp;&amp; isIdentifierPart(inputString.charAt(position))) {       ++position;     }     identifier = inputString.subSequence(tokenPosition, position).toString();   }    private void parseNumber() {     token = Token.NUMBER;     while (position &lt; inputString.length()          &amp;&amp; isDigit(inputString.charAt(position))) {       ++position;     }     if (position &lt; inputString.length()          &amp;&amp; inputString.charAt(position) == '.') {       ++position;       if (position >= inputString.length()            || !isDigit(inputString.charAt(position))) {         error(\"Invalid number literal\");       }       while (position &lt; inputString.length()            &amp;&amp; isDigit(inputString.charAt(position))) {         ++position;       }     }     try {       number = Double.parseDouble(inputString.subSequence(           tokenPosition, position).toString());     } catch (NumberFormatException e) {       error(\"Invalid number literal\");     }   }    private static boolean isIdentifierStart(char c) {     switch (c) {       case '$':       case '_':         return true;       default:         return c >= 'a' &amp;&amp; c &lt;= 'z' || c >= 'A' &amp;&amp; c &lt;= 'Z';     }   }    private static boolean isIdentifierPart(char c) {     return isIdentifierStart(c) || isDigit(c);   }    private static boolean isDigit(char c) {     return c >= '0' &amp;&amp; c &lt;= '9';   }    private void error(String error) {     throw new ParseException(error, position);   }    public int getTokenPosition() {     return tokenPosition;   }    public Token getToken() {     return token;   }    public double getNumber() {     return number;   }    public String getIdentifier() {     return identifier;   } }<\/code><\/pre>\n<p>\u041f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0443 \u043b\u0435\u043a\u0441\u0435\u0440\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0442 <code>next<\/code>, \u043e\u043d \u0447\u0438\u0442\u0430\u0435\u0442 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u0443\u044e \u043b\u0435\u043a\u0441\u0435\u043c\u0443, \u0438 \u0434\u0430\u043b\u0435\u0435 \u043c\u043e\u0436\u043d\u043e \u0447\u0435\u0440\u0435\u0437 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0435\u0451 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430.<\/p>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043f\u0430\u0440\u0441\u0435\u0440:<\/p>\n<pre><code class=\"java\">public class Parser {   private final Lexer lexer;   private final ParserConsumer consumer;    public Parser(Lexer lexer, ParserConsumer consumer) {     this.lexer = lexer;     this.consumer = consumer;   }    public void parse() {     lexer.next();     parseSum();     while (lexer.getToken() == Token.SEMICOLON) {       skipSemicolons();       if (lexer.getToken() == Token.EOF) {         break;       }       consumer.statement();       parseSum();     }     if (lexer.getToken() != Token.EOF) {       error(\"End of input expected\");     }   }    private void skipSemicolons() {     while (lexer.getToken() == Token.SEMICOLON) {       lexer.next();     }   }    private void parseSum() {     parseProd();     while (lexer.getToken() == Token.PLUS || lexer.getToken() == Token.MINUS) {       var token = lexer.getToken();       lexer.next();       parseProd();       if (token == Token.PLUS) {         consumer.add();       } else {         consumer.subtract();       }     }   }    private void parseProd() {     parsePrime();     while (lexer.getToken() == Token.STAR || lexer.getToken() == Token.SLASH) {       var token = lexer.getToken();       lexer.next();       parsePrime();       if (token == Token.STAR) {         consumer.multiply();       } else {         consumer.divide();       }     }   }    private void parsePrime() {     switch (lexer.getToken()) {       case NUMBER:         consumer.number(lexer.getNumber());         lexer.next();         break;       case IDENTIFIER:         parseIdentifierOrAssignment();         break;       case MINUS:         lexer.next();         parsePrime();         consumer.negate();         break;       case LEFT_BRACE:         lexer.next();         parseParenthesized();         break;       default:         error(\"Unexpected token\");         break;     }   }    private void parseIdentifierOrAssignment() {     var id = lexer.getIdentifier();     lexer.next();     if (lexer.getToken() == Token.ASSIGNMENT) {       lexer.next();       parseSum();       consumer.assignment(id);     } else {       consumer.identifier(id);     }   }    private void parseParenthesized() {     parseSum();     if (lexer.getToken() != Token.RIGHT_BRACE) {       error(\"Closing brace expected\");     }     lexer.next();   }    private void error(String error) {     throw new ParseException(error, lexer.getTokenPosition());   } }<\/code><\/pre>\n<h2>\u041f\u0440\u0438\u043c\u0435\u0440<\/h2>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0438\u0439\u0441\u044f \u043a\u0430\u043b\u044c\u043a\u0443\u043b\u044f\u0442\u043e\u0440:<\/p>\n<pre><code class=\"java\">var compiler = new Compiler(ClassLoader.getSystemClassLoader()); var expr = compiler.compile(\"pi = 3.14159; pi * r * r\");  var inputs = new HashMap&lt;String, Double>(); inputs.put(\"r\", 2.0); System.out.println(expr.evaluate(inputs::get));  inputs.put(\"r\", 5.0); System.out.println(expr.evaluate(inputs::get));<\/code><\/pre>\n<p>\u0432\u044b\u0432\u043e\u0434:<\/p>\n<pre><code>12.56636 78.53975<\/code><\/pre>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e, \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0435\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0431\u0430\u0439\u0442-\u043a\u043e\u0434. \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0441 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e\u043c <code>konsoletyper.exprbc.log=true<\/code>:<\/p>\n<pre><code class=\"assembly\">  ; pi = 3.14159   LDC 3.14159   DSTORE 2   DLOAD 2   POP2      ; \u043f\u0435\u0440\u0432\u043e\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 r   DLOAD 2   ALOAD 1   LDC \"r\"   INVOKEINTERFACE java\/util\/function\/Function.apply (Ljava\/lang\/Object;)Ljava\/lang\/Object; (itf)   DUP   IFNONNULL L0   NEW konsoletyper\/exprbc\/ExecutionException   DUP   LDC \"Undefined variable r\"   INVOKESPECIAL konsoletyper\/exprbc\/ExecutionException.&lt;init> (Ljava\/lang\/String;)V   ATHROW L0   CHECKCAST java\/lang\/Double   INVOKEVIRTUAL java\/lang\/Double.doubleValue ()D   DSTORE 4   DLOAD 4      ; pi * r   DMUL      ; \u0432\u0442\u043e\u0440\u043e\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 r   ; \u0442\u0435\u043f\u0435\u0440\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0437\u0430\u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u043e \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439   DLOAD 4      ; pi * r * r   DMUL   DRETURN <\/code><\/pre>\n<h2>\u0417\u0430\u0447\u0435\u043c \u044d\u0442\u043e \u0432\u0441\u0451?<\/h2>\n<p>\u041a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0431\u044b, \u044f \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u043b \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0441\u0442\u0430\u0442\u044c\u044e \u0432 \u0445\u0430\u0431 &#171;\u043d\u0435\u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435&#187;. \u041e\u0434\u043d\u0430\u043a\u043e, \u0443 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0431\u0430\u0439\u0442-\u043a\u043e\u0434\u0430 \u0435\u0441\u0442\u044c \u0441\u0432\u043e\u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f. \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u044d\u0442\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c. \u0425\u043e\u0442\u044f \u0440\u0435\u0434\u043a\u043e, \u043d\u043e \u0431\u044b\u0432\u0430\u0435\u0442, \u0447\u0442\u043e \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0443\u0437\u043a\u043e\u0435 \u043c\u0435\u0441\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0435\u0439 \u0431\u0430\u0439\u0442-\u043a\u043e\u0434\u0430. \u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445, \u044d\u0442\u043e \u043d\u0430\u0432\u0435\u0448\u0438\u0432\u0430\u043d\u0438\u0435 \u0432\u0441\u044f\u043a\u043e\u0439 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043d\u0430 \u0438\u043c\u0435\u044e\u0449\u0438\u0435\u0441\u044f \u043a\u043b\u0430\u0441\u0441\u044b (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f, RPC). \u0418 \u0445\u043e\u0442\u044f \u0432\u0441\u0451 \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 reflection, \u0443 reflection \u0435\u0441\u0442\u044c \u043e\u0434\u0438\u043d \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u043a: \u043e\u043d \u043f\u043b\u043e\u0445\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 AOT-\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0432 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043c\u0435\u0440\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, Android SDK, \u0430 \u0442\u043e\u0447\u043d\u0435\u0435 \u0435\u0433\u043e \u0447\u0430\u0441\u0442\u044c \u043f\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c r8. \u0421\u044e\u0434\u0430 \u0436\u0435 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f Graal Native Image, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 Java-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u043d\u0430 iOS. \u0410\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043e\u0439 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0431\u0430\u0439\u0442-\u043a\u043e\u0434\u0430 \u0437\u0434\u0435\u0441\u044c \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f annotation processor. \u041e\u0434\u043d\u0430\u043a\u043e, \u0443 \u043d\u0438\u0445 \u0435\u0441\u0442\u044c \u0440\u044f\u0434 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u043e\u0432:<\/p>\n<ol>\n<li>\n<p>\u041e\u043d\u0438 \u043f\u043b\u043e\u0445\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u043d\u0430 \u0441\u0442\u044b\u043a\u0435 Java \u0438 Kotlin.<\/p>\n<\/li>\n<li>\n<p>\u041e\u043d\u0438 \u043f\u043b\u043e\u0445\u043e \u0434\u0440\u0443\u0436\u0430\u0442 \u0441 \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0439 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0435\u0439. \u0422\u043e\u0447\u043d\u0435\u0435, \u043e\u043d\u0438 \u0441 \u043d\u0435\u0439 \u0434\u0440\u0443\u0436\u0430\u0442, \u043d\u043e \u043f\u043e\u0440\u043e\u0439 \u0432\u043d\u0435\u0437\u0430\u043f\u043d\u043e \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0441\u0431\u043e\u0440\u043a\u0438 \u0445\u043e\u0447\u0435\u0442 \u043f\u0435\u0440\u0435\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043c\u043d\u043e\u0433\u043e \u0432\u0441\u0435\u0433\u043e. \u0421\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0431\u0430\u0439\u0442-\u043a\u043e\u0434 \u043e\u0431\u044b\u0447\u043d\u043e \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u0431\u044b\u0441\u0442\u0440\u0435\u0435, \u0447\u0435\u043c \u0441\u043f\u0430\u0440\u0441\u0438\u0442\u044c \u0438 \u043f\u043e\u0440\u0435\u0437\u043e\u043b\u0432\u0438\u0442\u044c \u0447\u0430\u0441\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u043e\u0432 \u043c\u043e\u0434\u0443\u043b\u044f.<\/p>\n<\/li>\n<li>\n<p>\u0418\u043d\u043e\u0433\u0434\u0430 \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 generics \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430\u043c\u0438 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043e\u0447\u0435\u043d\u044c \u0441\u0438\u043b\u044c\u043d\u043e \u0437\u0430\u043c\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0442\u044c\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u0442\u0438\u043f\u043e\u0432\u044b\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b. \u0412 \u0431\u0430\u0439\u0442-\u043a\u043e\u0434\u0435 \u0432\u0441\u0435 generics \u0441\u0442\u0451\u0440\u0442\u044b \u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435\u0442.<\/p>\n<\/li>\n<\/ol>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u0431\u0430\u0439\u0442-\u043a\u043e\u0434 \u0438\u043d\u043e\u0433\u0434\u0430 \u043d\u0435 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u044e\u0442 \u0441 \u043d\u0443\u043b\u044f, \u0430 \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u044e\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439. \u0422\u0430\u043a\u043e\u0435 \u0443\u0436 \u0442\u043e\u0447\u043d\u043e \u043d\u0435\u043b\u044c\u0437\u044f \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u043d\u0438\u043a\u0430\u043a\u0438\u043c\u0438 reflection \u0438\u043b\u0438 annotation processor.<\/p>\n<p>\u0415\u0441\u0442\u044c, \u043f\u0440\u0430\u0432\u0434\u0430, \u043f\u0430\u0440\u0430 \u0442\u0440\u0443\u0434\u043d\u043e\u0441\u0442\u0435\u0439:<\/p>\n<ol>\n<li>\n<p>\u041e\u0442\u043b\u0430\u0436\u0438\u0432\u0430\u0442\u044c \u0432\u0441\u0451 \u044d\u0442\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0442\u044f\u0436\u0435\u043b\u043e \u2014 \u043d\u0435\u043a\u0443\u0434\u0430 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0431\u0440\u0435\u0439\u043a\u043f\u043e\u0438\u043d\u0442. \u0422\u0435\u043e\u0440\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043c\u043e\u0436\u043d\u043e \u0447\u0435\u0440\u0435\u0437 ASM \u0432\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0432 \u0431\u0430\u0439\u0442-\u043a\u043e\u0434 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u043e\u0442\u043b\u0430\u0434\u0447\u0438\u043a\u0430, \u043c\u043e\u0436\u043d\u043e \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a\u043e\u0439-\u043d\u0438\u0431\u0443\u0434\u044c \u043f\u0441\u0435\u0432\u0434\u043e\u043a\u043e\u0434. \u0412\u043e\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043c\u043d\u0435 \u043d\u0435 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b \u0441\u043f\u043e\u0441\u043e\u0431\u044b \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u0442\u044c IDE \u0432\u0441\u0451 \u044d\u0442\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c.<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0440\u043e\u0439 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0438\u043c\u0435\u0442\u044c \u0434\u0435\u043b\u043e \u0441 \u0431\u0430\u0433\u0430\u043c\u0438 ASM. \u041a\u043e\u0433\u0434\u0430 \u043c\u044b \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0437\u0430\u0432\u0435\u0434\u043e\u043c\u043e \u0432\u0430\u043b\u0438\u0434\u043d\u044b\u0439 \u0431\u0430\u0439\u0442-\u043a\u043e\u0434, \u0432\u0441\u0451 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u0430\u043a \u0447\u0430\u0441\u044b. \u041e\u0434\u043d\u0430\u043a\u043e, \u043f\u043e\u0440\u043e\u0439 \u043f\u0440\u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u043e\u0433\u043e \u0431\u0430\u0439\u0442-\u043a\u043e\u0434\u0430 ASM \u043f\u0440\u043e\u0441\u0442\u043e \u043a\u0440\u044d\u0448\u0438\u0442\u0441\u044f \u0432\u043c\u0435\u0441\u0442\u043e \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u043f\u0435\u0447\u0430\u0442\u0430\u0442\u044c \u043f\u043e\u043d\u044f\u0442\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435.<\/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\/articles\/759990\/\"> https:\/\/habr.com\/ru\/articles\/759990\/<\/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>\u041c\u043d\u043e\u0433\u0438\u0435, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0434\u0443\u043c\u0430\u044e\u0442, \u0447\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u0431\u0430\u0439\u0442-\u043a\u043e\u0434\u043e\u043c Java (\u0431\u0443\u0434\u044c \u0442\u043e \u0447\u0442\u0435\u043d\u0438\u0435 \u0438\u043b\u0438, \u0442\u0435\u043c \u0431\u043e\u043b\u0435\u0435, \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f) \u2014 \u044d\u0442\u043e \u043a\u0430\u043a\u0430\u044f-\u0442\u043e \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u0430\u044f \u043c\u0430\u0433\u0438\u044f, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c \u0441 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u043a\u0440\u0443\u0442\u044b\u043c \u043e\u043f\u044b\u0442\u043e\u043c. \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435, \u044f \u0441\u0447\u0438\u0442\u0430\u044e \u0442\u0430\u043a\u0443\u044e \u0442\u043e\u0447\u043a\u0443 \u0437\u0440\u0435\u043d\u0438\u044f \u043e\u0448\u0438\u0431\u043e\u0447\u043d\u043e\u0439. JVM \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u0430 \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043f\u0440\u043e\u0449\u0435, \u0447\u0435\u043c CPU; \u043e\u043d\u0430 \u043e\u043f\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0442\u0430\u043a\u0438\u043c\u0438 \u0432\u044b\u0441\u043e\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u043c\u0438 \u043f\u043e\u043d\u044f\u0442\u0438\u044f\u043c\u0438 \u043a\u0430\u043a \u043a\u043b\u0430\u0441\u0441\u044b, \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u044b, \u043c\u0435\u0442\u043e\u0434\u044b, \u0430 \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043b\u043e\u043f\u0430\u0442\u0438\u0442 \u0431\u0430\u0439\u0442\u044b \u0432 \u043f\u0430\u043c\u044f\u0442\u0438. \u0412 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 CPU, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043b\u0435\u0433\u043a\u043e \u0443\u0440\u043e\u043d\u0438\u0442\u044c \u043a\u0440\u0438\u0432\u043e \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u043c\u0430\u0448\u0438\u043d\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c, JVM \u0437\u0430\u0431\u043e\u0442\u043b\u0438\u0432\u043e \u043e\u0442\u0432\u0435\u0440\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u0442 \u043b\u044e\u0431\u043e\u0439 \u0431\u0430\u0439\u0442-\u043a\u043e\u0434 \u0438 \u0432 \u043e\u0431\u0449\u0435\u043c \u043d\u0435 \u0434\u0430\u0441\u0442 \u0432\u044b\u0441\u0442\u0440\u0435\u043b\u0438\u0442\u044c \u0432 \u043d\u043e\u0433\u0443.<\/p>\n<p>\u041d\u043e \u0441 \u0447\u0435\u0433\u043e \u043d\u0430\u0447\u0430\u0442\u044c \u043f\u043e\u0433\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u0432 \u0431\u0430\u0439\u0442-\u043a\u043e\u0434\u043d\u0443\u044e \u043c\u0430\u0433\u0438\u044e? \u0412 \u0441\u0435\u0442\u0438 \u0435\u0441\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u043e\u0432 \u043f\u043e \u044d\u0442\u043e\u043c\u0443 \u0432\u043e\u043f\u0440\u043e\u0441\u0443. \u041a\u0430\u043a \u043c\u043d\u0435 \u043a\u0430\u0436\u0435\u0442\u0441\u044f, \u043e\u043d\u0438 \u043b\u0438\u0431\u043e \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043f\u0440\u043e\u0441\u0442\u044b\u0435 \u0441\u043b\u0443\u0447\u0430\u0438, \u043e\u0442 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0435\u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u043a\u0430\u043a \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0447\u0435\u043c\u0443-\u0442\u043e \u0431\u043e\u043b\u0435\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u043c\u0443, \u043b\u0438\u0431\u043e \u043e\u0447\u0435\u043d\u044c \u043e\u0441\u043d\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0438 \u0442\u0440\u0435\u0431\u0443\u044e\u0442 \u0432\u043d\u0438\u043a\u0430\u0442\u044c \u0432 \u0442\u0435\u043e\u0440\u0438\u044e, \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u0446\u0435\u043b\u0438\u043a\u043e\u043c \u043a\u0430\u0440\u0442\u0438\u043d\u0443 \u0432 \u0433\u043e\u043b\u043e\u0432\u0435 \u043f\u043e \u043a\u0443\u0441\u043e\u0447\u043a\u0430\u043c. \u042f \u0445\u043e\u0442\u0435\u043b \u0431\u044b \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0432\u043d\u0435\u0441\u0442\u0438 \u0441\u0432\u043e\u0439 \u0432\u043a\u043b\u0430\u0434 \u0432 \u044d\u0442\u0443 \u0442\u0435\u043c\u0443 \u2014 \u043d\u0430\u0434\u0435\u044e\u0441\u044c, \u0443 \u043c\u0435\u043d\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0431\u043e\u0440\u043e\u0442\u044c \u043f\u0435\u0440\u0432\u044b\u0439 \u0441\u0442\u0440\u0430\u0445 \u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0445\u043e\u0436\u0435\u0435 \u043d\u0430 \u0440\u0435\u0430\u043b\u0438\u0441\u0442\u0438\u0447\u043d\u044b\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439 \u0431\u0435\u0437 \u043e\u0441\u043e\u0431\u043e\u0433\u043e \u0432\u043d\u0438\u043a\u0430\u043d\u0438\u044f \u0432 \u0442\u0435\u043e\u0440\u0438\u044e \u043d\u0430 \u043f\u0435\u0440\u0432\u043e\u043c \u044d\u0442\u0430\u043f\u0435.<\/p>\n<p>\u0412\u0435\u0441\u044c \u043f\u0440\u0438\u0432\u0435\u0434\u0451\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0432 <a href=\"https:\/\/github.com\/konsoletyper\/exprbc\/tree\/9630c3d8fb3bd507b6a6d0201ba84baa9000bff1\" rel=\"noopener noreferrer nofollow\">\u043c\u043e\u0451\u043c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/a>.<\/p>\n<h2>\u0417\u0430\u0434\u0430\u0447\u0430<\/h2>\n<p>\u042f \u0432\u0434\u043e\u0445\u043d\u043e\u0432\u0438\u043b\u0441\u044f \u043a\u043d\u0438\u0433\u043e\u0439 \u0411\u044c\u0451\u0440\u043d\u0430 \u0421\u0442\u0440\u0430\u0443\u0441\u0442\u0440\u0443\u043f\u0430, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043b\u0435\u0442 20 \u043d\u0430\u0437\u0430\u0434 \u0438\u0437\u0443\u0447\u0430\u043b C++. \u0412 \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 \u043f\u0435\u0440\u0432\u044b\u0445 \u0433\u043b\u0430\u0432 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u0434\u043b\u044f \u0432\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u0432 \u044f\u0437\u044b\u043a \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u0430\u043b\u044c\u043a\u0443\u043b\u044f\u0442\u043e\u0440 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439. \u042f \u0436\u0435 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043d\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0442\u044c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0430 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0431\u0430\u0439\u0442-\u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0418\u0442\u0430\u043a, \u0444\u043e\u0440\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u043a\u0430: \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043d\u0430 \u0432\u0445\u043e\u0434 \u0441\u0442\u0440\u043e\u043a\u0443 \u0441 \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u043c\u0438 \u0438 \u0432\u044b\u0434\u0430\u0451\u0442 \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0442\u0430\u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430:<\/p>\n<pre><code class=\"java\">public interface Expression {   double evaluate(Function&lt;String, Double> inputs); }<\/code><\/pre>\n<p>\u0412\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432 \u0441\u043f\u0438\u0441\u043a\u0435 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u044b \u0442\u043e\u0447\u043a\u043e\u0439 \u0441 \u0437\u0430\u043f\u044f\u0442\u043e\u0439 (<code>;<\/code>), \u043c\u0435\u0442\u043e\u0434 <code>evaluate<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0438\u0437 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439. \u0412\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u0442\u0430\u043a:<\/p>\n<ol>\n<li>\n<p>\u0427\u0438\u0441\u043b\u043e (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>2<\/code>, <code>42<\/code>, <code>3.14<\/code>) \u2014 \u044d\u0442\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435.<\/p>\n<\/li>\n<li>\n<p>\u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>foo<\/code>, <code>pi<\/code>, <code>myVar_1<\/code>) \u2014 \u044d\u0442\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435. \u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e-\u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0432\u044b\u0437\u043e\u0432\u0430 <code>inputs.apply(id)<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u0415\u0441\u043b\u0438 A \u0438 B \u2014 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0442\u043e A + B, A &#8212; B, A * B, A \/ B, -A, (A) \u2014 \u0442\u0430\u043a \u0436\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>\u0415\u0441\u043b\u0438 A \u2014 \u044d\u0442\u043e \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440, \u0438 B \u2014 \u044d\u0442\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u0442\u043e A = B \u2014 \u0442\u0430\u043a \u0436\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435<\/p>\n<\/li>\n<\/ol>\n<h2>\u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043b\u0430\u0441\u0441<\/h2>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u043a\u043b\u0430\u0441\u0441\u0430, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0435\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 <code>Expression<\/code>. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u043d\u0430\u0447\u0430\u043b\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 <a href=\"https:\/\/asm.ow2.io\/\" rel=\"noopener noreferrer nofollow\">ASM<\/a> (\u043a\u0441\u0442\u0430\u0442\u0438, \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u043f\u043e \u043d\u0435\u0439 \u2014 \u044d\u0442\u043e \u043e\u0442\u043b\u0438\u0447\u043d\u044b\u0439 \u043c\u0430\u043d\u0443\u0430\u043b \u0435\u0449\u0451 \u0438 \u043f\u043e \u0431\u0430\u0439\u0442-\u043a\u043e\u0434\u0443). \u0412 Gradle \u044d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code class=\"java\">dependencies {   implementation \"org.ow2.asm:asm:9.5\"   implementation \"org.ow2.asm:asm-util:9.5\" }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0437\u0430\u0433\u043e\u0442\u043e\u0432\u043a\u0443 \u043d\u0430\u0448\u0435\u0433\u043e \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0430:<\/p>\n<pre><code class=\"java\">public class ClassGenerator {   \/\/ \u0418\u043c\u044f \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430. \u0412 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043b\u044e\u0431\u044b\u043c.   public static final String CLASS_NAME = ClassGenerator.class.getName()        + \"$Generated\";      \/\/ \u0418\u043c\u044f \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430, \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u0445 JVM.   \/\/ \u0412 JVM \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u0435\u043b\u044f \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \/ \u0432\u043c\u0435\u0441\u0442\u043e .   private static final String CLASS_INTERNAL_NAME =        CLASS_NAME.replace('.', '\/');    public byte[] generate(String expr) {     \/\/ \u0422\u043e\u0447\u043a\u0430 \u0432\u0445\u043e\u0434\u0430 \u0432 ASM - ClassWriter.      \/\/ \u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043e\u043d \u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0431\u0430\u0439\u0442-\u043a\u043e\u0434.       var cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES          | ClassWriter.COMPUTE_MAXS);          \/\/ \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u044b\u0432\u043e\u0434 \u0434\u0438\u0437\u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0431\u0430\u0439\u0442-\u043a\u043e\u0434\u0430 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c     ClassVisitor cv = cw;     if (Boolean.getBoolean(\"konsoletyper.exprbc.log\")) {       cv = new TraceClassVisitor(cv, new PrintWriter(System.out));     }      \/\/ \u0421\u043e\u0437\u0434\u0430\u0451\u043c \u043a\u043b\u0430\u0441\u0441     cv.visit(       Opcodes.V11,         \/\/ \u0412\u0435\u0440\u0441\u0438\u044f JVM       Opcodes.ACC_PUBLIC,  \/\/ \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b (public)       CLASS_INTERNAL_NAME, \/\/ \u0438\u043c\u044f \u043a\u043b\u0430\u0441\u0441\u0430 (\u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u0445 JVM)       null,                \/\/ generic \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0430, \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u043d\u0430       Type.getInternalName(Object.class),         \/\/ \u0438\u043c\u044f \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430         \/\/ \u0432 Java \u043c\u043e\u0436\u043d\u043e \u043d\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c extends Object,         \/\/ \u043e\u0434\u043d\u0430\u043a\u043e \u0432 JVM \u043d\u0443\u0436\u043d\u043e \u0432\u0441\u0451 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u044f\u0432\u043d\u043e         \/\/ \u0438 \u043f\u0440\u0435\u0434\u0435\u043b\u044c\u043d\u043e \u0441\u043a\u0440\u0443\u043f\u0443\u043b\u0451\u0437\u043d\u043e       new String[] { Type.getInternalName(Expression.class) }         \/\/ \u0438\u043c\u0435\u043d\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c\u044b\u0445 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u0432     );      \/\/ \u0421\u043e\u0437\u0434\u0430\u0451\u043c \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440     \/\/ \u0412 Java \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u0435\u043d,     \/\/ \u043e\u0434\u043d\u0430\u043a\u043e \u0432 JVM \u043d\u0443\u0436\u043d\u043e \u0432\u0441\u0451 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u044f\u0432\u043d\u043e     generateEmptyConstructor(cv);          \/\/ \u0421\u043e\u0437\u0434\u0430\u0451\u043c \u043c\u0435\u0442\u043e\u0434 evaluate     generateWorkerMethod(cv, expr);      \/\/ \u0417\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u043b\u0430\u0441\u0441\u0430 \u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0431\u0430\u0439\u0442-\u043a\u043e\u0434     cv.visitEnd();     return cw.toByteArray();   } }<\/code><\/pre>\n<p>\u041f\u043e\u044f\u0441\u043d\u044e \u043f\u0430\u0440\u0443 \u043c\u043e\u043c\u0435\u043d\u0442\u043e\u0432.<\/p>\n<p>\u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u043c \u043d\u0435\u043a\u0438\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 <code>ClassWriter<\/code>. \u0412\u043e\u0442 \u0437\u0430\u0447\u0435\u043c \u044d\u0442\u043e \u043d\u0443\u0436\u043d\u043e. \u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0432 \u0431\u0430\u0439\u0442-\u043a\u043e\u0434\u0435 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u043c\u0435\u0440 \u0441\u0442\u0435\u043a\u0430 \u043c\u0435\u0442\u043e\u0434\u0430 \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u043b\u043e\u0442\u043e\u0432 \u043f\u043e\u0434 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435. \u0422\u0430\u043a \u0436\u0435 \u0441 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043f\u043e\u0440 \u0441\u0442\u0430\u043b\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0444\u0440\u0435\u0439\u043c\u0430\u0445 \u2014 \u0442\u0438\u043f\u0430\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u043d\u0430 \u0441\u0442\u0435\u043a\u0435 \u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0442\u043e\u0447\u043a\u0430\u0445 \u0431\u0430\u0439\u0442-\u043a\u043e\u0434\u0430, \u044d\u0442\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0443\u0441\u043a\u043e\u0440\u0438\u0442\u044c JIT-\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044e (\u0432 \u0434\u0430\u0432\u043d\u0438\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u0430 \u0444\u0440\u0435\u0439\u043c\u044b \u0431\u044b\u043b\u0438 \u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u043c\u0438). \u0421\u0443\u0440\u043e\u0432\u044b\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0449\u0438\u043a\u0438 \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e \u0432\u0441\u044e \u044d\u0442\u0443 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0442 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e, \u043d\u043e \u0438 \u0432 \u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0446\u0435\u043b\u044f\u0445, \u0438 \u0432\u043e \u043c\u043d\u043e\u0433\u0438\u0445 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0437\u0430\u0434\u0430\u0447\u0430\u0445 \u043f\u0440\u043e\u0449\u0435 \u043f\u043e\u0440\u0443\u0447\u0438\u0442\u044c \u044d\u0442\u0443 \u0437\u0430\u0434\u0430\u0447\u0443 ASM.<\/p>\n<p>\u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445, \u0434\u043b\u044f \u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u0438 \u0443\u0434\u043e\u0431\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0440\u0430\u0441\u043f\u0435\u0447\u0430\u0442\u043a\u0443 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0431\u0430\u0439\u0442-\u043a\u043e\u0434\u0430. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0439 <code>ClassVisitor<\/code>. \u0422\u0443\u0442 \u043d\u0430\u0434\u043e \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0440\u043e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 ASM. \u0412 \u043d\u0451\u043c \u0447\u0442\u0435\u043d\u0438\u0435 \u0438 \u0437\u0430\u043f\u0438\u0441\u044c \u0431\u0430\u0439\u0442-\u043a\u043e\u0434\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u044f\u0442\u0441\u044f <code>ClassVisitor<\/code>-\u0430\u043c\u0438 (\u0430 \u0442\u0430\u043a \u0436\u0435 <code>MethodVisitor<\/code>, <code>FieldVisitor<\/code> \u0438 \u0442.\u0434.). \u041f\u0440\u0438 \u0447\u0442\u0435\u043d\u0438\u0438 \u043a\u043b\u0430\u0441\u0441\u0430 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0451\u043c <code>ClassReader<\/code> \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u043c \u0442\u0443\u0434\u0430 <code>ClassVisitor<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043e\u0442 <code>ClassReader<\/code>-\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434. <code>ClassWriter<\/code> \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u0435\u0442\u0441\u044f \u043e\u0442 <code>ClassVisitor<\/code> \u0438 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043a\u043b\u0430\u0441\u0441\u0430 \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0432\u0441\u0451 \u0442\u0435 \u0436\u0435 \u043c\u0435\u0442\u043e\u0434\u044b, \u0447\u0442\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>ClassReader<\/code> \u043f\u0440\u0438 \u0447\u0442\u0435\u043d\u0438\u0438. \u0422\u0430\u043a \u043c\u043e\u0436\u043d\u043e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441\u044b, \u0432\u0441\u0442\u0430\u0432\u0438\u0432 \u043c\u0435\u0436\u0434\u0443 reader-\u043e\u043c \u0438 writer-\u043e\u043c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443, \u043e\u0434\u043d\u0430\u043a\u043e \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043c\u044b \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043b\u0430\u0441\u0441 \u0438\u0437 \u0432\u043e\u0437\u0434\u0443\u0445\u0430, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430\u043c\u0438 \u0442\u0430\u043a\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u0441\u043e\u0441\u0442\u0430\u0432\u0435 ASM \u0435\u0441\u0442\u044c <code>TraceClassVisitor<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0441\u0435 \u0432\u044b\u0437\u043e\u0432\u044b \u0432\u044b\u0432\u043e\u0434\u0438\u0442 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c, \u0447\u0435\u043c \u043c\u044b \u0438 \u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f, \u0437\u0430\u0432\u0435\u0440\u043d\u0443\u0432 \u0432 \u043d\u0435\u0433\u043e \u043d\u0430\u0448 <code>ClassWriter<\/code>.<\/p>\n<p>\u0418\u0442\u0430\u043a, \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u043f\u0443\u0441\u0442\u043e\u0433\u043e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430:<\/p>\n<pre><code class=\"java\">private void generateEmptyConstructor(ClassVisitor cv) {   \/\/ \u0421\u043e\u0437\u0434\u0430\u0451\u043c \u043c\u0435\u0442\u043e\u0434   var mv = cv.visitMethod(     Opcodes.ACC_PUBLIC,   \/\/ \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b     \"&lt;init>\",             \/\/ \u0438\u043c\u044f \u043c\u0435\u0442\u043e\u0434\u0430     Type.getMethodDescriptor(Type.VOID_TYPE),       \/\/ \u0434\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440 \u043c\u0435\u0442\u043e\u0434\u0430 - \u0442\u0438\u043f\u044b \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f     null,                 \/\/ \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0430 generic \u043c\u0435\u0442\u043e\u0434\u0430                           \/\/ (\u0434\u043b\u044f \u043d\u0430\u0441 \u043d\u0435 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e)     null                  \/\/ \u0432\u044b\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c\u044b\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f   );   mv.visitCode();    \/\/ \u041a\u043b\u0430\u0434\u0451\u043c \u043d\u0430 \u0441\u0442\u0435\u043a \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u0443\u044e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e 0    \/\/ (\u0432\u0441\u0435\u0433\u0434\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 this \u0434\u043b\u044f \u043d\u0435 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432)   mv.visitVarInsn(Opcodes.ALOAD, 0);      \/\/ \u0412\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u043c\u0435\u0442\u043e\u0434 Object.&lt;init>, \u0442.\u0435. \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440   \/\/ \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430   \/\/ (\u0430\u043d\u0430\u043b\u043e\u0433 super() \u0432 Java - \u043c\u044b \u0436\u0435 \u043f\u043e\u043c\u043d\u0438\u043c, \u0447\u0442\u043e \u0432 \u0431\u0430\u0439\u0442-\u043a\u043e\u0434\u0435   \/\/ \u0432\u0441\u0451 \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u044f\u0432\u043d\u043e)   mv.visitMethodInsn(     Opcodes.INVOKESPECIAL,     Type.getInternalName(Object.class),       \/\/ \u0443 \u043a\u0430\u043a\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u043c\u0435\u0442\u043e\u0434 -       \/\/ \u0434\u0430, \u0432 \u0431\u0430\u0439\u0442-\u043a\u043e\u0434\u0435 \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u043d\u0430\u0441\u0442\u043e\u043b\u044c\u043a\u043e       \/\/ \u0441\u043a\u0440\u0443\u043f\u0443\u043b\u0451\u0437\u043d\u044b\u043c     \"&lt;init>\",     Type.getMethodDescriptor(Type.VOID_TYPE),       \/\/ \u0434\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430     false  \/\/ \u0432\u044b\u0437\u043e\u0432 *\u043d\u0435* \u0443 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430   );      \/\/ \u042f\u0432\u043d\u043e \u043f\u0438\u0448\u0435\u043c return (\u0445\u043e\u0442\u044f \u0432 Java \u043e\u043d \u0438 \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u0435\u043d)   mv.visitInsn(Opcodes.RETURN);    \/\/ \u0422\u0443\u0442 \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0440\u0430\u0437\u043c\u0435\u0440 \u0441\u0442\u0435\u043a\u0430 \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u043b\u043e\u0442\u043e\u0432    \/\/ \u043f\u043e\u0434 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435, \u043f\u0440\u043e \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043b\u043e\u0441\u044c   \/\/ \u0432\u044b\u0448\u0435. \u041c\u044b \u043f\u043e\u043f\u0440\u043e\u0441\u0438\u043b\u0438 ASM \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0442\u044c \u0438\u0445 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438,   \/\/ \u043d\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c visitMaxs \u043c\u044b \u043e\u0431\u044f\u0437\u0430\u043d\u044b, \u043f\u0435\u0440\u0435\u0434\u0430\u0432 \u0438\u043c 0   mv.visitMaxs(0, 0);   mv.visitEnd(); }<\/code><\/pre>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0432 JVM \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0435 \u0442\u0430\u043a \u0436\u0435 \u043a\u0430\u043a \u043a\u043b\u0430\u0441\u0441 (\u043a\u0430\u043a \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0432 Java), \u0430 \u0438\u043c\u0435\u0435\u0442 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0435 \u0438\u043c\u044f <code>&lt;init><\/code>. \u0414\u043b\u044f \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0434\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440 \u2014 \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 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432. JVM \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u0434\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440\u043e\u0432, \u0432 \u0438 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0434\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440 \u0438\u043c\u0435\u0435\u0442 \u0432\u0438\u0434 <code>()V<\/code>. \u041e\u0434\u043d\u0430\u043a\u043e, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043f\u0440\u043e\u0441\u0438\u0442\u044c ASM \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440 \u0437\u0430 \u043d\u0430\u0441.<\/p>\n<p>JVM \u2014 \u044d\u0442\u043e \u0441\u0442\u0435\u043a\u043e\u0432\u0430\u044f \u043c\u0430\u0448\u0438\u043d\u0430. \u041b\u044e\u0431\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0431\u0435\u0440\u0451\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0441\u043e \u0441\u0442\u0435\u043a\u0430, \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442 \u043d\u0430\u0434 \u043d\u0438\u043c\u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0438 \u043a\u043b\u0430\u0434\u0451\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043d\u0430 \u0441\u0442\u0435\u043a. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0430\u0440\u0438\u0444\u043c\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b IADD, ISUB \u0438 \u043f\u0440\u043e\u0447\u0438\u0435, \u0441\u043d\u0438\u043c\u0430\u044e\u0442 \u0441 \u0432\u0435\u0440\u0448\u0438\u043d\u044b \u0441\u0442\u0435\u043a\u0430 \u0434\u0432\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438 \u043a\u043b\u0430\u0434\u0443\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0430 \u0432\u0435\u0440\u0448\u0438\u043d\u0443 \u0441\u0442\u0435\u043a\u0430. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u043d\u0435 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 \u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 INVOKESPECIAL \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u044c (receiver) \u043c\u0435\u0442\u043e\u0434\u0430, \u0442.\u0435. \u0442\u043e, \u0447\u0442\u043e \u0441\u0442\u043e\u0438\u0442 \u0441\u043b\u0435\u0432\u0430 \u043e\u0442 \u0442\u043e\u0447\u043a\u0438 (\u0445\u043e\u0442\u044f \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 c <code>super()<\/code> \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u0441 \u0442\u043e\u0447\u043a\u043e\u0439 \u043d\u0435 \u043f\u0440\u0435\u0434\u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043d).<\/p>\n<p>\u041a\u0441\u0442\u0430\u0442\u0438, \u043e\u0431 INVOKESPECIAL. \u0415\u0441\u0442\u044c \u0442\u0440\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u0430 \u043c\u0435\u0442\u043e\u0434\u0430: INVOKESPECIAL, INVOKEVIRTUAL \u0438 INVOKEINTERFACE. INVOKESPECIAL \u2014 \u044d\u0442\u043e \u0432\u044b\u0437\u043e\u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u0441 \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439, \u0442.\u0435. \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0438\u0441\u043a\u0430\u0442\u044c \u0432 \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0435. \u0412 \u043f\u0440\u043e\u0442\u0438\u0432\u043e\u0432\u0435\u0441 INVOKEVIRTUAL, \u043a\u043e\u0433\u0434\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043d\u0443\u0436\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0438\u0441\u043a\u0430\u0442\u044c \u0432 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u0435. \u0422\u0430\u043a\u043e\u0435 \u0431\u044b\u0432\u0430\u0435\u0442 \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445: \u0432\u044b\u0437\u043e\u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430, \u0432\u044b\u0437\u043e\u0432 super-\u043c\u0435\u0442\u043e\u0434\u0430, \u0432\u044b\u0437\u043e\u0432 \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430.<\/p>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u043c\u0435\u0442\u043e\u0434\u0430 <code>evaluate<\/code>:<\/p>\n<pre><code class=\"java\">private void generateWorkerMethod(ClassVisitor cv, String expr) {   var mv = cv.visitMethod(       Opcodes.ACC_PUBLIC,       \"evaluate\",       Type.getMethodDescriptor(Type.DOUBLE_TYPE,            Type.getType(Function.class)),        null, null   );   mv.visitCode();    var generator = new CodeGenerator(mv);   var lexer = new Lexer(expr);   var parser = new Parser(lexer, generator);   parser.parse();   mv.visitInsn(Opcodes.DRETURN);    mv.visitMaxs(0, 0);   mv.visitEnd(); }<\/code><\/pre>\n<p>\u0432\u0441\u044e \u043e\u0441\u043d\u043e\u0432\u043d\u0443\u044e \u0440\u0430\u0431\u043e\u0442\u0443 \u0434\u0435\u043b\u0430\u0435\u0442 \u043a\u043b\u0430\u0441\u0441 <code>CodeGenerator<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 <code>Parser<\/code>. \u0412 \u043a\u043e\u043d\u0446\u0435 \u0441\u0432\u043e\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u044b <code>CodeGenerator<\/code> \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043e\u0434\u043d\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043d\u0430 \u0441\u0442\u0435\u043a\u0435 \u2014 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u0415\u0433\u043e \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f DRETURN.<\/p>\n<h2>\u041f\u0438\u0448\u0435\u043c \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u0431\u0430\u0439\u0442-\u043a\u043e\u0434\u0430 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439<\/h2>\n<p>\u041f\u0430\u0440\u0441\u0435\u0440 \u043e\u0442\u0434\u0430\u0451\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u043e \u0432\u043d\u0435\u0448\u043d\u0438\u0439 \u043c\u0438\u0440 \u0447\u0435\u0440\u0435\u0437 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441:<\/p>\n<pre><code class=\"java\">public interface ParserConsumer {   void number(double value);   void identifier(String id);   void assignment(String id);   void add();   void subtract();   void multiply();   void divide();   void negate();   void statement(); }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 \u0432\u043d\u0430\u0447\u0430\u043b\u0435 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u044f\u0435\u0442 \u043e \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0435 \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u043e\u0432, \u0430 \u0437\u0430\u0442\u0435\u043c \u2014 \u043e \u0441\u0430\u043c\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f <code>2 + 3<\/code> \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0431\u0443\u0434\u0435\u0442 \u0442\u0430\u043a\u043e\u0439:<\/p>\n<ol>\n<li>\n<p><code>number(2)<\/code><\/p>\n<\/li>\n<li>\n<p><code>number(3)<\/code><\/p>\n<\/li>\n<li>\n<p><code>add()<\/code><\/p>\n<\/li>\n<\/ol>\n<p>\u041d\u0430\u0448 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440<\/p>\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-354434","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/354434","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=354434"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/354434\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=354434"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=354434"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=354434"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}