Liscript - web REPL: kisses, bicycles and excavators



    Some time ago I wrote an interpreter of a lisp-like language called Liscript. He published several articles on Habré, dedicated to the implementation features of the kernel, TCO, GUI, REPL bots, etc. Recently added a REPL web-interface (link at the end of the article).

    What does kisses and excavators have to do with it? I think most of them know such abbreviations as KISS (keep it simple stupid - make it simpler, you fool), YAGNI (You ain't gonna need it - as well as statements of people of varying degrees of grandeur about architectural astronauts, " everything should be done as simple as possible, but not easier ”, etc.

    Let's say you have a task - to dig a hole. What are the solution options? Taking a shovel and digging it yourself is cheap and cheerful, but for a long time and possibly not optimal (depends on your level of shovel possession and the size of the pit). Outsource to Tajiks (we will not consider this option here, although I should have mentioned it). To take an excavator is quick and effective, but expensive: gasoline / rent, plus not the fact that it will go to your garden gate, so you need to demolish / restore the fence, etc. Also, you need to decide on a model (sometimes out of 100,500 options), and if you manage it yourself, you need to understand all its levers and pedals.

    Of course, if you are a professional excavator, you dig 200 pits a day, or you strive to become one, and the initial task (digging a hole) is not necessary for you alone, but as a training or demonstration of your skills, then the choice is obvious (it remains only model issue). But even a professional will take a shovel, planting flowers.

    In general, about the choice of tools for the tasks, and the specific (I suspect that they are controversial) decisions that I chose during the project, under the cat.

    Implement a singly linked list

    Liscript does not have point pairs (cons cells), so the main structure of both the code and the data in it is a list. In the Java version of the interpreter, I wrote my own simplest class with the fields car and cdr. You could take standard Java collections like LinkedList or ArrayList - most likely they are better optimized in terms of allocations and friendship with the garbage collector. But I chose my own bike, although it is not difficult to refactor to the second option.

    Tokenizer / Lexer / Parser

    This is an interesting example. You need to read the input text / line and convert it to a finished AST (abstract syntax tree), extracting tokens from the text and organizing them into a hierarchical structure. The task is more than well-known, there is a whole vast theory of parsing and parsing, and many library implementations of various parsers, for example www.antlr.org But I decided to write my simple bike on a state machine - Lisp has a very simple grammar and syntax, although of course I had to consider multiline string literals and comments. Moreover, I have 3 such bikes: in the Haskell implementation (despite a lot of ready-made solutions: parsec, attoparsec, etc.), in the core of the Java implementation and in the Swing GUI for syntactically highlighting code text.

    WEB backend


    Case history: this is my first web-project, as the hosting of the application I chose Heroku, a free tariff plan. Of the build systems in one Java chat, I was advised by Gradle, not Maven, motivating me with various attractive words. I believed, I chose the Gradle-assembly option on Heroku, and the demo that downloaded to my disk used Ratpack (I don’t know what the Maven-assembly example is, it is possible that the same thing). Since I did not have experience with other web servers (and web technologies in general), I had to make a choice - or not to use this demo example, but to install some Jetty, on which IMHO much more available information on the Internet, or use Ratpack, ready and tuned, but somehow dealing with it. I chose the second option, among the examples found, two-thirds were on Groovy,

    WEB frontend


    Here, in general, there is simply a sea of ​​options for choosing the most diverse technologies, because the region has been developing rapidly for many years. And the apologists of different frameworks prove to the whole world (and to each other) that their choice is better / more efficient / more promising and the only way is to “write WEB in 2017” (C) Each of them is right in his own way, but what choice did I have? To solve the purely utilitarian tasks - to dig a hole to write web- sea interface its REPL-a.

    • Use Java frameworks that can generate a web interface: Vaadin, FX, etc. Heavy powerful excavators supporting the paradigm "it is written once - it digs everywhere."
    • Use numerous WEB frameworks / libraries, their name is Legion: Angular, React, ... Each with its own rich inner world of blackjack functionality and whistles.
    • Write everything yourself on bare vanilla Javascript / HTML / CSS.

    As you might guess, I certainly chose the third option :). Even without using jQuerry, because this machine would have to be studied too. Without Babel / Webpack and another 100,500 words that are trendy at the front. For the first time in my life, having experienced the joy of debugging for various browsers, including IE, I was forced to hardcode CSS constants instead of declaring them at the beginning of the file, which in itself is pathetic, but IE didn’t want to see these ads, and CSS generation technologies from others formats, as various trendy frameworks offer, implied the use of the mentioned frameworks.

    But of course I'm not as stubborn as a cyclist might have seemed to you , not an excavator. In a couple of tasks of the web interface, I selected ready-made libraries:

    Split panels

    For REPL, I really needed them. Powerful web GUI frameworks implement them in their composition, but, excluding heavy equipment, I considered smaller ready-made implementations, and after trying 3-4, I still chose one. Although it pulls jQuerry along, which I don’t really like (I don’t need it anymore), it reacts much better in terms of responsiveness of the interface. If there is time / desire, I can rewrite it on my bike, without jQuerry.

    Code highlighting

    Here I think I’m lucky - to solve this problem, I immediately found the magnificent codemirror.net library , figured out its capabilities, wrote a plug-in for the syntax of my language and design theme. I didn’t write my bicycle parsers / lexers, because this library is simple, lightweight and does a good job of it - both in static text areas and in dynamics when editing user code.

    Conclusion


    Of course, I am aware that the decisions I have made above are at least controversial and ambiguous. What could (and from some positions even better) was to use ready-made technological tools. What did I gain by writing my parsers / lexers? Experience in writing similar bikes on finite state machines, full control of what is happening, the possibility of easy customization. What is lost? I haven’t figured out ready-made existing parsers, I haven’t mastered them, and if I have to use them in the future, I will be forced to learn them from scratch. And the same verdict for each of the options for individual local tasks. But in any such case, you have to make a choice, so you have to weigh all the pros and cons, and take the consequences. What do you think about this?

    Liscript Website Home
    Online REPL

    Also popular now: