Writing a compiler in C# for pre-compiled templates

I have written high performance web application frameworks for JavaScript and PHP. Today I decided to start writing a high performance web application framework in C# (on Linux using Mono). Speed and simplicity are again the goals for this MVC framework. I have read that HttpListener is very fast (comparable to NodeJS), so that seemed like a logical starting point. The framework is far from done, but one of the most interesting things I did so far was that I looked into pre-compiled templates for optimal ease of use (template errors are shown during compile time). Normally these templates can be written in T4 or Razor, but the compile time errors are not so understandable (to me).

I hand-coded a few templates in C# and wrote some input in a template language that resembles “aspx” syntax (but is not). After that I wrote a compiler that would turn the template into that exact C# code to be compiled. The template:

<%@ Page Inherits="Layouts.Default" Using="System.Text,System.Text.RegularExpressions" %>
<% Context.Data ["title"] = Context.Data ["Name"]; %>
Email: <input type="text" value="<%= Context.Data["Email"] %>"></input>
Test: <input type="text" value="<%= "some string" %>"></input>

The generated C# code:

 * WARNING: Generated file, do not edit, changes will be lost!

using System;
using System.Text;
using System.Text.RegularExpressions;

namespace Maussoft.Mvc.CsTest.Views.Test
	public class Index: Layouts.Default
		public override void Content()
			Context.Data ["title"] = Context.Data ["Name"]; WriteLine();
			WriteLine(@"Email: <input type=""text"" value=""{0}""></input>",  Context.Data["Email"]);
			Write(@"Test: <input type=""text"" value=""{0}""></input>",  "some string");

I started with some regular expressions, but soon found out that I had to write a real parser. The compiler deliberately outputs multiple commands per line to ensure every line of the template corresponds to a single line of code. This is one of the design goals and this behavior should improve the ease of debugging of the code, since the errors on the compiled template will be reported on the generated C# code.

I was looking into turning this into a “Custom Tool”, but after seeing the implementation differences between MonoDevelop and Visual Studio I decided on making an executable that your run before building (as a pre-build step). Next step for the framework is probably to add something like Dapper to have simple database support. Also a run-time debugger toolbar in the browser (like symfony2 has) would be beneficial.

All code is available on Github.


Text mode 2048 game in C, algorithm explained

2048 is hot! It may be considered the next Flappy Bird. I implemented 2048 in the C programming language, so you can run it on your Linux server on the console (in text mode). You can find the 2048.c project on Github.



You can move the tiles in four directions using the arrow keys: up, down, left, and right. All numbers on the board will slide into that direction until they hit the wall and if they bump into each other then two numbers will be combined into one if they have the same value. Each number will only be combined once per move. Every move a new number 2 or 4 appears. If you have a 2048 on the board you have won, but you lose once the board is full and you cannot make a move.


I chose to store the field in a two-dimensional array called board that is 4×4.

[2][0][8][2]          [2][4][8][4]
[0][4][0][2]  press   [4][8][4][4]
[4][0][2][2]  up key  [0][0][0][0]
[0][8][2][2]          [0][0][0][0]

Since I want the board to be addressed as board[x][y], the board consists of a set of four columns size four. So the first column is the array [2,0,4,0]. If we press the up button this should become [2,4,0,0]. The function “slideArray()” is reponsible for this. This function will “slide” the numbers in the arrays like this:

[2,0,4,0] => [2,4,0,0]
[0,4,0,8] => [4,8,0,0]
[8,0,2,2] => [8,4,0,0]
[2,2,2,2] => [4,4,0,0]

The algorithm can just use board[x] to point to a column and work directly on that. In pseudocode, this is what the algorithm does:

- walk over the array from the first to the last number
  - for each original number in the array that is not zero
    - look backwards for a target position that does not contain a zero (unless it is position zero)
      - if the target position does not contain the original number use the next position
    - if the target position is different from the original position
      - add the number to the number on the target position
      - replace the original number by zero

The above algorithm executed will do all transformations, it will:

[2,2,2,2] => [4,4,0,0]
[0,8,2,2] => [8,4,0,0]

But there is a problem, it will also do this:

[2,2,4,4] => [8,4,0,0]

The two’s are merged into a four and then the first four is merged into that making it an eight. This is wrong. It should be doing this:

[2,2,4,4] => [4,8,0,0]

This is avoided by adding a “stop” variable that will be initially set to zero, but when a merge has been done it will be set to the merge position plus one. This will make sure any next slide will stop before it merges into this number again, since double merges are not allowed.

To prevent complex programming I use a function rotateBoard that rotates the board 90 degrees counter-clockwise. This allows the moveLeft(board) to be implemented as:


As long as you rotate four times in total everything works as expected. This method is not very efficient, but reduces the complexity of the code.

Compiling and running

Since 2048.c is a single C file it is easy to get running, just execute the following commands:

wget https://raw.githubusercontent.com/mevdschee/2048.c/master/2048.c
gcc -o 2048 2048.c

This will run on most machines. If not, then execute the following command to install the compiler:

sudo apt-get install build-essential

Further reading