The article tells about the module that allows you to create a subset of javascript with any keywords. Strictly for uncontrollable fun.
In the wake of an article about rucckuu.js, I envied me and decided to publish my creation: a small ecosystem to create arbitrary javascript subsets. If the idea that some keywords have a bad fit to the context of their application or the idea that javascript is too verbose (something happens) has long creeped in on you. If you want to good-humoredly make fun of colleagues or just explain to your mom what you do at work at all, welcome to the cat.
So, the task of transpilation itself is quite simple - to find and replace. The very same transpilation in the world of modern frontend is an integral part of the integration of new technologies and specifications: everyone knows what a babel or traceur-compiler is , and every self-respecting front-end developer occasionally looks at the esdiscuss mailing list . The lightning-fast development of our technology stack is a pain and a miracle in one bottle, because the possibilities are breathtaking, and the number of possible variations in the performance of some give up. Very lucky for those who have them go straight to their favorite or just the keyboard that came under them. For such brave heroes, this article may be of little academic interest, so I warn you - all of the following is intended only to satisfy the unbridled passion for creating interesting pieces. Yes.
Returning to transpilation, the task of replacing values in a string is very trivial. However, the task of replacing words that are integrated with the context is somewhat more interesting. Without affecting all the thousands of man-hours spent on the study and creation of a theoretical basis for creating parsers of various grammars, let us proceed immediately to the most important thing. The grammar of a programming language very clearly defines the context for the use of a particular keyword, and this use can be interpreted only in one predetermined way. Such determinism follows from the essence of the programs, I am sure that there is no one who would like to see two different results of the execution of the same program under the same initial conditions. Based on this, any program can be interpreted as a very specific syntax tree . So, for programming languages, it is enough just to curb the syntactic monster and get an unambiguous definition of the context of use of any word. With context in hand, you can literally do anything.
I think many have heard about esprima , the ECMAScript parser. A little less people know about jison . Without the first, we would not see jsx so soon, and the second is due to its CoffeeScript appearance, both tools are powerful enough, but esprima specializes in exactly what we want to do - change the appearance of our programs.
The mean entry is over, to the point.
node
, npm
by my assumption do not cause you horrornpm i your-script
to any convenient directorynode_modules/your-script/lexems
look at node_modules/your-script/lexems
meowscript.lex
javascript.lex
from the same folder somewhere nearbymeowscript.lex
replace the definition of keywords with something like: VAR meow LET meoww CONST meOw FOR meowwr ...
any-name.js
meowScript = new translator({ to: 'meowscript' }); let output = meowScript.parse(` var kitty = new Kitty(); if (kitty.isHungry()) {kitty.feed()} `, { from: 'javascript', to: 'meowscript' }); console.log(output); // stdout: // meow kitty = MEW Kitty(); meeow (kitty.isHungry()) {kitty.feed()}
Well, that's all.
The scope of the module is limited by your imagination. Under the hood is just esprima, which I mentioned, with the exception that this version is patched (manually and with love) in order to support an arbitrary set of keywords. I keep silent about the amount of labor that had to be done in order to manually find all hardcoded uses and replace them with the correct references. After that, it was necessary only to add a loader to support arbitrary replacement of sets of keywords during execution. The work is quite simple, but painstaking.
In addition, the packaged packaged primitive keyword provider with the most primitive parser .lex
. All modules are lying around in the public domain and are available for kicking for everyone.
In fact, with this toolkit, you can create arbitrary subsets of javascript in a few minutes. The only limitation is the inability of the module to find the standard interfaces of the node or browser. So alas, document.body.getBoundingClientRect, gentlemen. Adding support for the transfiguration of interfaces is also not so difficult, you just need to define the rules for identifiers and replace them according to them.
Finally, the picture in the post header is not accidental, as an example of using your-script, I wrote redscript - a Russian subset of javascript. Well, as a result of using this parser:
var = 'var';
will be correctly transported to:
= 'var';
The module itself rolls in npm. For the seed, an example of a transpiled program:
(, , ) { = 0; = {0: "", 1: ""}; = () { } (! > 10) { ( = 0; < 10; ++) { (j) { 0: = "zero"; ; 1: = "one"; ; } = > 5 ? " 5" : " 5"; } } { = 0; { ( < 10) { ( == || > 5) { a[] = + * 12; } = ( << 2) & 4; ++; } { --; } ( > 0) } (e) { alert(": " + e.message); } { (a, ); } } }
For advertising purposes, this is still the only module that allows you to make
() { (); }
In general, inventing alternatives is incredibly interesting. If you come up with something cool - please leave in the comments. Have a great weekend and lots and lots of fun, infinitely much pleasure from what you do :)
Source: https://habr.com/ru/post/283108/
All Articles