Rickard Lindberg | Blog | Projects

rlworkbench

rlworkbench is my project where I try to build a language workbench. What is that? What am I trying to build?

The way I think about it is that rlworkbench should be a text editor that is aware of the language of the text that is being edited. That awareness can give us syntax highlighting for example. But it can also give us more if it knows more about the language. For example, there might be an editor operation to expand the selection. If the cursor is inside a function, expanding the selection might select the whole function. Because the editor is aware of the language, it knows where the function starts and ends. Furthermore, defining the languages that rlworkbench knows about should be easy. And the norm should be to create many small domain specific languages. And when we define a language, it not only gives us editor support, but we can also define how that language should be compiled or translated.

Screenshots

Here is rlworkbench editing the README file. A markup language has been defined and it provides both the syntax highlighting as well as the ability to turn the README file into HTML for display on this webpage.

Screenshot of rlworkbench editing the README file.

Blog

When I write about rlworkbench on my blog, I tag the posts #rlworkbench.

Language Definitions

Languages are defined in a meta language called meta. Meta programs are turned into C programs (using the meta compiler) which are then turned into binaries using a C compiler.

+-------------------+       +----------------+       +--------------+
|                   |       |                |       |              |
| asciidiagram.meta | ----> | asciidiagram.c | ----> | asciidiagram |
|                   |       |                |       |              |
+-------------------+       +----------------+       +--------------+

What does a meta program look like? Let's have a look at an example that defines a language for ascii diagrams used to highlight the diagram above:

main = element*;

element =
    | arrow
    | boxBorder
    | .
    ;

arrow[Preprocessor] =
    | '-' '-'* '>'
    ;

boxBorder[Reserved] =
    | '-'
    | '+'
    | '|'
    ;

It defines syntactic elements of an ascii diagram and highlights different parts differently.

The compilation process is as follows. First, the meta program is turned into a C program:

meta <asciidiagram.meta >asciidiagram.c

Then the C program is turned into a binary:

gcc asciidiagram.c -o asciidiagram

Now, what can this binary do? By default it accepts asciidiagram programs on stdin and spits out how they are transformed to stdout:

echo "----> what?" | ./asciidiagram 2>/dev/null
----> what?

The asciidiagram language does not specify any transformations, so the consumed characters are printed as is.

We can also call asciidiagram with the highlight argument which then prints the input program to the terminal with syntax highlighting:

echo "----> what?" | ./asciidiagram highlight
----> what?

Alternatively it can spit out highlighted HTML with the --html flag:

echo "----> what?" | ./asciidiagram highlight --html
<pre class="highlight"><span class="Preprocessor">-</span><span class="Preprocessor">-</span><span class="Preprocessor">-</span><span class="Preprocessor">-</span><span class="Preprocessor">&gt;</span> what?
</pre>

We have to provide CSS for the different classes.

Let's look at another language that does include transformations. This is a simplified markup to HTML processor:

main = element*:xs -> { xs };

element =
    | '*' emInner:x '*' -> { "<em>" x "</em>" }
    | char:x            -> { x }
    ;

emInner[Meta] = nonStar*:xs -> { xs };

nonStar = !'*' char:x -> { x };

char =
    | '<' -> { "&lt;" }
    | '>' -> { "&gt;" }
    | '&' -> { "&amp;" }
    | .
    ;

Here is how it transforms an input string:

echo 'Is 2<1? No, *2>1*!' | ./examplemarkup 2>/dev/null
Is 2&lt;1? No, <em>2&gt;1</em>!

All languages that rlworkbench knows about also automatically get syntax highlighting in the editor.

Changelog

1.8.0

1.7.0 (2026-05-21)

1.6.0 (2026-05-15)

1.5.1 (2026-05-12)

1.5.0 (2026-05-12)

1.4.0 (2026-02-07)

1.3.0 (2026-01-10)

1.2.0 (2026-01-10)

1.1.0 (2026-01-09)

1.0.0 (2026-01-04)

TODO

Structure/C

Platform layer

Test framework

Editor

Highlighting

Language integration

Rendering

Markup language

Meta language/compiler

What is Rickard working on and thinking about right now?

Every month I write a newsletter about just that. You will get updates about my current projects and thoughts about programming, and also get a chance to hit reply and interact with me. Subscribe to it below.

Powered by Buttondown (My Newsletter)

Profile picture of Rickard.

I'm Rickard Lindberg from Sweden. This is my home on the web. I like programming. I like both the craft of it and also to write software that solves problems. I also like running.

Me elsewhere: GitHub, Mastodon.