Introduction

One way to understand how the RECC compiler, the microkernel, and the One Page CPU fit together is to compare the compile process of standard compilers to the compile process of RECC.

Typical Compile Process with Compilers Like GCC or Clang

1) .c and .h files Your project will consist of .c and .h files, however your .h files will be included into whatever C file you're compiling during the preprocessing step so you can think of the project as a bunch of flat C files without references to any other files.

2) Preprocessing When you tell the compiler to start compiling, the first thing it does is run the C preprocessor to get a single flat view of that one 'translation unit' that you are compiling. This involves expanding macros like #include or #define and replacing them with 'pure C' code. The resulting pure C will likely be compiler specific because certain macros will be implemented using functions that need to be built into the compiler, or need to talk to the OS.

3) 'Pure C' Normally you don't output the preprocessed output, but if you do the default file extension is .i with GCC or Clang. You can see the output from preprocessing with 'gcc -E file.c'. 'gcc -save-temps file.c' is also useful.

4) Machine code generation Once you have pure C code, you can output machine code for a specific architecture that could be executed by that target processor.

5) Object files The machine code is packed into object files that may use popular formats like ELF. The machine code doesn't have to be for the host architecture and this is the case when you're cross-compiling an application with the goal of running it somewhere else. Object files also contain symbol information to describe the size and location of variables and functions that it contains.

6) Linking Compilers like GCC typically use an external program like the 'ld' program to link multiple object files together into a single executable (or library).

7) Executable You end up with an executable that can be run on the target platform you compiled for.

Compile Process with RECC

5) L2 Files L2 files are like object files, but they contain the L2 Language. The L2 language is a human readable assembly like language that allows for symbol information, relative offsets and comments.

7) L1 File An L1 file contains the L1 Language. The L1 language is a proper subset of the L2 language, but doesn't allow for relative offsets, symbol information, or comments. The assembly in the L1 and L2 languages is intended to be run on the One Page CPU.

8) 'Preloading' One goal of the One Page CPU is to allow for easy CPU emulation inside other languages. Since L1 files need to be assembled, the 'preloading' step is mostly the same for every target programming language we wish to emulate computation in. The preloading step parses the L1 language and generates machine instructions, then packs them inside a well formed program written in the target language.

9) L0 Files The format of an L0 files is different for every target programming language. For example, with Python you end up with a module that contains a class that has a large array of data with the machine instructions represented as numbers. In Java you end up with a class that does the same thing. With javascript you can create a JSONP file.

10) Loading L0 files The data in L0 files is simple enough that it takes about 10 lines of code to load the executable image into the memory of the One Page CPU implementation of your faviourite language.

11) One Page CPU Emulators The One Page CPU emulator is simple enough that you can write one in your favourite language in about 300 lines of code. The CPU supports context switching I/O and timer interrupts. Here is a small microkernel running in a Javascript on the One Page CPU emulator.