{"id":307124,"date":"2020-07-17T21:00:55","date_gmt":"2020-07-17T21:00:55","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=307124"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=307124","title":{"rendered":"\u041a\u0430\u043a \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434 \u043d\u0430 Rust"},"content":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/511478\/\">\u0412 <a href=\"https:\/\/habr.com\/ru\/post\/474666\/\">\u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435<\/a> \u043c\u044b \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u0438 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u044b\u0432\u0430\u043d\u0438\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043d\u0430 Rust, \u043a\u043e\u0433\u0434\u0430 \u0432\u0430\u043c \u044d\u0442\u043e \u043d\u0435 \u043d\u0443\u0436\u043d\u043e. \u041d\u043e \u043a\u0430\u043a \u043d\u0430\u0441\u0447\u0451\u0442 \u0442\u0435\u0445 \u0441\u043b\u0443\u0447\u0430\u0435\u0432, \u043a\u043e\u0433\u0434\u0430 \u044d\u0442\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e?<\/p>\n<p>  \u0412 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0435 \u044f\u0437\u044b\u043a\u043e\u0432 \u0432\u0430\u043c \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0432\u0441\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u0441 \u043d\u0443\u043b\u044f, \u0430 \u043f\u0435\u0440\u0432\u044b\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043f\u043e\u044f\u0432\u044f\u0442\u0441\u044f \u0431\u043b\u0438\u0436\u0435 \u043a \u043a\u043e\u043d\u0446\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u0422\u0430\u043a\u0438\u0435 \u043f\u043e\u0440\u0442\u044b, \u043a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0434\u043e\u0440\u043e\u0433\u0438 \u0438 \u043f\u043e\u0434\u0432\u0435\u0440\u0436\u0435\u043d\u044b \u043e\u0448\u0438\u0431\u043a\u0430\u043c, \u0430 \u0447\u0430\u0441\u0442\u043e \u043e\u043d\u0438 \u0432\u044b\u0445\u043e\u0434\u044f\u0442 \u0438\u0437 \u0441\u0442\u0440\u043e\u044f \u043d\u0430 \u043f\u043e\u043b\u043f\u0443\u0442\u0438. <i>\u0414\u0436\u043e\u044d\u043b \u0421\u043f\u043e\u043b\u0441\u043a\u0438<\/i> \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043b\u0443\u0447\u0448\u0435 \u043c\u0435\u043d\u044f \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u0435\u0442 \u044d\u0442\u043e \u0432 \u0441\u0442\u0430\u0442\u044c\u0435 \u043e \u0442\u043e\u043c, <a href=\"https:\/\/www.joelonsoftware.com\/2000\/04\/06\/things-you-should-never-do-part-i\/\" rel=\"nofollow\">\u043f\u043e\u0447\u0435\u043c\u0443 \u043f\u043e\u043b\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u0434\u0435\u043b\u043a\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u2014 \u043f\u043b\u043e\u0445\u0430\u044f \u0438\u0434\u0435\u044f<\/a>.<\/p>\n<p>  \u041e\u0434\u043d\u0430\u043a\u043e \u0443 Rust \u0435\u0441\u0442\u044c \u0443\u0431\u0438\u0439\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c, \u043a\u043e\u0433\u0434\u0430 \u0440\u0435\u0447\u044c \u0437\u0430\u0445\u043e\u0434\u0438\u0442 \u043e \u0442\u0430\u043a\u0438\u0445 \u0432\u0435\u0449\u0430\u0445. \u041e\u043d \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 \u0421 \u0431\u0435\u0437 \u043d\u0430\u043a\u043b\u0430\u0434\u043d\u044b\u0445 \u0440\u0430\u0441\u0445\u043e\u0434\u043e\u0432 (\u0442. \u0435. \u0441\u0440\u0435\u0434\u0430 <a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/standard\/native-interop\/pinvoke\" rel=\"nofollow\">P\/Invoke \u0432 C#<\/a>), \u0438 \u043e\u043d \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 C \u0442\u0430\u043a \u0436\u0435, \u043a\u0430\u043a \u0438 \u043b\u044e\u0431\u044b\u0435 \u0434\u0440\u0443\u0433\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 \u0421. \u042d\u0442\u043e \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u0434\u0432\u0435\u0440\u044c \u0434\u043b\u044f \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430:<\/p>\n<p>  \u041f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043d\u0430 Rust \u043f\u043e \u043e\u0434\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438.<br \/>  <a name=\"habracut\"><\/a>  <\/p>\n<blockquote><p><b>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435<\/b><br \/>  \u041a\u043e\u0434 \u0438\u0437 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d <a href=\"https:\/\/github.com\/Michael-F-Bryan\/tinyvm-rs\" rel=\"nofollow\">\u043d\u0430 GitHub<\/a>. \u041d\u0435 \u0441\u0442\u0435\u0441\u043d\u044f\u0439\u0442\u0435\u0441\u044c \u0437\u0430\u0445\u043e\u0434\u0438\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u0438\u043c\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u0438\u043b\u0438 \u0432\u0434\u043e\u0445\u043d\u043e\u0432\u0435\u043d\u0438\u0435.<\/p>\n<p>  \u0415\u0441\u043b\u0438 \u0432\u044b \u043d\u0430\u0448\u043b\u0438 \u0441\u0442\u0430\u0442\u044c\u044e \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 \u0438\u043b\u0438 \u0437\u0430\u043c\u0435\u0442\u0438\u043b\u0438 \u043e\u0448\u0438\u0431\u043a\u0443, \u0434\u0430\u0439\u0442\u0435 \u0437\u043d\u0430\u0442\u044c \u0432 <a href=\"https:\/\/github.com\/Michael-F-Bryan\/adventures.michaelfbryan.com\" rel=\"nofollow\">\u0431\u0430\u0433-\u0442\u0440\u0435\u043a\u0435\u0440\u0435 \u0431\u043b\u043e\u0433\u0430<\/a>!<\/p><\/blockquote>\n<p>  <\/p>\n<h1>\u041f\u0440\u0438\u0441\u0442\u0443\u043f\u0430\u044f \u043a \u0440\u0430\u0431\u043e\u0442\u0435<\/h1>\n<p>  \u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u0447\u0442\u043e-\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442. \u0423 \u043c\u0435\u043d\u044f \u0435\u0441\u0442\u044c <a href=\"https:\/\/github.com\/Michael-F-Bryan\/github-template\" rel=\"nofollow\">\u0448\u0430\u0431\u043b\u043e\u043d<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 CI \u0438 \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u0438 \u0434\u043b\u044f <a href=\"https:\/\/crates.io\/crates\/cargo-generate\" rel=\"nofollow\">cargo-generate<\/a>.<\/p>\n<pre><code class=\"bash\">$ cargo generate --git https:\/\/github.com\/Michael-F-Bryan\/github-template --name tinyvm-rs $ cd tinyvm-rs &amp;&amp; tree tree -I 'vendor|target' . \u251c\u2500\u2500 Cargo.toml \u251c\u2500\u2500 LICENSE_APACHE.md \u251c\u2500\u2500 LICENSE_MIT.md \u251c\u2500\u2500 README.md \u251c\u2500\u2500 .travis.yml \u2514\u2500\u2500 src     \u2514\u2500\u2500 lib.rs  1 directory, 6 files<\/code><\/pre>\n<p>  \u041d\u0430\u0448\u0430 \u043f\u0435\u0440\u0432\u0430\u044f \u0440\u0435\u0430\u043b\u044c\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u2014 \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0438 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0432 \u043d\u0435\u0439 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f.<\/p>\n<p>  \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u044b \u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c <a href=\"https:\/\/github.com\/jakogut\/tinyvm\" rel=\"nofollow\">jakogut\/tinyvm<\/a>,<\/p>\n<blockquote><p>TinyVM \u2014 \u044d\u0442\u043e \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0430\u044f, \u0431\u044b\u0441\u0442\u0440\u0430\u044f, \u043b\u0451\u0433\u043a\u0430\u044f \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0430\u044f \u043c\u0430\u0448\u0438\u043d\u0430, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u0430\u044f \u043d\u0430 \u0447\u0438\u0441\u0442\u043e\u043c \u044f\u0437\u044b\u043a\u0435 ANSI C.<\/p><\/blockquote>\n<p>  \u0427\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0449\u0435 \u0441\u0441\u044b\u043b\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u043d\u0435\u0451 \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c, \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u043e\u0434\u043c\u043e\u0434\u0443\u043b\u044f \u0432 \u043d\u0430\u0448 \u043f\u0440\u043e\u0435\u043a\u0442.<\/p>\n<pre><code class=\"bash\">$ git submodule add https:\/\/github.com\/jakogut\/tinyvm vendor\/tinyvm<\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434. \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430, <code>README.md<\/code> \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 \u043f\u043e \u0441\u0431\u043e\u0440\u043a\u0435.<\/p>\n<blockquote><p>TinyVM \u2014 \u044d\u0442\u043e \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0430\u044f \u043c\u0430\u0448\u0438\u043d\u0430 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0430. \u041c\u0430\u043b\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u0438, \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043e\u0434\u0430 \u0438 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0439 \u043a\u043e\u0434.<\/p>\n<p>  \u0421\u0431\u043e\u0440\u043a\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u0430 UNIX-\u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0445 \u0441 make \u0438 GCC.<\/p>\n<p>  \u0412\u043d\u0435\u0448\u043d\u0438\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u043d\u0435\u0442, \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u0435 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u0421.<\/p>\n<p>  <b>\u0421\u0431\u043e\u0440\u043a\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e make \u0438\u043b\u0438 make rebuild.<\/b><\/p>\n<p>  \u0427\u0442\u043e\u0431\u044b \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u043e\u0442\u043b\u0430\u0434\u043e\u0447\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e, \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 DEBUG=yes \u043f\u043e\u0441\u043b\u0435 make. \u0427\u0442\u043e\u0431\u044b \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u0441 \u0432\u043a\u043b\u044e\u0447\u0451\u043d\u043d\u044b\u043c \u043f\u0440\u043e\u0444\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c, \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 PROFILE=yes \u043f\u043e\u0441\u043b\u0435 make.<\/p>\n<p>  \u0421\u043e \u043c\u043d\u043e\u0439 \u043c\u043e\u0436\u043d\u043e \u0441\u0432\u044f\u0437\u0430\u0442\u044c\u0441\u044f \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 joseph.kogut(at)gmail.com<\/p><\/blockquote>\n<p>(\u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e)<\/p>\n<p>  \u041b\u0430\u0434\u043d\u043e, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0437\u0430\u0433\u043b\u044f\u043d\u0435\u043c \u0432 \u043a\u0430\u0442\u0430\u043b\u043e\u0433 <code>tinyvm<\/code> \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0431\u0443\u0434\u0435\u0442 \u043b\u0438 \u0441\u0431\u043e\u0440\u043a\u0430 <i>\u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c<\/i>.<\/p>\n<pre><code class=\"bash\">$ cd vendor\/tinyvm $ make clang -Wall -pipe -Iinclude\/ -std=gnu11 -Werror -pedantic -pedantic-errors -O3 -c libtvm\/tvm_program.c -o libtvm\/tvm_program.o clang -Wall -pipe -Iinclude\/ -std=gnu11 -Werror -pedantic -pedantic-errors -O3 -c libtvm\/tvm_lexer.c -o libtvm\/tvm_lexer.o clang -Wall -pipe -Iinclude\/ -std=gnu11 -Werror -pedantic -pedantic-errors -O3 -c libtvm\/tvm.c -o libtvm\/tvm.o clang -Wall -pipe -Iinclude\/ -std=gnu11 -Werror -pedantic -pedantic-errors -O3 -c libtvm\/tvm_htab.c -o libtvm\/tvm_htab.o clang -Wall -pipe -Iinclude\/ -std=gnu11 -Werror -pedantic -pedantic-errors -O3 -c libtvm\/tvm_memory.c -o libtvm\/tvm_memory.o clang -Wall -pipe -Iinclude\/ -std=gnu11 -Werror -pedantic -pedantic-errors -O3 -c libtvm\/tvm_preprocessor.c -o libtvm\/tvm_preprocessor.o clang -Wall -pipe -Iinclude\/ -std=gnu11 -Werror -pedantic -pedantic-errors -O3 -c libtvm\/tvm_parser.c -o libtvm\/tvm_parser.o clang -Wall -pipe -Iinclude\/ -std=gnu11 -Werror -pedantic -pedantic-errors -O3 -c libtvm\/tvm_file.c -o libtvm\/tvm_file.o ar rcs lib\/libtvm.a libtvm\/tvm_program.o libtvm\/tvm_lexer.o libtvm\/tvm.o libtvm\/tvm_htab.o libtvm\/tvm_memory.o libtvm\/tvm_preprocessor.o libtvm\/tvm_parser.o libtvm\/tvm_file.o clang src\/tvmi.c -ltvm -Wall -pipe -Iinclude\/ -std=gnu11 -Werror -pedantic -pedantic-errors -O3 -Llib\/ -o bin\/tvmi clang -Wall -pipe -Iinclude\/ -std=gnu11 -Werror -pedantic -pedantic-errors -O3 -c tdb\/main.c -o tdb\/main.o clang -Wall -pipe -Iinclude\/ -std=gnu11 -Werror -pedantic -pedantic-errors -O3 -c tdb\/tdb.c -o tdb\/tdb.o clang tdb\/main.o tdb\/tdb.o -ltvm -Wall -pipe -Iinclude\/ -std=gnu11 -Werror -pedantic -pedantic-errors -O3 -Llib\/ -o bin\/tdb<\/code><\/pre>\n<p>  \u041c\u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 C \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u043f\u0440\u044f\u043c\u043e \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438 \u0431\u0435\u0437 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0435 \u043f\u0430\u043a\u0435\u0442\u044b <code>*-dev<\/code> \u0438\u043b\u0438 \u0432\u043e\u0437\u0438\u0442\u044c\u0441\u044f \u0441 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439 \u0441\u0431\u043e\u0440\u043a\u0438.<\/p>\n<p>  \u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0442\u0435\u0441\u0442\u043e\u0432, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u043c (\u0441\u0440\u0430\u0437\u0443) \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u0432\u0435\u0434\u0435\u043d\u044b \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e, \u043d\u043e \u043e\u043d\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0432\u044b\u0441\u043e\u043a\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f.<\/p>\n<p>  \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043c\u044b \u0437\u043d\u0430\u0435\u043c, \u0447\u0442\u043e \u043c\u043e\u0436\u0435\u043c \u0431\u0435\u0437 \u043e\u0441\u043e\u0431\u044b\u0445 \u0445\u043b\u043e\u043f\u043e\u0442 \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0435\u0451 \u0438\u0437 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438. \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u043d\u043e \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u043d\u0430\u0448 \u043a\u0440\u0435\u0439\u0442 <code>tinyvm<\/code> \u0441\u043f\u043e\u0441\u043e\u0431\u0435\u043d \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0432\u0441\u0451 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e.<\/p>\n<p>  \u0412\u043e\u0442 \u0442\u0443\u0442-\u0442\u043e \u0438 \u043f\u043e\u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438 \u0441\u0431\u043e\u0440\u043a\u0438. \u041d\u0430\u0448\u0430 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044f \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u043a\u0440\u0435\u0439\u0442 Rust \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u0441\u043a\u0440\u0438\u043f\u0442 \u0441\u0431\u043e\u0440\u043a\u0438 <code>build.rs<\/code> \u0438 \u043a\u0440\u0435\u0439\u0442 <code>cc<\/code> \u0434\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u0430 \u044d\u043a\u0432\u0438\u0432\u0430\u043b\u0435\u043d\u0442\u043d\u044b\u0445 \u043a\u043e\u043c\u0430\u043d\u0434 \u043a \u043d\u0430\u0448\u0435\u043c\u0443 \u0432\u044b\u0437\u043e\u0432\u0443 <code>make<\/code>. \u041e\u0442\u0442\u0443\u0434\u0430 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f \u043a <code>libtvm<\/code> \u0438\u0437 Rust \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a \u0436\u0435, \u043a\u0430\u043a \u0438 \u043a \u043b\u044e\u0431\u043e\u0439 \u0434\u0440\u0443\u0433\u043e\u0439 \u0440\u043e\u0434\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435.<\/p>\n<p>  \u041d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a\u0440\u0435\u0439\u0442 <code>cc<\/code> \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438.<\/p>\n<pre><code class=\"bash\">$ cargo add --build cc     Updating 'https:\/\/github.com\/rust-lang\/crates.io-index' index       Adding cc v1.0.47 to build-dependencies<\/code><\/pre>\n<p>  \u0410 \u0442\u0430\u043a\u0436\u0435 \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e <code>build.rs<\/code> \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u0442 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 <code>libtvm<\/code>.<\/p>\n<pre><code class=\"rust\">\/\/ build.rs  use cc::Build; use std::path::Path;  fn main() {     let tinyvm = Path::new(&quot;vendor\/tinyvm&quot;);     let include = tinyvm.join(&quot;include&quot;);     let src = tinyvm.join(&quot;libtvm&quot;);      Build::new()         .warnings(false)         .file(src.join(&quot;tvm_file.c&quot;))         .file(src.join(&quot;tvm_htab.c&quot;))         .file(src.join(&quot;tvm_lexer.c&quot;))         .file(src.join(&quot;tvm_memory.c&quot;))         .file(src.join(&quot;tvm_parser.c&quot;))         .file(src.join(&quot;tvm_preprocessor.c&quot;))         .file(src.join(&quot;tvm_program.c&quot;))         .file(src.join(&quot;tvm.c&quot;))         .include(&amp;include)         .compile(&quot;tvm&quot;); }<\/code><\/pre>\n<p>  <\/p>\n<blockquote><p><b>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435<\/b><br \/>  \u0415\u0441\u043b\u0438 \u0432\u044b \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e \u043a\u0440\u0435\u0439\u0442\u0430 <code>cc<\/code>, \u0442\u043e, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0437\u0430\u043c\u0435\u0442\u0438\u043b\u0438 \u043c\u0435\u0442\u043e\u0434 <code>Build::files()<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440 \u043f\u0443\u0442\u0435\u0439. \u041c\u044b <i>\u043c\u043e\u0433\u043b\u0438 \u0431\u044b<\/i> \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0442\u044c \u0432\u0441\u0435 \u0444\u0430\u0439\u043b\u044b <code>*.c<\/code> \u0432\u043d\u0443\u0442\u0440\u0438 <code>vendor\/tinyvm\/libtvm<\/code>, \u043d\u043e \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043c\u044b \u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434 \u043f\u043e \u043e\u0434\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043f\u0440\u043e\u0449\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0432\u044b\u0437\u043e\u0432\u044b <code>.file()<\/code> \u043f\u043e \u043c\u0435\u0440\u0435 \u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f.<\/p><\/blockquote>\n<p>  \u041d\u0430\u043c \u0442\u0430\u043a\u0436\u0435 \u043d\u0443\u0436\u0435\u043d \u0441\u043f\u043e\u0441\u043e\u0431 \u0441\u043e\u043e\u0431\u0449\u0438\u0442\u044c Rust, \u043a\u0430\u043a\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043e\u043d \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0438\u0437 <code>libtvm<\/code>. \u041e\u0431\u044b\u0447\u043d\u043e \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u043f\u0443\u0442\u0451\u043c \u0437\u0430\u043f\u0438\u0441\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0439 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432 <a href=\"https:\/\/doc.rust-lang.org\/reference\/items\/external-blocks.html\" rel=\"nofollow\">\u0431\u043b\u043e\u043a\u0435 extern<\/a>, \u043d\u043e, \u043a \u0441\u0447\u0430\u0441\u0442\u044c\u044e, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u043f\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c <a href=\"https:\/\/crates.io\/crates\/bindgen\" rel=\"nofollow\">bindgen<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u0447\u0438\u0442\u0430\u0442\u044c \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u0447\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u0432 \u0441\u0442\u0438\u043b\u0435 C \u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u043d\u0430\u0441.<\/p>\n<p>  \u0421\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0438 \u0438\u0437 <code>vendor\/tinyvm\/include\/tvm\/tvm.h<\/code>.<\/p>\n<pre><code class=\"bash\">$ cargo install bindgen $ bindgen vendor\/tinyvm\/include\/tvm\/tvm.h -o src\/ffi.rs $ wc --lines src\/ffi.rs 992 src\/ffi.rs<\/code><\/pre>\n<p>  \u041d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u043d\u0430\u0448 \u043a\u0440\u0435\u0439\u0442 \u043c\u043e\u0434\u0443\u043b\u044c <code>ffi<\/code>.<\/p>\n<pre><code class=\"rust\">\/\/ src\/lib.rs  #[allow(non_camel_case_types, non_snake_case)] pub mod ffi;<\/code><\/pre>\n<p>  \u0413\u043b\u044f\u0434\u044f \u043d\u0430 \u043a\u0430\u0442\u0430\u043b\u043e\u0433 <code>src\/<\/code> \u0432 <code>tinyvm<\/code>, \u043c\u044b \u043d\u0430\u0445\u043e\u0434\u0438\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u0430 <code>tinyvm<\/code>.<\/p>\n<pre><code class=\"rust\">\/\/ vendor\/tinyvm\/src\/tvmi.c  #include &lt;stdlib.h&gt; #include &lt;stdio.h&gt;  #include &lt;tvm\/tvm.h&gt;  int main(int argc, char **argv) { \tstruct tvm_ctx *vm = tvm_vm_create();  \tif (vm != NULL &amp;&amp; tvm_vm_interpret(vm, argv[1]) == 0) \t\ttvm_vm_run(vm);  \ttvm_vm_destroy(vm);  \treturn 0; }<\/code><\/pre>\n<p>  \u042d\u0442\u043e \u043d\u0435\u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e. \u0427\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u0438\u044f\u0442\u043d\u043e, \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044f, \u0447\u0442\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043e\u0434\u043d\u043e\u0433\u043e \u0438\u0437 \u043d\u0430\u0448\u0438\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432.<\/p>\n<p>  \u0410 \u043f\u043e\u043a\u0430 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0435\u0440\u0435\u0432\u0435\u0434\u0451\u043c \u0435\u0433\u043e \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432 Rust \u0438 \u0432\u0441\u0442\u0430\u0432\u0438\u043c \u0432 \u043a\u0430\u0442\u0430\u043b\u043e\u0433 <code>examples\/<\/code>.<\/p>\n<pre><code class=\"rust\">\/\/ examples\/tvmi.rs  use std::{env, ffi::CString}; use tinyvm::ffi;  fn main() {     let filename = CString::new(env::args().nth(1).unwrap()).unwrap();     \/\/ cast away the `const` because that's what libtvm expects     let filename = filename.as_ptr() as *mut _;      unsafe {         let vm = ffi::tvm_vm_create();          if !vm.is_null() &amp;&amp; ffi::tvm_vm_interpret(vm, filename) == 0 {             ffi::tvm_vm_run(vm);         }          ffi::tvm_vm_destroy(vm);     } }<\/code><\/pre>\n<p>  \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0443\u044e \u043c\u0430\u0448\u0438\u043d\u0443 \u0438 \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u0432\u0441\u0451 \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.<\/p>\n<pre><code class=\"bash\">$ cargo run --example tvmi -- vendor\/tinyvm\/programs\/tinyvm\/fact.vm     Finished dev [unoptimized + debuginfo] target(s) in 0.02s      Running `target\/debug\/examples\/tvmi vendor\/tinyvm\/programs\/tinyvm\/fact.vm` 1 2 6 24 120 720 5040 40320 362880 3628800<\/code><\/pre>\n<p>  \u041a\u043b\u0430\u0441\u0441!<\/p>\n<h1>\u041d\u0438\u0437\u043a\u043e \u0432\u0438\u0441\u044f\u0449\u0438\u0435 \u0444\u0440\u0443\u043a\u0442\u044b<\/h1>\n<p>  \u041a\u043e\u0433\u0434\u0430 \u0432\u044b \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0435 \u0441 \u0447\u0435\u0433\u043e-\u0442\u043e \u0432\u0440\u043e\u0434\u0435 \u044d\u0442\u043e\u0433\u043e, \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u0441\u043e\u0431\u043b\u0430\u0437\u043d \u043f\u043e\u0433\u0440\u0443\u0437\u0438\u0442\u044c\u0441\u044f \u0432 \u0441\u0430\u043c\u044b\u0435 \u0432\u0430\u0436\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u0438\u0445 \u043f\u0435\u0440\u0432\u044b\u043c\u0438. \u041f\u043e\u043f\u044b\u0442\u0430\u0439\u0442\u0435\u0441\u044c \u0441\u043e\u043f\u0440\u043e\u0442\u0438\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u0440\u044b\u0432\u0443. \u0412\u044b \u043b\u0435\u0433\u043a\u043e \u043e\u0442\u043a\u0443\u0441\u0438\u0442\u0435 \u0431\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0440\u043e\u0436\u0435\u0432\u0430\u0442\u044c, \u0438 \u0432 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c \u0438\u0442\u043e\u0433\u0435 \u043b\u0438\u0431\u043e \u043f\u043e\u0442\u0435\u0440\u044f\u0435\u0442\u0435 \u0432\u0440\u0435\u043c\u044f, \u043b\u0438\u0431\u043e \u044d\u0442\u043e \u0432\u0430\u0441 \u0434\u0435\u043c\u043e\u0440\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0438 \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u0442 \u0441\u0434\u0430\u0442\u044c\u0441\u044f.<\/p>\n<p>  \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0438\u0449\u0435\u043c \u0441\u0430\u043c\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u043e\u0435.<\/p>\n<pre><code class=\"bash\">$ ls libtvm tvm.c  tvm_file.c  tvm_htab.c  tvm_lexer.c  tvm_memory.c  tvm_parser.c tvm_preprocessor.c  tvm_program.c<\/code><\/pre>\n<p>  \u042d\u0442\u043e\u0442 \u0444\u0430\u0439\u043b <code>tvm_htab.\u0441<\/code> \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043c\u043d\u043e\u0433\u043e\u043e\u0431\u0435\u0449\u0430\u044e\u0449\u0435. \u042f \u043f\u043e\u0447\u0442\u0438 \u0443\u0432\u0435\u0440\u0435\u043d, \u0447\u0442\u043e <code>htab<\/code> \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u00ab\u0445\u044d\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0430\u00bb, \u0430 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 Rust \u0443\u0436\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432\u044b\u0441\u043e\u043a\u043e\u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e. \u041c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 \u043f\u043e\u043c\u0435\u043d\u044f\u0442\u044c \u044d\u0442\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043b\u0435\u0433\u043a\u043e.<\/p>\n<p>  \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u0447\u043d\u044b\u0439 \u0444\u0430\u0439\u043b <code>tvm_htab.h<\/code> \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c, \u0441 \u0447\u0435\u043c \u0438\u043c\u0435\u0435\u043c \u0434\u0435\u043b\u043e.<\/p>\n<pre><code class=\"cpp\">\/\/ vendor\/tinyvm\/include\/tvm\/tvm_htab.h  #ifndef TVM_HTAB_H_ #define TVM_HTAB_H_  #define KEY_LENGTH 64 #define HTAB_SIZE 4096  struct tvm_htab_node { \tchar *key; \tint value; \tvoid *valptr; \tstruct tvm_htab_node *next; };  struct tvm_htab_ctx { \tunsigned int num_nodes; \tunsigned int size; \tstruct tvm_htab_node **nodes; };  struct tvm_htab_ctx *tvm_htab_create(); void tvm_htab_destroy(struct tvm_htab_ctx *htab);  int tvm_htab_add(struct tvm_htab_ctx *htab, const char *key, int value); int tvm_htab_add_ref(struct tvm_htab_ctx *htab, \tconst char *key, const void *valptr, int len); int tvm_htab_find(struct tvm_htab_ctx *htab, const char *key); char *tvm_htab_find_ref(struct tvm_htab_ctx *htab, const char *key);  #endif<\/code><\/pre>\n<p>  \u0412\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043b\u0435\u0433\u043a\u043e \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438. \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 <code>tvm_htab_ctx<\/code> \u0438 <code>tvm_htab_node<\/code> \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u044b \u0432 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u0447\u043d\u044b\u0439 \u0444\u0430\u0439\u043b, \u0430 \u044d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043a\u043e\u0434 \u043c\u043e\u0436\u0435\u0442 \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043a \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c \u0445\u044d\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u044b, \u0430 \u043d\u0435 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441.<\/p>\n<p>  \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u0438\u043c\u0435\u0435\u0442 \u043b\u0438 \u0447\u0442\u043e-\u043d\u0438\u0431\u0443\u0434\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c \u0445\u044d\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u044b, \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0432 <code>tvm_htab.c<\/code> \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u0432\u0441\u0451 \u043b\u0438 \u0435\u0449\u0451 \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u0442\u0441\u044f.<\/p>\n<pre><code class=\"cpp\">diff --git a\/include\/tvm\/tvm_htab.h b\/include\/tvm\/tvm_htab.h index 9feb7a9..e7346b7 100644 --- a\/include\/tvm\/tvm_htab.h +++ b\/include\/tvm\/tvm_htab.h @@ -4,18 +4,8 @@  #define KEY_LENGTH 64  #define HTAB_SIZE 4096  -struct tvm_htab_node { -       char *key; -       int value; -       void *valptr; -       struct tvm_htab_node *next; -}; - -struct tvm_htab_ctx { -       unsigned int num_nodes; -       unsigned int size; -       struct tvm_htab_node **nodes; -}; +struct tvm_htab_node; +struct tvm_htab_ctx;   struct tvm_htab_ctx *tvm_htab_create();  void tvm_htab_destroy(struct tvm_htab_ctx *htab);<\/code><\/pre>\n<p>  \u0410 \u0437\u0430\u0442\u0435\u043c \u0435\u0449\u0451 \u0440\u0430\u0437 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c <code>make<\/code>:<\/p>\n<pre><code class=\"bash\">$ make make clang -Wall -pipe -Iinclude\/ -std=gnu11 -Werror -pedantic -pedantic-errors -O3 -c libtvm\/tvm_htab.c -o libtvm\/tvm_htab.o ar rcs lib\/libtvm.a libtvm\/tvm_program.o libtvm\/tvm_lexer.o libtvm\/tvm.o libtvm\/tvm_htab.o libtvm\/tvm_memory.o libtvm\/tvm_preprocessor.o libtvm\/tvm_parser.o libtvm\/tvm_file.o clang src\/tvmi.c -ltvm -Wall -pipe -Iinclude\/ -std=gnu11 -Werror -pedantic -pedantic-errors -O3 -Llib\/ -o bin\/tvmi clang tdb\/main.o tdb\/tdb.o -ltvm -Wall -pipe -Iinclude\/ -std=gnu11 -Werror -pedantic -pedantic-errors -O3 -Llib\/ -o bin\/tdb<\/code><\/pre>\n<p>  \u041f\u043e\u0445\u043e\u0436\u0435, \u0432\u0441\u0451 \u043f\u043e-\u043f\u0440\u0435\u0436\u043d\u0435\u043c\u0443 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0430\u0435\u043c \u043a\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u0444\u0430\u0437\u0435; \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0438\u0434\u0435\u043d\u0442\u0438\u0447\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 <code>HashMap&lt;K, V&gt;<\/code>.<\/p>\n<p>  \u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0448\u0438\u0441\u044c \u0437\u0430\u0433\u043b\u0443\u0448\u043a\u043e\u0439 \u0441 \u0441\u0430\u043c\u044b\u043c \u043c\u0438\u043d\u0438\u043c\u0443\u043c\u043e\u043c, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c:<\/p>\n<pre><code class=\"rust\">\/\/ src\/htab.rs  use std::{     collections::HashMap,     ffi::CString,     os::raw::{c_char, c_int, c_void}, };  #[derive(Debug, Default, Clone, PartialEq)] pub struct HashTable(pub(crate) HashMap&lt;CString, Item&gt;);  #[derive(Debug, Clone, PartialEq)] pub(crate) struct Item {     \/\/ not sure what to put here yet }  #[no_mangle] pub unsafe extern &quot;C&quot; fn tvm_htab_create() -&gt; *mut HashTable {     unimplemented!() }  #[no_mangle] pub unsafe extern &quot;C&quot; fn tvm_htab_destroy(htab: *mut HashTable) {     unimplemented!() }  #[no_mangle] pub unsafe extern &quot;C&quot; fn tvm_htab_add(     htab: *mut HashTable,     key: *const c_char,     value: c_int, ) -&gt; c_int {     unimplemented!() }  #[no_mangle] pub unsafe extern &quot;C&quot; fn tvm_htab_add_ref(     htab: *mut HashTable,     key: *const c_char,     value_ptr: *mut c_void,     length: c_int, ) -&gt; c_int {     unimplemented!() }  #[no_mangle] pub unsafe extern &quot;C&quot; fn tvm_htab_find(     htab: *mut HashTable,     key: *const c_char, ) -&gt; c_int {     unimplemented!() }  #[no_mangle] pub unsafe extern &quot;C&quot; fn tvm_htab_find_ref(     htab: *mut HashTable,     key: *const c_char, ) -&gt; *mut c_char {     unimplemented!() }<\/code><\/pre>\n<p>  \u0422\u0430\u043a\u0436\u0435 \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044c <code>htab<\/code> \u0438 \u0440\u0435\u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438\u0437 <code>lib.rs<\/code>.<\/p>\n<pre><code class=\"rust\">\/\/ src\/lib.rs  mod htab; pub use htab::*;<\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u043d\u043e \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 <code>tvm_htab.c<\/code> \u043d\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0438 \u043d\u0435 \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0441 \u043e\u043a\u043e\u043d\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u043e\u0439, \u0438\u043d\u0430\u0447\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u043e\u0432\u0449\u0438\u043a \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u0442 \u043d\u0430\u0441 \u0441\u0442\u0435\u043d\u043e\u0439 \u043e\u0448\u0438\u0431\u043e\u043a \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u044e\u0449\u0438\u0445\u0441\u044f \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432.<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0421\u0442\u0435\u043d\u0430 \u043e\u0448\u0438\u0431\u043e\u043a \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u044e\u0449\u0438\u0445\u0441\u044f \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"bash\">error: linking with `\/usr\/bin\/clang` failed: exit code: 1   |   = note: &quot;\/usr\/bin\/clang&quot; &quot;-Wl,--as-needed&quot; &quot;-Wl,-z,noexecstack&quot; &quot;-m64&quot; &quot;-L&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-599d57f523fdb1a4.17q5thi94e1eoj5i.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-599d57f523fdb1a4.19e8sqirbm56nu8g.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-599d57f523fdb1a4.1g6ljku8dwzpfvhi.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-599d57f523fdb1a4.1h5e5mxmiptpb7iz.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-599d57f523fdb1a4.1herotdop66zv9ot.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-599d57f523fdb1a4.1qbfxpvgd885u6o.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-599d57f523fdb1a4.21psdg8ni4vgdrzk.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-599d57f523fdb1a4.2albhpxlxxvc0ccu.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-599d57f523fdb1a4.2btm2dc9rhjhhna1.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-599d57f523fdb1a4.2kct5ftnkrqqr0mf.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-599d57f523fdb1a4.2lwgg3uosup4mkh0.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-599d57f523fdb1a4.2xduj46e9sw5vuan.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-599d57f523fdb1a4.35h8y7f23ua1qnz0.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-599d57f523fdb1a4.3cgfdtku63ltd8oc.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-599d57f523fdb1a4.3ot768hzkzzy7r76.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-599d57f523fdb1a4.3u2xnetcch8f2o02.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-599d57f523fdb1a4.4ldrdjvfzk58myrv.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-599d57f523fdb1a4.4omnum6bdjqsrq8b.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-599d57f523fdb1a4.4s8ch4ccmewulj22.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-599d57f523fdb1a4.4syl3x2rb8328h8x.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-599d57f523fdb1a4.532awiysf0h9r50f.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-599d57f523fdb1a4.5b2qwmmtc5pvnbh.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-599d57f523fdb1a4.dfjs079cp9si4o5.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-599d57f523fdb1a4.qxp6yb2gjpj0v6n.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-599d57f523fdb1a4.xz7ld20yvprst1r.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-599d57f523fdb1a4.z35ukhvchmmby1c.rcgu.o&quot; &quot;-o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-599d57f523fdb1a4&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-599d57f523fdb1a4.1d7wvlwdjap8p3g4.rcgu.o&quot; &quot;-Wl,--gc-sections&quot; &quot;-pie&quot; &quot;-Wl,-zrelro&quot; &quot;-Wl,-znow&quot; &quot;-nodefaultlibs&quot; &quot;-L&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps&quot; &quot;-L&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/build\/tinyvm-3f1a2766f78b5580\/out&quot; &quot;-L&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib&quot; &quot;-Wl,-Bstatic&quot; &quot;-Wl,--whole-archive&quot; &quot;-ltvm&quot; &quot;-Wl,--no-whole-archive&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/libtest-a39a3e9a77b17f55.rlib&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/libterm-97a69cd310ff0925.rlib&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/libgetopts-66a42b1d94e3e6f9.rlib&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/libunicode_width-dd7761d848144e0d.rlib&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/librustc_std_workspace_std-f722acdb78755ba0.rlib&quot; &quot;-Wl,--start-group&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/libstd-974c3c08f6def4b3.rlib&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/libpanic_unwind-eb49676f33a2c8a6.rlib&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/libhashbrown-7ae0446feecc60f2.rlib&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/librustc_std_workspace_alloc-2de299b65d7f5721.rlib&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/libbacktrace-64514775bc06309a.rlib&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/libbacktrace_sys-1ed8aa185c63b9a5.rlib&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/librustc_demangle-a839df87f563fba5.rlib&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/libunwind-8e726bdc2018d836.rlib&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/libcfg_if-5285f42cbadf207d.rlib&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/liblibc-b0362d20f8aa58fa.rlib&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/liballoc-f3dd7051708453a4.rlib&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/librustc_std_workspace_core-83744846c43307ce.rlib&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/libcore-d5565a3a0f4cfe21.rlib&quot; &quot;-Wl,--end-group&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/libcompiler_builtins-ea790e85415e3bbf.rlib&quot; &quot;-Wl,-Bdynamic&quot; &quot;-ldl&quot; &quot;-lrt&quot; &quot;-lpthread&quot; &quot;-lgcc_s&quot; &quot;-lc&quot; &quot;-lm&quot; &quot;-lrt&quot; &quot;-lpthread&quot; &quot;-lutil&quot; &quot;-lutil&quot; &quot;-fuse-ld=lld&quot;   = note: ld.lld: error: duplicate symbol: tvm_htab_create           &gt;&gt;&gt; defined at htab.rs:14 (src\/htab.rs:14)           &gt;&gt;&gt;            \/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-599d57f523fdb1a4.5b2qwmmtc5pvnbh.rcgu.o:(tvm_htab_create)           &gt;&gt;&gt; defined at tvm_htab.c:23 (vendor\/tinyvm\/libtvm\/tvm_htab.c:23)           &gt;&gt;&gt;            tvm_htab.o:(.text.tvm_htab_create+0x0) in archive \/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/build\/tinyvm-3f1a2766f78b5580\/out\/libtvm.a            ld.lld: error: duplicate symbol: tvm_htab_destroy           &gt;&gt;&gt; defined at htab.rs:17 (src\/htab.rs:17)           &gt;&gt;&gt;            \/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-599d57f523fdb1a4.5b2qwmmtc5pvnbh.rcgu.o:(tvm_htab_destroy)           &gt;&gt;&gt; defined at tvm_htab.c:35 (vendor\/tinyvm\/libtvm\/tvm_htab.c:35)           &gt;&gt;&gt;            tvm_htab.o:(.text.tvm_htab_destroy+0x0) in archive \/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/build\/tinyvm-3f1a2766f78b5580\/out\/libtvm.a            ld.lld: error: duplicate symbol: tvm_htab_add_ref           &gt;&gt;&gt; defined at htab.rs:29 (src\/htab.rs:29)           &gt;&gt;&gt;            \/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-599d57f523fdb1a4.5b2qwmmtc5pvnbh.rcgu.o:(tvm_htab_add_ref)           &gt;&gt;&gt; defined at tvm_htab.c:160 (vendor\/tinyvm\/libtvm\/tvm_htab.c:160)           &gt;&gt;&gt;            tvm_htab.o:(.text.tvm_htab_add_ref+0x0) in archive \/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/build\/tinyvm-3f1a2766f78b5580\/out\/libtvm.a            ld.lld: error: duplicate symbol: tvm_htab_add           &gt;&gt;&gt; defined at htab.rs:20 (src\/htab.rs:20)           &gt;&gt;&gt;            \/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-599d57f523fdb1a4.5b2qwmmtc5pvnbh.rcgu.o:(tvm_htab_add)           &gt;&gt;&gt; defined at tvm_htab.c:147 (vendor\/tinyvm\/libtvm\/tvm_htab.c:147)           &gt;&gt;&gt;            tvm_htab.o:(.text.tvm_htab_add+0x0) in archive \/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/build\/tinyvm-3f1a2766f78b5580\/out\/libtvm.a            ld.lld: error: duplicate symbol: tvm_htab_find           &gt;&gt;&gt; defined at htab.rs:39 (src\/htab.rs:39)           &gt;&gt;&gt;            \/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-599d57f523fdb1a4.5b2qwmmtc5pvnbh.rcgu.o:(tvm_htab_find)           &gt;&gt;&gt; defined at tvm_htab.c:189 (vendor\/tinyvm\/libtvm\/tvm_htab.c:189)           &gt;&gt;&gt;            tvm_htab.o:(.text.tvm_htab_find+0x0) in archive \/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/build\/tinyvm-3f1a2766f78b5580\/out\/libtvm.a            ld.lld: error: duplicate symbol: tvm_htab_find_ref           &gt;&gt;&gt; defined at htab.rs:47 (src\/htab.rs:47)           &gt;&gt;&gt;            \/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-599d57f523fdb1a4.5b2qwmmtc5pvnbh.rcgu.o:(tvm_htab_find_ref)           &gt;&gt;&gt; defined at tvm_htab.c:199 (vendor\/tinyvm\/libtvm\/tvm_htab.c:199)           &gt;&gt;&gt;            tvm_htab.o:(.text.tvm_htab_find_ref+0x0) in archive \/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/build\/tinyvm-3f1a2766f78b5580\/out\/libtvm.a           clang: error: linker command failed with exit code 1 (use -v to see invocation)   error: aborting due to previous error  error: could not compile `tinyvm`.<\/code><\/pre>\n<\/div><\/div>\n<p>  \u0418\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0435.<\/p>\n<pre><code class=\"rust\">diff --git a\/build.rs b\/build.rs index 6f274c8..af9d467 100644 --- a\/build.rs +++ b\/build.rs @@ -9,7 +9,6 @@ fn main() {      Build::new()          .warnings(false)          .file(src.join(&quot;tvm_file.c&quot;)) -        .file(src.join(&quot;tvm_htab.c&quot;))          .file(src.join(&quot;tvm_lexer.c&quot;))          .file(src.join(&quot;tvm_memory.c&quot;))          .file(src.join(&quot;tvm_parser.c&quot;))<\/code><\/pre>\n<p>  \u0418 \u043f\u043e\u043f\u044b\u0442\u043a\u0430 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440 <code>tvmi<\/code> \u0441\u043d\u043e\u0432\u0430 \u0442\u0435\u0440\u043f\u0438\u0442 \u043a\u0440\u0430\u0445, \u043a\u0430\u043a \u0438 \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043b\u043e \u043e\u0436\u0438\u0434\u0430\u0442\u044c \u043e\u0442 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b, \u043f\u043e\u043b\u043d\u043e\u0439 <code>unimplemented!()<\/code>.<\/p>\n<pre><code class=\"bash\">$ cargo run --example tvmi -- vendor\/tinyvm\/programs\/tinyvm\/fact.vm     Finished dev [unoptimized + debuginfo] target(s) in 0.02s      Running `target\/debug\/examples\/tvmi vendor\/tinyvm\/programs\/tinyvm\/fact.vm` thread 'main' panicked at 'not yet implemented', src\/htab.rs:14:57 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.<\/code><\/pre>\n<p>  \u041f\u0440\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 FFI \u0434\u043b\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u043f\u0440\u043e\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u043d\u0430\u0447\u0430\u0442\u044c \u0441 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430 \u0438 \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430.<\/p>\n<blockquote><p><b>\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f<\/b><br \/>  \u041a\u043e\u0434 C \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043d\u0430\u0448\u0435\u0439 \u0445\u044d\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0435\u0440\u0435\u0437 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u0434\u0435\u043b\u0438\u0442\u044c \u043e\u0434\u0438\u043d \u0438\u0437 \u043d\u0438\u0445 \u0432 \u043a\u0443\u0447\u0435, \u0430 \u0437\u0430\u0442\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043f\u0440\u0430\u0432\u043e \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u043d\u0430 \u044d\u0442\u043e\u0442 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0439 \u043a\u0443\u0447\u0435\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0435\u043c\u0443 \u043e\u0431\u044a\u0435\u043a\u0442\u0443.<\/p><\/blockquote>\n<p>  <\/p>\n<pre><code class=\"rust\">\/\/ src\/htab.rs  #[no_mangle] pub unsafe extern &quot;C&quot; fn tvm_htab_create() -&gt; *mut HashTable {     let hashtable = Box::new(HashTable::default());     Box::into_raw(hashtable) }  #[no_mangle] pub unsafe extern &quot;C&quot; fn tvm_htab_destroy(htab: *mut HashTable) {     if htab.is_null() {         \/\/ nothing to free         return;     }      let hashtable = Box::from_raw(htab);     \/\/ explicitly destroy the hashtable     drop(hashtable); }<\/code><\/pre>\n<p>  <\/p>\n<blockquote><p><b>\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435<\/b><br \/>  \u0412\u0430\u0436\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u0435 \u0430\u0431\u043e\u043d\u0435\u043d\u0442\u044b \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0430\u043b\u0438 <code>HashTable<\/code> \u0442\u043e\u043b\u044c\u043a\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>tvm_htab_destroy ()<\/code>!<\/p>\n<p>  \u0415\u0441\u043b\u0438 \u043e\u043d\u0438 \u043d\u0435 \u0441\u0434\u0435\u043b\u0430\u044e\u0442 \u044d\u0442\u043e\u0433\u043e \u0438 \u0432\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u043f\u044b\u0442\u0430\u044e\u0442\u0441\u044f \u0432\u044b\u0437\u0432\u0430\u0442\u044c <code>free()<\/code> \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e, \u0443 \u043d\u0430\u0441 \u043f\u043e\u0447\u0442\u0438 \u043d\u0430\u0432\u0435\u0440\u043d\u044f\u043a\u0430 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0435\u0442 \u043f\u043b\u043e\u0445\u0430\u044f \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f. \u0412 \u043b\u0443\u0447\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u0442 \u043a \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0443\u0442\u0435\u0447\u043a\u0435 \u043f\u0430\u043c\u044f\u0442\u0438, \u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u0432\u043f\u043e\u043b\u043d\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0447\u0442\u043e \u043d\u0430\u0448 <code>Box<\/code> \u0432 Rust \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0442\u0443 \u0436\u0435 \u043a\u0443\u0447\u0443, \u0447\u0442\u043e <code>malloc()<\/code> \u0438 <code>free ()<\/code>, \u0430 \u044d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0435\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 Rust \u043e\u0442 C \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0432\u0440\u0435\u0434\u0438\u0442\u044c \u043a\u0443\u0447\u0443 \u0438 \u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432\u0441\u0451 \u0432 \u0441\u043b\u043e\u043c\u0430\u043d\u043d\u043e\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438.<\/p><\/blockquote>\n<p>  \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u0445\u044d\u0448-\u043a\u0430\u0440\u0442\u0443 \u043f\u043e\u0447\u0442\u0438 \u0442\u0430\u043a \u0436\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c.<\/p>\n<pre><code class=\"rust\">\/\/ src\/hmap.rs  #[derive(Debug, Clone, PartialEq)] pub(crate) struct Item {     \/\/\/ An integer value.     value: c_int,     \/\/\/ An opaque value used with [`tvm_htab_add_ref()`].     \/\/\/     \/\/\/ # Safety     \/\/\/     \/\/\/ Storing the contents of a `void *` in a `Vec&lt;u8&gt;` *would* normally     \/\/\/ result in alignment issues, but we've got access to the `libtvm` source     \/\/\/ code and know it will only ever store `char *` strings.     opaque_value: Vec&lt;u8&gt;, }  impl Item {     pub(crate) fn integer(value: c_int) -&gt; Item {         Item {             value,             opaque_value: Vec::new(),         }     }      pub(crate) fn opaque&lt;V&gt;(opaque_value: V) -&gt; Item     where         V: Into&lt;Vec&lt;u8&gt;&gt;,     {         Item {             value: 0,             opaque_value: opaque_value.into(),         }     }      pub(crate) fn from_void(pointer: *mut c_void, length: c_int) -&gt; Item {         \/\/ we need to create an owned copy of the value         let opaque_value = if pointer.is_null() {             Vec::new()         } else {             unsafe {                 std::slice::from_raw_parts(pointer as *mut u8, length as usize)                     .to_owned()             }         };          Item::opaque(opaque_value)     } }  #[no_mangle] pub unsafe extern &quot;C&quot; fn tvm_htab_add(     htab: *mut HashTable,     key: *const c_char,     value: c_int, ) -&gt; c_int {     let hashtable = &amp;mut *htab;     let key = CStr::from_ptr(key).to_owned();      hashtable.0.insert(key, Item::integer(value));      \/\/ the only time insertion can fail is if allocation fails. In that case     \/\/ we'll abort the process anyway, so if this function returns we can     \/\/ assume it was successful (0 = success).     0 }  #[no_mangle] pub unsafe extern &quot;C&quot; fn tvm_htab_add_ref(     htab: *mut HashTable,     key: *const c_char,     value_ptr: *mut c_void,     length: c_int, ) -&gt; c_int {     let hashtable = &amp;mut *htab;     let key = CStr::from_ptr(key).to_owned();      hashtable.0.insert(key, Item::from_void(value_ptr, length));      0 }<\/code><\/pre>\n<p>  <\/p>\n<blockquote><p><b>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435<\/b><br \/>  \u0412\u0430\u0436\u043d\u043e \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u043c\u044b \u0437\u0434\u0435\u0441\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <code>CString<\/code>, \u0430 \u043d\u0435 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 <code>String<\/code>, \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043a\u043b\u044e\u0447\u0430 \u0445\u044d\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u044b, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e <code>*const c_char<\/code> \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043b\u044e\u0431\u044b\u0435 \u043d\u0435\u043d\u0443\u043b\u0435\u0432\u044b\u0435 \u0431\u0430\u0439\u0442\u044b, \u0442\u043e\u0433\u0434\u0430 \u043a\u0430\u043a <code>String<\/code> \u0432 Rust \u0442\u0440\u0435\u0431\u0443\u0435\u0442, \u0447\u0442\u043e\u0431\u044b \u0441\u0442\u0440\u043e\u043a\u0430 \u0431\u044b\u043b\u0430 \u0432\u0430\u043b\u0438\u0434\u043d\u043e\u0439 UTF-8.<\/p>\n<p>  \u0412\u0435\u0440\u043e\u044f\u0442\u043d\u043e, \u043d\u0430\u043c \u0441\u043e\u0439\u0434\u0435\u0442 \u0441 \u0440\u0443\u043a \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 <code>CStr<\/code> \u0432 <code>&amp;str<\/code>, \u0430 \u0437\u0430\u0442\u0435\u043c \u0432 <code>String<\/code> \u0441 \u0432\u043b\u0430\u0434\u0435\u043d\u0438\u0435\u043c, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0431\u0443\u0434\u0443\u0442 ASCII, \u043d\u043e \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044f, \u0447\u0442\u043e \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u043e\u0434\u0438\u043d \u0438\u043b\u0438 \u0434\u0432\u0430 <code>unwrap()<\/code>, \u043f\u0440\u043e\u0449\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432\u0441\u0451 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c <code>CString<\/code>.<\/p><\/blockquote>\n<p>  \u0414\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>*_find()<\/code> \u043c\u043e\u0436\u043d\u043e \u0434\u0435\u043b\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u044f\u043c\u043e \u0432\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 <code>HashMap&lt;CString, Item&gt;<\/code>.<\/p>\n<p>  \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435, \u0433\u0434\u0435 \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u043e\u0441\u0442\u043e\u0440\u043e\u0436\u043d\u044b\u043c, \u2014 \u044d\u0442\u043e \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0430\u0439\u0434\u0435\u043d. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0432 \u043d\u0430 <code>tvm_htab.c<\/code> \u043c\u044b \u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e <code>tvm_htab_find()<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>\u22121<\/code>, \u0430 <code>tvm_htab_find_ref()<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>NULL<\/code>.<\/p>\n<pre><code class=\"rust\">\/\/ src\/hmap.rs  #[no_mangle] pub unsafe extern &quot;C&quot; fn tvm_htab_find(     htab: *mut HashTable,     key: *const c_char, ) -&gt; c_int {     let hashtable = &amp;mut *htab;     let key = CStr::from_ptr(key);      match hashtable.get(key) {         Some(item) =&gt; item.value,         None =&gt; -1,     } }  #[no_mangle] pub unsafe extern &quot;C&quot; fn tvm_htab_find_ref(     htab: *mut HashTable,     key: *const c_char, ) -&gt; *mut c_char {     let hashtable = &amp;mut *htab;     let key = CStr::from_ptr(key);      match hashtable.0.get(key) {         Some(item) =&gt; item.value_ptr as *mut c_char,         None =&gt; ptr::null_mut(),     } }<\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0437\u0430\u0433\u043b\u0443\u0448\u043a\u0438, \u0432\u0441\u0451 \u0434\u043e\u043b\u0436\u043d\u043e \u0441\u043d\u043e\u0432\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c.<\/p>\n<p>  \u0421\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u044d\u0442\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u2014 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043d\u0430\u0448 \u043f\u0440\u0438\u043c\u0435\u0440.<\/p>\n<pre><code class=\"bash\">cargo run --example tvmi -- vendor\/tinyvm\/programs\/tinyvm\/fact.vm     Finished dev [unoptimized + debuginfo] target(s) in 0.02s      Running `target\/debug\/examples\/tvmi vendor\/tinyvm\/programs\/tinyvm\/fact.vm` 1 2 6 24 120 720 5040 40320 362880 3628800<\/code><\/pre>\n<p>  \u0418 \u0447\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0435\u0433\u043e \u0447\u0435\u0440\u0435\u0437 <code>valgrind<\/code>, \u0447\u0442\u043e\u0431\u044b \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u043d\u0435\u0442 \u0443\u0442\u0435\u0447\u0435\u043a \u043f\u0430\u043c\u044f\u0442\u0438 \u0438\u043b\u0438 \u0447\u0435\u0433\u043e-\u0442\u043e \u0445\u0438\u0442\u0440\u043e\u0433\u043e \u0441 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f\u043c\u0438.<\/p>\n<pre><code class=\"bash\">$ valgrind target\/debug\/examples\/tvmi vendor\/tinyvm\/programs\/tinyvm\/fact.vm ==1492== Memcheck, a memory error detector ==1492== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==1492== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info ==1492== Command: target\/debug\/examples\/tvmi vendor\/tinyvm\/programs\/tinyvm\/fact.vm ==1492== 1 2 6 24 120 720 5040 40320 362880 3628800 ==1492== ==1492== HEAP SUMMARY: ==1492==     in use at exit: 0 bytes in 0 blocks ==1492==   total heap usage: 270 allocs, 270 frees, 67,129,392 bytes allocated ==1492== ==1492== All heap blocks were freed -- no leaks are possible ==1492== ==1492== For lists of detected and suppressed errors, rerun with: -s ==1492== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)<\/code><\/pre>\n<p>  \u0423\u0441\u043f\u0435\u0445!<\/p>\n<h1>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445<\/h1>\n<p>  \u0412\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0430\u044f \u043c\u0430\u0448\u0438\u043d\u0430 <code>tinyvm<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 <a href=\"https:\/\/github.com\/jakogut\/tinyvm\/blob\/10c25d83e442caf0c1fc4b0ab29a91b3805d72ec\/SYNTAX\" rel=\"nofollow\">\u0443\u043f\u0440\u043e\u0449\u0451\u043d\u043d\u0443\u044e \u0444\u043e\u0440\u043c\u0443 \u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u0430<\/a>, \u043f\u043e\u0445\u043e\u0436\u0443\u044e \u043d\u0430 \u0442\u0440\u0430\u0434\u0438\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440 Intel x86. \u041f\u0435\u0440\u0432\u044b\u043c \u0448\u0430\u0433\u043e\u043c \u043f\u0440\u0438 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0435 \u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u0430 tinyvm \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u043f\u0443\u0441\u043a \u043f\u0440\u0435\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u0443\u0435\u0442 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b <code>%include filename<\/code> \u0438 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b <code>%define identifier value<\/code>.<\/p>\n<p>  \u0422\u0430\u043a\u043e\u0433\u043e \u0440\u043e\u0434\u0430 \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0438 \u0441 \u0442\u0435\u043a\u0441\u0442\u043e\u043c \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0449\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0442\u0438\u043f\u043e\u0432 <code>&amp;str<\/code> \u0432 Rust, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u043b\u0436\u0435\u043d \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0448 \u043a\u0440\u0435\u0439\u0442.<\/p>\n<pre><code class=\"cpp\">\/\/ vendor\/tinyvm\/include\/tvm\/tvm_preprocessor.h  #ifndef TVM_PREPROCESSOR_H_ #define TVM_PREPROCESSOR_H_  #include &quot;tvm_htab.h&quot;  int tvm_preprocess(char **src, int *src_len, struct tvm_htab_ctx *defines);  #endif<\/code><\/pre>\n<p>  \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 <code>char **<\/code> \u0438 <code>int *<\/code> \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 <code>src<\/code> \u0438 <code>src_len<\/code> \u043f\u043e\u043d\u0430\u0447\u0430\u043b\u0443 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0441\u0442\u0440\u0430\u043d\u043d\u044b\u043c, \u043d\u043e \u0435\u0441\u043b\u0438 \u0431\u044b \u0432\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 \u044d\u043a\u0432\u0438\u0432\u0430\u043b\u0435\u043d\u0442 \u0432 Rust, \u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0431\u044b \u0447\u0442\u043e-\u0442\u043e \u0432\u0440\u043e\u0434\u0435 \u044d\u0442\u043e\u0433\u043e:<\/p>\n<pre><code class=\"rust\">fn tvm_preprocess(     src: String,     defines: &amp;mut HashTable, ) -&gt; Result&lt;String, PreprocessorError&gt; {     ... }<\/code><\/pre>\n<p>  \u041a\u043e\u0434 C \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0434\u043b\u044f \u0437\u0430\u043c\u0435\u043d\u044b \u0441\u0442\u0440\u043e\u043a\u0438 <code>src<\/code> \u043d\u0430 \u043c\u0435\u0441\u0442\u0435, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043e\u043d \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u043a\u0430\u043a \u043d\u043e\u0432\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443, \u0442\u0430\u043a \u0438 \u043a\u043e\u0434 \u043e\u0448\u0438\u0431\u043a\u0438.<\/p>\n<p>  \u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u0435\u0449\u0451, \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0435\u0441\u0442 \u0434\u043b\u044f <code>tvm_preprocess()<\/code>. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0447\u0442\u043e \u043d\u0430\u0448\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f Rust \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e \u044d\u043a\u0432\u0438\u0432\u0430\u043b\u0435\u043d\u0442\u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u0443.<\/p>\n<p>  \u041c\u044b \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u0435\u043c \u0441 \u0444\u0430\u0439\u043b\u043e\u0432\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0442\u0430\u0449\u0438\u0442\u044c <a href=\"https:\/\/crates.io\/crates\/tempfile\" rel=\"nofollow\">\u043a\u0440\u0435\u0439\u0442 tempfile<\/a>.<\/p>\n<pre><code class=\"bash\">$ cargo add --dev tempfile     Updating 'https:\/\/github.com\/rust-lang\/crates.io-index' index       Adding tempfile v3.1.0 to dev-dependencies<\/code><\/pre>\n<p>  \u041d\u0430\u043c \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u043a\u0440\u0435\u0439\u0442 <code>libc<\/code>, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0438 <code>libtvm<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0435\u043c\u0443, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043e\u0441\u0432\u043e\u0431\u043e\u0434\u0438\u0442\u044c.<\/p>\n<pre><code class=\"rust\">cargo add libc     Updating 'https:\/\/github.com\/rust-lang\/crates.io-index' index       Adding libc v0.2.66 to dev-dependencies<\/code><\/pre>\n<p>  \u0413\u043b\u044f\u0434\u044f \u043d\u0430 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434, \u043c\u044b \u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>tvm_preprocess()<\/code> \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0442\u044c \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u0442\u044c <code>%include<\/code> \u0438 <code>%define<\/code> \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u0438\u0445 \u043d\u0435 \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f \u043d\u0438 \u043e\u0434\u043d\u043e\u0433\u043e.<\/p>\n<p>  \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0442\u0435\u0441\u0442, \u0447\u0442\u043e\u0431\u044b \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u043f\u0440\u0435\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 <code>%define<\/code>. \u041c\u044b \u0437\u043d\u0430\u0435\u043c, \u0447\u0442\u043e \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 \u0443\u0436\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 (\u0432 \u043a\u043e\u043d\u0446\u0435 \u043a\u043e\u043d\u0446\u043e\u0432, \u044d\u0442\u043e \u043a\u043e\u0434 \u043e\u0442 <code>tinyvm<\/code>), \u0442\u0430\u043a \u0447\u0442\u043e \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0441\u044e\u0440\u043f\u0440\u0438\u0437\u043e\u0432 \u0431\u044b\u0442\u044c \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u043e.<\/p>\n<pre><code class=\"rust\">\/\/ src\/preprocessing.rs  #[cfg(test)] mod tests {     use crate::ffi;     use std::{         ffi::{CStr, CString},         io::Write,         os::raw::c_int,     };      #[test]     fn find_all_defines() {         let src = &quot;%define true 1\\nsome random text\\n%define FOO_BAR -42\\n&quot;;         let original_length = src.len();         let src = CString::new(src).unwrap();          unsafe {             \/\/ get a copy of `src` that was allocated using C's malloc             let mut src = libc::strdup(src.as_ptr());             let mut len = original_length as c_int;             let defines = ffi::tvm_htab_create();              let ret = ffi::tvm_preprocess(&amp;mut src, &amp;mut len, defines);              \/\/ preprocessing should have been successful             assert_eq!(ret, 0);              \/\/ make sure the define lines were removed             let preprocessed = CStr::from_ptr(src).to_bytes();             let preprocessed =                 std::str::from_utf8(&amp;preprocessed[..len as usize]).unwrap();             assert_eq!(preprocessed, &quot;\\nsome random text\\n\\n&quot;);              \/\/ make sure the &quot;true&quot; and &quot;FOO_BAR&quot; defines were set             let true_define =                 ffi::tvm_htab_find_ref(defines, b&quot;true\\0&quot;.as_ptr().cast());             let got = CStr::from_ptr(true_define).to_str().unwrap();             assert_eq!(got, &quot;1&quot;);             let foo_bar =                 ffi::tvm_htab_find_ref(defines, b&quot;FOO_BAR\\0&quot;.as_ptr().cast());             let got = CStr::from_ptr(foo_bar).to_str().unwrap();             assert_eq!(got, &quot;-42&quot;);              \/\/ clean up our hashtable and copied source text             ffi::tvm_htab_destroy(defines);             libc::free(src.cast());         }     } }<\/code><\/pre>\n<p>  45 \u0441\u0442\u0440\u043e\u043a \u044d\u0442\u043e \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u0431\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c \u043c\u043d\u0435 \u043e\u0431\u044b\u0447\u043d\u043e \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f \u0432 \u0442\u0435\u0441\u0442\u0430\u0445, \u043d\u043e \u0434\u043b\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u0443\u0434\u0430 \u0438 \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u043c\u0435\u0436\u0434\u0443 \u0441\u0442\u0440\u043e\u043a\u0430\u043c\u0438 C \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0438\u0437\u0440\u044f\u0434\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430.<\/p>\n<p>  \u041d\u0430\u043c \u0442\u0430\u043a\u0436\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u0435\u0449\u0451 \u043e\u0434\u0438\u043d \u0444\u0430\u0439\u043b.<\/p>\n<pre><code class=\"rust\">\/\/ src\/preprocessing.rs  #[cfg(test)] mod tests {     ...      #[test]     fn include_another_file() {         const TOP_LEVEL: &amp;str = &quot;first line\\n%include nested\\nlast line\\n&quot;;         const NESTED: &amp;str = &quot;nested\\n&quot;;          \/\/ the preprocessor imports files from the filesystem, so we need to         \/\/ copy NESTED to a temporary location         let mut nested = NamedTempFile::new().unwrap();         nested.write_all(NESTED.as_bytes()).unwrap();         let nested_filename = nested.path().display().to_string();          \/\/ substitute the full path to the &quot;nested&quot; file         let top_level_src = TOP_LEVEL.replace(&quot;nested&quot;, &amp;nested_filename);         std::fs::write(&amp;nested, NESTED).unwrap();          unsafe {             let top_level_src = CString::new(top_level_src).unwrap();             \/\/ create a copy of the top_level_src which can be freed by C             let mut src = libc::strdup(top_level_src.as_ptr());             let mut len = libc::strlen(src) as c_int;             let defines = ffi::tvm_htab_create();              \/\/ after all that setup code we can *finally* call the preprocessor             let ret = ffi::tvm_preprocess(&amp;mut src, &amp;mut len, defines);              assert_eq!(ret, 0);              \/\/ make sure the define and import lines were removed             let preprocessed = CStr::from_ptr(src).to_bytes();             let got =                 std::str::from_utf8(&amp;preprocessed[..len as usize]).unwrap();              \/\/ after preprocessing, all include and define lines should have             \/\/ been removed             assert_eq!(got, &quot;first line\\nnested\\nlast line\\n&quot;);              ffi::tvm_htab_destroy(defines);             libc::free(src.cast());         }     }<\/code><\/pre>\n<p>  <\/p>\n<blockquote><p><b>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435<\/b><br \/>  \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u044f, \u0442\u0435\u0441\u0442 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u0431\u044b\u043b \u043d\u0430\u043f\u0438\u0441\u0430\u043d \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u0432\u043b\u043e\u0436\u0438\u0442\u044c \u0432\u0441\u0451 \u0432 \u0442\u0440\u0438 \u0441\u043b\u043e\u044f \u0433\u043b\u0443\u0431\u0438\u043d\u043e\u0439 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>top_level.vm<\/code> \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f nested.vm, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f really_nested.vm), \u0447\u0442\u043e\u0431\u044b \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u043e\u043d \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0431\u043e\u043b\u0435\u0435 \u043e\u0434\u043d\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f <code>%include<\/code>, \u043d\u043e \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043e\u043d \u0431\u044b\u043b \u043d\u0430\u043f\u0438\u0441\u0430\u043d, \u0442\u0435\u0441\u0442 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u043b \u0441\u0435\u0433\u0444\u043e\u043b\u0442\u0438\u0442\u044c.<\/p>\n<p>  \u0417\u0430\u0442\u0435\u043c \u044f \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u043b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0439 \u0444\u0430\u0439\u043b C <code>tvmi<\/code>\u2026<\/p>\n<pre><code class=\"bash\">$ cd vendor\/tinyvm\/ $ cat top_level.vm   %include nested $ cat nested.vm   %include really_nested $ cat really_nested.vm   Hello World $ .\/bin\/tvmi top_level.vm   [1]    10607 segmentation fault (core dumped)  .\/bin\/tvmi top_level.vm<\/code><\/pre>\n<p>  \u041e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 tinyvm \u043f\u043e \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0435 \u043f\u0430\u0434\u0430\u0435\u0442, \u043a\u043e\u0433\u0434\u0430 \u0443 \u0432\u0430\u0441 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043b\u043e\u0451\u0432 <code>include<\/code>&#8230;<\/p><\/blockquote>\n<p>  \u0418\u0442\u0430\u043a, \u0442\u0435\u043f\u0435\u0440\u044c \u0443 \u043d\u0430\u0441 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u0441\u0442\u043e\u0432, \u0442\u0430\u043a \u0447\u0442\u043e \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u0447\u0430\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c <code>tvm_preprocess()<\/code>.<br \/>  \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u043d\u0443\u0436\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0442\u0438\u043f \u043e\u0448\u0438\u0431\u043a\u0438.<\/p>\n<pre><code class=\"rust\">\/\/ src\/preprocessing.rs  #[derive(Debug)] pub enum PreprocessingError {     FailedInclude {         name: String,         inner: IoError,     },     DuplicateDefine {         name: String,         original_value: String,         new_value: String,     },     EmptyDefine,     DefineWithoutValue(String), }<\/code><\/pre>\n<p>  \u0413\u043b\u044f\u0434\u044f \u043d\u0430 <a href=\"https:\/\/github.com\/jakogut\/tinyvm\/blob\/10c25d83e442caf0c1fc4b0ab29a91b3805d72ec\/libtvm\/tvm_preprocessor.c\" rel=\"nofollow\">\u0444\u0443\u043d\u043a\u0446\u0438\u0438 process_includes() \u0438 process_derives()<\/a>, \u043a\u0430\u0436\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u043e\u043d\u0438 \u0441\u043a\u0430\u043d\u0438\u0440\u0443\u044e\u0442 \u0441\u0442\u0440\u043e\u043a\u0443 \u0432 \u043f\u043e\u0438\u0441\u043a\u0430\u0445 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u043e\u0439 \u0434\u0438\u0440\u0435\u043a\u0442\u0438\u0432\u044b, \u0430 \u0437\u0430\u0442\u0435\u043c \u0437\u0430\u043c\u0435\u043d\u044f\u044e\u0442 \u044d\u0442\u0443 \u0441\u0442\u0440\u043e\u043a\u0443 \u0447\u0435\u043c-\u0442\u043e \u0434\u0440\u0443\u0433\u0438\u043c (\u043b\u0438\u0431\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u044b\u043c \u0444\u0430\u0439\u043b\u0430, \u043b\u0438\u0431\u043e \u043d\u0438\u0447\u0435\u043c, \u0435\u0441\u043b\u0438 \u0441\u0442\u0440\u043e\u043a\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u0443\u0434\u0430\u043b\u0435\u043d\u0430).<\/p>\n<p>  \u041c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 \u0438\u0437\u0432\u043b\u0435\u0447\u044c \u044d\u0442\u0443 \u043b\u043e\u0433\u0438\u043a\u0443 \u0432 \u0445\u0435\u043b\u043f\u0435\u0440 \u0438 \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043d\u0435\u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0434\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<pre><code class=\"rust\">\/\/ src\/preprocessing.rs  \/\/\/ Scan through the input string looking for a line starting with some \/\/\/ directive, using a callback to figure out what to replace the directive line \/\/\/ with. fn process_line_starting_with_directive&lt;F&gt;(     mut src: String,     directive: &amp;str,     mut replace_line: F, ) -&gt; Result&lt;(String, usize), PreprocessingError&gt; where     F: FnMut(&amp;str) -&gt; Result&lt;String, PreprocessingError&gt;, {     \/\/ try to find the first instance of the directive     let directive_delimiter = match src.find(directive) {         Some(ix) =&gt; ix,         None =&gt; return Ok((src, 0)),     };      \/\/ calculate the span from the directive to the end of the line     let end_ix = src[directive_delimiter..]         .find('\\n')         .map(|ix| ix + directive_delimiter)         .unwrap_or(src.len());      \/\/ the rest of the line after the directive     let directive_line =         src[directive_delimiter + directive.len()..end_ix].trim();      \/\/ use the callback to figure out what we should replace the line with     let replacement = replace_line(directive_line)?;      \/\/ remove the original line     let _ = src.drain(directive_delimiter..end_ix);     \/\/ then insert our replacement     src.insert_str(directive_delimiter, &amp;replacement);      Ok((src, 1)) }<\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0445\u0435\u043b\u043f\u0435\u0440 <code>process_line_starting_with_directive()<\/code>, \u0442\u0430\u043a \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0430\u0440\u0441\u0435\u0440 <code>%include<\/code>.<\/p>\n<pre><code class=\"rust\">\/\/ src\/preprocessing.rs  fn process_includes(     src: String, ) -&gt; Result&lt;(String, usize), PreprocessingError&gt; {     const TOK_INCLUDE: &amp;str = &quot;%include&quot;;      process_line_starting_with_directive(src, TOK_INCLUDE, |line| {         std::fs::read_to_string(line).map_err(|e| {             PreprocessingError::FailedInclude {                 name: line.to_string(),                 inner: e,             }         })     }) }<\/code><\/pre>\n<p>  \u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u043f\u0430\u0440\u0441\u0435\u0440 %define \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0441\u043b\u043e\u0436\u043d\u0435\u0435.<\/p>\n<pre><code class=\"rust\">\/\/ src\/preprocessing.rs  n process_defines(     src: String,     defines: &amp;mut HashTable, ) -&gt; Result&lt;(String, usize), PreprocessingError&gt; {     const TOK_DEFINE: &amp;str = &quot;%define&quot;;      process_line_starting_with_directive(src, TOK_DEFINE, |line| {         parse_define(line, defines)?;         Ok(String::new())     }) }  fn parse_define(     line: &amp;str,     defines: &amp;mut HashTable, ) -&gt; Result&lt;(), PreprocessingError&gt; {     if line.is_empty() {         return Err(PreprocessingError::EmptyDefine);     }      \/\/ The syntax is &quot;%define key value&quot;, so after removing the leading     \/\/ &quot;%define&quot; everything after the next space is the value     let first_space = line.find(' ').ok_or_else(|| {         PreprocessingError::DefineWithoutValue(line.to_string())     })?;      \/\/ split the rest of the line into key and value     let (key, value) = line.split_at(first_space);     let value = value.trim();      match defines.0.entry(         CString::new(key).expect(&quot;The text shouldn't contain null bytes&quot;),     ) {         \/\/ the happy case, this symbol hasn't been defined before so we can just         \/\/ insert it.         Entry::Vacant(vacant) =&gt; {             vacant.insert(Item::opaque(value));         },         \/\/ looks like this key has already been defined, report an error         Entry::Occupied(occupied) =&gt; {             return Err(PreprocessingError::DuplicateDefine {                 name: key.to_string(),                 original_value: occupied                     .get()                     .opaque_value_str()                     .unwrap_or(&quot;&lt;invalid&gt;&quot;)                     .to_string(),                 new_value: value.to_string(),             });         },     }      Ok(()) }<\/code><\/pre>\n<p>  \u0427\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0442\u0435\u043a\u0441\u0442\u0443 \u0432 \u043d\u0430\u0448\u0435\u0439 \u0445\u044d\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0435, \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0434\u0430\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443 <code>Item<\/code> \u043f\u0430\u0440\u0443 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432:<\/p>\n<pre><code class=\"rust\">\/\/ src\/htab.rs  impl Item {     ...      pub(crate) fn opaque_value(&amp;self) -&gt; &amp;[u8] { &amp;self.opaque_value }      pub(crate) fn opaque_value_str(&amp;self) -&gt; Option&lt;&amp;str&gt; {         std::str::from_utf8(self.opaque_value()).ok()     } }<\/code><\/pre>\n<p>  \u041d\u0430 \u044d\u0442\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u043d\u0435\u043f\u043b\u043e\u0445\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0435\u0449\u0451 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u0441\u0442\u043e\u0432.<\/p>\n<pre><code class=\"rust\">\/\/ src\/preprocessing.rs  #[cfg(test)] mod tests {     ...      #[test]     fn empty_string() {         let src = String::from(&quot;&quot;);         let mut hashtable = HashTable::default();          let (got, replacements) = process_defines(src, &amp;mut hashtable).unwrap();          assert!(got.is_empty());         assert_eq!(replacements, 0);         assert!(hashtable.0.is_empty());     }      #[test]     fn false_percent() {         let src = String::from(&quot;this string contains a % symbol&quot;);         let mut hashtable = HashTable::default();          let (got, replacements) =             process_defines(src.clone(), &amp;mut hashtable).unwrap();          assert_eq!(got, src);         assert_eq!(replacements, 0);         assert!(hashtable.0.is_empty());     }      #[test]     fn define_without_key_and_value() {         let src = String::from(&quot;%define\\n&quot;);         let mut hashtable = HashTable::default();          let err = process_defines(src.clone(), &amp;mut hashtable).unwrap_err();          match err {             PreprocessingError::EmptyDefine =&gt; {},             other =&gt; panic!(&quot;Expected EmptyDefine, found {:?}&quot;, other),         }     }      #[test]     fn define_without_value() {         let src = String::from(&quot;%define key\\n&quot;);         let mut hashtable = HashTable::default();          let err = process_defines(src.clone(), &amp;mut hashtable).unwrap_err();          match err {             PreprocessingError::DefineWithoutValue(key) =&gt; {                 assert_eq!(key, &quot;key&quot;)             },             other =&gt; panic!(&quot;Expected DefineWithoutValue, found {:?}&quot;, other),         }     }      #[test]     fn valid_define() {         let src = String::from(&quot;%define key value\\n&quot;);         let mut hashtable = HashTable::default();          let (got, num_defines) = process_defines(src.clone(), &amp;mut hashtable).unwrap();          assert_eq!(got, &quot;\\n&quot;);         assert_eq!(num_defines, 1);         assert_eq!(hashtable.0.len(), 1);         let key = CString::new(&quot;key&quot;).unwrap();         let item = hashtable.0.get(&amp;key).unwrap();         assert_eq!(item.opaque_value_str().unwrap(), &quot;value&quot;);     } }<\/code><\/pre>\n<p>  \u041d\u0430 \u044d\u0442\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u043c\u044b \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u043b\u0438 \u0431\u043e\u043b\u044c\u0448\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0438 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0442\u0430\u043a \u0447\u0442\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0443\u0436\u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0442\u044c \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b <code>%include<\/code> \u0438 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c <code>%define<\/code> \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u0438\u0445 \u043d\u0435 \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f.<\/p>\n<pre><code class=\"rust\">\/\/ src\/preprocessing.rs  pub fn preprocess(     src: String,     defines: &amp;mut HashTable, ) -&gt; Result&lt;String, PreprocessingError&gt; {     let mut src = src;      loop {         let (modified, num_includes) = process_includes(src)?;         let (modified, num_defines) = process_defines(modified, defines)?;          if num_includes + num_defines == 0 {             return Ok(modified);         }          src = modified;     } }<\/code><\/pre>\n<p>  \u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>preprocess()<\/code> \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f Rust. \u041d\u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c <code>extern &quot;C&quot; fn<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u0438\u0437 \u0442\u0438\u043f\u043e\u0432 C \u0432\u043e \u0447\u0442\u043e-\u0442\u043e, \u0441 \u0447\u0435\u043c \u043c\u043e\u0436\u0435\u0442 \u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c\u0441\u044f Rust, \u0430 \u0437\u0430\u0442\u0435\u043c \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442 \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0432 C.<\/p>\n<pre><code class=\"rust\">\/\/ src\/preprocessing.rs  #[no_mangle] pub unsafe extern &quot;C&quot; fn tvm_preprocess(     src: *mut *mut c_char,     src_len: *mut c_int,     defines: *mut tvm_htab_ctx, ) -&gt; c_int {     if src.is_null() || src_len.is_null() || defines.is_null() {         return -1;     }      \/\/ Safety: This assumes the tvm_htab_ctx is actually our ported HashTable     let defines = &amp;mut *(defines as *mut HashTable);      \/\/ convert the input string to an owned Rust string so it can be     \/\/ preprocessed     let rust_src = match CStr::from_ptr(*src).to_str() {         Ok(s) =&gt; s.to_string(),         \/\/ just error out if it's not valid UTF-8         Err(_) =&gt; return -1,     };      match preprocess(rust_src, defines) {         Ok(s) =&gt; {             let preprocessed = CString::new(s).unwrap();             \/\/ create a copy of the preprocessed string that can be free'd by C             \/\/ and use the output arguments to pass it to the caller             *src = libc::strdup(preprocessed.as_ptr());             \/\/ the original C implementation didn't add a null terminator to the             \/\/ preprocessed string, so we're required to set the length as well.             *src_len = libc::strlen(*src) as c_int;              \/\/ returning 0 indicates success             0         },         \/\/ tell the caller &quot;an error occurred&quot;         Err(_) =&gt; -1,     } }<\/code><\/pre>\n<p>  <\/p>\n<blockquote><p><b>\u0421\u043e\u0432\u0435\u0442<\/b><br \/>  \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0432\u044b \u0437\u0430\u043c\u0435\u0442\u0438\u043b\u0438, \u0447\u0442\u043e \u043d\u0430\u0448\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f tvm_preprocess() \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043d\u0438\u043a\u0430\u043a\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0438 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u043e\u0445\u043e\u0436\u0430 \u043d\u0430 \u0430\u0434\u0430\u043f\u0442\u0435\u0440 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0434\u043b\u044f \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043e\u0448\u0438\u0431\u043e\u043a.<\/p>\n<p>  \u042d\u0442\u043e \u043d\u0435 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e\u0441\u0442\u044c.<\/p>\n<p>  \u0421\u0435\u043a\u0440\u0435\u0442 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f FFI \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u043f\u0438\u0441\u0430\u0442\u044c \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043c\u0435\u043d\u044c\u0448\u0435 \u0438 \u0438\u0437\u0431\u0435\u0433\u0430\u0442\u044c <i>\u00ab\u0443\u043c\u043d\u044b\u0445\u00bb<\/i> \u0442\u0440\u044e\u043a\u043e\u0432. \u0412 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 \u0431\u043e\u043b\u044c\u0448\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u043a\u043e\u0434\u0430 Rust, \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u0442\u0430\u043a\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u0445 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043c\u043e\u0433\u0443\u0442 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a \u043e\u0448\u0438\u0431\u043a\u0430\u043c \u0432 \u043b\u043e\u0433\u0438\u043a\u0435 \u0438 \u043f\u0430\u043c\u044f\u0442\u0438.<\/p>\n<p>  \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0442\u043e\u043d\u043a\u043e\u0439 \u043e\u0431\u043e\u043b\u043e\u0447\u043a\u0438 \u0432\u043e\u043a\u0440\u0443\u0433 \u043d\u0430\u0448\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>preprocess()<\/code> \u0442\u0430\u043a\u0436\u0435 \u043e\u0431\u043b\u0435\u0433\u0447\u0430\u0435\u0442 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443: \u043a\u043e\u0433\u0434\u0430 \u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043a\u043e\u0434\u043e\u0432\u043e\u0439 \u0431\u0430\u0437\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0430 \u043d\u0430 Rust, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u043e\u0431\u043e\u043b\u043e\u0447\u043a\u0443 \u0438 \u0432\u044b\u0437\u0432\u0430\u0442\u044c <code>preprocess()<\/code> \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e.<\/p><\/blockquote>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>tvm_preprocess()<\/code> \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0430, \u0438 \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b \u043a \u0440\u0430\u0431\u043e\u0442\u0435.<\/p>\n<pre><code class=\"bash\"> Compiling tinyvm v0.1.0 (\/home\/michael\/Documents\/tinyvm-rs) error: linking with `\/usr\/bin\/clang` failed: exit code: 1   |   = note: &quot;\/usr\/bin\/clang&quot; &quot;-Wl,--as-needed&quot; &quot;-Wl,-z,noexecstack&quot; &quot;-m64&quot; &quot;-L&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.13h6j6k0dzqf6zi2.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.13l2b4uvr7p3ht4k.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.14bdbjhozo3id49g.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.14fw2gyd6mrq5730.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.19xc7n0bb25uaxgk.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.1duzy573vjvyihco.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.1e0yejy24qufh7ie.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.1k4xuir9ezt4vkzp.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.1mqdnrarww1zjlt.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.1ubflbxzxkx7grpn.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.1vtvcpzzusyku3mk.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.1wal3ebwyfg4qllf.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.235k75fk09i43ba3.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.253rt7mnjcp3n8ex.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.27phuscrye2lmkyq.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.2bwv51h7gucjizh0.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.2ghuai4hs88aroml.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.2gqnd9h4nmhvgxbn.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.2hjvtf620gtog0qz.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.2hq7kc2w3vix8i5q.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.2ibwag4iedx494ft.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.2jdt9fes53g5mxlp.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.2kv4bwega1wfr8z6.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.2lja418hz58xlryz.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.2o0foimqe73p8ujt.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.2ouuhyii88vg8tqs.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.2tnynvvdxge4sv9a.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.2u1hzhj3v0d8kn4s.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.2v1ii2legejcp3ir.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.2vkkoofkb7zs04v1.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.2w5mgql1gpr1f9uz.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.2wdyioq7lxh9uxu7.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.2wokgurbjsmgz12r.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.2wwcrmvusj07mx2n.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.310mxv7piqfbf4tr.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.3352aele91geo33m.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.36f4wrjtv0x5y00b.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.38f6o2m900r5q63j.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.3b67z5wg30f9te4l.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.3gyajmii4500y81t.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.3ovwslgcz03sp0ov.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.3vwhwp967j90qfpp.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.41ox17npnikcezii.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.4472ut4qn508rg19.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.4bbcvjauqmyr7tjc.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.4c9lrc1xbvaru030.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.4fzwdkjhjtwv5uik.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.4gy2dy14zw2o60sh.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.4i8qxpi0pmwn8d2e.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.4isstj7ytb9d9yep.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.4isz4o5d1flv8pme.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.4lnnaom9zd4u3xmv.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.4mgvbbhn4jewmy60.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.4q7wf9d53jp9j6y6.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.4qimnegzmsif2zbr.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.4scm7492lh4yspgt.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.4ten9b8okg10ap4i.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.4vrj7dhlet4j6oe.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.4wtf4i2ggbrvqt63.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.4zsqxnhj8yusiplh.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.50o8i1bmvqwd5eg7.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.50urmck1r52hucuw.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.51w3uc6agh3gynn3.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.55o6ad6nlq4o2zyt.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.57gih8p2bu1jbo0l.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.57rpuf5wpgkfmf1z.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.5920w55mlosqy9aj.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.5c1ra5cheein740g.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.5cuuq0m7tzehyrti.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.5e85z18y46lhofte.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.6yu7c01lw47met2.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.cn69np51jgriev2.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.d224rq9cs4mbv0q.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.e0vaqgnhc25c4ox.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.edm0ce3nfzegp4d.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.elxjhifv4wlzkc2.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.ifqyaukx6gnbb0a.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.kr8s9rcy6ux2d02.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.ley637x8c2etn66.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.njyqsm0frvb1j4d.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.r9ttxk3s5kacz9k.rcgu.o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.xrorvssabbgfjqz.rcgu.o&quot; &quot;-o&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.1iplfu0pt8fy07e4.rcgu.o&quot; &quot;-Wl,--gc-sections&quot; &quot;-pie&quot; &quot;-Wl,-zrelro&quot; &quot;-Wl,-znow&quot; &quot;-nodefaultlibs&quot; &quot;-L&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps&quot; &quot;-L&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/build\/tinyvm-3f1a2766f78b5580\/out&quot; &quot;-L&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib&quot; &quot;-Wl,-Bstatic&quot; &quot;-Wl,--whole-archive&quot; &quot;-ltvm&quot; &quot;-Wl,--no-whole-archive&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/libtest-a39a3e9a77b17f55.rlib&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/libterm-97a69cd310ff0925.rlib&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/libgetopts-66a42b1d94e3e6f9.rlib&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/libunicode_width-dd7761d848144e0d.rlib&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/librustc_std_workspace_std-f722acdb78755ba0.rlib&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/libtempfile-b08849d192e5c2e1.rlib&quot;  &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/librand-c85ceffb304c7385.rlib&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/librand_chacha-4e4839e3036afe89.rlib&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/libc2_chacha-7555b62a53de8bdf.rlib&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/libppv_lite86-0097c0f425957d6e.rlib&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/librand_core-de2208c863d15e9b.rlib&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/libgetrandom-c696cd809d660e17.rlib&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/liblibc-d52d0b97a33a5f02.rlib&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/libremove_dir_all-4035fb46dbd6fb92.rlib&quot; &quot;\/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/libcfg_if-6adeb646d05b676c.rlib&quot; &quot;-Wl,--start-group&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/libstd-974c3c08f6def4b3.rlib&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/libpanic_unwind-eb49676f33a2c8a6.rlib&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/libhashbrown-7ae0446feecc60f2.rlib&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/librustc_std_workspace_alloc-2de299b65d7f5721.rlib&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/libbacktrace-64514775bc06309a.rlib&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/libbacktrace_sys-1ed8aa185c63b9a5.rlib&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/librustc_demangle-a839df87f563fba5.rlib&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/libunwind-8e726bdc2018d836.rlib&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/libcfg_if-5285f42cbadf207d.rlib&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/liblibc-b0362d20f8aa58fa.rlib&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/liballoc-f3dd7051708453a4.rlib&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/librustc_std_workspace_core-83744846c43307ce.rlib&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/libcore-d5565a3a0f4cfe21.rlib&quot; &quot;-Wl,--end-group&quot; &quot;\/home\/michael\/.rustup\/toolchains\/nightly-x86_64-unknown-linux-gnu\/lib\/rustlib\/x86_64-unknown-linux-gnu\/lib\/libcompiler_builtins-ea790e85415e3bbf.rlib&quot; &quot;-Wl,-Bdynamic&quot; &quot;-lutil&quot; &quot;-lutil&quot; &quot;-ldl&quot; &quot;-lrt&quot; &quot;-lpthread&quot; &quot;-lgcc_s&quot; &quot;-lc&quot; &quot;-lm&quot; &quot;-lrt&quot; &quot;-lpthread&quot; &quot;-lutil&quot; &quot;-lutil&quot; &quot;-fuse-ld=lld&quot;   = note: ld.lld: error: duplicate symbol: tvm_preprocess           &gt;&gt;&gt; defined at preprocessing.rs:13 (src\/preprocessing.rs:13)           &gt;&gt;&gt;            \/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/deps\/tinyvm-8eca24ff9a1cde88.4mgvbbhn4jewmy60.rcgu.o:(tvm_preprocess)           &gt;&gt;&gt; defined at tvm_preprocessor.c:135 (vendor\/tinyvm\/libtvm\/tvm_preprocessor.c:135)           &gt;&gt;&gt;            tvm_preprocessor.o:(.text.tvm_preprocess+0x0) in archive \/home\/michael\/Documents\/tinyvm-rs\/target\/debug\/build\/tinyvm-3f1a2766f78b5580\/out\/libtvm.a           clang: error: linker command failed with exit code 1 (use -v to see invocation)   error: aborting due to previous error  error: could not compile `tinyvm`.  To learn more, run the command again with --verbose.<\/code><\/pre>\n<p>  \u041e\u0439, \u043b\u0438\u043d\u043a\u0435\u0440 \u0436\u0430\u043b\u0443\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0438 <code>preprocessing.rs<\/code>, \u0438 <code>tvm_preprocessor.c<\/code> \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>tvm_preprocess()<\/code>. \u041f\u043e\u0445\u043e\u0436\u0435, \u043c\u044b \u0437\u0430\u0431\u044b\u043b\u0438 \u0443\u0434\u0430\u043b\u0438\u0442\u044c <code>tvm_preprocessor.c<\/code> \u0438\u0437 \u0441\u0431\u043e\u0440\u043a\u0438\u2026<\/p>\n<pre><code class=\"rust\">diff --git a\/build.rs b\/build.rs index 0ed012c..42b8fa0 100644 --- a\/build.rs +++ b\/build.rs @@ -14,6 +14,7 @@ fn main() {          .file(src.join(&quot;tvm_memory.c&quot;))          .file(src.join(&quot;tvm_parser.c&quot;))          .file(src.join(&quot;tvm_program.c&quot;)) -        .file(src.join(&quot;tvm_preprocessor.c&quot;))          .file(src.join(&quot;tvm.c&quot;))          .include(&amp;include)          .compile(&quot;tvm&quot;); (END)<\/code><\/pre>\n<p>  \u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0435\u0449\u0451 \u0440\u0430\u0437.<\/p>\n<pre><code class=\"bash\">cargo run --example tvmi -- vendor\/tinyvm\/programs\/tinyvm\/fact.vm     Finished dev [unoptimized + debuginfo] target(s) in 0.02s      Running `target\/debug\/examples\/tvmi vendor\/tinyvm\/programs\/tinyvm\/fact.vm` 1 2 6 24 120 720 5040 40320 362880 3628800<\/code><\/pre>\n<p>  \u0413\u043e\u0440\u0430\u0437\u0434\u043e \u043b\u0443\u0447\u0448\u0435!<\/p>\n<p>  \u041f\u043e\u043c\u043d\u0438\u0442\u0435 \u0442\u043e\u0442 \u043f\u0440\u043e\u0448\u043b\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440, \u0433\u0434\u0435 <code>tvmi<\/code> \u043f\u0430\u0434\u0430\u043b, \u043f\u043e\u043b\u0443\u0447\u0430\u044f \u0442\u0440\u0438 \u0443\u0440\u043e\u0432\u043d\u044f \u0433\u043b\u0443\u0431\u0438\u043d\u044b \u043a\u043e\u0434\u0430? \u041a\u0430\u043a \u043f\u0440\u0438\u044f\u0442\u043d\u044b\u0439 \u043f\u043e\u0431\u043e\u0447\u043d\u044b\u0439 \u044d\u0444\u0444\u0435\u043a\u0442, \u043f\u043e\u0441\u043b\u0435 \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0430 \u043a\u043e\u0434\u0430 \u043d\u0430 Rust \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u0443\u0440\u043e\u0432\u043d\u0438 <i>\u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442<\/i>.<\/p>\n<blockquote><p><b>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435<\/b><br \/>  \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0432\u044b \u0442\u0430\u043a\u0436\u0435 \u0437\u0430\u043c\u0435\u0442\u0438\u043b\u0438, \u0447\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>preprocess()<\/code> \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043d\u0438 \u043e\u0434\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0445\u044d\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0438\u0437 <code>tvm_htab.h<\/code>. \u041f\u043e\u0441\u043b\u0435 \u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u043e\u0434\u0443\u043b\u044f \u043d\u0430 Rust \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0442\u0438\u043f\u044b Rust \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e.<\/p>\n<p>  \u0412 \u044d\u0442\u043e\u043c \u0432\u0441\u044f \u043f\u0440\u0435\u043b\u0435\u0441\u0442\u044c \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430. \u041a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u044b \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u043b\u0438 \u0447\u0442\u043e-\u0442\u043e \u043d\u0430 Rust, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u044d\u0442\u043e, \u0447\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0438\u043f\u044b\/\u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u00a0\u2014 \u0438 \u043c\u0433\u043d\u043e\u0432\u0435\u043d\u043d\u043e \u0432\u044b\u0438\u0433\u0440\u0430\u0442\u044c \u0432 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043e\u0448\u0438\u0431\u043e\u043a \u0438 \u044d\u0440\u0433\u043e\u043d\u043e\u043c\u0438\u043a\u0435.<\/p><\/blockquote>\n<p>  <\/p>\n<h1>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h1>\n<p>  \u0415\u0441\u043b\u0438 \u0432\u044b \u0432\u0441\u0435 \u0435\u0449\u0435 \u0447\u0438\u0442\u0430\u0435\u0442\u0435 \u0441\u0442\u0430\u0442\u044c\u044e, \u043f\u043e\u0437\u0434\u0440\u0430\u0432\u043b\u044f\u044e, \u043c\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u043e \u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u0434\u0432\u0430 \u043c\u043e\u0434\u0443\u043b\u044f \u0441 <code>tinyvm<\/code> \u043d\u0430 Rust.<\/p>\n<p>  \u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u044d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u0443\u0436\u0435 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0434\u043b\u0438\u043d\u043d\u0430\u044f. \u041d\u043e \u043d\u0430\u0434\u0435\u044e\u0441\u044c, \u0447\u0442\u043e \u043a \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u043c\u0443 \u043c\u043e\u043c\u0435\u043d\u0442\u0443 \u0432\u044b \u0443\u043b\u043e\u0432\u0438\u043b\u0438 \u043e\u0431\u0449\u0443\u044e \u043a\u0430\u0440\u0442\u0438\u043d\u0443.<\/p>\n<ol>\n<li>\u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u0447\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438 \u043d\u0430\u0439\u0442\u0438 \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e\/\u043c\u043e\u0434\u0443\u043b\u044c  <\/li>\n<li>\u041d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u0441\u0442\u043e\u0432, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043d\u044f\u0442\u044c, \u043a\u0430\u043a \u0434\u043e\u043b\u0436\u043d\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f  <\/li>\n<li>\u041d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u044d\u043a\u0432\u0438\u0432\u0430\u043b\u0435\u043d\u0442\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0430 Rust \u0438 \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u043e\u043d\u0438 \u043f\u0440\u043e\u0445\u043e\u0434\u044f\u0442 \u0442\u0435 \u0436\u0435 \u0442\u0435\u0441\u0442\u044b  <\/li>\n<li>\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0442\u043e\u043d\u043a\u0443\u044e \u043f\u0440\u043e\u043a\u043b\u0430\u0434\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044e Rust \u0441 \u0442\u0435\u043c \u0436\u0435 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u043c C, \u043d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u044f \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e\/\u043c\u043e\u0434\u0443\u043b\u044c \u0438\u0437 \u0441\u0431\u043e\u0440\u043a\u0438, \u0447\u0442\u043e\u0431\u044b \u043a\u043e\u043c\u043f\u043e\u043d\u043e\u0432\u0449\u0438\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u043a\u043e\u0434 Rust \u0432\u043c\u0435\u0441\u0442\u043e C  <\/li>\n<li>\u041f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0448\u0430\u0433\u0443 1<\/li>\n<\/ol>\n<p>  \u0421\u0430\u043c\u043e\u0435 \u043b\u0443\u0447\u0448\u0435\u0435 \u0432 \u044d\u0442\u043e\u043c \u043c\u0435\u0442\u043e\u0434\u0435 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0432\u044b \u043f\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043d\u043e \u0443\u043b\u0443\u0447\u0448\u0430\u0435\u0442\u0435 \u043a\u043e\u0434\u043e\u0432\u0443\u044e \u0431\u0430\u0437\u0443, \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c, \u0430 \u0432\u044b \u043d\u0435 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0435 \u0432\u0441\u0451 \u043e\u0442 \u043d\u0430\u0447\u0430\u043b\u0430 \u0434\u043e \u043a\u043e\u043d\u0446\u0430.<\/p>\n<p>  \u042d\u0442\u043e \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u0447\u0442\u043e \u043c\u0435\u043d\u044f\u0442\u044c \u043a\u043e\u043b\u0435\u0441\u043e \u043d\u0430 \u0445\u043e\u0434\u0443.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/de6\/610\/e72\/de6610e72081e422b0f0f684d88f41eb.gif\"><br \/>  <i><font color=\"gray\">\u041f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 C \u0432 Rust<\/font><\/i><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/511478\/\"> https:\/\/habr.com\/ru\/post\/511478\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/511478\/\">\u0412 <a href=\"https:\/\/habr.com\/ru\/post\/474666\/\">\u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435<\/a> \u043c\u044b \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u0438 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u044b\u0432\u0430\u043d\u0438\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043d\u0430 Rust, \u043a\u043e\u0433\u0434\u0430 \u0432\u0430\u043c \u044d\u0442\u043e \u043d\u0435 \u043d\u0443\u0436\u043d\u043e. \u041d\u043e \u043a\u0430\u043a \u043d\u0430\u0441\u0447\u0451\u0442 \u0442\u0435\u0445 \u0441\u043b\u0443\u0447\u0430\u0435\u0432, \u043a\u043e\u0433\u0434\u0430 \u044d\u0442\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e?<\/p>\n<p>  \u0412 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0435 \u044f\u0437\u044b\u043a\u043e\u0432 \u0432\u0430\u043c \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0432\u0441\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u0441 \u043d\u0443\u043b\u044f, \u0430 \u043f\u0435\u0440\u0432\u044b\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043f\u043e\u044f\u0432\u044f\u0442\u0441\u044f \u0431\u043b\u0438\u0436\u0435 \u043a \u043a\u043e\u043d\u0446\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u0422\u0430\u043a\u0438\u0435 \u043f\u043e\u0440\u0442\u044b, \u043a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0434\u043e\u0440\u043e\u0433\u0438 \u0438 \u043f\u043e\u0434\u0432\u0435\u0440\u0436\u0435\u043d\u044b \u043e\u0448\u0438\u0431\u043a\u0430\u043c, \u0430 \u0447\u0430\u0441\u0442\u043e \u043e\u043d\u0438 \u0432\u044b\u0445\u043e\u0434\u044f\u0442 \u0438\u0437 \u0441\u0442\u0440\u043e\u044f \u043d\u0430 \u043f\u043e\u043b\u043f\u0443\u0442\u0438. <i>\u0414\u0436\u043e\u044d\u043b \u0421\u043f\u043e\u043b\u0441\u043a\u0438<\/i> \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043b\u0443\u0447\u0448\u0435 \u043c\u0435\u043d\u044f \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u0435\u0442 \u044d\u0442\u043e \u0432 \u0441\u0442\u0430\u0442\u044c\u0435 \u043e \u0442\u043e\u043c, <a href=\"https:\/\/www.joelonsoftware.com\/2000\/04\/06\/things-you-should-never-do-part-i\/\" rel=\"nofollow\">\u043f\u043e\u0447\u0435\u043c\u0443 \u043f\u043e\u043b\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u0434\u0435\u043b\u043a\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u2014 \u043f\u043b\u043e\u0445\u0430\u044f \u0438\u0434\u0435\u044f<\/a>.<\/p>\n<p>  \u041e\u0434\u043d\u0430\u043a\u043e \u0443 Rust \u0435\u0441\u0442\u044c \u0443\u0431\u0438\u0439\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c, \u043a\u043e\u0433\u0434\u0430 \u0440\u0435\u0447\u044c \u0437\u0430\u0445\u043e\u0434\u0438\u0442 \u043e \u0442\u0430\u043a\u0438\u0445 \u0432\u0435\u0449\u0430\u0445. \u041e\u043d \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 \u0421 \u0431\u0435\u0437 \u043d\u0430\u043a\u043b\u0430\u0434\u043d\u044b\u0445 \u0440\u0430\u0441\u0445\u043e\u0434\u043e\u0432 (\u0442. \u0435. \u0441\u0440\u0435\u0434\u0430 <a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/standard\/native-interop\/pinvoke\" rel=\"nofollow\">P\/Invoke \u0432 C#<\/a>), \u0438 \u043e\u043d \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 C \u0442\u0430\u043a \u0436\u0435, \u043a\u0430\u043a \u0438 \u043b\u044e\u0431\u044b\u0435 \u0434\u0440\u0443\u0433\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 \u0421. \u042d\u0442\u043e \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u0434\u0432\u0435\u0440\u044c \u0434\u043b\u044f \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430:<\/p>\n<p>  \u041f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043d\u0430 Rust \u043f\u043e \u043e\u0434\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438.  <\/p>\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-307124","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/307124","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=307124"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/307124\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=307124"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=307124"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=307124"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}