Skip to content

DOC GOAL Document Red System

iArnold edited this page Mar 27, 2017 · 2 revisions

Document the workings of Red/System.

The Red/System documentation for how the Red/System language is to be used is very good. You can also always find it from the red-lang.org homepage on the red-lang Documentation page there are more useful links there as well.

This wiki now includes the original article about the inner workings of the Red/System compiler from the red-lang blog too, Red/System Compiler overview

This is to describe

a. how the Red/System inner working is accomplished.

b. how the Red/System code handles creating system code for the different supported operating systems

Red / System

Red/System is a DSL or Domain Specific Language of the Red programming language.

Red/System is the low level language, in that sense we compare it to the level C operates upon.

Red code is compiled to Red/System code.

Where the Red files have extension .red, we use .reds as extension for Red/System files.

Red/System takes care of generating bytecode for the various supported platforms. One important reason to document Red/System is to understand how this works so in future support can be extended to other platforms as well as support of 64 bit.

Startpoint of Red/System

Because Red is not yet bootstrapped, the toolchain of Red/System also consists of REBOL scripts.

Former startpoint of Red/System compilation is the rsc.r script. But this script now has been deprecated and only kept for convenient integration in other REBOL apps.

Compilation must now start with %red.r too.

So the other scripts in the system directory are:

  • compiler.r
  • config.r
  • emitter.r
  • linker.r
  • loader.r

We will revisit these as we pass along them.

Almost at the bottom of %red.r is

redc/fail-try "Driver" [redc/main]

This fail-try function is a construction to get information back when the function that is performed somehow fails. Just like it says ;-)

So here the main function from the previously defined context with the name redc is performed.

This main function checks if the passed command is valid and then calls the compiler function

result: compile src opts

(Well there is also some code catching the libRed here but for simplicity and getting up to speed we skip that here)

Because this code is inside the redc context the redc/ we saw before is not used here.

The compile function checks if the source is a Red source or a Red/System source.

In case of a Red/System source, the first compilation step, creating Red/System code from the Red code can obviously be skipped.

In this part we directly head to the compiling of Red/System source code.

;--- 2nd pass: Red/System compiler ---

Here the directory is changed to the Red/System folder

unless encap? [change-dir %system/]

And now depending if the source is a Red/System source it will be compiled, but when it was coming from Red, of course the result of the first compilation step should be used and not the original Red source.

At the end of this process the directory will be changed back one level up again. Unfortunately if some error is encountered this step is not performed, leaving to correct this to the user. Sometimes after a compilation error has occurred it is best to end the session and start a new one.

So the function now called is in context system-dialect. This context is created inside the compiler.r from /system/ folder, the Red/System compiler

system-dialect: make-profilable context [...]

For explanation of make-profilable see the explanation document for this.

So now we have entered Red/System country!

But how does the compile continue now?

One of the first things the compile function does is call the emitter/init function from the emitter.r file.

emitter/init opts/link? job

In the emitter/init function it says

path: pick [%system/targets/ %targets/] encap?
target: do-cache rejoin [path job/target %.r]

This “does” (i.e. includes) the file %IA-32.r or %ARM.r depending on the value of job/target.

Thereby, all function calls inside %emitter.r which are like <target/emit-something> are now going to the right functions for code generation, as it should be.