<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title>RReverser&#39;s</title>
	<subtitle>Obsessed D2D programmer (parsers, compilers, tools &amp; specs). Sometimes human.</subtitle>
	
	<link href="https://rreverser.com/feed/feed.xml" rel="self"/>
	<link href="https://rreverser.com/"/>
	<updated>2023-08-03T00:00:00Z</updated>
	<id>https://rreverser.com/</id>
	<author>
		<name>Ingvar Stepanyan</name>
		<email>me@rreverser.com</email>
	</author>
	
	<entry>
		<title>Bringing Sharp to WebAssembly and WebContainers</title>
		<link href="https://blog.stackblitz.com/posts/bringing-sharp-to-wasm-and-webcontainers/"/>
		<updated>2023-08-03T00:00:00Z</updated>
		<id>https://blog.stackblitz.com/posts/bringing-sharp-to-wasm-and-webcontainers/</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: serde-ndim</title>
		<link href="https://github.com/RReverser/serde-ndim"/>
		<updated>2023-04-02T14:12:44Z</updated>
		<id>https://github.com/RReverser/serde-ndim</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: ascom-alpaca-rs</title>
		<link href="https://github.com/RReverser/ascom-alpaca-rs"/>
		<updated>2023-03-18T21:47:25Z</updated>
		<id>https://github.com/RReverser/ascom-alpaca-rs</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: eos-remote-web</title>
		<link href="https://github.com/RReverser/eos-remote-web"/>
		<updated>2023-02-27T12:38:18Z</updated>
		<id>https://github.com/RReverser/eos-remote-web</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Drawing to canvas in Emscripten</title>
		<link href="https://web.dev/articles/drawing-to-canvas-in-emscripten"/>
		<updated>2022-02-07T00:00:00Z</updated>
		<id>https://web.dev/articles/drawing-to-canvas-in-emscripten</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Porting USB applications to the web. Part 2: gPhoto2</title>
		<link href="https://web.dev/articles/porting-gphoto2-to-the-web"/>
		<updated>2022-02-01T00:00:00Z</updated>
		<id>https://web.dev/articles/porting-gphoto2-to-the-web</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>WebAssembly feature detection</title>
		<link href="https://web.dev/articles/webassembly-feature-detection"/>
		<updated>2022-01-27T00:00:00Z</updated>
		<id>https://web.dev/articles/webassembly-feature-detection</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Porting USB applications to the web. Part 1: libusb</title>
		<link href="https://web.dev/articles/porting-libusb-to-webusb"/>
		<updated>2022-01-20T00:00:00Z</updated>
		<id>https://web.dev/articles/porting-libusb-to-webusb</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Embedding JavaScript snippets in C++ with Emscripten</title>
		<link href="https://web.dev/articles/emscripten-embedding-js-snippets"/>
		<updated>2022-01-18T00:00:00Z</updated>
		<id>https://web.dev/articles/emscripten-embedding-js-snippets</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Bundling non-JavaScript resources</title>
		<link href="https://web.dev/articles/bundling-non-js-resources"/>
		<updated>2021-09-08T00:00:00Z</updated>
		<id>https://web.dev/articles/bundling-non-js-resources</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Using WebAssembly threads from C, C++ and Rust</title>
		<link href="https://web.dev/articles/webassembly-threads"/>
		<updated>2021-07-12T00:00:00Z</updated>
		<id>https://web.dev/articles/webassembly-threads</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Using asynchronous web APIs from WebAssembly</title>
		<link href="https://web.dev/articles/asyncify"/>
		<updated>2021-04-26T00:00:00Z</updated>
		<id>https://web.dev/articles/asyncify</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: lutz</title>
		<link href="https://github.com/RReverser/lutz"/>
		<updated>2021-04-10T22:37:29Z</updated>
		<id>https://github.com/RReverser/lutz</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: wasm-bindgen-rayon</title>
		<link href="https://github.com/RReverser/wasm-bindgen-rayon"/>
		<updated>2021-03-08T17:39:29Z</updated>
		<id>https://github.com/RReverser/wasm-bindgen-rayon</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: sep-sys-rs</title>
		<link href="https://github.com/RReverser/sep-sys-rs"/>
		<updated>2021-02-21T23:59:05Z</updated>
		<id>https://github.com/RReverser/sep-sys-rs</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>WebAssembly shell with a real filesystem access in a browser</title>
		<link href="https://rreverser.com/webassembly-shell-with-a-real-filesystem-access-in-a-browser/"/>
		<updated>2020-10-19T00:14:30Z</updated>
		<id>https://rreverser.com/webassembly-shell-with-a-real-filesystem-access-in-a-browser/</id>
		<content type="html">&lt;p&gt;I&#39;ve built and open-sourced a new thing - WebAssembly shell with a real filesystem access in a browser.&lt;/p&gt;
&lt;p&gt;It&#39;s powered by &lt;a href=&quot;https://webassembly.org/&quot;&gt;WebAssembly&lt;/a&gt;, &lt;a href=&quot;https://wasi.dev/&quot;&gt;WASI&lt;/a&gt;, &lt;a href=&quot;https://emscripten.org/docs/porting/asyncify.html&quot;&gt;Asyncify&lt;/a&gt; and &lt;a href=&quot;https://wicg.github.io/file-system-access/&quot;&gt;File System Access API&lt;/a&gt;, and, I believe, shows just how powerful Web can be today when its different components are connected together in a single app.&lt;/p&gt;
&lt;p&gt;You can access the live version here: &lt;a href=&quot;https://wasi.rreverser.com/&quot;&gt;https://wasi.rreverser.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Check out the code here: &lt;a href=&quot;https://github.com/GoogleChromeLabs/wasi-fs-access&quot;&gt;https://github.com/GoogleChromeLabs/wasi-fs-access&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Or watch a video demonstrating some of the powerful features:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://youtu.be/qRmO-8b4WmE&quot;&gt;https://youtu.be/qRmO-8b4WmE&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;how&quot; tabindex=&quot;-1&quot;&gt;How &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/webassembly-shell-with-a-real-filesystem-access-in-a-browser/#how&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;It provides &lt;a href=&quot;https://github.com/GoogleChromeLabs/wasi-fs-access/blob/main/src/bindings.ts#LC511:~:text=getWasiImports()%20%7B&quot;&gt;WASI bindings implementation&lt;/a&gt; that proxies any filesystem requests to a real, host filesystem. This allows apps built in languages like C, C++, Rust and others to be compiled to WebAssembly and work as usual within a browser sandbox, accessing and manipulating files in a &amp;quot;real world&amp;quot;.&lt;/p&gt;
&lt;p&gt;Since WASI APIs are synchronous by nature, but Web APIs are traditionally asynchronous to avoid blocking the main thread, Asyncify is used to bridge the two types of APIs together. Asyncify is a feature created as part of &lt;a href=&quot;https://emscripten.org/&quot;&gt;Emscripten&lt;/a&gt; and later extended to work with arbitrary WebAssembly files with the help of a &lt;a href=&quot;https://github.com/GoogleChromeLabs/asyncify&quot;&gt;custom JavaScript wrapper&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A &lt;a href=&quot;https://github.com/RReverser/coreutils&quot;&gt;Rust port of coreutils with some patches&lt;/a&gt; was chosen for the demo purposes, but it should be possible to extract and reuse same bindings for any applications compiled for the WebAssembly + WASI target.&lt;/p&gt;
&lt;p&gt;Note that some commands in the demo might not work due to either limitations of the WASI itself (such as an &lt;a href=&quot;https://github.com/WebAssembly/WASI/issues/303&quot;&gt;absent concept of &amp;quot;current working directory&amp;quot;&lt;/a&gt; and, correspondingly, relative paths and such), limitations of the File System Access API (such as an &lt;a href=&quot;https://github.com/WICG/file-system-access/issues/113&quot;&gt;absent support for symlinks&lt;/a&gt;), or simply due to hardcoded assumptions about the target system in the used coreutils codebase itself. Most of those limitations can be easily worked around or will be naturally fixed as both APIs develop over time.&lt;/p&gt;
&lt;h3 id=&quot;want-to-learn-more&quot; tabindex=&quot;-1&quot;&gt;Want to learn more? &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/webassembly-shell-with-a-real-filesystem-access-in-a-browser/#want-to-learn-more&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Check out my presentation from the &lt;a href=&quot;https://webassembly.live/&quot;&gt;WebAssembly Live!&lt;/a&gt; here: &lt;a href=&quot;https://www.slideshare.net/RReverser/asyncifying-webassembly-for-the-modern-web&quot;&gt;https://www.slideshare.net/RReverser/asyncifying-webassembly-for-the-modern-web&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I&#39;ll also write a more detailed blog post later, but, meanwhile, feel free to check out the code and ping me &lt;a href=&quot;https://twitter.com/RReverser&quot;&gt;on Twitter&lt;/a&gt; with any questions.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>wasmbin: a self-generating WebAssembly parser &amp; serializer</title>
		<link href="https://rreverser.com/wasmbin-yet-another-webassembly-parser-serializer/"/>
		<updated>2020-10-17T19:01:08Z</updated>
		<id>https://rreverser.com/wasmbin-yet-another-webassembly-parser-serializer/</id>
		<content type="html">&lt;p&gt;&lt;em&gt;If you prefer to skip right to the code, go here: &lt;a href=&quot;https://github.com/RReverser/wasmbin&quot;&gt;https://github.com/RReverser/wasmbin&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;backstory&quot; tabindex=&quot;-1&quot;&gt;Backstory &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/wasmbin-yet-another-webassembly-parser-serializer/#backstory&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Few months ago, I&#39;ve been playing with various WebAssembly analysis and transformations in Rust and had a chance to try out several parsing / transformation / serialization toolchains.&lt;/p&gt;
&lt;p&gt;As I was exploring this space, I&#39;ve realised that what I really want is an API that would be high-level enough to allow me to work with the WebAssembly module AST as a natural Rust structure, yet low-level enough to preserve the binary contents of the module for any parts I don&#39;t modify in the process.&lt;/p&gt;
&lt;p&gt;Here are some examples of toolchains I&#39;ve tried and their pros/cons &lt;em&gt;for my particular goals&lt;/em&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wasmparser&quot;&gt;wasmparser&lt;/a&gt;:
&lt;ul&gt;
&lt;li&gt;(+) Low-level access to the WebAssembly binary.&lt;/li&gt;
&lt;li&gt;(+) Allows to lazily skip parts of the binary that you&#39;re not interested in parsing more deeply.&lt;/li&gt;
&lt;li&gt;(+) Allows to parse individual items and not only module as a whole.&lt;/li&gt;
&lt;li&gt;(+) Provides event-driven as well as structural API for reading.&lt;/li&gt;
&lt;li&gt;(-) Allows parsing only from a byte slice, making the structural result hard to store / relocate without things like owning-ref.&lt;/li&gt;
&lt;li&gt;(-) No support for serialization, making unsuitable for any transforms on its own.&lt;/li&gt;
&lt;li&gt;(-) Some places could use newtypes a bit more actively (e.g. I&#39;d love to see separate types for function ids / tables ids / etc., rather than all being generic numbers).&lt;/li&gt;
&lt;li&gt;(-) The produced data structures lack standard basic trait implementations (e.g. PartialEq / Eq, Hash, etc.).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/rustwasm/walrus&quot;&gt;walrus&lt;/a&gt;:
&lt;ul&gt;
&lt;li&gt;(+) Support for both parsing (based on wasmparser) and serialization.&lt;/li&gt;
&lt;li&gt;(+) Very high-level IR, making most modifications easy without worrying about details. For example, one of the problems tricky to solve with lower-level APIs is when you add an import and suddenly all function IDs are shifted and all call instructions are pointing to wrong places - walrus takes care of this for you.&lt;/li&gt;
&lt;li&gt;(+) All IDs are strongly typed, making them harder to mix up.&lt;/li&gt;
&lt;li&gt;(+) Allows parsing from arbitrary sources, the result doesn&#39;t have a lifetime linked to the input and can be moved anywhere.&lt;/li&gt;
&lt;li&gt;(+) Very well tested, has built-in debugging helpers like GraphViz output.&lt;/li&gt;
&lt;li&gt;(-) Roundtrip is a non-goal and unsupported, entire module is rebuilt from IR upon serialization. On pre-optimised binaries, this also means that the result can be larger than the original, making it hard to use for writing custom optimisations.&lt;/li&gt;
&lt;li&gt;(-) Due to the IR being very high-level, no standard trait implementations like &lt;code&gt;Eq&lt;/code&gt;, &lt;code&gt;Hash&lt;/code&gt;, &lt;code&gt;Clone&lt;/code&gt; and so on, making it hard to store parsed items in other data structures.&lt;/li&gt;
&lt;li&gt;(-) Working with function bodies can be sometimes awkward as they are represented in SSA-like form. You can&#39;t get access to the entire function body as a flat instruction list - instead, you&#39;re only given an entry instruction sequence, and a special visitor API that can walk from it to other connected instruction sequences. Similarly, on the other side of the API, there is a builder which you can use to build up instruction sequences and connect them together. This works well for many cases, but, for example, when I wanted to &lt;em&gt;just&lt;/em&gt; make a copy of a function, I found it rather hard to make two APIs to correctly sync up with each other and gave up.&lt;/li&gt;
&lt;li&gt;(-) No lazy parsing or a way to parse separate parts, it&#39;s all or nothing.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/paritytech/parity-wasm&quot;&gt;parity-wasm&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;(+) Very close to a simple AST I wanted, with clear correspondence to the module structure.&lt;/li&gt;
&lt;li&gt;(+) Support for both parsing and serialization.&lt;/li&gt;
&lt;li&gt;(+) &lt;em&gt;(follows from two points above)&lt;/em&gt; Preserves most of the module during round-trip.&lt;/li&gt;
&lt;li&gt;(+) Provides most of the expected traits, others are easy to contribute.&lt;/li&gt;
&lt;li&gt;(+) Allows parsing / serializing separate parts.&lt;/li&gt;
&lt;li&gt;(+) Convenience helpers for common tasks (e.g. setting function as main, inserting section in a correct place etc.).&lt;/li&gt;
&lt;li&gt;(+) Parsing from any source.&lt;/li&gt;
&lt;li&gt;(-) No lazy parsing, entire module is parsed at the same time.&lt;/li&gt;
&lt;li&gt;(-) Although gives access to &amp;quot;raw&amp;quot; representation of all fields, for some reason hides them behind function-based accessors, making them hard to use in pattern matching.&lt;/li&gt;
&lt;li&gt;(-) Like in wasmparser, IDs are simple numbers rather than specialised newtypes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once again, I want to reiterate that since are my personal pet peeves that applied to the weird and fun use-cases I&#39;ve been playing with, and by no means are indicative of how good one or another library is - all of them are successfully used by a lot of other people, and are likely to work for you too!&lt;/p&gt;
&lt;h2 id=&quot;let-s-build-one-more&quot; tabindex=&quot;-1&quot;&gt;Let&#39;s build one more &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/wasmbin-yet-another-webassembly-parser-serializer/#let-s-build-one-more&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now, one thing you should know about me (in case you haven&#39;t noticed from my blog yet) is that I&#39;m a parsing nerd. So what these &amp;quot;downsides&amp;quot; did provide for me, was an excuse to try and build my own low-level parsing/serialization library for WebAssembly.&lt;/p&gt;
&lt;p&gt;Moreover, as any parsing nerd, I &lt;strong&gt;love&lt;/strong&gt; Rust macros. I&#39;ve &lt;a href=&quot;https://rreverser.com/writing-complex-macros-in-rust/&quot;&gt;blogged about writing them&lt;/a&gt; before, I&#39;ve &lt;a href=&quot;https://rreverser.com/building-fast-interpreters-in-rust/&quot;&gt;used them&lt;/a&gt; in various projects, and generally consider them a powerful tool that can significantly increase readability and maintainability of code when used correctly.&lt;/p&gt;
&lt;p&gt;So what I wanted to do for a while is to build a parser &amp;amp; serializer that would fully self-generate themselves using a macros. This way, I as a maintainer would only have to correctly describe all the structures and not bother with handwriting any implementations except for the core types. Think &lt;a href=&quot;https://github.com/serde-rs/serde&quot;&gt;serde&lt;/a&gt;, but combining &lt;a href=&quot;https://serde.rs/impl-deserialize.html&quot;&gt;custom Deserialize&lt;/a&gt; &amp;amp; &lt;a href=&quot;https://serde.rs/impl-deserializer.html&quot;&gt;Deserializer&lt;/a&gt; for one specific format &lt;em&gt;(offtop: there are reasons why &amp;quot;just&amp;quot; using Serde wouldn&#39;t work here, but it&#39;s a bit out of scope of this post)&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;This brings us to custom derives. To recap, most of the Rust code out there relies on a powerful feature called &lt;code&gt;derive&lt;/code&gt; - a special kind of macros that can be put on any user-defined type and used to auto-generate an accompanying implementation block.&lt;/p&gt;
&lt;p&gt;For example, when you write something like:&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token attribute attr-name&quot;&gt;#[derive(Debug, Hash, PartialEq, Eq)]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token type-definition class-name&quot;&gt;MyStruct&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;pub&lt;/span&gt; field&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;pub&lt;/span&gt; another_field&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;pub&lt;/span&gt; yet_another_field&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;AnotherStruct&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;those &lt;code&gt;Hash&lt;/code&gt; and &lt;code&gt;PartialEq&lt;/code&gt; within the &lt;code&gt;derive&lt;/code&gt; attribute get expanded into a code that recursively walks the structure fields and does the &amp;quot;right thing&amp;quot; to fold the results together:&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;core&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;hash&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Hash&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MyStruct&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;__H&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;core&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;hash&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Hasher&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;__H&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;MyStruct&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            field&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;ref&lt;/span&gt; __self_0_0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            another_field&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;ref&lt;/span&gt; __self_0_1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            yet_another_field&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;ref&lt;/span&gt; __self_0_2 &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;core&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;hash&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Hash&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;__self_0_0&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;core&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;hash&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Hash&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;__self_0_1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;core&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;hash&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Hash&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;__self_0_2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;core&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;cmp&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;PartialEq&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MyStruct&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;eq&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; other&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;MyStruct&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;other &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;MyStruct&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            field&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;ref&lt;/span&gt; __self_1_0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            another_field&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;ref&lt;/span&gt; __self_1_1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            yet_another_field&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;ref&lt;/span&gt; __self_1_2 &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token class-name&quot;&gt;MyStruct&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                field&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;ref&lt;/span&gt; __self_0_0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                another_field&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;ref&lt;/span&gt; __self_0_1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                yet_another_field&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;ref&lt;/span&gt; __self_0_2 &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;__self_0_0&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;__self_1_0&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;__self_0_1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;__self_1_1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;__self_0_2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;__self_1_2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What if I could define all the necessary structures corresponding to the WebAssembly spec and put a custom derive in the end that would take care of generating the rest - parsing, serializing and visiting code?&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token attribute attr-name&quot;&gt;#[derive(..., Wasmbin)]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And this is how Wasmbin was born. First of all, I&#39;ve defined a couple of core traits:&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;token type-definition class-name&quot;&gt;Encode&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; w&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;std&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;io&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Write&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;std&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;io&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;token type-definition class-name&quot;&gt;Decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Sized&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;r&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;std&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;io&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Read&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DecodeError&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;Encode&lt;/code&gt; is for serializing the given object into an arbitrary write stream, and &lt;code&gt;Decode&lt;/code&gt; is for reading it from an arbitrary read stream.&lt;/p&gt;
&lt;p&gt;Then (not without a help of few other macros for templating) I&#39;ve defined those traits on all necessary core types, according to the rules of the WebAssembly spec.&lt;/p&gt;
&lt;p&gt;For example, the implementation for &lt;code&gt;u8&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Encode&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;u8&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; w&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;std&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;io&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Write&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;std&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;io&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token namespace&quot;&gt;std&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;slice&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;from_ref&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;w&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Decode&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;u8&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;r&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;std&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;io&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Read&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DecodeError&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;mut&lt;/span&gt; dest &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        r&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;read_exact&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;std&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;slice&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;from_mut&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;mut&lt;/span&gt; dest&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dest&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or integers:&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;macro_rules!&lt;/span&gt; def_integer &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;ident&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$leb128_method&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;ident&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Encode&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$ty&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; w&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;std&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;io&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Write&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;std&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;io&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token namespace&quot;&gt;leb128&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;write&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$leb128_method&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;w&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;into&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token closure-params&quot;&gt;&lt;span class=&quot;token closure-punctuation punctuation&quot;&gt;|&lt;/span&gt;_&lt;span class=&quot;token closure-punctuation punctuation&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Decode&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$ty&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;r&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;std&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;io&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Read&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DecodeError&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;LIMIT&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;u64&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;std&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;mem&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;size_of&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ty&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;u64&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

                &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;mut&lt;/span&gt; r &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;std&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;io&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Read&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;take&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;r&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;LIMIT&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; as_64 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;leb128&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;read&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$leb128_method&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;mut&lt;/span&gt; r&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; res &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;try_from&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;as_64&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map_err&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token closure-params&quot;&gt;&lt;span class=&quot;token closure-punctuation punctuation&quot;&gt;|&lt;/span&gt;_&lt;span class=&quot;token closure-punctuation punctuation&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DecodeError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Leb128&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;leb128&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;read&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Overflow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

                &lt;span class=&quot;token class-name&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;res&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Visit&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$ty&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token macro property&quot;&gt;def_integer!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; unsigned&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token macro property&quot;&gt;def_integer!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; signed&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token macro property&quot;&gt;def_integer!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;u64&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; unsigned&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token macro property&quot;&gt;def_integer!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; signed&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then I needed to do the same for container types. E.g. slices / vectors of &amp;quot;countable&amp;quot; items:&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;WasmbinCountable&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Encode&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Encode&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; w&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;std&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;io&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Write&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;std&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;io&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;w&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; item &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            item&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;w&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;WasmbinCountable&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Decode&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Decode&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;r&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;std&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;io&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Read&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DecodeError&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; count &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;r&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token namespace&quot;&gt;std&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;iter&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;repeat_with&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token closure-params&quot;&gt;&lt;span class=&quot;token closure-punctuation punctuation&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;token closure-punctuation punctuation&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;r&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;take&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;count&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;collect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once I was done with all the core &amp;amp; helper types, I could write a proc-macro to handle the custom derive. From here on, defining the Wasm structures was a breeze.&lt;/p&gt;
&lt;p&gt;Let&#39;s take an &lt;code&gt;Import&lt;/code&gt; node for the example:&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token attribute attr-name&quot;&gt;#[derive(Wasmbin, ...)]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token type-definition class-name&quot;&gt;Import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;pub&lt;/span&gt; path&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ImportPath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;pub&lt;/span&gt; desc&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ImportDesc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Under the hood, this auto-generates corresponding implementations by recursively walking over fields, just like other traits do:&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Encode&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; w&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;std&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;io&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Write&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;std&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;io&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;Import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                path&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;ref&lt;/span&gt; __binding_0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                desc&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;ref&lt;/span&gt; __binding_1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token class-name&quot;&gt;Encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;__binding_0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; w&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token class-name&quot;&gt;Encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;__binding_1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; w&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Decode&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;r&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;std&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;io&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Read&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DecodeError&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            path&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;r&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            desc&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;r&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For enums, I&#39;ve leveraged the recently added &lt;a href=&quot;https://github.com/rust-lang/rust/issues/60553&quot;&gt;discriminant support for arbitrary enums&lt;/a&gt;. It&#39;s currently natively supported only on nightly Rust, but if I drop another custom proc-macro in front (&lt;code&gt;#[wasmbin_discriminants]&lt;/code&gt;), then I can &amp;quot;polyfill&amp;quot; the support by reading the discriminants and stripping them away for the stable compiler:&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token attribute attr-name&quot;&gt;#[wasmbin_discriminants]&lt;/span&gt;
&lt;span class=&quot;token attribute attr-name&quot;&gt;#[derive(Wasmbin, ...)]&lt;/span&gt;
&lt;span class=&quot;token attribute attr-name&quot;&gt;#[repr(u8)]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;token type-definition class-name&quot;&gt;ImportDesc&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;Func&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;TypeId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x00&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;Table&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;TableType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x01&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;Mem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;MemType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x02&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;Global&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;GlobalType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x03&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This way, I&#39;m telling my derive code that the discriminant should be parsed as a &lt;code&gt;u8&lt;/code&gt; and then matched to parse the corresponding variant (and vice versa during serialization). The example above generates code like following:&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Encode&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ImportDesc&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; w&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;std&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;io&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Write&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;std&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;io&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;ImportDesc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Func&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;ref&lt;/span&gt; __binding_0&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;u8&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Encode&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0x00&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; w&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;ImportDesc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Table&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;ref&lt;/span&gt; __binding_0&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;u8&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Encode&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0x01&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; w&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;ImportDesc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Mem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;ref&lt;/span&gt; __binding_0&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;u8&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Encode&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0x02&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; w&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;ImportDesc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Global&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;ref&lt;/span&gt; __binding_0&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;u8&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Encode&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0x03&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; w&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            _ &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;ImportDesc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Func&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;ref&lt;/span&gt; __binding_0&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;__binding_0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; w&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;ImportDesc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Table&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;ref&lt;/span&gt; __binding_0&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;__binding_0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; w&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;ImportDesc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Mem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;ref&lt;/span&gt; __binding_0&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;__binding_0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; w&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;ImportDesc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Global&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;ref&lt;/span&gt; __binding_0&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;__binding_0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; w&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DecodeWithDiscriminant&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ImportDesc&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;token type-definition class-name&quot;&gt;Discriminant&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;maybe_decode_with_discriminant&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        discriminant&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        r&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;std&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;io&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Read&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DecodeError&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;match&lt;/span&gt; discriminant &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token number&quot;&gt;0x00&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ImportDesc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Func&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;r&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token number&quot;&gt;0x01&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ImportDesc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Table&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;r&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token number&quot;&gt;0x02&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ImportDesc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Mem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;r&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token number&quot;&gt;0x03&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ImportDesc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Global&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;r&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            _ &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, you might notice that I&#39;ve introduced another intermediate decode trait for enums. The reason here is that I&#39;ve made my API work with arbitrary streams. It means that, once a &amp;quot;discriminant&amp;quot; (the byte which determines which variant should be parsed) is taken from the stream, it can&#39;t be put back.&lt;/p&gt;
&lt;p&gt;This could be a problem for nested enums, where we don&#39;t know in advance which variant is going to be matched. For example, before the introduction of multi-value types, my &lt;code&gt;BlockType&lt;/code&gt; definition looked like this:&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token attribute attr-name&quot;&gt;#[derive(Wasmbin, ...)]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;token type-definition class-name&quot;&gt;BlockType&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token class-name&quot;&gt;Empty&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x80&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token class-name&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;ValueType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, the autogenerated code needs to read a discriminant and match it against &lt;code&gt;0x80&lt;/code&gt;. If it matches, then the variant is &lt;code&gt;Empty&lt;/code&gt;, but if it doesn&#39;t, it needs to reuse the same discriminant to parse the nested &lt;code&gt;ValueType&lt;/code&gt; instead:&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Encode&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BlockType&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; w&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;std&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;io&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Write&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;std&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;io&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;BlockType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Empty&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;u8&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Encode&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0x80&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; w&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            _ &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;BlockType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Empty&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;BlockType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;ref&lt;/span&gt; __binding_0&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;__binding_0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; w&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DecodeWithDiscriminant&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ImportDesc&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;token type-definition class-name&quot;&gt;Discriminant&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;maybe_decode_with_discriminant&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        discriminant&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        r&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;std&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;io&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Read&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DecodeError&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;match&lt;/span&gt; discriminant &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token number&quot;&gt;0x80&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BlockType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Empty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            _ &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;res&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DecodeWithDiscriminant&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;maybe_decode_with_discriminant&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;discriminant&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; r&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token keyword&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;res&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If &lt;code&gt;ValueType&lt;/code&gt; would implement only &lt;code&gt;Decode&lt;/code&gt; directly, there would be no way to pass the same discriminant again (another alternative could be to allow only peekable streams, but it would be a user-facing inconvenience and not worth it for just passing one byte around).&lt;/p&gt;
&lt;p&gt;Similarly, I can put &lt;code&gt;derive(Wasmbin)&lt;/code&gt; on most other structs and enums that Wasm module consists of. For example, this is how the definition of the &lt;code&gt;ValueType&lt;/code&gt; enum looks like:&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token attribute attr-name&quot;&gt;#[derive(Wasmbin, ...)]&lt;/span&gt;
&lt;span class=&quot;token attribute attr-name&quot;&gt;#[repr(u8)]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;token type-definition class-name&quot;&gt;ValueType&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token constant&quot;&gt;I32&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x7F&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token constant&quot;&gt;I64&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x7E&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token constant&quot;&gt;F32&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x7D&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token constant&quot;&gt;F64&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x7C&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or, probably the most interesting one, &lt;code&gt;Instruction&lt;/code&gt; enum (showing only part of the list because &lt;a href=&quot;https://github.com/RReverser/wasmbin/blob/bfc5de8aa474257128f5b49551c51bf968bc3764/src/instructions.rs#L81-L284&quot;&gt;the full one&lt;/a&gt; is &lt;strong&gt;huge&lt;/strong&gt; and would require even more, potentially erroneous, code if not for auto-generation):&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token attribute attr-name&quot;&gt;#[wasmbin_discriminants]&lt;/span&gt;
&lt;span class=&quot;token attribute attr-name&quot;&gt;#[derive(Wasmbin, ...)]&lt;/span&gt;
&lt;span class=&quot;token attribute attr-name&quot;&gt;#[repr(u8)]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;token type-definition class-name&quot;&gt;Instruction&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token class-name&quot;&gt;Unreachable&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x00&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token class-name&quot;&gt;Nop&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x01&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token class-name&quot;&gt;BlockStart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;BlockType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;OP_CODE_BLOCK_START&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token class-name&quot;&gt;LoopStart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;BlockType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;OP_CODE_LOOP_START&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token class-name&quot;&gt;IfStart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;BlockType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;OP_CODE_IF_START&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token class-name&quot;&gt;IfElse&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x05&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token class-name&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;OP_CODE_END&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token class-name&quot;&gt;Br&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;LabelId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x0C&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token class-name&quot;&gt;BrIf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;LabelId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x0D&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token class-name&quot;&gt;BrTable&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; branches&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;LabelId&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; otherwise&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LabelId&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x0E&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token class-name&quot;&gt;Return&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x0F&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token class-name&quot;&gt;Call&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;FuncId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token class-name&quot;&gt;CallIndirect&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; ty&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;TypeId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; table&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;TableId&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x11&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;/* ... truncated as it&#39;s reallllly long */&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Of course, there are few exceptions that can&#39;t be mapped as easily and need to be handled manually. For example, I&#39;ve mentioned that the &lt;code&gt;BlockType&lt;/code&gt; definition above was before the introduction of multi-value types to WebAssembly.&lt;/p&gt;
&lt;p&gt;In order to accomodate for multi-value types, the spec definition was modified to the following:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Block types are encoded in special compressed form, by either the byte 0x40 indicating the empty type, as a single value type, or as a type index encoded as a positive signed integer.&lt;/p&gt;
&lt;pre class=&quot;language-abnf&quot;&gt;&lt;code class=&quot;language-abnf&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;blocktype&lt;/span&gt; ::&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token repetition operator&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token definition keyword&quot;&gt;x40&lt;/span&gt;          &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&gt; ε
            | &lt;span class=&quot;token rule&quot;&gt;t&lt;/span&gt;:&lt;span class=&quot;token rule&quot;&gt;valtype&lt;/span&gt;     &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&gt; &lt;span class=&quot;token rule&quot;&gt;t&lt;/span&gt;
            | &lt;span class=&quot;token rule&quot;&gt;x&lt;/span&gt;:&lt;span class=&quot;token rule&quot;&gt;s33&lt;/span&gt;         &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&gt; &lt;span class=&quot;token rule&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token rule&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token rule&quot;&gt;x&lt;/span&gt; &gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token repetition operator&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;That is, now only a difference in the bit pattern determines whether something is a &lt;code&gt;ValueType&lt;/code&gt;, or a beginning of a LEB128-encoded 33-bit signed integer that should be treated as a type index for the multi-value type... Yeah, there is no &lt;em&gt;good&lt;/em&gt; way to automate this and it&#39;s easier to &lt;a href=&quot;https://github.com/RReverser/wasmbin/blob/d34d41fa7e17a63777f7879023df79f29ac1b2c3/src/types.rs#L42-L80&quot;&gt;define encoding/decoding manually&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Decode&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BlockType&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;r&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;std&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;io&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Read&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DecodeError&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; discriminant &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;r&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; discriminant &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;OP_CODE_EMPTY_BLOCK&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;BlockType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Empty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ty&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ValueType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;maybe_decode_with_discriminant&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;discriminant&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; r&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;BlockType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ty&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; index &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* ... */&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;BlockType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;MultiValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;TypeId&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; index &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Still, aside from those edge-cases, the autogenerated implementations are covering the majority of the spec and have been a huge boost to the maintainability and ease of future additions.&lt;/p&gt;
&lt;p&gt;For example, this is all it took to &lt;a href=&quot;https://github.com/RReverser/wasmbin/commit/4b51596360425a2871f12b2f6bc0388be3248925&quot;&gt;implement the &lt;code&gt;tail-call&lt;/code&gt; proposal&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-diff-rust&quot;&gt;&lt;code class=&quot;language-diff-rust&quot;&gt;&lt;span class=&quot;token inserted-sign inserted language-rust&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token attribute attr-name&quot;&gt;#[derive(Wasmbin, Debug, Arbitrary, PartialEq, Eq, Hash, Clone, Visit)]&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token type-definition class-name&quot;&gt;CallIndirect&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;    ty&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;TypeId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;    table&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;TableId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token unchanged language-rust&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token attribute attr-name&quot;&gt;#[wasmbin_discriminants]&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token attribute attr-name&quot;&gt;#[derive(Wasmbin, Debug, Arbitrary, PartialEq, Eq, Hash, Clone, Visit)]&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token attribute attr-name&quot;&gt;#[repr(u8)]&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;token type-definition class-name&quot;&gt;Instruction&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;    &lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;    &lt;span class=&quot;token class-name&quot;&gt;Call&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;FuncId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token deleted-sign deleted language-rust&quot;&gt;&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt;    &lt;span class=&quot;token class-name&quot;&gt;CallIndirect&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt;        ty&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;TypeId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt;        table&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;TableId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x11&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted language-rust&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;    &lt;span class=&quot;token class-name&quot;&gt;CallIndirect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;CallIndirect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x11&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;    &lt;span class=&quot;token attribute attr-name&quot;&gt;#[cfg(feature = &lt;span class=&quot;token string&quot;&gt;&quot;tail-call&quot;&lt;/span&gt;)]&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;    &lt;span class=&quot;token class-name&quot;&gt;ReturnCall&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;FuncId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x12&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;    &lt;span class=&quot;token attribute attr-name&quot;&gt;#[cfg(feature = &lt;span class=&quot;token string&quot;&gt;&quot;tail-call&quot;&lt;/span&gt;)]&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;    &lt;span class=&quot;token class-name&quot;&gt;ReturnCallIndirect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;CallIndirect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x13&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token unchanged language-rust&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;    &lt;span class=&quot;token class-name&quot;&gt;Drop&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x1A&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;    &lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;high-level-api&quot; tabindex=&quot;-1&quot;&gt;High-level API &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/wasmbin-yet-another-webassembly-parser-serializer/#high-level-api&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Generally, you can access and modify fields directly on arbitrary type, as well as &lt;a href=&quot;https://docs.rs/wasmbin/0.1.0/wasmbin/io/trait.Decode.html&quot;&gt;&lt;code&gt;::decode(...)&lt;/code&gt;&lt;/a&gt; it from a stream or &lt;a href=&quot;https://docs.rs/wasmbin/0.1.0/wasmbin/io/trait.Encode.html&quot;&gt;&lt;code&gt;.encode(...)&lt;/code&gt;&lt;/a&gt; to one.&lt;/p&gt;
&lt;p&gt;Aside from that, the top-level &lt;a href=&quot;https://docs.rs/wasmbin/0.1.0/wasmbin/module/struct.Module.html&quot;&gt;&lt;code&gt;Module&lt;/code&gt;&lt;/a&gt; type has a couple of extra convenience helpers, with few of them - in particular, retrieving and inserting sections in the correct order - inspired by other libraries mentioned above:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.rs/wasmbin/0.1.0/wasmbin/module/struct.Module.html&quot;&gt;&lt;img src=&quot;https://rreverser.com/images/2020/10/Screenshot-2020-10-17-201952.png&quot; alt=&quot;Module API&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.rs/wasmbin/0.1.0/wasmbin/sections/enum.Section.html&quot;&gt;Sections&lt;/a&gt; are represented as a vector of tagged enums rather than properties to guarantee order preservation.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.rs/wasmbin/0.1.0/wasmbin/sections/enum.Section.html&quot;&gt;&lt;img src=&quot;https://rreverser.com/images/2020/10/section.png&quot; alt=&quot;Section enum&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In the WebAssembly spec, each section is preceded with a byte length to make it easier for parsers to read them lazily, skip them, or even read in parallel. In the Wasmbin type system, this is implemented via a lazy &lt;code&gt;Blob&lt;/code&gt; wrapper which you can see in the bodies of each &lt;code&gt;Section&lt;/code&gt; variant above.&lt;/p&gt;
&lt;p&gt;It means that, when you decode a &lt;code&gt;Module&lt;/code&gt;, then only raw byte vectors are read for each section. Later, you can choose which sections you &lt;em&gt;actually&lt;/em&gt; want to decode and when. For example, if you were to find an import for &lt;code&gt;env.memory&lt;/code&gt; you could write code like the following:&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;imports&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; wasmbin&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find_std_section&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;payload&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Import&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; import &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; imports&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;try_contents&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;match&lt;/span&gt; import&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;desc &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token class-name&quot;&gt;ImportDesc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Mem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; import&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;module &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;env&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; import&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;memory&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* ... */&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      _ &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this case, &lt;a href=&quot;https://docs.rs/wasmbin/0.1.0/wasmbin/builtins/struct.Blob.html#method.try_contents&quot;&gt;&lt;code&gt;Blob::try_contents&lt;/code&gt;&lt;/a&gt; will lazily parse the contents on the first access and store them for future reads.&lt;/p&gt;
&lt;p&gt;As an extra optimisation, if you don&#39;t modify the section, then during reserialization it will use the original raw bytes, but if some section is modified by accessing &lt;a href=&quot;https://docs.rs/wasmbin/0.1.0/wasmbin/builtins/struct.Blob.html#method.try_contents_mut&quot;&gt;&lt;code&gt;Blob::try_contents_mut&lt;/code&gt;&lt;/a&gt; instead, then it will recursively serialize the contents, too.&lt;/p&gt;
&lt;p&gt;You can find the full API with several more traits and methods here: &lt;a href=&quot;https://docs.rs/wasmbin/latest/wasmbin/module/struct.Module.html&quot;&gt;https://docs.rs/wasmbin/latest/wasmbin/module/struct.Module.html&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;trade-offs&quot; tabindex=&quot;-1&quot;&gt;Trade-offs &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/wasmbin-yet-another-webassembly-parser-serializer/#trade-offs&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This post wouldn&#39;t be complete and fair without talking about trade-offs and downsides of this approach and the current implementation. Just to name a few major ones I keep in mind:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The type structures are intentionally mirroring the WebAssembly spec rather than abstracting it away. On one hand, this is what allows to auto-generate parsing, serialization and visiting code for most structures, but, on another, it also means that any change to the spec structure has a higher risk of being a breaking API change in the crate. One example of this can be seen above in the &lt;code&gt;tail-call&lt;/code&gt; proposal example - &lt;code&gt;CallIndirect&lt;/code&gt; structure got extracted as it&#39;s now reused by several variants, so any users will have to make minor adjustment to their code to adapt on upgrade.&lt;/li&gt;
&lt;li&gt;The encoding / decoding code is currently designed to work with arbitrary &lt;code&gt;std::io::Read&lt;/code&gt; / &lt;code&gt;std::io::Write&lt;/code&gt; streams. On one hand, it makes it easier to integrate with any I/O sources, but, on another, this choice makes it slower and more memory-consuming for the common scenario of working with byte vectors.&lt;/li&gt;
&lt;li&gt;While most of the changes require &lt;em&gt;less&lt;/em&gt; code to work, the expansive usage of macros (derive, proc-macros as well as regular ones) is likely to make the contribution curve steeper than in alternatives for people who are less accustomed to this language feature.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;feedback&quot; tabindex=&quot;-1&quot;&gt;Feedback &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/wasmbin-yet-another-webassembly-parser-serializer/#feedback&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Let me know if you find &lt;code&gt;wasmbin&lt;/code&gt; useful or have any questions about the article, please do let me know either on the &lt;a href=&quot;https://github.com/RReverser/wasmbin&quot;&gt;repo&lt;/a&gt; or &lt;a href=&quot;https://twitter.com/RReverser&quot;&gt;Twitter&lt;/a&gt;!&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Debugging memory leaks in WebAssembly using Emscripten</title>
		<link href="https://web.dev/articles/webassembly-memory-debugging"/>
		<updated>2020-08-13T00:00:00Z</updated>
		<id>https://web.dev/articles/webassembly-memory-debugging</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Bringing OxiPNG to Squoosh</title>
		<link href="https://rreverser.com/bringing-oxipng-to-squoosh/"/>
		<updated>2020-04-15T12:29:58Z</updated>
		<id>https://rreverser.com/bringing-oxipng-to-squoosh/</id>
		<content type="html">&lt;p&gt;It took only 7.5 months 😅 (j/k, there were reasons) since opening the PR, but Squoosh.app now utilises OxiPNG instead of OptiPNG for PNG compression!&lt;/p&gt;
&lt;h2 id=&quot;first-attempt&quot; tabindex=&quot;-1&quot;&gt;First attempt &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/bringing-oxipng-to-squoosh/#first-attempt&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/shssoichiro/oxipng&quot;&gt;OxiPNG&lt;/a&gt; is a Rust alternative to &lt;a href=&quot;http://optipng.sourceforge.net/&quot;&gt;OptiPNG&lt;/a&gt; - a popular PNG compressor.&lt;/p&gt;
&lt;p&gt;The main benefit of OxiPNG over OptiPNG is it utilises multi-threading on platforms that support it, and we wanted to provide a path to leverage it on WebAssembly.&lt;/p&gt;
&lt;p&gt;Unfortunately, during the initial attempt, we &lt;a href=&quot;https://github.com/GoogleChromeLabs/squoosh/pull/689#issuecomment-527806615&quot;&gt;found out&lt;/a&gt; that OxiPNG always results in a worse compression 😞&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Squoosh logo: 33.9k vs 34.3k (1.2% bigger)&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://upload.wikimedia.org/wikipedia/commons/thumb/1/1a/Su25-kompo-vers2.svg/2880px-Su25-kompo-vers2.svg.png&quot;&gt;https://upload.wikimedia.org/wikipedia/commons/thumb/1/1a/Su25-kompo-vers2.svg/2880px-Su25-kompo-vers2.svg.png&lt;/a&gt; 472k vs 573k (21% bigger)&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://upload.wikimedia.org/wikipedia/commons/thumb/2/2f/Google_2015_logo.svg/1000px-Google_2015_logo.svg.png&quot;&gt;https://upload.wikimedia.org/wikipedia/commons/thumb/2/2f/Google_2015_logo.svg/1000px-Google_2015_logo.svg.png&lt;/a&gt; No difference.&lt;/p&gt;
&lt;p&gt;The above image, but reduced to 53 colours: 10.3k vs 11k (6.8% bigger).&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://upload.wikimedia.org/wikipedia/commons/thumb/3/3b/Android_new_logo_2019.svg/1000px-Android_new_logo_2019.svg.png&quot;&gt;https://upload.wikimedia.org/wikipedia/commons/thumb/3/3b/Android_new_logo_2019.svg/1000px-Android_new_logo_2019.svg.png&lt;/a&gt; also reduced to 53 colours. 7.18k vs 7.66k (6.7% bigger).&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://upload.wikimedia.org/wikipedia/en/thumb/a/a4/Flag_of_the_United_States.svg/1024px-Flag_of_the_United_States.svg.png&quot;&gt;https://upload.wikimedia.org/wikipedia/en/thumb/a/a4/Flag_of_the_United_States.svg/1024px-Flag_of_the_United_States.svg.png&lt;/a&gt; also reduced to 53 colours. 12.2k vs 12.7k (4% bigger).&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://upload.wikimedia.org/wikipedia/en/thumb/a/ae/Flag_of_the_United_Kingdom.svg/1024px-Flag_of_the_United_Kingdom.svg.png&quot;&gt;https://upload.wikimedia.org/wikipedia/en/thumb/a/ae/Flag_of_the_United_Kingdom.svg/1024px-Flag_of_the_United_Kingdom.svg.png&lt;/a&gt; reduced to 53 colours. 3.48k vs 4.1k (17.8% bigger).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;On its own, this could be written off as just an unfortunate difference between libraries, and, as such, a dead end...&lt;/p&gt;
&lt;p&gt;What has been surprising though, is that these regressions &lt;a href=&quot;https://github.com/GoogleChromeLabs/squoosh/pull/689#issuecomment-527806615&quot;&gt;didn&#39;t reproduce&lt;/a&gt; on OxiPNG outside of our integration 🤨&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I wonder if we&#39;re holding it wrong. Using ImageOptim, in &amp;quot;extreme&amp;quot; mode:&lt;/p&gt;
&lt;p&gt;Squoosh logo:&lt;br /&gt;
Our optipng: 33.9k&lt;br /&gt;
Our oxipng: 34.3k&lt;br /&gt;
ImageOptim oxi: 33.9k&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://upload.wikimedia.org/wikipedia/commons/thumb/1/1a/Su25-kompo-vers2.svg/2880px-Su25-kompo-vers2.svg.png&quot;&gt;https://upload.wikimedia.org/wikipedia/commons/thumb/1/1a/Su25-kompo-vers2.svg/2880px-Su25-kompo-vers2.svg.png&lt;/a&gt;&lt;br /&gt;
Our opti: 472k&lt;br /&gt;
Our oxi: 573k&lt;br /&gt;
ImageOptim oxi: 574k&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://upload.wikimedia.org/wikipedia/commons/thumb/2/2f/Google_2015_logo.svg/1000px-Google_2015_logo.svg.png&quot;&gt;https://upload.wikimedia.org/wikipedia/commons/thumb/2/2f/Google_2015_logo.svg/1000px-Google_2015_logo.svg.png&lt;/a&gt; reduced to 53 colours&lt;br /&gt;
Our opti: 10.3k&lt;br /&gt;
Our oxi: 11k&lt;br /&gt;
ImageOptim oxi: 10.3k&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://upload.wikimedia.org/wikipedia/en/thumb/a/a4/Flag_of_the_United_States.svg/1024px-Flag_of_the_United_States.svg.png&quot;&gt;https://upload.wikimedia.org/wikipedia/en/thumb/a/a4/Flag_of_the_United_States.svg/1024px-Flag_of_the_United_States.svg.png&lt;/a&gt; also reduced to 53 colours&lt;br /&gt;
Our opti: 12.2k&lt;br /&gt;
Our oxi: 12.7k&lt;br /&gt;
ImageOptim oxi: 12.2k.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://upload.wikimedia.org/wikipedia/en/thumb/a/ae/Flag_of_the_United_Kingdom.svg/1024px-Flag_of_the_United_Kingdom.svg.png&quot;&gt;https://upload.wikimedia.org/wikipedia/en/thumb/a/ae/Flag_of_the_United_Kingdom.svg/1024px-Flag_of_the_United_Kingdom.svg.png&lt;/a&gt; reduced to 53 colours.&lt;br /&gt;
Our opti: 3.48k&lt;br /&gt;
Our oxi: 4.1k&lt;br /&gt;
ImageOptim oxi: 3.5k&lt;/p&gt;
&lt;p&gt;ImageOptim&#39;s version/integration of oxi is better than our&#39;s. Although there&#39;s the odd output size regression, the only major regression in that large airplane image.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There is no way same code compiled to Wasm could result in a worse compression.&lt;/p&gt;
&lt;p&gt;Indeed, upon further inspection, it turned out that OxiPNG utilises two different DEFLATE libraries to compress PNG image data, depending on the target platform support.&lt;/p&gt;
&lt;p&gt;One is a &lt;a href=&quot;https://gitlab.com/kornelski/cloudflare-zlib-sys&quot;&gt;Rust wrapper&lt;/a&gt; for &lt;a href=&quot;https://github.com/cloudflare/zlib&quot;&gt;Cloudflare&#39;s fork&lt;/a&gt; of the common zlib library that provides fantastic compression speed improvements, but works only on x64 and ARM64 targets.&lt;/p&gt;
&lt;p&gt;Another is &lt;code&gt;miniz_oxide&lt;/code&gt; - a &lt;a href=&quot;https://github.com/Frommi/miniz_oxide&quot;&gt;Rust port&lt;/a&gt; of a &lt;a href=&quot;https://github.com/richgel999/miniz&quot;&gt;miniz library&lt;/a&gt;, which is used on all other platforms by OxiPNG - including our WebAssembly target. miniz is designed to be a fast &amp;amp; tiny drop-in replacement for zlib, but doesn&#39;t provide as good compression, which explains the results above.&lt;/p&gt;
&lt;p&gt;Once we found this out, there were a few possible paths to explore.&lt;/p&gt;
&lt;h2 id=&quot;cloudflare-zlib-c-fork&quot; tabindex=&quot;-1&quot;&gt;cloudflare-zlib (C fork) &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/bringing-oxipng-to-squoosh/#cloudflare-zlib-c-fork&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;First, &lt;a href=&quot;https://github.com/cloudflare/zlib&quot;&gt;cloudflare-zlib&lt;/a&gt; could add support for Wasm. Unfortunately, &lt;a href=&quot;https://v8.dev/features/simd&quot;&gt;SIMD in WebAssembly&lt;/a&gt; is not yet stable, and while it can be experimented with, it wouldn&#39;t solve our immediate problem for most users yet.&lt;/p&gt;
&lt;p&gt;cloudflare-zlib could also add fallbacks to regular implementation of functions for unsupported targets, but that doesn&#39;t align with goals of the fork and would likely result in maintenance complications, so wasn&#39;t brought up.&lt;/p&gt;
&lt;h2 id=&quot;cloudflare-zlib-rust-wrapper&quot; tabindex=&quot;-1&quot;&gt;cloudflare-zlib (Rust wrapper) &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/bringing-oxipng-to-squoosh/#cloudflare-zlib-rust-wrapper&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Second, the &lt;a href=&quot;https://gitlab.com/kornelski/cloudflare-zlib-sys&quot;&gt;Rust wrapper&lt;/a&gt; could fall back to a regular zlib on unsupported targets. We talked a bit about this with the author of the wrapper in DMs, but this could be tricky to do in a general case, because the wrapper wants to detect SIMD support at runtime and we can&#39;t link to both libraries statically due to symbol conflicts.&lt;/p&gt;
&lt;p&gt;It might still work if we decide to use regular zlib at least on platforms that are definitely not supported by cloudflare-zlib, but meanwhile I decided to look into other approaches.&lt;/p&gt;
&lt;h2 id=&quot;flate2-rs&quot; tabindex=&quot;-1&quot;&gt;flate2-rs &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/bringing-oxipng-to-squoosh/#flate2-rs&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Third was to make OxiPNG use another wrapper that already abstracts over these libraries statically.&lt;/p&gt;
&lt;p&gt;Luckily, a popular flate2-rs library has already supported miniz-oxide as well as zlib, and someone &lt;a href=&quot;https://github.com/alexcrichton/flate2-rs/pull/228&quot;&gt;has recently contributed cloudflare-zlib support&lt;/a&gt; too, which made it a perfect match!.. Well, almost.&lt;/p&gt;
&lt;p&gt;One problem is that OxiPNG, like OptiPNG, works by iterating over various combinations of PNG filters as well as low-level zlib options and essentially brute-forcing its way to the one that works best for the given image.&lt;/p&gt;
&lt;p&gt;flate2 exposes these on &lt;a href=&quot;https://github.com/alexcrichton/flate2-rs/blob/5ef87027cf9a9a6c876886279f74215c7965a902/src/mem.rs&quot;&gt;low-level zlib bindings&lt;/a&gt;, but &lt;a href=&quot;https://github.com/alexcrichton/flate2-rs/issues/233&quot;&gt;not yet&lt;/a&gt; on a high-level API. It wouldn&#39;t be hard to propagate these options, but it still requires some extra work.&lt;/p&gt;
&lt;h3 id=&quot;zlib-raw-rust-bindings&quot; tabindex=&quot;-1&quot;&gt;zlib (raw Rust bindings) &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/bringing-oxipng-to-squoosh/#zlib-raw-rust-bindings&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Another problem is that, by default, zlib depends on some libc functions to take care of allocation, deallocation and copying memory around.&lt;/p&gt;
&lt;p&gt;Unfortunately, Clang ships with a completely bare-bones &lt;code&gt;wasm32-unknown-unknown&lt;/code&gt; target, which doesn&#39;t provide &lt;em&gt;any&lt;/em&gt; functions or headers, even platform-independent ones. It expects you to bring your own sysroot.&lt;/p&gt;
&lt;p&gt;Some projects that provide their own sysroot are &lt;a href=&quot;https://github.com/emscripten-core/emscripten&quot;&gt;Emscripten&lt;/a&gt; and &lt;a href=&quot;https://github.com/WebAssembly/wasi-sdk&quot;&gt;WASI SDK&lt;/a&gt;, but it feels like an overkill to bring an entire new toolchain to build a library that doesn&#39;t even need any platform-specific APIs.&lt;/p&gt;
&lt;p&gt;Moreover, Rust provides its own allocator for the &lt;code&gt;wasm32-unknown-unknown&lt;/code&gt; target and we would want to reuse it rather than bring an extra libc one &lt;em&gt;(I wonder if two allocators even work on the same Wasm memory)&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;As it turned out, zlib has already &lt;a href=&quot;https://github.com/madler/zlib/commit/f442c1e89e99ae5a0068a2d32e7284c2623f09fd&quot;&gt;taken care of this&lt;/a&gt; back in 2011 - not for WebAssembly, I presume 😀 - by introducing a separate compilation &amp;quot;solo&amp;quot; mode that avoids any library dependencies at the cost of losing some &lt;a href=&quot;https://www.zlib.net/manual.html#Utility&quot;&gt;high-level utilities&lt;/a&gt; as well as helpers that could &lt;a href=&quot;https://www.zlib.net/manual.html#Gzip&quot;&gt;operate on files&lt;/a&gt;, and requires embedders to always specify custom alloc / free functions via options.&lt;/p&gt;
&lt;p&gt;Luckily, flate2 already checks all these boxes - it doesn&#39;t use any of these helpers anyway and already passes custom allocation functions to reuse Rust allocator - so it can be made to work with this solo mode quite easily.&lt;/p&gt;
&lt;p&gt;As the first step, I&#39;ve made &lt;a href=&quot;https://github.com/rust-lang/libz-sys/pull/60&quot;&gt;an upstream PR&lt;/a&gt; to official &amp;quot;raw&amp;quot; Rust + zlib bindings to add such support.&lt;/p&gt;
&lt;p&gt;I&#39;ve also updated flate2 locally to use these updated bindings, and verified that it finally compiles and works great on &lt;code&gt;wasm32-unknown-unknown&lt;/code&gt; target, and even provides some nice size savings for other platforms!&lt;/p&gt;
&lt;p&gt;Unfortunately, the raw bindings don&#39;t seem to be actively maintained these days, so the PR is still waiting for a review, and I&#39;ve decided to explore yet another approach meanwhile.&lt;/p&gt;
&lt;h2 id=&quot;libdeflate&quot; tabindex=&quot;-1&quot;&gt;libdeflate &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/bringing-oxipng-to-squoosh/#libdeflate&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I was looking through alternative wrappers for zlib as well as pure-Rust libraries in case I missed an even better solution.&lt;/p&gt;
&lt;p&gt;There were mostly decoder implementations, some basic encoders, the already known bindings to zlib / cloudflare-zlib / miniz, the mentioned miniz port, bindings to the best-in-class-but-unbearably-slow zopfli encoder... and then there was one crate that caught my eye: &lt;a href=&quot;https://crates.io/crates/libdeflater&quot;&gt;&lt;code&gt;libdeflater&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;From the description:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Rust bindings to &lt;a href=&quot;https://github.com/ebiggers/libdeflate&quot;&gt;libdeflate&lt;/a&gt;. A high-performance library for working with gzip/zlib/deflate data.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Warning&lt;/strong&gt;: libdeflate is for specialized use-cases. You should use something like flate2 if you want a general-purpose deflate library.&lt;/p&gt;
&lt;p&gt;libdeflate is optimal in applications that have all input data up and have a mechanism for chunking large input datasets (e.g. genomic &lt;a href=&quot;https://samtools.github.io/hts-specs/SAMv1.pdf&quot;&gt;bam&lt;/a&gt; files, some object stores, specialized backends, game netcode packets). It has a much simpler API than &lt;a href=&quot;https://www.zlib.net/manual.html&quot;&gt;zlib&lt;/a&gt; but can&#39;t stream data.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Usually I&#39;m &lt;s&gt;sceptical&lt;/s&gt; cautious about &amp;quot;high-performance&amp;quot; claims in READMEs, unless they&#39;re backed by reproducible benchmarks as well as explanation on which corners has been cut to achieve such performance, but this description checked all the boxes and made the library hard to pass by.&lt;/p&gt;
&lt;p&gt;It seemed particularly intriguing that &lt;code&gt;libdeflate&lt;/code&gt; chose to focus on optimising compression (both speed- and ratio-wise) just for a &lt;em&gt;fixed-size&lt;/em&gt; data, rather than attempting to replicate the full streaming zlib API.&lt;/p&gt;
&lt;p&gt;This matches our use-case (fixed-size image data) perfectly, so I&#39;ve decided to go ahead and try and integrate it with OxiPNG, and compare with cloudflare-zlib implementation on a native x64. Benchmarking it against the corpus of test files in the OxiPNG repo gave mixed, but promising results.&lt;/p&gt;
&lt;p&gt;Check out &lt;a href=&quot;https://docs.google.com/spreadsheets/d/1WOKgeYZBhLkQvMGAC36snN4azilElzOFhx63RJu0EZY/edit?usp=sharing&quot;&gt;the spreadsheet&lt;/a&gt; for raw numbers, or just the highlights below for the improvement/regression distribution diagrams:&lt;/p&gt;
&lt;h3 id=&quot;time-difference&quot; tabindex=&quot;-1&quot;&gt;Time difference &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/bringing-oxipng-to-squoosh/#time-difference&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://rreverser.com/images/2020/04/chart--2-.svg&quot; alt=&quot;chart&quot; /&gt;&lt;/p&gt;
&lt;h3 id=&quot;idat-size-difference&quot; tabindex=&quot;-1&quot;&gt;IDAT size difference &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/bringing-oxipng-to-squoosh/#idat-size-difference&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://rreverser.com/images/2020/04/chart--1-.svg&quot; alt=&quot;chart&quot; /&gt;&lt;/p&gt;
&lt;h3 id=&quot;total-size-difference&quot; tabindex=&quot;-1&quot;&gt;Total size difference &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/bringing-oxipng-to-squoosh/#total-size-difference&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://rreverser.com/images/2020/04/chart.svg&quot; alt=&quot;chart&quot; /&gt;&lt;/p&gt;
&lt;p&gt;If we ignore some outliers (mainly tiny files that contribute too much when converted to relative differences), it&#39;s clear that in most cases OxiPNG + libdeflate provides both better compression ratio &lt;em&gt;and&lt;/em&gt; does it even faster than OxiPNG + SIMD-optimised cloudflare-zlib. Seems promising!&lt;/p&gt;
&lt;p&gt;If you look at the code in &lt;a href=&quot;https://github.com/shssoichiro/oxipng/pull/203&quot;&gt;the PR&lt;/a&gt;, you might say that it&#39;s not a fair comparison, because libdeflate doesn&#39;t provide as many fine-tuning knobs as zlib, so OxiPNG ends up iterating over far fewer iterations with libdeflate than it would otherwise.&lt;/p&gt;
&lt;p&gt;You would be correct in saying so, and for other cases (cloudflare-)zlib could still be the right choice, but for our use-case it&#39;s the end result that matters, and not the speed of a single iteration. We don&#39;t really care about the lost fine-tuning knobs either - instead, we just use the maximum compression level (12 in libdeflate) and as long as it does provide better ratio/speed balance, I&#39;d say we take it.&lt;/p&gt;
&lt;p&gt;This integration is now merged upstream in OxiPNG, and it was time to test it on the Squoosh PR again.&lt;/p&gt;
&lt;p&gt;One limitation of the WebAssembly target is that we can&#39;t yet benefit from the SIMD optimisations, so we lose some of the native libdeflate speed improvements. On the other hand, we couldn&#39;t benefit from SIMD in cloudflare-zlib either, so I&#39;d say it&#39;s a fair game in the end.&lt;/p&gt;
&lt;p&gt;Moreover, unlike other mentioned solutions, libdeflate already provides fallbacks for unsupported platforms, so it&#39;s one less thing to worry about that made the integration quite straightforward.&lt;/p&gt;
&lt;p&gt;Let&#39;s take one more look at &lt;a href=&quot;https://github.com/GoogleChromeLabs/squoosh/pull/689#issuecomment-610415281&quot;&gt;the updated numbers&lt;/a&gt; for files mentioned in the beginning of the post, but now with OptiPNG vs OxiPNG + Libdeflate integration in Squoosh:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;File&lt;/th&gt;
&lt;th&gt;optipng&lt;/th&gt;
&lt;th&gt;oxipng&lt;/th&gt;
&lt;th&gt;optipng time (ms)&lt;/th&gt;
&lt;th&gt;oxipng time (ms)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Device screen demo&lt;/td&gt;
&lt;td&gt;1.49MB&lt;/td&gt;
&lt;td&gt;1.42MB&lt;/td&gt;
&lt;td&gt;76909&lt;/td&gt;
&lt;td&gt;6991&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google logo (53 colours)&lt;/td&gt;
&lt;td&gt;10.3KB&lt;/td&gt;
&lt;td&gt;9.37KB&lt;/td&gt;
&lt;td&gt;1975&lt;/td&gt;
&lt;td&gt;832&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Android logo (53 colours)&lt;/td&gt;
&lt;td&gt;7.22KB&lt;/td&gt;
&lt;td&gt;6.75KB&lt;/td&gt;
&lt;td&gt;1191&lt;/td&gt;
&lt;td&gt;412&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;US flag (53 colours)&lt;/td&gt;
&lt;td&gt;12.3KB&lt;/td&gt;
&lt;td&gt;10.9KB&lt;/td&gt;
&lt;td&gt;2841&lt;/td&gt;
&lt;td&gt;963&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UK flag (53 colours)&lt;/td&gt;
&lt;td&gt;3.48KB&lt;/td&gt;
&lt;td&gt;3.72KB&lt;/td&gt;
&lt;td&gt;2438&lt;/td&gt;
&lt;td&gt;1028&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Just like in the general test suite, there are some regressions, but usually we get a better ratio, and always a much higher throughput.&lt;/p&gt;
&lt;h2 id=&quot;what-now&quot; tabindex=&quot;-1&quot;&gt;What now? &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/bringing-oxipng-to-squoosh/#what-now&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now that all the PRs are merged upstream, I have more potential optimisations to play with.&lt;/p&gt;
&lt;p&gt;One, already mentioned in the beginning of the post, is utilising WebAssembly threads on supported platforms. Even though we are already much faster (up to 11x for the files above) than where we started at, we could do even better by leveraging OxiPNG multithreading support, now that the basic integration is complete and this path is unlocked.&lt;/p&gt;
&lt;p&gt;Another potentially interesting idea is to add a mode that would use both libdeflate and zlib in parallel in OxiPNG.&lt;/p&gt;
&lt;p&gt;This would eliminate any regressions by always choosing the best encoder possible, but at the cost of eliminating any speed wins as well (since now we have to try even more different encoder+options combinations than we started with).&lt;/p&gt;
&lt;p&gt;Also, it still requires getting at least one of the high-level wrappers to compile with both cloudflare-zlib and regular zlib depending on the target platform, to make it work on WebAssembly. All in all, it&#39;s not yet clear if this path is worth pursuing, or it&#39;s better to find and report specific poorly compressable patterns to libdeflate and hope that they can be improved upstream.&lt;/p&gt;
&lt;p&gt;Finally, we could play with upcoming &lt;a href=&quot;https://v8.dev/features/simd&quot;&gt;WebAssembly + SIMD&lt;/a&gt; support in both libdeflate and cloudflare-zlib to get even faster single-thread compression. There are some potential big upcoming changes to the bytecode, so we wouldn&#39;t want to ship code using SIMD to production yet, but nothing stops us from already playing with it in forks / branches by using corresponding intrinsics.&lt;/p&gt;
&lt;p&gt;But these are all separate stories for later 🙂 Stay tuned and stay safe!&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Github project: cow-utils-rs</title>
		<link href="https://github.com/RReverser/cow-utils-rs"/>
		<updated>2020-02-16T17:02:59Z</updated>
		<id>https://github.com/RReverser/cow-utils-rs</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>A History of HTML Parsing at Cloudflare: Part 1</title>
		<link href="https://blog.cloudflare.com/html-parsing-1/"/>
		<updated>2019-11-28T00:00:00Z</updated>
		<id>https://blog.cloudflare.com/html-parsing-1/</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: asyncify</title>
		<link href="https://github.com/GoogleChromeLabs/asyncify"/>
		<updated>2019-10-02T10:38:42Z</updated>
		<id>https://github.com/GoogleChromeLabs/asyncify</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: lazyhtml</title>
		<link href="https://github.com/cloudflare/lazyhtml"/>
		<updated>2019-06-20T16:25:08Z</updated>
		<id>https://github.com/cloudflare/lazyhtml</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Faster script loading with BinaryAST?</title>
		<link href="https://blog.cloudflare.com/binary-ast/"/>
		<updated>2019-05-17T00:00:00Z</updated>
		<id>https://blog.cloudflare.com/binary-ast/</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: serde-wasm-bindgen</title>
		<link href="https://github.com/RReverser/serde-wasm-bindgen"/>
		<updated>2019-05-02T15:09:28Z</updated>
		<id>https://github.com/RReverser/serde-wasm-bindgen</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: astexplorer-syn</title>
		<link href="https://github.com/RReverser/astexplorer-syn"/>
		<updated>2019-03-19T00:11:31Z</updated>
		<id>https://github.com/RReverser/astexplorer-syn</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Building fast interpreters in Rust</title>
		<link href="https://blog.cloudflare.com/building-fast-interpreters-in-rust/"/>
		<updated>2019-03-04T00:00:00Z</updated>
		<id>https://blog.cloudflare.com/building-fast-interpreters-in-rust/</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Improving request debugging in Cloudflare Workers</title>
		<link href="https://blog.cloudflare.com/better-workers-debugging-with-a-network-panel/"/>
		<updated>2018-12-28T00:00:00Z</updated>
		<id>https://blog.cloudflare.com/better-workers-debugging-with-a-network-panel/</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>#[derive(Debug)] on serde steroids</title>
		<link href="https://rreverser.com/derive-serdebug/"/>
		<updated>2018-07-31T15:00:45Z</updated>
		<id>https://rreverser.com/derive-serdebug/</id>
		<content type="html">&lt;p&gt;In this post I&#39;d like to introduce a &lt;a href=&quot;https://docs.rs/serdebug&quot;&gt;&lt;code&gt;serdebug&lt;/code&gt;&lt;/a&gt; helper which is a drop-in replacement for &lt;code&gt;#[derive(Debug)]&lt;/code&gt; with some of the advanced features that &lt;code&gt;serde&lt;/code&gt; can provide.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Yes, it&#39;s meant to be read as &amp;quot;ser&amp;quot;+&amp;quot;debug&amp;quot; (serialise to Debug) or &amp;quot;serde&amp;quot;+&amp;quot;debug&amp;quot; (Debug with serde) and not the way you thought ;).&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;why-would-i-want-it&quot; tabindex=&quot;-1&quot;&gt;Why would I want it? &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/derive-serdebug/#why-would-i-want-it&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Often enough, in Rust I&#39;ve ran into situations where I wanted to make &lt;a href=&quot;https://doc.rust-lang.org/std/fmt/trait.Debug.html&quot;&gt;&lt;code&gt;Debug&lt;/code&gt;&lt;/a&gt; representations more readable by hiding certain fields (like &lt;a href=&quot;https://doc.rust-lang.org/std/marker/struct.PhantomData.html&quot;&gt;&lt;code&gt;PhantomData&lt;/code&gt;&lt;/a&gt; or similar markers that don&#39;t contain any useful information) or providing custom representation for some of them (which is especially hard in case of third-party types).&lt;/p&gt;
&lt;p&gt;Unfortunately, what this usually means is a choice between giving up on auto-derived representation completely and implementing &lt;code&gt;Debug&lt;/code&gt; for your types manually, which might be quite verbose for large structures or enums, or wrapping types into intermediate newtype, which is a popular pattern in Rust lands, but not very convenient one (IMO), as it pollutes every usage side and/or requires reimplementing all traits you care about on top of the wrapper (often manually, unless you are lucky and it&#39;s easy to &lt;code&gt;#[derive(...)]&lt;/code&gt; with existing crates).&lt;/p&gt;
&lt;p&gt;When I looked for solutions on &lt;a href=&quot;https://crates.io/search?q=derive%20debug&quot;&gt;crates.io&lt;/a&gt;, surely, I found that some of these issues were already tackled by others - for example, you can use &lt;a href=&quot;https://docs.rs/debug_stub_derive&quot;&gt;&lt;code&gt;debug_stub_derive&lt;/code&gt;&lt;/a&gt; to provide custom formatting function for certain fields or &lt;a href=&quot;https://mcarton.github.io/rust-derivative/&quot;&gt;&lt;code&gt;derivative&lt;/code&gt;&lt;/a&gt; to also unwrap newtypes or rename fields (the latter also has a number of customisations for other standard traits like &lt;code&gt;Hash&lt;/code&gt;, &lt;code&gt;Clone&lt;/code&gt;, &lt;code&gt;PartialEq&lt;/code&gt;, etc., so definitely check it out if you ever wanted to customise them too).&lt;/p&gt;
&lt;p&gt;What bothered me however, is that they still felt not flexible enough, and at the same time I already use &lt;a href=&quot;https://github.com/serde-rs/serde&quot;&gt;&lt;code&gt;serde&lt;/code&gt;&lt;/a&gt; for most of my types which provides these and many more customisations out of the box, as it has to deal with all sorts of output formats, and usually I&#39;d just want my debug representation to use the same names and fields as I&#39;m already serialising, expect in a more human-readable format that &lt;code&gt;Debug&lt;/code&gt; provides.&lt;/p&gt;
&lt;p&gt;So then I thought, what is &lt;code&gt;Debug&lt;/code&gt; if not just another serialisation format? Moreover, looking at the advanced API, it&#39;s easy to see how &lt;a href=&quot;https://doc.rust-lang.org/std/fmt/struct.DebugMap.html&quot;&gt;&lt;code&gt;DebugMap&lt;/code&gt;&lt;/a&gt; is similar to &lt;a href=&quot;https://docs.rs/serde/1.0.70/serde/ser/trait.SerializeMap.html&quot;&gt;&lt;code&gt;SerializeMap&lt;/code&gt;&lt;/a&gt; or &lt;a href=&quot;https://doc.rust-lang.org/std/fmt/struct.DebugTuple.html&quot;&gt;&lt;code&gt;DebugTuple&lt;/code&gt;&lt;/a&gt; to &lt;a href=&quot;https://docs.rs/serde/1.0.70/serde/ser/trait.SerializeTuple.html&quot;&gt;&lt;code&gt;SerializeTuple&lt;/code&gt;&lt;/a&gt; and so on.&lt;/p&gt;
&lt;p&gt;So yes, I&#39;ve decided to wrap all these &lt;a href=&quot;https://doc.rust-lang.org/std/fmt/index.html&quot;&gt;&lt;code&gt;std::fmt&lt;/code&gt;&lt;/a&gt; structures into newtypes that implement &lt;a href=&quot;https://docs.rs/serde/1.0.70/serde/ser/index.html&quot;&gt;&lt;code&gt;serde::ser&lt;/code&gt;&lt;/a&gt; traits, and then to implement main &lt;a href=&quot;https://docs.rs/serde/1.0.70/serde/trait.Serializer.html&quot;&gt;&lt;code&gt;Serializer&lt;/code&gt;&lt;/a&gt; interface that would call out to them simulating exact same output that &lt;code&gt;#[derive(Debug)]&lt;/code&gt; would normally produce for you with its own auto-generated code, unless you enabled some of the &lt;code&gt;serde&lt;/code&gt;-specific attributes to control serialisation behaviour.&lt;/p&gt;
&lt;h2 id=&quot;how-do-i-use-it&quot; tabindex=&quot;-1&quot;&gt;How do I use it? &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/derive-serdebug/#how-do-i-use-it&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;On any types where you already use &lt;code&gt;#[derive(Debug)]&lt;/code&gt;, you can replace with &lt;code&gt;#[derive(SerDebug)]&lt;/code&gt; and add serde-provided &lt;code&gt;#[derive(Serialize)]&lt;/code&gt; if you don&#39;t already have it.&lt;/p&gt;
&lt;p&gt;As mentioned above, by default the output is aimed to exactly match the built-in derive, and that&#39;s not very interesting to observe, so instead, let&#39;s add a bunch of &lt;code&gt;serde&lt;/code&gt; attributes to customise it (usually you won&#39;t need that many, this is done purely for demonstration purposes):&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token attribute attr-name&quot;&gt;#[derive(Serialize, SerDebug)]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;token type-definition class-name&quot;&gt;MyEnum&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// renaming items works as expected&lt;/span&gt;
    &lt;span class=&quot;token attribute attr-name&quot;&gt;#[serde(rename = &lt;span class=&quot;token string&quot;&gt;&quot;AAAAAAA!!!&quot;&lt;/span&gt;)]&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;C&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; flag&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token attribute attr-name&quot;&gt;#[derive(Serialize, SerDebug)]&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// so does bulk rename on containers&lt;/span&gt;
&lt;span class=&quot;token attribute attr-name&quot;&gt;#[serde(rename_all = &lt;span class=&quot;token string&quot;&gt;&quot;PascalCase&quot;&lt;/span&gt;)]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token type-definition class-name&quot;&gt;MyStruct&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    number&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

    my_enum&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;MyEnum&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// we might want to hide some items from the output&lt;/span&gt;
    &lt;span class=&quot;token attribute attr-name&quot;&gt;#[serde(skip_serializing)]&lt;/span&gt;
    hidden&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// or override serialisation for otherwise verbose wrappers or&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// third-party types that don&#39;t implement `Debug` and/or `Serialize`&lt;/span&gt;
    &lt;span class=&quot;token attribute attr-name&quot;&gt;#[serde(serialize_with = &lt;span class=&quot;token string&quot;&gt;&quot;custom_serialize&quot;&lt;/span&gt;)]&lt;/span&gt;
    custom_type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CustomType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;custom_serialize&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;S&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;serde&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Serializer&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;CustomType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ser&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;S&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;S&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;S&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;serde&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Serialize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    value&lt;span class=&quot;token number&quot;&gt;.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;serialize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ser&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, if we try to define a sample &lt;code&gt;MyStruct&lt;/code&gt; value&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; s &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MyStruct&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    number&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    my_enum&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token macro property&quot;&gt;vec!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;MyEnum&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MyEnum&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MyEnum&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;C&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; flag&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    hidden&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    custom_type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CustomType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and print its debug representation as we normally would&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;{:#?}&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;you will see that the output still resembles &lt;code&gt;Debug&lt;/code&gt; but has our customisations applied:&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;MyStruct&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;Number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;MyEnum&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token macro property&quot;&gt;AAAAAAA!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;C&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            flag&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;CustomType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;why-you-might-not-want-it&quot; tabindex=&quot;-1&quot;&gt;Why you might not want it &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/derive-serdebug/#why-you-might-not-want-it&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;serde&lt;/code&gt;, especially &lt;code&gt;serde_derive&lt;/code&gt;, might be a heavy dependency to add to your project as it sometimes adds non-trivial overhead to compilation times.&lt;/p&gt;
&lt;p&gt;On average-sized and larger projects, chances are that you already have it somewhere in your tree and use for other (de)serialisation targets. In that case the difference should be negligible as now you will need to compile just one more custom derive (which you will need anyway if you decided to customise your output with one of the helper crates). However, if you do not use serde yet, you might be better off with &lt;a href=&quot;https://mcarton.github.io/rust-derivative/&quot;&gt;&lt;code&gt;derivative&lt;/code&gt;&lt;/a&gt; helper - I haven&#39;t personally compared compilation times, but I do think that it will be faster than all of &lt;code&gt;serde&lt;/code&gt; + &lt;code&gt;serde_derive&lt;/code&gt; + &lt;code&gt;serdebug&lt;/code&gt; combined.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;This is it for now, but if you find any bugs or have improvement suggestions which are specific to &lt;code&gt;serdebug&lt;/code&gt; and not &lt;code&gt;serde&lt;/code&gt; in general, please do report them at &lt;a href=&quot;https://github.com/RReverser/serdebug&quot;&gt;github issue tracker&lt;/a&gt;.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Github project: xmatch</title>
		<link href="https://github.com/RReverser/xmatch"/>
		<updated>2018-04-30T19:30:10Z</updated>
		<id>https://github.com/RReverser/xmatch</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: ws-proxy</title>
		<link href="https://github.com/RReverser/ws-proxy"/>
		<updated>2018-04-13T14:34:45Z</updated>
		<id>https://github.com/RReverser/ws-proxy</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Writing complex macros in Rust: Reverse Polish Notation</title>
		<link href="https://rreverser.com/writing-complex-macros-in-rust/"/>
		<updated>2018-01-15T16:25:00Z</updated>
		<id>https://rreverser.com/writing-complex-macros-in-rust/</id>
		<content type="html">&lt;p&gt;Among other interesting features, Rust has a powerful macro system. Unfortunately, even after reading The Book and various tutorials, when it came to trying to implement a macro which involved processing complex lists of different elements, I still struggled to understand how it should be done, and it took some time till I got to that &amp;quot;ding&amp;quot; moment and started misusing macros for everything :) &lt;em&gt;(ok, not everything as in the i-am-using-macros-because-i-dont-want-to-use-functions-and-specify-types-and-lifetimes everything like I&#39;ve seen some people do, but anywhere it&#39;s actually useful)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;So, here is my take on describing the principles behind writing such macros. It assumes you have read the &lt;a href=&quot;https://doc.rust-lang.org/book/first-edition/macros.html&quot;&gt;Macros&lt;/a&gt; section from The Book and are familiar with basic macros definitions and token types.&lt;/p&gt;
&lt;p&gt;I&#39;ll take a &lt;a href=&quot;https://en.wikipedia.org/wiki/Reverse_Polish_notation&quot;&gt;Reverse Polish Notation&lt;/a&gt; as an example for this tutorial. It&#39;s interesting because it&#39;s simple enough, you might be already familiar with it from school, and yet to implement it statically at compile time, you already need to use a recursive macros approach.&lt;/p&gt;
&lt;p&gt;Reverse Polish Notation (also called postfix notation) uses a stack for all its operations, so that any operand is pushed onto the stack, and any &lt;em&gt;[binary]&lt;/em&gt; operator takes two operands from the stack, evaluates the result and puts it back. So an expression like following:&lt;/p&gt;
&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;2 3 + 4 *&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;translates into:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Put &lt;code&gt;2&lt;/code&gt; onto the stack.&lt;/li&gt;
&lt;li&gt;Put &lt;code&gt;3&lt;/code&gt; onto the stack.&lt;/li&gt;
&lt;li&gt;Take two last values from the stack (&lt;code&gt;3&lt;/code&gt; and &lt;code&gt;2&lt;/code&gt;), apply operator &lt;code&gt;+&lt;/code&gt; and put the result (&lt;code&gt;5&lt;/code&gt;) back onto the stack.&lt;/li&gt;
&lt;li&gt;Put &lt;code&gt;4&lt;/code&gt; onto the stack.&lt;/li&gt;
&lt;li&gt;Take two last values from the stack (&lt;code&gt;4&lt;/code&gt; and &lt;code&gt;5&lt;/code&gt;), apply operator &lt;code&gt;*&lt;/code&gt; (&lt;code&gt;4 * 5&lt;/code&gt;) and put the result (&lt;code&gt;20&lt;/code&gt;) back onto the stack.&lt;/li&gt;
&lt;li&gt;End of expression, the single value on the stack is the result (&lt;code&gt;20&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In a more common infix notation, used in math and most modern programming languages, the expression would look like &lt;code&gt;(2 + 3) * 4&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;So let&#39;s write a macro that would evaluate RPN at compile-time by converting it into an infix notation that Rust understands.&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;macro_rules!&lt;/span&gt; rpn &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// TODO&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token macro property&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;{}&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token macro property&quot;&gt;rpn!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 20&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&#39;s start with pushing numbers onto the stack.&lt;/p&gt;
&lt;p&gt;Macros currently don&#39;t allow matching literals, and &lt;code&gt;expr&lt;/code&gt; won&#39;t work for us because it can accidentally match sequence like &lt;code&gt;2 + 3 ...&lt;/code&gt; instead of taking just a single number, so we&#39;ll resort to &lt;code&gt;tt&lt;/code&gt; - a generic token matcher that matches only one token tree (whether it&#39;s a primitive token like literal/identifier/lifetime/etc. or a &lt;code&gt;()&lt;/code&gt;/&lt;code&gt;[]&lt;/code&gt;/&lt;code&gt;{}&lt;/code&gt;-parenthesized expression containing more tokens):&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;macro_rules!&lt;/span&gt; rpn &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$num&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// TODO&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, we&#39;ll need a variable for the stack.&lt;/p&gt;
&lt;p&gt;Macros can&#39;t use real variables, because we want this stack to exist only at compile time. So, instead, the trick is to have a separate token sequence that can be passed around, and so used as kind of an accumulator.&lt;/p&gt;
&lt;p&gt;In our case, let&#39;s represent it as a comma-separated sequence of &lt;code&gt;expr&lt;/code&gt; (since we will be using it not only for simple numbers but also for intermediate infix expressions) and wrap it into brackets to separate from the rest of the input:&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;macro_rules!&lt;/span&gt; rpn &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;expr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$num&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// TODO&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, a token sequence is not really a variable - you can&#39;t modify it in-place and do something afterwards. Instead, you can create a new copy of this token sequence with necessary modifications, and recursively call same macro again.&lt;/p&gt;
&lt;p&gt;If you are coming from functional language background or worked with any library providing immutable data before, both of these approaches - mutating data by creating a modified copy and processing lists with a recursion - are likely already familiar to you:&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;macro_rules!&lt;/span&gt; rpn &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;expr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$num&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token macro property&quot;&gt;rpn!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$num&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, obviously, the case with just a single number is rather unlikely and not very interesting to us, so we&#39;ll need to match anything else after that number as a sequence of zero or more &lt;code&gt;tt&lt;/code&gt; tokens, which can be passed to next invocation of our macro for further matching and processing:&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;macro_rules!&lt;/span&gt; rpn &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;expr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$num&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token macro property&quot;&gt;rpn!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$num&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At this point we&#39;re still missing operator support. How do we match operators?&lt;/p&gt;
&lt;p&gt;If our RPN would be a sequence of tokens that we would want to process in an exactly same way, we could simply use a list like &lt;code&gt;$($token:tt)*&lt;/code&gt;. Unfortunately, that wouldn&#39;t give us an ability to go through list and either push an operand or apply an operator depending on each token.&lt;/p&gt;
&lt;p&gt;The Book says that &amp;quot;macro system does not deal with parse ambiguity at all&amp;quot;, and that&#39;s true for a single macros branch - we can&#39;t match a sequence of numbers followed by an operator like &lt;code&gt;$($num:tt)* +&lt;/code&gt; because &lt;code&gt;+&lt;/code&gt; is also a valid token and could be matched by the &lt;code&gt;tt&lt;/code&gt; group, but this is where recursive macros helps again.&lt;/p&gt;
&lt;p&gt;If you have different branches in your macro definition, Rust will try them one by one, so we can put our operator branches before the numeric one and, this way, avoid any conflict:&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;macro_rules!&lt;/span&gt; rpn &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;expr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// TODO&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;expr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// TODO&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;expr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// TODO&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;expr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// TODO&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;expr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$num&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token macro property&quot;&gt;rpn!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$num&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As I said earlier, operators are applied to the last two numbers on the stack, so we&#39;ll need to match them separately, &amp;quot;evaluate&amp;quot; the result (construct a regular infix expression) and put it back:&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;macro_rules!&lt;/span&gt; rpn &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$b&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;expr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;expr&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;expr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token macro property&quot;&gt;rpn!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$b&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$b&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;expr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;expr&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;expr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token macro property&quot;&gt;rpn!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$b&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$b&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;expr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;expr&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;expr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token macro property&quot;&gt;rpn!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$b&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$b&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;expr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;expr&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;expr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token macro property&quot;&gt;rpn!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$b&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;expr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$num&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token macro property&quot;&gt;rpn!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$num&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I&#39;m not really fan of such obvious repetitions, but, just like with literals, there is no special token type to match operators.&lt;/p&gt;
&lt;p&gt;What we can do, however, is add a helper that would be responsible for the evaluation, and delegate any explicit operator branch to it.&lt;/p&gt;
&lt;p&gt;In macros, you can&#39;t really use an external helper, but the only thing you can be sure about is that your macros is already in scope, so the usual trick is to have a branch in the same macro &amp;quot;marked&amp;quot; with some unique token sequence, and call it recursively like we did in regular branches.&lt;/p&gt;
&lt;p&gt;Let&#39;s use &lt;code&gt;@op&lt;/code&gt; as such marker, and accept any operator via &lt;code&gt;tt&lt;/code&gt; inside it (&lt;code&gt;tt&lt;/code&gt; would be unambiguous in such context because we&#39;ll be passing only operators to this helper).&lt;/p&gt;
&lt;p&gt;And the stack does not need to be expanded in each separate branch anymore - since we wrapped it into &lt;code&gt;[]&lt;/code&gt; brackets earlier, it can be matched as any another token tree (&lt;code&gt;tt&lt;/code&gt;), and then passed into our helper:&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;macro_rules!&lt;/span&gt; rpn &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;@&lt;/span&gt;op &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$b&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;expr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;expr&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;expr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$op&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token macro property&quot;&gt;rpn!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$a&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$op&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$b&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token macro property&quot;&gt;rpn!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;@&lt;/span&gt;op &lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token macro property&quot;&gt;rpn!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;@&lt;/span&gt;op &lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token macro property&quot;&gt;rpn!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;@&lt;/span&gt;op &lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token macro property&quot;&gt;rpn!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;@&lt;/span&gt;op &lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;expr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$num&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token macro property&quot;&gt;rpn!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$num&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now any tokens are processed by corresponding branches, and we need to just handle final case when stack contains a single item, and no more tokens are left:&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;macro_rules!&lt;/span&gt; rpn &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;

  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;expr&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$result&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At this point, if you invoke this macro with an empty stack and RPN expression, it will already produce a correct result:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://play.rust-lang.org/?gist=cd56f6d7335e2d27c05e7fa89545b2cd&amp;amp;version=stable&quot;&gt;Playground&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;{}&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token macro property&quot;&gt;rpn!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 20&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, our stack is an implementation detail and we really wouldn&#39;t want every consumer to pass an empty stack in, so let&#39;s add another catch-all branch in the end that would serve as an entry point and add &lt;code&gt;[]&lt;/code&gt; automatically:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://play.rust-lang.org/?gist=d94abc0e20aa5c7f689706af06fd1923&amp;amp;version=stable&quot;&gt;Playground&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;macro_rules!&lt;/span&gt; rpn &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;

  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;$&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tokens&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token macro property&quot;&gt;rpn!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tokens&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token macro property&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;{}&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token macro property&quot;&gt;rpn!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 20&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Our macro even works for more complex expressions, like the one &lt;a href=&quot;https://en.wikipedia.org/wiki/Reverse_Polish_notation#Example&quot;&gt;from Wikipedia page about RPN&lt;/a&gt;!&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;{}&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token macro property&quot;&gt;rpn!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 5&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;error-handling&quot; tabindex=&quot;-1&quot;&gt;Error handling &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/writing-complex-macros-in-rust/#error-handling&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Now everything seems to work smoothly for correct RPN expressions, but for a macros to be production-ready we need to be sure that it can handle invalid input as well, with a reasonable error message.&lt;/p&gt;
&lt;p&gt;First, let&#39;s try to insert another number in the middle and see what happens:&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;{}&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token macro property&quot;&gt;rpn!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Output:&lt;/p&gt;
&lt;pre class=&quot;language-log&quot;&gt;&lt;code class=&quot;language-log&quot;&gt;error&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;E0277&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; the trait bound `&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;{&lt;/span&gt;integer&lt;span class=&quot;token operator&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; std&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;fmt&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;Display` is not satisfied
  &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; src&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;main&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;rs&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;36&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;
   &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;36&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;     println&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;{}&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rpn&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;                    &lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt; `&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;{&lt;/span&gt;integer&lt;span class=&quot;token operator&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;` cannot be formatted with the default formatter&lt;span class=&quot;token operator&quot;&gt;;&lt;/span&gt; try using `&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;` instead if you are using a format string
   &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; help&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; the trait `std&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;fmt&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;Display` is not implemented for `&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;{&lt;/span&gt;integer&lt;span class=&quot;token operator&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;`
   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; note&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; required by `std&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;fmt&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;Display&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;fmt`&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Okay, that definitely doesn&#39;t look helpful as it doesn&#39;t provide any information relevant to the actual mistake in the expression.&lt;/p&gt;
&lt;p&gt;In order to figure out what happened, we will need to debug our macros. For that, we&#39;ll use a &lt;a href=&quot;https://doc.rust-lang.org/beta/unstable-book/library-features/trace-macros.html&quot;&gt;&lt;code&gt;trace_macros&lt;/code&gt;&lt;/a&gt; feature (and, like for any other optional compiler feature, you&#39;ll need a nightly version of Rust). We don&#39;t want to trace &lt;code&gt;println!&lt;/code&gt; call, so we&#39;ll separate our RPN calculation to a variable:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://play.rust-lang.org/?gist=610bc0c241aacda3d30a916f89b244cd&amp;amp;version=nightly&quot;&gt;Playground&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token attribute attr-name&quot;&gt;#![feature(trace_macros)]&lt;/span&gt;

&lt;span class=&quot;token macro property&quot;&gt;macro_rules!&lt;/span&gt; rpn &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* ... */&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token macro property&quot;&gt;trace_macros!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; e &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token macro property&quot;&gt;rpn!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token macro property&quot;&gt;trace_macros!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token macro property&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;{}&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the output we&#39;ll now see how our macro is being recursively evaluated step by step:&lt;/p&gt;
&lt;pre class=&quot;language-log&quot;&gt;&lt;code class=&quot;language-log&quot;&gt;&lt;span class=&quot;token property&quot;&gt;note:&lt;/span&gt; trace_macro
  &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; src&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;main&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;rs&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;39&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;13&lt;/span&gt;
   &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;39&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;     let e &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; rpn&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;             &lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;
   &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; note&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; expanding `rpn&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;}&lt;/span&gt;`
   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; note&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; to `rpn &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;)&lt;/span&gt;`
   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; note&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; expanding `rpn&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;}&lt;/span&gt;`
   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; note&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; to `rpn &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;)&lt;/span&gt;`
   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; note&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; expanding `rpn&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;}&lt;/span&gt;`
   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; note&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; to `rpn &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;)&lt;/span&gt;`
   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; note&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; expanding `rpn&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;}&lt;/span&gt;`
   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; note&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; to `rpn &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;)&lt;/span&gt;`
   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; note&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; expanding `rpn&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;}&lt;/span&gt;`
   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; note&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; to `rpn &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;@&lt;/span&gt; op &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;)&lt;/span&gt;`
   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; note&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; expanding `rpn&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;@&lt;/span&gt; op &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;}&lt;/span&gt;`
   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; note&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; to `rpn &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;)&lt;/span&gt;`
   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; note&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; expanding `rpn&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;}&lt;/span&gt;`
   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; note&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; to `rpn &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;)&lt;/span&gt;`
   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; note&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; expanding `rpn&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;}&lt;/span&gt;`
   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; note&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; to `rpn &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;@&lt;/span&gt; op &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;)&lt;/span&gt;`
   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; note&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; expanding `rpn&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;@&lt;/span&gt; op &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;}&lt;/span&gt;`
   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; note&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; to `rpn &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;)&lt;/span&gt;`
   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; note&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; expanding `rpn&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;}&lt;/span&gt;`
   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; note&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; to `rpn &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;)&lt;/span&gt;`
   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; note&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; expanding `rpn&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;}&lt;/span&gt;`
   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; note&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; to `rpn &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;)&lt;/span&gt;`
   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; note&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; expanding `rpn&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;}&lt;/span&gt;`
   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; note&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; to `&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;`&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If we carefully look through the trace, we&#39;ll notice that the problem originates in these steps:&lt;/p&gt;
&lt;pre class=&quot;language-log&quot;&gt;&lt;code class=&quot;language-log&quot;&gt;   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; note&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; expanding `rpn&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;}&lt;/span&gt;`
   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; note&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; to `rpn &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;)&lt;/span&gt;`&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since &lt;code&gt;[ 3 + 7 * 4 , 2 ]&lt;/code&gt; was not matched by &lt;code&gt;([$result:expr]) =&amp;gt; ...&lt;/code&gt; branch as a final expression, it was caught by our final catch-all &lt;code&gt;($($tokens:tt)*) =&amp;gt; ...&lt;/code&gt; branch instead, prepended with an empty stack &lt;code&gt;[]&lt;/code&gt; and then the original &lt;code&gt;[ 3 + 7 * 4 , 2 ]&lt;/code&gt; was matched by generic &lt;code&gt;$num:tt&lt;/code&gt; and pushed onto the stack as a single final value.&lt;/p&gt;
&lt;p&gt;In order to prevent this from happening, let&#39;s insert another branch between these last two that would match any stack.&lt;/p&gt;
&lt;p&gt;It would be hit only when we ran out of tokens, but stack didn&#39;t have exactly one final value, so we can treat it as a compile error and produce a more helpful error message using a built-in &lt;a href=&quot;https://doc.rust-lang.org/std/macro.compile_error.html&quot;&gt;&lt;code&gt;compile_error!&lt;/code&gt;&lt;/a&gt; macro.&lt;/p&gt;
&lt;p&gt;Note that we can&#39;t use &lt;code&gt;format!&lt;/code&gt; in this context since it uses runtime APIs to format a string, and instead we&#39;ll have to limit ourselves to built-in &lt;code&gt;concat!&lt;/code&gt; and &lt;code&gt;stringify!&lt;/code&gt; macros to format a message:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://play.rust-lang.org/?gist=e56be9422387bcae54aab3b8405a11e7&amp;amp;version=stable&quot;&gt;Playground&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;macro_rules!&lt;/span&gt; rpn &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;

  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;expr&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$result&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;expr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token macro property&quot;&gt;compile_error!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token macro property&quot;&gt;concat!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&quot;Could not find final value for the expression, perhaps you missed an operator? Final stack: &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token macro property&quot;&gt;stringify!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;$&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tokens&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token macro property&quot;&gt;rpn!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tokens&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The error message is now more meaningful and contains at least some details about current state of evaluation:&lt;/p&gt;
&lt;pre class=&quot;language-log&quot;&gt;&lt;code class=&quot;language-log&quot;&gt;&lt;span class=&quot;token property&quot;&gt;error:&lt;/span&gt; Could not find final value for the expression&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; perhaps you missed an operator&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; Final stack&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; src&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;main&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;rs&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;31&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;9&lt;/span&gt;
   &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;31&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;         compile_error&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;(&lt;/span&gt;concat&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Could not find final value for the expression, perhaps you missed an operator? Final stack: &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; stringify&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt;stack&lt;span class=&quot;token operator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;         &lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;40&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;     println&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;{}&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rpn&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;                    &lt;span class=&quot;token separator comment&quot;&gt;-----------------&lt;/span&gt; in this macro invocation&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But what if, instead, we miss some number?&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://play.rust-lang.org/?gist=ce40630b8c1aa610c46b94557fdc9905&amp;amp;version=stable&quot;&gt;Playground&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;{}&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token macro property&quot;&gt;rpn!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Unfortunately, this one is still not too helpful:&lt;/p&gt;
&lt;pre class=&quot;language-log&quot;&gt;&lt;code class=&quot;language-log&quot;&gt;&lt;span class=&quot;token property&quot;&gt;error:&lt;/span&gt; expected expression&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; found `&lt;span class=&quot;token operator&quot;&gt;@&lt;/span&gt;`
  &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; src&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;main&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;rs&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;14&lt;/span&gt;
   &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;         rpn&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;@&lt;/span&gt;op &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt;stack &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt;rest&lt;span class=&quot;token operator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;              &lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;40&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;     println&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;{}&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rpn&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;                    &lt;span class=&quot;token separator comment&quot;&gt;-------------&lt;/span&gt; in this macro invocation&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you try to use &lt;code&gt;trace_macros&lt;/code&gt;, even it won&#39;t expand the stack here for some reason, but, luckily, it&#39;s relatively clear what&#39;s going on - &lt;code&gt;@op&lt;/code&gt; has very specific conditions as to what should be matched (it expects at least two values on the stack), and, when it can&#39;t, &lt;code&gt;@&lt;/code&gt; gets matched by the same way-too-greedy &lt;code&gt;$num:tt&lt;/code&gt; and pushed onto the stack.&lt;/p&gt;
&lt;p&gt;To avoid this, again, we&#39;ll add another branch to match anything starting with &lt;code&gt;@op&lt;/code&gt; that wasn&#39;t matched already, and produce a compile error:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://play.rust-lang.org/?gist=8729a8f3c96fa58ed62d35804c48782d&amp;amp;version=stable&quot;&gt;Playground&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;macro_rules!&lt;/span&gt; rpn &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;@&lt;/span&gt;op &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$b&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;expr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;expr&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;expr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$op&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token macro property&quot;&gt;rpn!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$a&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$op&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$b&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;@&lt;/span&gt;op &lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$op&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$rest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token fragment-specifier punctuation&quot;&gt;tt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token macro property&quot;&gt;compile_error!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token macro property&quot;&gt;concat!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&quot;Could not apply operator `&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token macro property&quot;&gt;stringify!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$op&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&quot;` to the current stack: &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token macro property&quot;&gt;stringify!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&#39;s try again:&lt;/p&gt;
&lt;pre class=&quot;language-log&quot;&gt;&lt;code class=&quot;language-log&quot;&gt;&lt;span class=&quot;token property&quot;&gt;error:&lt;/span&gt; Could not apply operator `&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;` to the current stack&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; src&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;main&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;rs&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;9&lt;/span&gt;
   &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;9&lt;/span&gt;  &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;         compile_error&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;(&lt;/span&gt;concat&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Could not apply operator &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; stringify&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt;op&lt;span class=&quot;token operator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; to current stack: &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; stringify&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt;stack&lt;span class=&quot;token operator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;         &lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;46&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;     println&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;{}&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rpn&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;                    &lt;span class=&quot;token separator comment&quot;&gt;-------------&lt;/span&gt; in this macro invocation&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Much better! Now our macro can evaluate any RPN expression at compile-time, and gracefully handles most common mistakes, so let&#39;s call it a day and say it&#39;s production-ready :)&lt;/p&gt;
&lt;p&gt;There are many more small improvements we could add, but I&#39;d like to leave them outside this demonstration tutorial.&lt;/p&gt;
&lt;p&gt;Feel free to let me know if this has been useful and/or what topics you&#39;d like to see better covered &lt;a href=&quot;https://twitter.com/RReverser&quot;&gt;on Twitter&lt;/a&gt;!&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Conditional enum variants in Rust</title>
		<link href="https://rreverser.com/conditional-enum-variants-in-rust/"/>
		<updated>2017-12-26T23:30:00Z</updated>
		<id>https://rreverser.com/conditional-enum-variants-in-rust/</id>
		<content type="html">&lt;p&gt;Recently, I had to implement a set of types (AST nodes) in Rust that would be generic over boolean flags. More specifically, they had to be statically dependant on compile-time boolean parameters, where instances of the same type with &lt;code&gt;false&lt;/code&gt; and &lt;code&gt;true&lt;/code&gt; values of such parameter would be incompatible, as these flags would not only determine behaviour of &lt;code&gt;impl&lt;/code&gt; but also affect e.g. which branches of &lt;code&gt;enum&lt;/code&gt; are allowed. Pseudo code sample for demonstration purposes:&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;token type-definition class-name&quot;&gt;MyEnum&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;AllowB&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token class-name&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token class-name&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AllowB&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// this won&#39;t be allowed on MyEnum&amp;lt;false&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;AllowB&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MyEnum&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;AllowB&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;is_a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token class-name&quot;&gt;MyEnum&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      _ &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MyEnum&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// this won&#39;t be allowed on MyEnum&amp;lt;false&gt;, giving a helpful compile-time error&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;is_b&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token class-name&quot;&gt;MyEnum&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      _ &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first thing that comes to mind is the &lt;a href=&quot;https://github.com/rust-lang/rfcs/blob/master/text/2000-const-generics.md&quot;&gt;RFC #2000&lt;/a&gt; for const generics which would allow parametrising types over any compile-time constant values. Unfortunately, while the RFC has been accepted, it&#39;s not implemented even in nightly yet, and some implementation details are still in flux. Apart from that, it&#39;s unlikely to help with the &lt;code&gt;enum&lt;/code&gt; variants requirement, even though it does ensure the other two.&lt;/p&gt;
&lt;p&gt;What can we do instead? Well, why don&#39;t we try and implement booleans using the Rust type system? Then we will be able to pass them around, check and manipulate purely at compile-time.&lt;/p&gt;
&lt;p&gt;First of all, let&#39;s define trait for our &lt;code&gt;Bool&lt;/code&gt; which would determine what we can do with such boolean flags.&lt;/p&gt;
&lt;p&gt;For the beginning, let&#39;s say we want to have just conversion to actual runtime boolean value. This will be done through an associated constant as our boolean variants are statically determined at compile-time.&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;token type-definition class-name&quot;&gt;Bool&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;VALUE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, let&#39;s implement actual variants of our &lt;code&gt;Bool&lt;/code&gt; as zero-size types implementing this trait:&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token type-definition class-name&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Bool&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;True&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;VALUE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token type-definition class-name&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Bool&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;False&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;VALUE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Great! Now we can use these flags to implement our &lt;code&gt;enum&lt;/code&gt;. Note that &lt;code&gt;if someFlag&lt;/code&gt; is still not a valid Rust syntax, so instead we just store the flag inside of the variant payload:&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;token type-definition class-name&quot;&gt;MyEnum&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;AllowB&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token class-name&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token class-name&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;AllowB&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// TODO: disallow on MyEnum&amp;lt;False&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;AllowB&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MyEnum&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;AllowB&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;is_a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token class-name&quot;&gt;MyEnum&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      _ &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MyEnum&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// this won&#39;t be allowed on MyEnum&amp;lt;False&gt;, giving a helpful compile-time error&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;is_b&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token class-name&quot;&gt;MyEnum&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      _ &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If we try it, we can see that &lt;code&gt;impl&lt;/code&gt; blocks work as expected:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://play.rust-lang.org/?gist=18f0cfb2a012f5257d3d7f5f5f45cf58&amp;amp;version=stable&quot;&gt;[playground]&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MyEnum&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MyEnum&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token macro property&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;{}&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;is_a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// prints &quot;true&quot;&lt;/span&gt;
&lt;span class=&quot;token macro property&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;{}&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;is_b&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// error[E0599]: no method named `is_b` found for type `MyEnum&amp;lt;False&gt;` in the current scope&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Great! One issue remains though: while these flags are visible in the generated docs and should help the developer using our API understand that they should never use the &lt;code&gt;B&lt;/code&gt; variant when &lt;code&gt;AllowB&lt;/code&gt; is false-ish, this is not a strong enough guarantee which might still lead to accidental mistakes:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://play.rust-lang.org/?gist=2a2ed6990da44b0c0e5308cac32a07e8&amp;amp;version=stable&quot;&gt;[playground]&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MyEnum&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MyEnum&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// compiles while it shouldn&#39;t&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apart from that, the compiler doesn&#39;t know either that &lt;code&gt;B&lt;/code&gt; variant simply can&#39;t exist on &lt;code&gt;MyEnum&amp;lt;False&amp;gt;&lt;/code&gt; and so can&#39;t provide better optimisations. If we look at the generated code for, say, &lt;code&gt;MyEnum&amp;lt;False&amp;gt;::is_a&lt;/code&gt;, we can see that it still tries to check the tag at the beginning of our enum at runtime even though it should be able to statically determine the result as &lt;code&gt;true&lt;/code&gt; since only variant &lt;code&gt;A&lt;/code&gt; can exist on such type!&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://godbolt.org/g/fdcaHu&quot;&gt;[disassembly]&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-nasm&quot;&gt;&lt;code class=&quot;language-nasm&quot;&gt;&lt;span class=&quot;token label function&quot;&gt;example:&lt;/span&gt;:test_is_a:
  xor dil, &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
  mov &lt;span class=&quot;token register variable&quot;&gt;eax&lt;/span&gt;, &lt;span class=&quot;token register variable&quot;&gt;edi&lt;/span&gt;
  ret&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To solve these two issues, we can use a trick with so-called uninhabited type:&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;token type-definition class-name&quot;&gt;Void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The trick is, while this type definition is perfectly valid in Rust, it has no variants, which means that you can&#39;t actually construct values of this type (unlike in C, Rust enums have much stronger guarantees and are not just glorified integer constants).&lt;/p&gt;
&lt;p&gt;Moreover, such type &amp;quot;infects&amp;quot; all its usages - since you can&#39;t construct values of this type, any type containing &lt;code&gt;Void&lt;/code&gt; becomes uninhabited too, and, in turn, any place where you&#39;re dealing with values of any such type, becomes unreachable and can be optimised out as dead code.&lt;/p&gt;
&lt;p&gt;This is often used as a placeholder for generic params which we know can&#39;t be ever instantiated. For example, it&#39;s used by standard library as a &lt;a href=&quot;https://doc.rust-lang.org/std/string/enum.ParseError.html&quot;&gt;&lt;code&gt;ParseError&lt;/code&gt;&lt;/a&gt; for &lt;a href=&quot;https://doc.rust-lang.org/std/string/struct.String.html#impl-FromStr&quot;&gt;&lt;code&gt;FromStr&lt;/code&gt; implementation on &lt;code&gt;String&lt;/code&gt;&lt;/a&gt; - indeed, since string can be always converted to string, there is no way an error could be produced by this operation, which means we can provide a placeholder for &lt;code&gt;Err&lt;/code&gt; part of &lt;code&gt;Result&lt;/code&gt; which can&#39;t be actually constructed, and compiler will know that this operation is infallible.&lt;/p&gt;
&lt;p&gt;Let&#39;s see how we can use this property for our original task. Assuming that our desired flag is always true-ish (and if not, we can implement unary not operator), we can make &lt;code&gt;False&lt;/code&gt; an uninhabited type, which in turn will make any variants containing it uninhabited too. This might sound complicated, but the change is as simple as:&lt;/p&gt;
&lt;pre class=&quot;language-diff-rust&quot;&gt;&lt;code class=&quot;language-diff-rust&quot;&gt;&lt;span class=&quot;token deleted-sign deleted language-rust&quot;&gt;&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token type-definition class-name&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted language-rust&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;token type-definition class-name&quot;&gt;False&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, if we try this with our last example, we will immediately get a compile error as &lt;code&gt;False&lt;/code&gt; is an enum now:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://play.rust-lang.org/?gist=1ca97ce4675508b255960a2803350524&amp;amp;version=stable&quot;&gt;[playground]&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;error&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;E0423&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; expected value&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; found &lt;span class=&quot;token keyword&quot;&gt;enum&lt;/span&gt; `&lt;span class=&quot;token class-name&quot;&gt;False&lt;/span&gt;`
  &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&gt;&lt;/span&gt; src&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;main&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;rs&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;36&lt;/span&gt;
   &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;42&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;   &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; _e&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MyEnum&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MyEnum&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;                                    &lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt; not a value&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And, since it has no variants, there is nothing you can put on the right-hand side of this assignment to make it work. Neither you can assign &lt;code&gt;MyEnum::B(True)&lt;/code&gt; to &lt;code&gt;MyEnum&amp;lt;False&amp;gt;&lt;/code&gt; variable:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://play.rust-lang.org/?gist=c63d7a32f680226eec61e194d62bec34&amp;amp;version=stable&quot;&gt;[playground]&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token number&quot;&gt;42&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;   &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; _e&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MyEnum&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MyEnum&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;                                     &lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt; expected &lt;span class=&quot;token keyword&quot;&gt;enum&lt;/span&gt; `&lt;span class=&quot;token class-name&quot;&gt;False&lt;/span&gt;`&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; found &lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; `&lt;span class=&quot;token class-name&quot;&gt;True&lt;/span&gt;`
   &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; note&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; expected &lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; `&lt;span class=&quot;token class-name&quot;&gt;False&lt;/span&gt;`
              found &lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; `&lt;span class=&quot;token class-name&quot;&gt;True&lt;/span&gt;`&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, if you set the &lt;code&gt;AllowB&lt;/code&gt; to &lt;code&gt;True&lt;/code&gt;, you can start accepting &lt;code&gt;MyEnum::B&lt;/code&gt; as expected:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://play.rust-lang.org/?gist=3f9cb7cf6bd7131729637a99ef64df1d&amp;amp;version=stable&quot;&gt;[playground]&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; _e&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MyEnum&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MyEnum&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// compiles&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apart from type safety, the advanced optimisations are now possible too. In particular, &lt;code&gt;MyEnum&amp;lt;False&amp;gt;::is_a&lt;/code&gt; now just returns constant &lt;code&gt;true&lt;/code&gt; as we wanted:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://godbolt.org/g/DWH21r&quot;&gt;[disassembly]&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-nasm&quot;&gt;&lt;code class=&quot;language-nasm&quot;&gt;&lt;span class=&quot;token label function&quot;&gt;example:&lt;/span&gt;:test_is_a:
  mov &lt;span class=&quot;token register variable&quot;&gt;al&lt;/span&gt;, &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
  ret&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So we can see everything works as expected, even if with the little annoyance of having to store the &lt;code&gt;True&lt;/code&gt; flag on the variant.&lt;/p&gt;
&lt;p&gt;If we wish, we could now implement all the logical operators on top of these values (after all, Rust&#39;s type system is Turing-complete), but I wouldn&#39;t go that far in this post.&lt;/p&gt;
&lt;p&gt;Hope this has been useful. Let me know &lt;a href=&quot;https://twitter.com/RReverser&quot;&gt;on Twitter&lt;/a&gt; if you have any thoughts about the approach.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Github project: derex</title>
		<link href="https://github.com/RReverser/derex"/>
		<updated>2017-09-26T10:56:15Z</updated>
		<id>https://github.com/RReverser/derex</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: emnapi</title>
		<link href="https://github.com/RReverser/emnapi"/>
		<updated>2017-06-04T14:18:06Z</updated>
		<id>https://github.com/RReverser/emnapi</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Parsing JavaScript using SpiderMonkey from Rust</title>
		<link href="https://rreverser.com/parsing-javascript-using-spidermonkey-from-rust/"/>
		<updated>2017-06-03T14:21:00Z</updated>
		<id>https://rreverser.com/parsing-javascript-using-spidermonkey-from-rust/</id>
		<content type="html">&lt;p&gt;&lt;a href=&quot;https://github.com/RReverser/esmozy&quot;&gt;View on GitHub&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;SpiderMonkey AST is largely compatible with &lt;a href=&quot;https://github.com/estree/estree&quot;&gt;ESTree&lt;/a&gt;, and can be made fully compatible by overriding AST builders via options.&lt;/p&gt;
&lt;p&gt;Additionally, SpiderMonkey, unlike all the other JavaScript engines, exposes its parser via a public API - &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Parser_API#Reflect.parse(src_options)&quot;&gt;&lt;code&gt;Reflect.parse&lt;/code&gt;&lt;/a&gt; - available even from their JavaScript console.&lt;/p&gt;
&lt;p&gt;This repo is a prototype to get ESTree AST in Rust by literally embedding SpiderMonkey and invoking JavaScript that calls &lt;code&gt;Reflect.parse&lt;/code&gt; and passes result back in JSON format, which is easily consumable by Rust side or can be passed further.&lt;/p&gt;
&lt;p&gt;As turned out, &lt;em&gt;(surprise!)&lt;/em&gt; speed of such approach is not very appealing, but it might work for prototyping JavaScript tooling in Rust until better parsers are available.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Reducing test cases for JavaScript tooling</title>
		<link href="https://rreverser.com/reducing-test-cases-for-javascript-tooling/"/>
		<updated>2017-05-10T08:15:17Z</updated>
		<id>https://rreverser.com/reducing-test-cases-for-javascript-tooling/</id>
		<content type="html">&lt;p&gt;At some point, I&#39;ve performed testing of one Go-based streaming JavaScript minifier for compatibility with real-world code.&lt;/p&gt;
&lt;p&gt;I&#39;ve decided to run it against CDNjs repo (&lt;a href=&quot;https://cdnjs.com/libraries&quot;&gt;https://cdnjs.com/libraries&lt;/a&gt;) as a source of all the possible popular libraries, which makes it a decent test suite for JavaScript/CSS tooling.&lt;/p&gt;
&lt;p&gt;After narrowing the list to just JavaScript libraries, then only to latest version of each, and then to those that don&#39;t end with .min.js to avoid obviously pre-minified ones (and speed up testing), I&#39;ve got 17,547 JavaScript files with a total weight of 771 MB.&lt;/p&gt;
&lt;p&gt;Then, I&#39;ve run them all against latest &lt;code&gt;minify&lt;/code&gt; binary and parsed with a full-featured (non-streaming) ES5 parser to compare ASTs before and after transformation to detect semantic mismatches or syntactically broken files.&lt;/p&gt;
&lt;p&gt;You can see detailed results and findings on the &lt;a href=&quot;https://github.com/tdewolff/minify/issues/132&quot;&gt;original issue&lt;/a&gt;, but I&#39;d like to stop on one interesting case.&lt;/p&gt;
&lt;p&gt;Minification of &lt;a href=&quot;https://cdnjs.cloudflare.com/ajax/libs/webshim/1.16.0/minified/shims/moxie/js/moxie-html4.js&quot;&gt;moxie-html4.js&lt;/a&gt; from &lt;a href=&quot;https://cdnjs.com/libraries/webshim&quot;&gt;webshim&lt;/a&gt; library and further AST (format-agnostic) comparison revealed the following changes:&lt;/p&gt;
&lt;pre class=&quot;language-diff-js&quot;&gt;&lt;code class=&quot;language-diff-js&quot;&gt;&lt;span class=&quot;token coord&quot;&gt;@@ -2736,12 +2736,12 @@&lt;/span&gt;
&lt;span class=&quot;token unchanged language-js&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;                    &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Flash&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;                    &lt;span class=&quot;token number&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Fine weather&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;                    &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Cloudy weather&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;                    &lt;span class=&quot;token number&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Shade&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token deleted-sign deleted language-js&quot;&gt;&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt;                    &lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Daylight fluorescent (D 5700 - 7100K)&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt;                    &lt;span class=&quot;token number&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Day white fluorescent (N 4600 -5400K)&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt;                    &lt;span class=&quot;token number&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Cool white fluorescent (W 3900 - 4500K)&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt;                    &lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;White fluorescent (WW 3200 - 3700K)&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted language-js&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;                    &lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Daylight fluorescent(D 5700-7100K)&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;                    &lt;span class=&quot;token number&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Day white fluorescent(N 4600-5400K)&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;                    &lt;span class=&quot;token number&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Cool white fluorescent(W 3900-4500K)&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;                    &lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;White fluorescent(WW 3200-3700K)&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token unchanged language-js&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;                    &lt;span class=&quot;token number&quot;&gt;17&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Standard light A&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;                    &lt;span class=&quot;token number&quot;&gt;18&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Standard light B&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;                    &lt;span class=&quot;token number&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Standard light C&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;                    &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;D55&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;...&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Clearly, something went wrong that caused significant spaces in strings to disappear.&lt;/p&gt;
&lt;p&gt;But how do we figure out what exactly caused that, given that the rest of the file was correct? We can&#39;t just manually remove lines here and there in 74 KB minified file expecting that we will be lucky and reduce it quickly (believe me, I tried that first :) ).&lt;/p&gt;
&lt;p&gt;Luckily, there is an automatic solution for that: &lt;a href=&quot;https://github.com/csmith-project/creduce&quot;&gt;creduce&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Wait, you might say, but it&#39;s README says it&#39;s a reducer for C programs. Yeah, it happens to be primarily designed for C, but, by its nature, it can also work on JavaScript, Rust and any other C-like languages, even if they have custom syntax.&lt;/p&gt;
&lt;p&gt;Basically, this tool tries to remove blocks (&lt;code&gt;{ ... }&lt;/code&gt;), expressions (identifiers, numbers, parenthesized expressions &lt;code&gt;( ... )&lt;/code&gt;, etc.), comments, pieces of strings etc. as long as provided script still fails (erm, passes), resulting in a minimal reproducible test case.&lt;/p&gt;
&lt;p&gt;First of all, we should store the original file for the base sample:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; https://cdnjs.cloudflare.com/ajax/libs/webshim/1.16.0/minified/shims/moxie/js/moxie-html4.js &lt;span class=&quot;token parameter variable&quot;&gt;-o&lt;/span&gt; html4.js&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, &lt;code&gt;creduce&lt;/code&gt; expects an &amp;quot;interestingness test&amp;quot; - a script that returns &lt;code&gt;0&lt;/code&gt; (succeeds) by default on our example, and fails otherwise. That means, we should &lt;em&gt;fail&lt;/em&gt; when resulting code either doesn&#39;t parse or it&#39;s structurally &lt;em&gt;equal&lt;/em&gt; to the original.&lt;/p&gt;
&lt;p&gt;Let&#39;s install, for example, Esprima to parse scripts and use it for a simple one-off script that will perform the actual comparison:&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token hashbang comment&quot;&gt;#!/usr/bin/node&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; readFileSync &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;fs&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; parse &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;esprima&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; notDeepEqual &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;assert&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;ast1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ast2&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;argv
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;slice&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// skip node executable and script filename&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;readFileSync&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;file&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;utf-8&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// read given files as strings&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;code&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;code&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// parse into ASTs&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;notDeepEqual&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ast1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ast2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// ensure they&#39;re still not equal&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Assume we saved it as &lt;code&gt;compare.js&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now, we need to call it right after the minifier, so let&#39;s write a wrapper shell script (&lt;code&gt;compare.sh&lt;/code&gt;) for that (we could do that from Node as well, but this might be a bit easier):&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token shebang important&quot;&gt;#!/usr/bin/env bash&lt;/span&gt;
~/minify html4.js &lt;span class=&quot;token parameter variable&quot;&gt;-o&lt;/span&gt; html4.min.js &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; ~/compare.js html4.js html4.min.js&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Make sure you&#39;re using absolute paths for custom executables. &lt;code&gt;creduce&lt;/code&gt; will be generating reduced test cases with same file name as original in temporary folders (in order to parallelize reduction) and so you can&#39;t expect your script to be caled from the same working directory as you&#39;re launching &lt;code&gt;creduce&lt;/code&gt; in.&lt;/p&gt;
&lt;p&gt;Time to ensure that it returns exit code 0 by invoking &lt;code&gt;./compare.sh&lt;/code&gt; manually, and ready to go:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ ./compare.sh
$ &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$?&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
$ creduce compare.sh html4.js&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, after quite some time of waiting and log lines, &lt;code&gt;creduce&lt;/code&gt; ends up with this JavaScript in &lt;code&gt;html4.js&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; e &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; &quot;moxie&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;runtime&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;html5&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;image&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;ExifParsersRGBUncalibratedUnknownAverageCenterWeightedAverageSpotMultiSpotPatternPartialOtherDaylightFliorescentTungstenFlashFine
                                                                                                                                                   longitude&quot; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is much better than original, and, while there are few more small things we could still reduce manually, it already reveals the problem - indeed, it&#39;s the most common problem in JavaScript parsing where context affects tokenizations and &lt;code&gt;/&lt;/code&gt; after &lt;code&gt;)&lt;/code&gt; can be parsed either as a division or a regular expression depending on tokens before the matching &lt;code&gt;)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Depending on that, it&#39;s either safe to remove space after &lt;code&gt;/&lt;/code&gt; in &lt;code&gt;if ( 0 ) /, /&lt;/code&gt; example or not - and in the given failure the tested minifier removes it despite this construct being, in fact, a regular expression.&lt;/p&gt;
&lt;p&gt;As you can see, &lt;code&gt;creduce&lt;/code&gt; is quite a powerful tool for manual reductions before trying to fix or report issues to language tooling - where it&#39;s C, Rust, JavaScript or, who knows, CSS.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Emscripten + Rust: how to interop with real JavaScript</title>
		<link href="https://rreverser.com/rust-javascript-interop/"/>
		<updated>2017-05-06T17:43:27Z</updated>
		<id>https://rreverser.com/rust-javascript-interop/</id>
		<content type="html">&lt;p&gt;My slides from &lt;a href=&quot;http://2017.rustfest.eu/&quot;&gt;RustFest 2017&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.slideshare.net/RReverser/rust-javascript&quot;&gt;https://www.slideshare.net/RReverser/rust-javascript&lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;UPD&lt;/strong&gt;: Video is up!&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://youtu.be/zxIbTfsOJZE&quot;&gt;https://youtu.be/zxIbTfsOJZE&lt;/a&gt;&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Github project: override-hosts</title>
		<link href="https://github.com/RReverser/override-hosts"/>
		<updated>2017-04-21T15:03:31Z</updated>
		<id>https://github.com/RReverser/override-hosts</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: esmod</title>
		<link href="https://github.com/RReverser/esmod"/>
		<updated>2017-03-14T21:29:56Z</updated>
		<id>https://github.com/RReverser/esmod</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: serde-xml-rs</title>
		<link href="https://github.com/RReverser/serde-xml-rs"/>
		<updated>2017-02-16T16:54:58Z</updated>
		<id>https://github.com/RReverser/serde-xml-rs</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>How we brought HTTPS Everywhere to the cloud</title>
		<link href="https://blog.cloudflare.com/how-we-brought-https-everywhere-to-the-cloud-part-1/"/>
		<updated>2016-09-24T00:00:00Z</updated>
		<id>https://blog.cloudflare.com/how-we-brought-https-everywhere-to-the-cloud-part-1/</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Tabs vs spaces: the ultimate argument</title>
		<link href="https://rreverser.com/tabs-vs-space/"/>
		<updated>2016-04-19T08:11:48Z</updated>
		<id>https://rreverser.com/tabs-vs-space/</id>
		<content type="html">&lt;p&gt;Did you know that using specific code style can affect your JavaScript performance? Gave a 1.5x performance boost in my case ;)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;That beautiful moment when you change indentation from spaces to tabs and your function suddenly becomes short enough to get inlined by V8.
— Ingvar Stepanyan (@RReverser) &lt;a href=&quot;https://twitter.com/RReverser/status/722092088213565440&quot;&gt;April 18, 2016&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
</content>
	</entry>
	
	<entry>
		<title>Github project: buffer-utf8-length</title>
		<link href="https://github.com/RReverser/buffer-utf8-length"/>
		<updated>2015-10-26T14:51:02Z</updated>
		<id>https://github.com/RReverser/buffer-utf8-length</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>GOTOs in JavaScript are now possible</title>
		<link href="https://rreverser.com/gotos-in-javascript-now-its-real/"/>
		<updated>2015-10-20T14:08:50Z</updated>
		<id>https://rreverser.com/gotos-in-javascript-now-its-real/</id>
		<content type="html">&lt;p&gt;And I&#39;m back with my crazy experiments.&lt;/p&gt;
&lt;p&gt;Currently I&#39;m actively playing with &lt;a href=&quot;http://www.colm.net/open-source/ragel/&quot;&gt;Ragel&lt;/a&gt; - state machine compiler that generates highly optimized code for streaming lexers, scanners etc. in a set of languages (C, Java, Ruby, C#, ...). Unfortunately, it didn&#39;t have support for JavaScript, and I &lt;a href=&quot;https://twitter.com/RReverser/status/654424973159870464&quot;&gt;recently implemented it&lt;/a&gt; (likely to be included in Ragel 7.0, but it&#39;s anyway worth dedicated article).&lt;/p&gt;
&lt;p&gt;Now, Ragel can generate code with various levels of optimizations. The least optimized one uses arrays of indices to search through using binary search and jump between, and the more optimized ones use &lt;code&gt;goto&lt;/code&gt; instruction for quick jumps directly between states.&lt;/p&gt;
&lt;p&gt;For languages such as C or Assembler this works great and generates proper jumps/gotos. However higher-level languages (Java, C#, Ruby, ..., and of course JavaScript) don&#39;t have any instruction like that due to &amp;quot;dirt&amp;quot; associated with this operator that discourages it&#39;s use for handwritten code - simply because it becomes unmaintainable. But this doesn&#39;t matter when our code is anyway generated from other language and result doesn&#39;t have to be comprehensible.&lt;/p&gt;
&lt;p&gt;JavaScript has a long history of compilation and transpiling from other langs (and across versions of itself), and yet it doesn&#39;t have operator that could be used when generating direct jumps. So what&#39;s the solution? Of course, to implement own extension to language with the most EVIL feature ever!&lt;/p&gt;
&lt;p&gt;And here we go: I forked &lt;a href=&quot;http://facebook.github.io/regenerator/&quot;&gt;regenerator&lt;/a&gt; - transpiler for resumable generator and async functions. It already had all the needed state analysis and expansion which are easy to reuse, and all that you need is to add new instructions and tell it where they might break code into pieces, to which places you can jump and so on.&lt;/p&gt;
&lt;p&gt;For &lt;code&gt;goto&lt;/code&gt; statements theirselves I decided to simplify task and not to introduce new syntax, but reuse existing but rare one - labels - so that you can write:&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;goto&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;do not enter&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;goto&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; z&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;goto&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; y&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Let&#39;s do some evil!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Result:&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And you get in console:&lt;/p&gt;
&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Let&#39;s do some evil!
1
2
3
Result: 4&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can play with my fork here: &lt;a href=&quot;https://github.com/RReverser/js-goto-transpiler&quot;&gt;js-goto-transpiler&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;DISCLAIMER: I&#39;m not responsible if you decide to use this feature in production and will be fired for using it :)&lt;/em&gt;&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>ES6 modules are dead, long live C preprocessor!</title>
		<link href="https://rreverser.com/es6-modules-are-dead-long-live-c-preprocessor/"/>
		<updated>2015-08-13T16:40:35Z</updated>
		<id>https://rreverser.com/es6-modules-are-dead-long-live-c-preprocessor/</id>
		<content type="html">&lt;p&gt;Did you know you could use C preprocessor even for JavaScript files? (yes, it doesn&#39;t care about syntax that much)&lt;/p&gt;
&lt;p&gt;Say, we want to implement C-like &amp;quot;modules&amp;quot; (inclusions) in JavaScript.&lt;/p&gt;
&lt;p&gt;Create first file &lt;code&gt;1.js&lt;/code&gt; (filenames don&#39;t matter) like this:&lt;/p&gt;
&lt;pre class=&quot;language-c&quot;&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;ifndef&lt;/span&gt; &lt;span class=&quot;token expression&quot;&gt;HELLO_1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;token macro-name&quot;&gt;HELLO_1&lt;/span&gt;&lt;/span&gt;

console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;hello&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;endif&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(&lt;code&gt;#ifndef&lt;/code&gt;/&lt;code&gt;#define&lt;/code&gt; is standard C practice for avoiding double-inclusion)&lt;/p&gt;
&lt;p&gt;Then, create &lt;code&gt;2.js&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-c&quot;&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;ifndef&lt;/span&gt; &lt;span class=&quot;token expression&quot;&gt;HELLO_2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;token macro-name&quot;&gt;HELLO_2&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1.js&quot;&lt;/span&gt;&lt;/span&gt;
console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;world&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;endif&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And now you can bundle them into one file with:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;cpp &lt;span class=&quot;token parameter variable&quot;&gt;-P&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-Wundef&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-nostdinc&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-C&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;.js&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(here we ask &lt;code&gt;cpp&lt;/code&gt; just to preprocess our file with basic warning and preserving comments; also we ask not to search standard C library for includes)&lt;/p&gt;
&lt;p&gt;And as a result you would get:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;hello&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;world&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that you can even define and use full-featured macroses inside of your JavaScript - just &lt;code&gt;#define&lt;/code&gt; them and ready to go!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;P.S.&lt;/strong&gt; Yes this is a crazy hack (as most of other stuff in my blog), and there are more appropriate tools for transforming JavaScript, but why not to try if we can? :)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UPD [17.08.2015]&lt;/strong&gt;: Turns out it&#39;s not as crazy experiment as I initially thought. Ryan Grove on Twitter just mentioned that they actually used this technique at Yahoo Search in 2007:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://twitter.com/RReverser&quot;&gt;@RReverser&lt;/a&gt; Believe it or not, we used this technique in our production JS workflow at Y! Search ~2007. Worked well. &lt;a href=&quot;http://t.co/HGSFfU1W1u&quot;&gt;http://t.co/HGSFfU1W1u&lt;/a&gt; &amp;gt; — Ryan Grove (@yaypie) &lt;a href=&quot;https://twitter.com/yaypie/status/633062183585234944&quot;&gt;August 16, 2015&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
</content>
	</entry>
	
	<entry>
		<title>ECMAScript Syntax Graph</title>
		<link href="https://rreverser.com/ecmascript-syntax-graph/"/>
		<updated>2015-08-09T22:12:05Z</updated>
		<id>https://rreverser.com/ecmascript-syntax-graph/</id>
		<content type="html">&lt;p&gt;Ever wondered how ECMAScript syntax spec would look like if represented as a graph? Wonder no more - I just built one for fun!&lt;/p&gt;
&lt;p&gt;Here it is in &lt;a href=&quot;https://rreverser.com/images/2015/Aug/es_spec.svg&quot;&gt;SVG&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://rreverser.com/images/2015/Aug/es_spec.svg&quot;&gt;&lt;img src=&quot;https://rreverser.com/images/2015/Aug/es_spec.svg&quot; alt=&quot;SVG&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If your browser doesn&#39;t support SVG, you can view &lt;a href=&quot;https://rreverser.com/images/2015/Aug/es_spec.png&quot;&gt;PNG&lt;/a&gt; version instead (&lt;strong&gt;but be careful on metered connections - it&#39;s 3.4 MB&lt;/strong&gt;).&lt;/p&gt;
&lt;p&gt;Note: for simplicity literals and exclusion relations (&amp;quot;but not&amp;quot; / &amp;quot;but not one of&amp;quot;) were removed from the graph - it&#39;s already too complex IMO :)&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>ECMAScript decorators on functions</title>
		<link href="https://rreverser.com/ecmascript-decorators-and-functions/"/>
		<updated>2015-08-08T00:49:14Z</updated>
		<id>https://rreverser.com/ecmascript-decorators-and-functions/</id>
		<content type="html">&lt;p&gt;&lt;a href=&quot;https://github.com/wycats/javascript-decorators/issues/4&quot;&gt;This&lt;/a&gt; &lt;a href=&quot;https://github.com/wycats/javascript-decorators/issues/30&quot;&gt;one&lt;/a&gt; &lt;a href=&quot;https://github.com/wycats/javascript-decorators/issues/31&quot;&gt;particular&lt;/a&gt; &lt;a href=&quot;https://twitter.com/dan_abramov/status/629758730951901186&quot;&gt;question&lt;/a&gt; is being often raised around the usage of the new ECMAScript &lt;a href=&quot;https://github.com/wycats/javascript-decorators&quot;&gt;decorators proposal&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;why can&#39;t I use it for regular function declarations?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Well, the answer is simple: hoisting :(&lt;/p&gt;
&lt;p&gt;Since JS hoists up function declarations, those expressions that you use inside of decorators, depending on proposed &amp;quot;solution&amp;quot;, might get hoisted up too, and thus break execution flow, or prevent function from hoisting, and thus break backwards compatibility. See Sebastian McKenzie&#39;s answer &lt;a href=&quot;https://github.com/wycats/javascript-decorators/issues/4#issuecomment-83542840&quot;&gt;here&lt;/a&gt; for a complete example and explanation. (This is not an issue for classes since those are specified as non-hoistable)&lt;/p&gt;
&lt;p&gt;Now, let&#39;s switch to a more interesting question: how can we workaround this?&lt;/p&gt;
&lt;h3 id=&quot;workaround-1-just-call-it&quot; tabindex=&quot;-1&quot;&gt;Workaround #1 (just call it) &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/ecmascript-decorators-and-functions/#workaround-1-just-call-it&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Well, first of all, decorators are just function calls. That is, whenever you do&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;@decorator
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;that is equivalent of&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token constant&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;decorator&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So, apart from &lt;code&gt;||&lt;/code&gt; part, imaginable decorator for funtions&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;@decorator
&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;could be written in old good JavaScript as simply as&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; f &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;decorator&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(note that this also prevents ambiguity caused by hoisting since in this case variable will be hoisted, but expression won&#39;t)&lt;/p&gt;
&lt;p&gt;The case where it makes a difference is when you have a bunch of decorators that you want to compose onto the original definition (class, method, function). No-one really wants to write things like&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; f &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;reportErrors&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;customReporter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;measureTime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;debounce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// whatever&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;workaround-2-runtime-boring-but-works&quot; tabindex=&quot;-1&quot;&gt;Workaround #2 (runtime - boring but works) &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/ecmascript-decorators-and-functions/#workaround-2-runtime-boring-but-works&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Just use some fancy runtime API that would allow you to pass a bunch of decorators that would be wrapped around your function. For example, Lodash can definitely do this, and I&#39;m pretty sure there is a lot of others around. Again, this works in old good pre-ES6 JavaScript.&lt;/p&gt;
&lt;h3 id=&quot;workaround-3-hacky-but-with-true-decorators&quot; tabindex=&quot;-1&quot;&gt;Workaround #3 (hacky but with true decorators) &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/ecmascript-decorators-and-functions/#workaround-3-hacky-but-with-true-decorators&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Since decorators can be defined on object methods, we can use a simple trick: define decorator on the method and then extract the function back:&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;debounce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;target&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; key&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; desc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; fn &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; desc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      lastStart &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    desc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; now &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;now &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; lastStart &lt;span class=&quot;token operator&quot;&gt;&gt;=&lt;/span&gt; time&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        lastStart &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; now&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; arguments&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;measureTime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;target&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; key&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; desc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; fn &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; desc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; name &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; fn&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  desc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; arguments&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;timeEnd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; result&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; myFn &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  @&lt;span class=&quot;token function&quot;&gt;debounce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  @measureTime
  &lt;span class=&quot;token function&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;myFn(&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;n&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;func&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;myFn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;myFn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;myFn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;setTimeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;myFn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;http://babeljs.io/repl/#?experimental=true&amp;amp;evaluate=true&amp;amp;loose=true&amp;amp;spec=false&amp;amp;playground=false&amp;amp;code=%2F%2F%20this%20is%20oversimplified%20polyfill%20of%20console.time%20just%20for%20Babel%20REPL%0A%7B%0A%20%20let%20starts%20%3D%20new%20Map%28%29%3B%0A%20%20let%20now%20%3D%20typeof%20performance%20!%3D%3D%20%27undefined%27%20%26%26%20performance.now%20%3F%20%3A%3Aperformance.now%20%3A%20%3A%3ADate.now%3B%0A%20%20Object.assign%28console%2C%20%7B%0A%20%20%20%20time%28name%29%20%7B%0A%20%20%20%20%20%20starts.set%28name%2C%20now%28%29%29%3B%0A%20%20%20%20%7D%2C%0A%20%20%20%20timeEnd%28name%29%20%7B%0A%20%20%20%20%20%20var%20end%20%3D%20starts.get%28name%29%3B%0A%20%20%20%20%20%20console.log%28now%28%29%20-%20end%29%3B%0A%20%20%20%20%20%20starts.delete%28name%29%3B%0A%20%20%20%20%7D%0A%20%20%7D%29%3B%0A%7D%0A%0Afunction%20debounce%28time%29%20%7B%0A%20%20return%20function%20%28target%2C%20key%2C%20desc%29%20%7B%0A%20%20%20%20var%20fn%20%3D%20desc.value%2C%20lastStart%20%3D%200%3B%0A%20%20%20%20desc.value%20%3D%20function%20%28%29%20%7B%0A%20%20%20%20%20%20var%20now%20%3D%20Date.now%28%29%3B%0A%20%20%20%20%20%20if%20%28now%20-%20lastStart%20%3E%3D%20time%29%20%7B%0A%20%20%20%20%20%20%20%20lastStart%20%3D%20now%3B%0A%20%20%20%20%20%20%20%20return%20fn.apply%28this%2C%20arguments%29%3B%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%3B%0A%20%20%7D%3B%0A%7D%0A%0Afunction%20measureTime%28target%2C%20key%2C%20desc%29%20%7B%0A%20%20var%20fn%20%3D%20desc.value%2C%20%7B%20name%20%7D%20%3D%20fn%3B%0A%20%20desc.value%20%3D%20function%20%28%29%20%7B%0A%20%20%09console.time%28name%29%3B%0A%20%20%20%20var%20result%20%3D%20fn.apply%28this%2C%20arguments%29%3B%0A%20%20%20%20console.timeEnd%28name%29%3B%0A%20%20%20%20return%20result%3B%0A%20%20%7D%3B%0A%7D%0A%0Avar%20myFn%20%3D%20%7B%0A%20%20%40debounce%28200%29%0A%20%20%40measureTime%0A%20%20func%28n%29%20%7B%0A%20%20%20%20console.log%28%60myFn%28%24%7Bn%7D%29%60%29%3B%0A%20%20%7D%0A%7D.func%3B%0A%0AmyFn%281%29%3B%0AmyFn%282%29%3B%0AmyFn%283%29%3B%0A%0AsetTimeout%28%28%29%20%3D%3E%20myFn%284%29%2C%20500%29%3B&quot;&gt;See it in action in Babel REPL&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;workaround-4-syntactic-and-my-favourite&quot; tabindex=&quot;-1&quot;&gt;Workaround #4 (syntactic and my favourite) &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/ecmascript-decorators-and-functions/#workaround-4-syntactic-and-my-favourite&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;So, what we can actually do here, is use another composable operator similar to pipe operator from functional languages (F#, Elixir etc.) - it&#39;s a &lt;a href=&quot;https://rreverser.com/potentially-es7-function-bind-syntax-in-babel/&quot;&gt;bind operator&lt;/a&gt; (&lt;strong&gt;NOTE: this operator wasn&#39;t proposed to TC39 yet and is implemented by Babel purely for experimental and feedback purposes&lt;/strong&gt;)&lt;/p&gt;
&lt;p&gt;Here&#39;s how it works when used as a function call:&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token literal-property property&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fn1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;a&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fn2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;b&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fn3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;c&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;turns into&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;fn3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fn2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fn1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;context&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;a&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;b&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;c&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Beautiful, isn&#39;t it?&lt;/p&gt;
&lt;p&gt;So, why don&#39;t we just put original function itself as a context for operator? In that case, we can decorate it with as much decorators as we wish in a truly composable way!&lt;/p&gt;
&lt;p&gt;Here&#39;s a simple example of how such pseudo-decorators can be implemented and used:&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;debounce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; fn &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    lastStart &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; now &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;now &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; lastStart &lt;span class=&quot;token operator&quot;&gt;&gt;=&lt;/span&gt; time&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      lastStart &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; now&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; arguments&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;measureTime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; fn &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; name &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; arguments&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;timeEnd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; result&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; myFn &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;myFn(&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;n&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;measureTime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;debounce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;myFn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;myFn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;myFn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;setTimeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;myFn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;http://babeljs.io/repl/#?experimental=true&amp;amp;evaluate=true&amp;amp;loose=false&amp;amp;spec=false&amp;amp;playground=false&amp;amp;code=%2F%2F%20this%20is%20oversimplified%20polyfill%20of%20console.time%20just%20for%20Babel%20REPL%0A%7B%0A%20%20let%20starts%20%3D%20new%20Map%28%29%3B%0A%20%20let%20now%20%3D%20typeof%20performance%20!%3D%3D%20%27undefined%27%20%26%26%20performance.now%20%3F%20%3A%3Aperformance.now%20%3A%20%3A%3ADate.now%3B%0A%20%20Object.assign%28console%2C%20%7B%0A%20%20%20%20time%28name%29%20%7B%0A%20%20%20%20%20%20starts.set%28name%2C%20now%28%29%29%3B%0A%20%20%20%20%7D%2C%0A%20%20%20%20timeEnd%28name%29%20%7B%0A%20%20%20%20%20%20var%20end%20%3D%20starts.get%28name%29%3B%0A%20%20%20%20%20%20console.log%28now%28%29%20-%20end%29%3B%0A%20%20%20%20%20%20starts.delete%28name%29%3B%0A%20%20%20%20%7D%0A%20%20%7D%29%3B%0A%7D%0A%0Afunction%20debounce%28time%29%20%7B%0A%20%20var%20fn%20%3D%20this%2C%20lastStart%20%3D%200%3B%0A%20%20return%20function%20%28%29%20%7B%0A%20%20%20%20var%20now%20%3D%20Date.now%28%29%3B%0A%20%20%20%20if%20%28now%20-%20lastStart%20%3E%3D%20time%29%20%7B%0A%20%20%20%20%20%20lastStart%20%3D%20now%3B%0A%20%20%20%20%20%20return%20fn.apply%28this%2C%20arguments%29%3B%0A%20%20%20%20%7D%0A%20%20%7D%3B%0A%7D%0A%0Afunction%20measureTime%28%29%20%7B%0A%20%20var%20fn%20%3D%20this%2C%20%7B%20name%20%7D%20%3D%20this%3B%0A%20%20return%20function%20%28%29%20%7B%0A%20%20%09console.time%28name%29%3B%0A%20%20%20%20var%20result%20%3D%20fn.apply%28this%2C%20arguments%29%3B%0A%20%20%20%20console.timeEnd%28name%29%3B%0A%20%20%20%20return%20result%3B%0A%20%20%7D%3B%0A%7D%0A%0Avar%20myFn%20%3D%0A%20%20%28n%20%3D%3E%20console.log%28%60myFn%28%24%7Bn%7D%29%60%29%29%0A%20%20%3A%3AmeasureTime%28%29%0A%20%20%3A%3Adebounce%28200%29%3B%0A%0AmyFn%281%29%3B%0AmyFn%282%29%3B%0AmyFn%283%29%3B%0A%0AsetTimeout%28%28%29%20%3D%3E%20myFn%284%29%2C%20500%29%3B&quot;&gt;See it in action in Babel REPL&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UPD:&lt;/strong&gt; On Twitter I&#39;ve got &lt;a href=&quot;https://twitter.com/schtoeffel/status/629937533980381184&quot;&gt;a response&lt;/a&gt; with another beautiful example of decorator that can be used with &lt;code&gt;::&lt;/code&gt; syntax - and it&#39;s proper &lt;a href=&quot;https://github.com/stoeffel/curry-this&quot;&gt;currying&lt;/a&gt; in JavaScript!&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;That&#39;s it! Feel free to ask any questions in comments.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Github project: typescript-estree</title>
		<link href="https://github.com/RReverser/typescript-estree"/>
		<updated>2015-07-31T08:41:41Z</updated>
		<id>https://github.com/RReverser/typescript-estree</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: babel-plugin-uglify</title>
		<link href="https://github.com/RReverser/babel-plugin-uglify"/>
		<updated>2015-07-30T00:01:33Z</updated>
		<id>https://github.com/RReverser/babel-plugin-uglify</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Started work on ES6 -&gt; asm.js conversion</title>
		<link href="https://rreverser.com/started-work-on-es6-asm-js-conversion/"/>
		<updated>2015-07-12T07:41:27Z</updated>
		<id>https://rreverser.com/started-work-on-es6-asm-js-conversion/</id>
		<content type="html">&lt;p&gt;&lt;a href=&quot;https://github.com/RReverser/babel-plugin-asm-js&quot;&gt;View on GitHub&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I know this sounds crazy, but I always wondered why do we always give out such a speedup technique as asm.js (&lt;a href=&quot;https://hacks.mozilla.org/2015/03/asm-speedups-everywhere/&quot;&gt;it speeds up code in all the modern browsers!&lt;/a&gt;) to developers from other languages if we can use it for own code in JavaScript as well?&lt;/p&gt;
&lt;p&gt;The answer is that handwriting asm.js is tricky due to limited set of operations and complex rules for satisfying asm.js. So I decided to start this side project. It&#39;s goal is to compile statically typed ES6 (Flow-flavoured) module into asm.js while preserving ES6 module interface. So it&#39;s still a subset of JavaScript, but much more suitable for hand-writing.&lt;/p&gt;
&lt;p&gt;You don&#39;t need to use C/C++ -&amp;gt; Emscripten -&amp;gt; asm.js for heavy calculation anymore - just create module, drop Babel with this plugin and you&#39;re ready to go!&lt;/p&gt;
&lt;h2 id=&quot;currently-supported&quot; tabindex=&quot;-1&quot;&gt;Currently supported: &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/started-work-on-es6-asm-js-conversion/#currently-supported&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ES6 &lt;code&gt;import&lt;/code&gt; and named &lt;code&gt;export&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;automatic &lt;code&gt;var&lt;/code&gt;, &lt;code&gt;let&lt;/code&gt;, &lt;code&gt;const&lt;/code&gt; extraction and conversion&lt;/li&gt;
&lt;li&gt;automatic function layout&lt;/li&gt;
&lt;li&gt;function parameter annotations&lt;/li&gt;
&lt;li&gt;function return type annotation&lt;/li&gt;
&lt;li&gt;assignment with automatic type conversion&lt;/li&gt;
&lt;li&gt;Flow type cast into asm.js type cast&lt;/li&gt;
&lt;li&gt;automatic asm.js imports for stdlib and foreign references&lt;/li&gt;
&lt;li&gt;automatic program layout&lt;/li&gt;
&lt;li&gt;automatic wrapping into asm.js module with &lt;code&gt;initialize&lt;/code&gt; for passing own &lt;code&gt;heap&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;todo&quot; tabindex=&quot;-1&quot;&gt;TODO: &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/started-work-on-es6-asm-js-conversion/#todo&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;bug fixing&lt;/li&gt;
&lt;li&gt;global variable support&lt;/li&gt;
&lt;li&gt;string support (literals are already converted to IDs, need to support operations)&lt;/li&gt;
&lt;li&gt;better asm.js&amp;lt;-&amp;gt;normal code communication&lt;/li&gt;
&lt;li&gt;limited object and array support&lt;/li&gt;
&lt;li&gt;&lt;em&gt;sky is the limit!&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
	</entry>
	
	<entry>
		<title>Github project: proxyfill</title>
		<link href="https://github.com/RReverser/proxyfill"/>
		<updated>2015-06-11T15:22:47Z</updated>
		<id>https://github.com/RReverser/proxyfill</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: better-log</title>
		<link href="https://github.com/RReverser/better-log"/>
		<updated>2015-05-22T09:54:26Z</updated>
		<id>https://github.com/RReverser/better-log</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>[Potentially ES7] function bind syntax in Babel</title>
		<link href="https://rreverser.com/potentially-es7-function-bind-syntax-in-babel/"/>
		<updated>2015-05-16T08:01:59Z</updated>
		<id>https://rreverser.com/potentially-es7-function-bind-syntax-in-babel/</id>
		<content type="html">&lt;p&gt;&lt;a href=&quot;http://babeljs.io/blog/2015/05/14/function-bind/&quot;&gt;View original post&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Babel 5.4 was just released and with it comes support for a new&lt;br /&gt;
&lt;a href=&quot;https://github.com/zenparsing/es-function-bind&quot;&gt;experimental ES7 syntax&lt;/a&gt;&lt;br /&gt;
proposed by Kevin Smith (&lt;a href=&quot;https://github.com/zenparsing&quot;&gt;@zenparsing&lt;/a&gt;) and&lt;br /&gt;
implemented in Babel by Ingvar Stepanyan&lt;br /&gt;
(&lt;a href=&quot;https://github.com/RReverser&quot;&gt;@RReverser&lt;/a&gt;).&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Warning: This syntax is highly experimental and you should not use&lt;br /&gt;
it for anything serious (yet).&lt;/em&gt;&lt;/strong&gt; If you do use this syntax, please&lt;br /&gt;
provide feedback on &lt;a href=&quot;https://github.com/zenparsing/es-function-bind&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The function bind syntax introduces a new operator &lt;code&gt;::&lt;/code&gt; which performs function&lt;br /&gt;
binding and method extraction.&lt;/p&gt;
&lt;h3 id=&quot;virtual-methods&quot; tabindex=&quot;-1&quot;&gt;Virtual Methods &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/potentially-es7-function-bind-syntax-in-babel/#virtual-methods&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Using an iterator library implemented as a module of &amp;quot;virtual methods&amp;quot;:&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* ES7 */&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; map&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; takeWhile&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; forEach &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;iterlib&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;getPlayers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;character&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;takeWhile&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;strength &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* ES6 */&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; map&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; takeWhile&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; forEach &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;iterlib&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; _val&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
_val &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getPlayers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
_val &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_val&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;character&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
_val &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;takeWhile&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;val&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;strength &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
_val &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;vall&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Babel&#39;s &lt;a href=&quot;https://babeljs.io/repl/#?experimental=true&amp;amp;evaluate=false&amp;amp;loose=false&amp;amp;spec=false&amp;amp;playground=false&amp;amp;code=import%20%7B%20map%2C%20takeWhile%2C%20forEach%20%7D%20from%20%22iterlib%22%3B%0A%0AgetPlayers%28%29%0A%3A%3Amap%28x%20%3D%3E%20x.character%28%29%29%0A%3A%3AtakeWhile%28x%20%3D%3E%20x.strength%20%3E%20100%29%0A%3A%3AforEach%28x%20%3D%3E%20console.log%28x%29%29%3B&quot;&gt;output&lt;/a&gt;&lt;br /&gt;
looks different than this in order to be more concise.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Using a jquery-like library of virtual methods:&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* ES7 */&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Create bindings for just the methods that we need&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; find&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; html &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; jake&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Find all the divs with class=&quot;myClass&quot;, then get all of the&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// &quot;p&quot;s and replace their content.&lt;/span&gt;
document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;querySelectorAll&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;div.myClass&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;p&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;hahaha&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* ES6 */&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; _val&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
_val &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;querySelectorAll&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;div.myClass&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
_val &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_val&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;p&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
_val &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_val&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;hahaha&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;method-extraction&quot; tabindex=&quot;-1&quot;&gt;Method Extraction &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/potentially-es7-function-bind-syntax-in-babel/#method-extraction&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Using method extraction to print the eventual value of a promise to the console:&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* ES7 */&lt;/span&gt;
Promise&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;resolve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;log&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* ES6 */&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Which could be written in ES6 as:&lt;/span&gt;
Promise&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;resolve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;console&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Using method extraction to call an object method when a DOM event occurs:&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* ES7 */&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;.some-link&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;click&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;view&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;reset&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* ES6 */&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;.some-link&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;click&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; view&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;reset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;view&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You can read more about this syntax in the&lt;br /&gt;
&lt;a href=&quot;https://github.com/zenparsing/es-function-bind&quot;&gt;Function Bind Syntax proposal&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;usage&quot; tabindex=&quot;-1&quot;&gt;Usage &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/potentially-es7-function-bind-syntax-in-babel/#usage&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Enable by stage:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ babel &lt;span class=&quot;token parameter variable&quot;&gt;--stage&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Enable by transformer:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ babel &lt;span class=&quot;token parameter variable&quot;&gt;--optional&lt;/span&gt; es7.functionBind&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;p&gt;The function bind syntax will only make it into ES7 if there is enough interest.&lt;br /&gt;
If you would like to see this syntax make it in, please give it a star on&lt;br /&gt;
&lt;a href=&quot;https://github.com/zenparsing/es-function-bind&quot;&gt;GitHub&lt;/a&gt; and provide any&lt;br /&gt;
feedback you have on &lt;a href=&quot;https://github.com/zenparsing/es-function-bind/issues&quot;&gt;GitHub issues&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Special thanks to Ingvar Stepanyan (&lt;a href=&quot;https://github.com/RReverser&quot;&gt;@RReverser&lt;/a&gt;)&lt;br /&gt;
for the &lt;a href=&quot;https://github.com/babel/babel/pull/1518&quot;&gt;implementation&lt;/a&gt; in Babel.&lt;/p&gt;
&lt;p&gt;— The Babel team&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Quickly view Wi-Fi password under OSX and Windows</title>
		<link href="https://rreverser.com/quickly-view-wi-fi-password-under-osx-and-windows/"/>
		<updated>2015-02-15T18:52:29Z</updated>
		<id>https://rreverser.com/quickly-view-wi-fi-password-under-osx-and-windows/</id>
		<content type="html">&lt;p&gt;Today I&#39;ve found this neat tool called &lt;a href=&quot;https://github.com/rauchg/wifi-password&quot;&gt;wifi-password&lt;/a&gt; by &lt;a href=&quot;https://github.com/rauchg&quot;&gt;@rauchg&lt;/a&gt; and figured out that it&#39;s extremely useful. Just look at this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/rauchg/wifi-password&quot;&gt;&lt;img src=&quot;https://camo.githubusercontent.com/553e1755e772f9986165014da298013f88036f08/68747470733a2f2f692e636c6f756475702e636f6d2f75556f386953624b5852682f6b6d36694a542e676966&quot; alt=&quot;OSX screenshot&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Simple, isn&#39;t? And README says it:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;People ask you for the Wi-Fi password. Answer quickly.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So I wanted to answer quickly, too. &lt;s&gt;Unfortunately&lt;/s&gt; I&#39;m a Windows user and so had to create &lt;a href=&quot;https://github.com/RReverser/WiFi-Password&quot;&gt;own analog&lt;/a&gt; for PowerShell:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/RReverser/WiFi-Password&quot;&gt;&lt;img src=&quot;https://cloud.githubusercontent.com/assets/557590/6204307/05ab9f88-b54f-11e4-9293-b2bd8c20a409.png&quot; alt=&quot;Windows screenshot&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So now you just:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Install it&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;First of all, install &lt;a href=&quot;http://psget.net/&quot;&gt;PsGet&lt;/a&gt; if you don&#39;t have it yet - it&#39;s awesome module manager for PowerShell:&lt;/p&gt;
&lt;pre class=&quot;language-powershell&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;New-Object&lt;/span&gt; Net&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;WebClient&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;DownloadString&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http://psget.net/GetPsGet.ps1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;iex&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, you can easily install module itself:&lt;/p&gt;
&lt;pre class=&quot;language-powershell&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;Install-Module&lt;/span&gt; WiFi-Password&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;2. Use it:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;To get the password for the WiFi you&#39;re currently logged onto:&lt;/p&gt;
&lt;pre class=&quot;language-powershell&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;Show-WiFiPassword&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or just&lt;/p&gt;
&lt;pre class=&quot;language-powershell&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;wifi-password&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To get it for a specific SSID:&lt;/p&gt;
&lt;pre class=&quot;language-powershell&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;$ wifi-password &amp;lt;ssid&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To list all the stored WiFi networks:&lt;/p&gt;
&lt;pre class=&quot;language-powershell&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;Select-WiFi&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;3. PROFIT!&lt;/strong&gt;&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Tail recursion and 6to5</title>
		<link href="https://rreverser.com/tail-recursion-and-6to5/"/>
		<updated>2015-02-08T14:06:48Z</updated>
		<id>https://rreverser.com/tail-recursion-and-6to5/</id>
		<content type="html">&lt;p&gt;Just added &lt;a href=&quot;http://en.wikipedia.org/wiki/Tail_call#Tail_recursion_modulo_cons&quot;&gt;tail call&lt;/a&gt; optimization to &lt;a href=&quot;http://6to5.org/&quot;&gt;6to5&lt;/a&gt;, so it became the first ES6 implementation across all the browsers and transpilers to have this feature:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://kangax.github.io/compat-table/es6/&quot;&gt;&lt;img src=&quot;https://pbs.twimg.com/media/B9TneTwCUAImtgD.png:large&quot; alt=&quot;Support across engines&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Unfortunately, generic tail call optimization is still too complex thing as for transpiler level and it introduces significant overhead compared to simple calls, so should be better done on browser level. However, most use cases for TCO involve recursion, where function returns result of itself, but with different arguments (and possibly context), which is perfectly covered by this implementation.&lt;/p&gt;
&lt;p&gt;&lt;strike&gt;There is still work that can (and eventually will) be done in order to beat &lt;a href=&quot;http://jsperf.com/tco/11&quot;&gt;performance of other possible solutions&lt;/a&gt; by manually resetting state and converting recursion into regular loop, but it&#39;s another story.&lt;/strike&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UPDATE&lt;/strong&gt;: As per 3.6.0, some investigations were made that allowed to increase performance &lt;em&gt;a bit&lt;/em&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://jsperf.com/tco/17&quot;&gt;&lt;img src=&quot;https://pbs.twimg.com/media/B9l_ObXCMAAuPvh.png&quot; alt=&quot;JSPerf graph&quot; /&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As you can see, all the previous solutions (including hand-written non-recursive variants) were beaten by new heuristics which analyze your code and heavily optimize the most common cases (simple recursion that doesn&#39;t use &lt;code&gt;arguments&lt;/code&gt; variable nor default/rest parameters inside).&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Gitty - unofficial Gitter client for WinRT</title>
		<link href="https://rreverser.com/gitty-unofficial-gitter-client-for-winrt/"/>
		<updated>2015-01-09T17:53:15Z</updated>
		<id>https://rreverser.com/gitty-unofficial-gitter-client-for-winrt/</id>
		<content type="html">&lt;p&gt;&lt;a href=&quot;https://gitter.im/&quot;&gt;&lt;img src=&quot;http://wscont2.apps.microsoft.com/winstore/1x/851fdef7-1983-4c97-a1f8-0142b3de530a/Screenshot.429853.100000.jpg&quot; alt=&quot;Gitter&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://gitter.im/&quot;&gt;Gitter&lt;/a&gt; is a great real-time messaging service built specifically to help teams communicate better. It provides free public chat rooms for communities and open source projects and private chat rooms for teams and businesses. All of the rooms are based on Github repos, so you can easily get and use one for your favourite project.&lt;/p&gt;
&lt;p&gt;The only downside for me was absence of native app for Windows RT, and always keeping a dedicated tab in browser and switching to it whenever you get message is not so convenient. So I did what any developer does in such situation - created one.&lt;/p&gt;
&lt;p&gt;Fortunately, Gitter provides pretty convenient API for all the functions it provides in it&#39;s UI: &lt;a href=&quot;http://developer.gitter.im/&quot;&gt;http://developer.gitter.im/&lt;/a&gt;. Unfortunately, some parts of it are not documented, but team guys are very responsive and even fixed some pretty specific bugs in real-time, so I could continue development with almost no interruptions!&lt;/p&gt;
&lt;p&gt;I&#39;ll probably write a bit more about complex implementation details in separate articles, but for now - you can find initial release of the app in the Store and I hope you enjoy it:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://apps.microsoft.com/windows/en-us/app/gitty/16998cba-b1d7-4d82-a8d0-131a40009168&quot;&gt;http://apps.microsoft.com/windows/en-us/app/gitty/16998cba-b1d7-4d82-a8d0-131a40009168&lt;/a&gt;&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Github project: Bayeux.NET</title>
		<link href="https://github.com/RReverser/Bayeux.NET"/>
		<updated>2014-12-17T01:34:05Z</updated>
		<id>https://github.com/RReverser/Bayeux.NET</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: github-editorconfig</title>
		<link href="https://github.com/RReverser/github-editorconfig"/>
		<updated>2014-10-22T21:00:10Z</updated>
		<id>https://github.com/RReverser/github-editorconfig</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: gulp-wrap-js</title>
		<link href="https://github.com/RReverser/gulp-wrap-js"/>
		<updated>2014-10-17T09:48:16Z</updated>
		<id>https://github.com/RReverser/gulp-wrap-js</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: acorn-csp</title>
		<link href="https://github.com/RReverser/acorn-csp"/>
		<updated>2014-09-06T12:28:04Z</updated>
		<id>https://github.com/RReverser/acorn-csp</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>aster - AST-based code builder</title>
		<link href="https://rreverser.com/aster-ast-based-code-builder/"/>
		<updated>2014-08-28T13:37:40Z</updated>
		<id>https://rreverser.com/aster-ast-based-code-builder/</id>
		<content type="html">&lt;p&gt;&lt;a href=&quot;https://github.com/asterjs/aster&quot;&gt;View on GitHub&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://avatars2.githubusercontent.com/u/6579498?s=300&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2 id=&quot;what-s-that&quot; tabindex=&quot;-1&quot;&gt;What&#39;s that &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/aster-ast-based-code-builder/#what-s-that&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;aster is reactive builder specialized for code processing and transformations. It&#39;s built with debugging in mind and makes building JavaScript code more reliable and faster.&lt;/p&gt;
&lt;p&gt;You may want to check out presentation below:&lt;/p&gt;
&lt;h2 id=&quot;why-one-more&quot; tabindex=&quot;-1&quot;&gt;Why one more &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/aster-ast-based-code-builder/#why-one-more&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Source maps are a great invention that is meant to simplify life by allowing developers to debug the original code (the one that they actually write, whatever language it is) on production.&lt;/p&gt;
&lt;p&gt;However, using them is pretty hard in any of existing build systems whenever you have at least one plugin in your build pipeline - and you most likely do - that doesn&#39;t support emitting them or even consuming from previous step; some plugins even treat code as simple strings discarding all it&#39;s inner logic and structure.&lt;/p&gt;
&lt;p&gt;Your code isn&#39;t just a string. It has a soul and rich inner world and aster is built to treat it like that. As result, it provides complex yet easy and fast transformations that are transparent for browser debugger out of the box.&lt;/p&gt;
&lt;p&gt;You can think of aster for JS as of &lt;a href=&quot;https://github.com/reworkcss/rework&quot;&gt;rework&lt;/a&gt; for CSS.&lt;/p&gt;
&lt;h2 id=&quot;but-i-like-x-builder-should-i-throw-it-out&quot; tabindex=&quot;-1&quot;&gt;But I like X builder! Should I throw it out? &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/aster-ast-based-code-builder/#but-i-like-x-builder-should-i-throw-it-out&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Definitely no! aster doesn&#39;t try to fight your favorite build system. It has only one specific area that it&#39;s exceptionally good at - code processing. Everything else (CSS, images, publishing to CDN, etc.) is left for generic builders, and you can use them together.&lt;/p&gt;
&lt;p&gt;Currently there are following bindings:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/asterjs/grunt-aster&quot;&gt;grunt-aster&lt;/a&gt; - binding for &lt;a href=&quot;http://gruntjs.com/&quot;&gt;Grunt&lt;/a&gt; JavaScript Task Runner.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/asterjs/gulp-aster&quot;&gt;gulp-aster&lt;/a&gt; - binding for &lt;a href=&quot;http://gulpjs.com/&quot;&gt;Gulp&lt;/a&gt; streaming build system.&lt;/li&gt;
&lt;li&gt;...more to come!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you wish, you can define aster pipeline as custom task in any existing build system on your own since aster uses &lt;a href=&quot;http://reactive-extensions.github.io/RxJS/&quot;&gt;RxJS&lt;/a&gt; under the hood, which is interoperable with events, streams, promises, callbacks and any other asynchronous primitives and patterns out of the box.&lt;/p&gt;
&lt;h2 id=&quot;api&quot; tabindex=&quot;-1&quot;&gt;API &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/aster-ast-based-code-builder/#api&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;aster is completely modular and main package is just a centralized API wrapper for core parts published as separate modules (check out their documentations for details):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/asterjs/aster-src&quot;&gt;aster.src&lt;/a&gt; - Single-pass source files reader.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/asterjs/aster-watch&quot;&gt;aster.watch&lt;/a&gt; - Continuous source files reader.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/asterjs/aster-dest&quot;&gt;aster.dest&lt;/a&gt; - File writer.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/asterjs/aster-runner&quot;&gt;aster.runner&lt;/a&gt; - Build pipeline runner with built-in logger.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;usage&quot; tabindex=&quot;-1&quot;&gt;Usage &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/aster-ast-based-code-builder/#usage&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;First, install &lt;code&gt;aster&lt;/code&gt; as a development dependency:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; --save-dev aster&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, create build script and use it. Example (&lt;code&gt;require&lt;/code&gt;s omitted):&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;aster
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;watch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;src/**/*.js&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;src/**/*.coffee&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;src/**/*.jsx&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;throttle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;changed&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; src&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;token function&quot;&gt;equery&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token string-property property&quot;&gt;&quot;if ($cond) return $expr1; else return $expr2;&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
                        &lt;span class=&quot;token string&quot;&gt;&quot;return &amp;lt;%= cond %&gt; ? &amp;lt;%= expr1 %&gt; : &amp;lt;%= expr2 %&gt;&quot;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;concat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;built.js&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;umd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;superLib&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;aster&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;dest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;dist&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;sourceMap&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;aster&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;runner&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;aster doesn&#39;t provide task runner - npm is already good one, and we don&#39;t want to create one more bicycle. You can simply define every needed task as separate script, or use aster as part of exising builder as mentioned before.&lt;/p&gt;
&lt;h2 id=&quot;license&quot; tabindex=&quot;-1&quot;&gt;License &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/aster-ast-based-code-builder/#license&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/MIT_License&quot;&gt;MIT License&lt;/a&gt;&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Github project: TSX</title>
		<link href="https://github.com/RReverser/TSX"/>
		<updated>2014-08-10T15:08:24Z</updated>
		<id>https://github.com/RReverser/TSX</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Using Mozilla AST with UglifyJS</title>
		<link href="https://rreverser.com/using-mozilla-ast-with-uglifyjs/"/>
		<updated>2014-08-04T12:23:04Z</updated>
		<id>https://rreverser.com/using-mozilla-ast-with-uglifyjs/</id>
		<content type="html">&lt;p&gt;Hi there.&lt;/p&gt;
&lt;p&gt;I&#39;m continuing my work on tools for manipulating SpiderMonkey AST - as creating new as well as improving existing ones.&lt;/p&gt;
&lt;p&gt;This time it was &lt;a href=&quot;https://github.com/mishoo/UglifyJS2/&quot;&gt;UglifyJS&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It&#39;s great JavaScript minifier, but what always bothered me (and &lt;a href=&quot;https://github.com/michaelficarra/esfuzz/issues/2&quot;&gt;other developers&lt;/a&gt;) was incompatibility of it&#39;s internal AST representation and Mozilla format, and so impossibility of combining it with other tools without dirty and slow hacks like:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Transform Mozilla AST to UglifyJS AST (thanks Mihail, we already got method for this).&lt;/li&gt;
&lt;li&gt;Compress, mangle etc. it with UglifyJS API.&lt;/li&gt;
&lt;li&gt;Generate code and source map with UglifyJS API.&lt;/li&gt;
&lt;li&gt;Parse generated code with either &lt;a href=&quot;https://github.com/ariya/esprima&quot;&gt;esprima&lt;/a&gt; or &lt;a href=&quot;https://github.com/marijnh/acorn&quot;&gt;acorn&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Translate generated source map onto existing AST with &lt;a href=&quot;https://github.com/RReverser/sourcemap-to-ast&quot;&gt;sourcemap-to-ast&lt;/a&gt; helper.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;(I had to use this hackchain for &lt;a href=&quot;https://github.com/asterjs/aster-uglify&quot;&gt;aster-uglify&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;So I&#39;ve decided to add back-conversion from UglifyJS to SpiderMonkey AST format, and it&#39;s already &lt;a href=&quot;https://github.com/mishoo/UglifyJS2/pull/526&quot;&gt;landed&lt;/a&gt; in UglifyJS!&lt;/p&gt;
&lt;p&gt;Now you can use UglifyJS as any other intermediate tool for transforming JavaScript ASTs using it&#39;s native API.&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Parsing&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; ast &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; acorn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;code&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;locations&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;ranges&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Any AST pre-transformations here&lt;/span&gt;
ast &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;preTransform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ast&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Conversion&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; uAST &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; UglifyJS&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;AST_Node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;from_mozilla_ast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ast&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Compression&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; compressor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; UglifyJS&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Compressor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;options&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
uAST&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;figure_out_scope&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
uAST &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; uAST&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;compressor&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Mangling (optional)&lt;/span&gt;
uAST&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;figure_out_scope&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
uAST&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;compute_char_frequency&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
uAST&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;mangle_names&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Back-conversion&lt;/span&gt;
ast &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; uAST&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;to_mozilla_ast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Any AST post-transformations here&lt;/span&gt;
ast &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;postTransform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ast&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Generating output code and source map&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; output &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; escodegen&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;generate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ast&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;sourceMapWithCode&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;sourceMap&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Done!&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;update&quot; tabindex=&quot;-1&quot;&gt;UPDATE &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/using-mozilla-ast-with-uglifyjs/#update&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;In Twitter, I was asked about speed of such conversion, so decided to show timings for above example executed against &lt;a href=&quot;http://code.jquery.com/jquery.js&quot;&gt;jQuery v1.11.1 development source&lt;/a&gt; without pre-/post-transformations:&lt;/p&gt;
&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Parsing:             175ms   (5%)
Conversion:          148ms   (4%)
Compression:         2155ms  (56%)
Mangling:            502ms   (13%)
Back-conversion:     48ms    (1%)
Generating output:   829ms   (21%)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or, in grouped view:&lt;/p&gt;
&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;I/O             1004ms  (26%)
Conversions     196ms   (5%)
Compressions    2657ms  (69%)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So, as you can see, speed of conversions has negligible performance impact.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Github project: jsx-ast</title>
		<link href="https://github.com/RReverser/jsx-ast"/>
		<updated>2014-07-29T11:33:24Z</updated>
		<id>https://github.com/RReverser/jsx-ast</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Added ES6 support to Acorn</title>
		<link href="https://rreverser.com/added-es6-support-to-acorn/"/>
		<updated>2014-07-29T10:16:37Z</updated>
		<id>https://rreverser.com/added-es6-support-to-acorn/</id>
		<content type="html">&lt;p&gt;Worked on and added following ES6 features support to &lt;a href=&quot;https://github.com/marijnh/acorn&quot;&gt;Acorn - small, fast JavaScript parser&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Unicode Code Point Escape Sequences (&lt;code&gt;&#92;u{ABCDEF}&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Numeric Literals (octal, binary).&lt;/li&gt;
&lt;li&gt;Arrow Functions.&lt;/li&gt;
&lt;li&gt;Spread Element.&lt;/li&gt;
&lt;li&gt;Classes.&lt;/li&gt;
&lt;li&gt;Destructuring assignments.&lt;/li&gt;
&lt;li&gt;Computed object properties.&lt;/li&gt;
&lt;li&gt;Object methods.&lt;/li&gt;
&lt;li&gt;Shorthand object properties.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;for (... of ...)&lt;/code&gt; loops.&lt;/li&gt;
&lt;li&gt;Array Comprehensions.&lt;/li&gt;
&lt;li&gt;Modules. (newest specs)&lt;/li&gt;
&lt;li&gt;Template Strings.&lt;/li&gt;
&lt;li&gt;Generators.&lt;/li&gt;
&lt;li&gt;Generator Comprehensions.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are still some pending discussions with guys from Mozilla &amp;amp; Esprima on new AST types &amp;amp; properties used for new syntax features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=1044459&quot;&gt;Support default and named bindings in one ImportDeclaration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=1044462&quot;&gt;Support newest export syntax&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=1044467&quot;&gt;Support new &lt;code&gt;import * as X from &amp;quot;Y&amp;quot;&lt;/code&gt; alternative of &lt;code&gt;module X from Y&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://code.google.com/p/esprima/issues/detail?id=572&quot;&gt;ES6: Generator Comprehension support&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Stay tuned - more to come!&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Github project: jsx-transpiler</title>
		<link href="https://github.com/RReverser/jsx-transpiler"/>
		<updated>2014-07-28T20:14:33Z</updated>
		<id>https://github.com/RReverser/jsx-transpiler</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>A few more words on Acorn-JSX</title>
		<link href="https://rreverser.com/a-few-more-words-on-acorn-jsx/"/>
		<updated>2014-07-27T20:59:10Z</updated>
		<id>https://rreverser.com/a-few-more-words-on-acorn-jsx/</id>
		<content type="html">&lt;p&gt;&lt;em&gt;Initially this was part of my email response to Lou Husson after mentioning Acorn-JSX in &lt;a href=&quot;http://facebook.github.io/react/blog/2014/07/28/community-roundup-20.html&quot;&gt;Facebook React Community Round-up #20&lt;/a&gt; and reaching me out, but decided that someone else might find it useful too.&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;UPD (June 12, 2015)&lt;/strong&gt;: Facebook &lt;a href=&quot;https://facebook.github.io/react/blog/2015/06/12/deprecating-jstransform-and-react-tools.html&quot;&gt;deprecates own parsing and transformation tools&lt;/a&gt; in favor of Acorn, Acorn-JSX and Babel. Looks like I&#39;ll need to be more careful about updates starting from now 😜&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As for today, I’ve &lt;a href=&quot;https://github.com/marijnh/acorn/pull/110&quot;&gt;developed complete ES6 support&lt;/a&gt; for Acorn (as far as it can be complete in such a dynamic world; anyway it contains even newest specs than Esprima supports). So I’ve &lt;a href=&quot;https://github.com/RReverser/acorn-jsx/commit/bb0610b1a64a8edc3544172cce7c0c1ed93a0057&quot;&gt;merged&lt;/a&gt; it to Acorn-JSX; also I’ve &lt;a href=&quot;https://github.com/RReverser/acorn-jsx/commit/6897ff73856983568badea72a60f09f42c2cb198&quot;&gt;added spread attribute support&lt;/a&gt; (&lt;code&gt;&amp;lt;div {…attr} /&amp;gt;&lt;/code&gt;), took all the tests from official parser, adapted them for Acorn test runner - and it passes them all. So &lt;a href=&quot;https://github.com/RReverser/acorn-jsx/commit/3851cccd724cd2fe753ec5728e656881c0a2758c&quot;&gt;caveat about different syntax&lt;/a&gt; level supported in my and official parser was removed, and “official parser is maintained by authors of React.js itself, so it&#39;s recommended to be used in production” was left as the only reason for not using it.&lt;/p&gt;
&lt;p&gt;Everything else works in the same way. Just 2x faster.&lt;/p&gt;
&lt;p&gt;Also wanted to notice that it’s not the only tool for JSX AST I’ve worked on, so maybe you find following one useful as well. Earlier from unworking recast-based fork I’ve developed &lt;a href=&quot;https://github.com/RReverser/jsx-transpiler&quot;&gt;very simple JSX transpiler&lt;/a&gt; based on &lt;a href=&quot;https://github.com/facebook/esprima&quot;&gt;official Esprima-FB parser&lt;/a&gt;, &lt;a href=&quot;https://github.com/RReverser/estraverse-fb&quot;&gt;own JSX-enabling drop-in for Estraverse&lt;/a&gt; and &lt;a href=&quot;https://github.com/Constellation/escodegen&quot;&gt;Escodegen&lt;/a&gt; AST tools. It allows you to either 1) parse JSX to AST with attached comments (supported in official Esprima, but not in Esprima-FB), 2) convert it directly to code + source map or 3) use as browserify transformer plugin.&lt;/p&gt;
&lt;p&gt;Stay tuned for updates about new JS(X) AST tools!&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Github project: serialize-js</title>
		<link href="https://github.com/RReverser/serialize-js"/>
		<updated>2014-07-22T10:35:57Z</updated>
		<id>https://github.com/RReverser/serialize-js</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: biscript</title>
		<link href="https://github.com/RReverser/biscript"/>
		<updated>2014-07-21T18:12:21Z</updated>
		<id>https://github.com/RReverser/biscript</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: estraverse-fb</title>
		<link href="https://github.com/RReverser/estraverse-fb"/>
		<updated>2014-05-31T19:09:15Z</updated>
		<id>https://github.com/RReverser/estraverse-fb</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: gh2ost</title>
		<link href="https://github.com/RReverser/gh2ost"/>
		<updated>2014-05-14T00:51:24Z</updated>
		<id>https://github.com/RReverser/gh2ost</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: stack-displayname</title>
		<link href="https://github.com/RReverser/stack-displayname"/>
		<updated>2014-05-05T15:19:32Z</updated>
		<id>https://github.com/RReverser/stack-displayname</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: when-traverse</title>
		<link href="https://github.com/RReverser/when-traverse"/>
		<updated>2014-04-17T17:27:17Z</updated>
		<id>https://github.com/RReverser/when-traverse</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: apartjs</title>
		<link href="https://github.com/RReverser/apartjs"/>
		<updated>2014-04-11T21:11:54Z</updated>
		<id>https://github.com/RReverser/apartjs</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: promise-array</title>
		<link href="https://github.com/RReverser/promise-array"/>
		<updated>2014-03-12T13:17:41Z</updated>
		<id>https://github.com/RReverser/promise-array</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: winremote</title>
		<link href="https://github.com/RReverser/winremote"/>
		<updated>2013-12-10T16:30:41Z</updated>
		<id>https://github.com/RReverser/winremote</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: grunt-pure-cjs</title>
		<link href="https://github.com/RReverser/grunt-pure-cjs"/>
		<updated>2013-12-08T11:10:26Z</updated>
		<id>https://github.com/RReverser/grunt-pure-cjs</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: pure-cjs</title>
		<link href="https://github.com/RReverser/pure-cjs"/>
		<updated>2013-12-03T23:37:46Z</updated>
		<id>https://github.com/RReverser/pure-cjs</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Creating own language made easy</title>
		<link href="https://rreverser.com/creating-own-language-made-easy/"/>
		<updated>2013-12-02T03:33:20Z</updated>
		<id>https://rreverser.com/creating-own-language-made-easy/</id>
		<content type="html">&lt;p&gt;Slides from my talk from &lt;a href=&quot;http://www.jquerybulgaria.com/jquery2013/&quot;&gt;jQuery Bulgaria 2013&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.slideshare.net/RReverser/creating-own-language-made-easy&quot;&gt;https://www.slideshare.net/RReverser/creating-own-language-made-easy&lt;/a&gt;&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Github project: compile2js</title>
		<link href="https://github.com/RReverser/compile2js"/>
		<updated>2013-11-27T18:57:42Z</updated>
		<id>https://github.com/RReverser/compile2js</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>HTTP Live Streaming JavaScript player</title>
		<link href="https://rreverser.com/http-live-streaming-javascript-player/"/>
		<updated>2013-11-25T19:08:02Z</updated>
		<id>https://rreverser.com/http-live-streaming-javascript-player/</id>
		<content type="html">&lt;p&gt;I&#39;ve created &lt;a href=&quot;http://developer.apple.com/streaming/&quot;&gt;Apple HTTP Live Streaming&lt;/a&gt; JavaScript player created by performing realtime conversion of MPEG-TS video chunks to MPEG-4 in parallel thread using Web Worker and playing them one by one in main thread.&lt;/p&gt;
&lt;h2 id=&quot;how-does-it-work&quot; tabindex=&quot;-1&quot;&gt;How does it work? &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/http-live-streaming-javascript-player/#how-does-it-work&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Conversion is done using &lt;a href=&quot;https://github.com/jDataView/jBinary&quot;&gt;jBinary&lt;/a&gt; library with programmatically described data structures according to ISO 13818-1, ISO-14496-2, ISO-14496-12 and ITU-T H.222.0 specifications.&lt;/p&gt;
&lt;h2 id=&quot;where-does-it-work&quot; tabindex=&quot;-1&quot;&gt;Where does it work? &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/http-live-streaming-javascript-player/#where-does-it-work&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Works best in Chrome (stable branch), having more noticable lags when switching videos but still working in latest Firefox versions and IE10+.&lt;/p&gt;
&lt;h2 id=&quot;disclaimer&quot; tabindex=&quot;-1&quot;&gt;Disclaimer &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/http-live-streaming-javascript-player/#disclaimer&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Please note that demo uses 3rd-party HLS demo source and service &lt;a href=&quot;http://www.corsproxy.com/&quot;&gt;http://www.corsproxy.com/&lt;/a&gt; for proxying it with needed Cross-Origin-Request headers for browsers to allow chunk downloading, so it may be unstable.&lt;/p&gt;
&lt;h2 id=&quot;where-i-can-see-that&quot; tabindex=&quot;-1&quot;&gt;Where I can see that? &lt;a class=&quot;direct-link&quot; href=&quot;https://rreverser.com/http-live-streaming-javascript-player/#where-i-can-see-that&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Check out &lt;a href=&quot;http://rreverser.github.io/mpegts/&quot;&gt;http://rreverser.github.io/mpegts/&lt;/a&gt; for live demo.&lt;/p&gt;
&lt;p&gt;Screenshot: &lt;a href=&quot;http://rreverser.github.io/mpegts/&quot;&gt;&lt;img src=&quot;https://github-camo.global.ssl.fastly.net/ad8fc78acea3584512442d4c95cccf588d52282e/687474703a2f2f7272657665727365722e6769746875622e696f2f6d70656774732f73637265656e73686f742e706e673f&quot; alt=&quot;Screenshot&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Github project: es6-import</title>
		<link href="https://github.com/RReverser/es6-import"/>
		<updated>2013-10-13T19:40:32Z</updated>
		<id>https://github.com/RReverser/es6-import</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: knockout-protector</title>
		<link href="https://github.com/RReverser/knockout-protector"/>
		<updated>2013-09-13T12:14:46Z</updated>
		<id>https://github.com/RReverser/knockout-protector</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: bt-parser</title>
		<link href="https://github.com/RReverser/bt-parser"/>
		<updated>2013-09-10T16:50:20Z</updated>
		<id>https://github.com/RReverser/bt-parser</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: travis-publish-js</title>
		<link href="https://github.com/RReverser/travis-publish-js"/>
		<updated>2013-09-04T17:09:57Z</updated>
		<id>https://github.com/RReverser/travis-publish-js</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>&quot;Ingvar Stepanyan: Serious JS&quot; at FrontendConf Zurich 2013</title>
		<link href="https://rreverser.com/serious-js-at-frontendconf-zurich-2013/"/>
		<updated>2013-09-02T20:29:32Z</updated>
		<id>https://rreverser.com/serious-js-at-frontendconf-zurich-2013/</id>
		<content type="html">&lt;p&gt;(this used to include a link to the video, but looks like it was since deleted)&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Github project: jBinary.Hex</title>
		<link href="https://github.com/RReverser/jBinary.Hex"/>
		<updated>2013-08-01T10:19:48Z</updated>
		<id>https://github.com/RReverser/jBinary.Hex</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: LikeIE9</title>
		<link href="https://github.com/RReverser/LikeIE9"/>
		<updated>2013-06-17T22:28:12Z</updated>
		<id>https://github.com/RReverser/LikeIE9</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: AndroidMouse</title>
		<link href="https://github.com/RReverser/AndroidMouse"/>
		<updated>2013-06-17T22:18:36Z</updated>
		<id>https://github.com/RReverser/AndroidMouse</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: BMPImage</title>
		<link href="https://github.com/RReverser/BMPImage"/>
		<updated>2013-06-17T22:18:31Z</updated>
		<id>https://github.com/RReverser/BMPImage</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: JSPiano</title>
		<link href="https://github.com/RReverser/JSPiano"/>
		<updated>2013-06-17T22:18:09Z</updated>
		<id>https://github.com/RReverser/JSPiano</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: FilePipes</title>
		<link href="https://github.com/RReverser/FilePipes"/>
		<updated>2013-06-17T22:17:52Z</updated>
		<id>https://github.com/RReverser/FilePipes</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: PingPong</title>
		<link href="https://github.com/RReverser/PingPong"/>
		<updated>2013-06-17T22:17:41Z</updated>
		<id>https://github.com/RReverser/PingPong</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: tasks.js</title>
		<link href="https://github.com/RReverser/tasks.js"/>
		<updated>2013-06-17T22:17:36Z</updated>
		<id>https://github.com/RReverser/tasks.js</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: hubot-skype4com</title>
		<link href="https://github.com/RReverser/hubot-skype4com"/>
		<updated>2013-06-17T22:17:29Z</updated>
		<id>https://github.com/RReverser/hubot-skype4com</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: GitSync</title>
		<link href="https://github.com/RReverser/GitSync"/>
		<updated>2013-06-17T22:17:23Z</updated>
		<id>https://github.com/RReverser/GitSync</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: SharpScript</title>
		<link href="https://github.com/RReverser/SharpScript"/>
		<updated>2013-06-17T22:17:11Z</updated>
		<id>https://github.com/RReverser/SharpScript</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>Github project: LiveReload.Opera</title>
		<link href="https://github.com/RReverser/LiveReload.Opera"/>
		<updated>2013-06-17T22:16:58Z</updated>
		<id>https://github.com/RReverser/LiveReload.Opera</id>
		<content type="html"></content>
	</entry>
	
	<entry>
		<title>JS: Audio Data Processing</title>
		<link href="https://rreverser.com/js-audio-data-processing/"/>
		<updated>2012-03-04T15:56:18Z</updated>
		<id>https://rreverser.com/js-audio-data-processing/</id>
		<content type="html">&lt;p&gt;My lightning talk presentation from JSGroup aka first KyivJS (18.02.2012):&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.slideshare.net/RReverser/js-audio-data-processing&quot;&gt;https://www.slideshare.net/RReverser/js-audio-data-processing&lt;/a&gt;&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Google Translate suggestion in Opera</title>
		<link href="https://rreverser.com/opera-google-translate-suggestion/"/>
		<updated>2010-07-07T11:18:58Z</updated>
		<id>https://rreverser.com/opera-google-translate-suggestion/</id>
		<content type="html">&lt;p&gt;There is a way to add Google Translate suggestions in Opera (at least, for those who has PHP on local machine; if you don&#39;t, please choose any free PHP hosting with allowed HTTP request). So, firstly create and upload such PHP file:&lt;/p&gt;
&lt;pre class=&quot;language-php&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token php language-php&quot;&gt;&lt;span class=&quot;token delimiter important&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&#39;Content-Type: text/javascript&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token variable&quot;&gt;$q&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;stripslashes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$_GET&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&#39;q&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$sl&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$_GET&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&#39;sl&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tl&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$_GET&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&#39;tl&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token variable&quot;&gt;$t&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;file_get_contents&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&#39;http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&amp;amp;q=&#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;urlencode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$q&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&#39;&amp;amp;langpair=&#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;urlencode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$sl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&#39;|&#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;urlencode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$tl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;json_decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$t&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&#39;responseStatus&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$q&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&#39;responseData&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&#39;translatedText&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It will return google translate using OpenSearch formatting.&lt;/p&gt;
&lt;p&gt;Then, you should open &lt;code&gt;search.ini&lt;/code&gt; (in profile folder) and find there your Google Translate&#39;s section. Add those two lines to it:&lt;/p&gt;
&lt;pre class=&quot;language-ini&quot;&gt;&lt;code class=&quot;language-ini&quot;&gt;&lt;span class=&quot;token key attr-name&quot;&gt;Suggest Protocol&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;JSON&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;Suggest URL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;http://localhost/gsearch.php?q={SearchTerm} (your URL)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Restart Opera. That&#39;s all.&lt;/p&gt;
</content>
	</entry>
</feed>
