Monday, August 28, 2017

Writing a Simple DSL Compiler with Delphi [2. Abstract Syntax Tree]

This article provides a description of an abstract syntax tree used to represent "The Language". If you are new to this series, I would recommend to start reading with this post. 

Please note that this article describes an initial implementation of the AST. If you want to browse the code while reading the article, make sure that you have switched to branch dsl_v1.

An abstract syntax tree (AST) is, simply put, a symbolic representation of the program in a form of a tree.

While the textual representation of a program is great for us, humans, computers have hard time dealing with it. Because of that, a special part of any interpreter/compiler, called parser, reads the input and converts it into a computer-readable format - AST. This tree can then be used for multiple purposes. We can, for example, feed to into an interpreter which will then run the program for us, or we can feed it into a compiler to generate an executable program or cross-compiler to generate an equivalent program in a different programming language.

Friday, August 25, 2017

Writing a Simple DSL Compiler with Delphi [1. The Language]

Part 1: The Language

This article provides an informal definition of a simple language (a.k.a. "The Language") I am writing a compiler for. If you are new to this series, I would recommend to start reading with this post.

Let's start with a simple example which calculates an i-th Fibonacci number.

 fib(i) {
   if i < 3 {
     return 1
   } else {
     return fib(i-2) + fib(i-1)
   }
 }

The code is quite simple. First two numbers in a Fibonacci sequence are 1 and every other Fibonacci number is a sum of previous two in the sequence.

Wednesday, August 23, 2017

Writing a Simple DSL Compiler with Delphi [0. Introduction]

Part 0: Introduction

Some time ago I was listening to the Hanselminutes podcast where a guy described how he wrote a simple interpreter in Go language (YOU should write an interpreter with Thorsten Ball). I was not really interested in writing an interpreter - I did that a long time ago - but a thought crossed my mind. I asked myself whether I can do something better - write a compiler. (Or, rather, a kinda-compiler. You'll see.)

What I wanted to do is to take a small language, parse it, generate an abstract syntax tree, and then convert this into one large anonymous function calling other anonymous functions calling other anonymous functions and so on and so on. It is hard to explain, so let me try using a very simple example.

Tuesday, August 01, 2017

OmniThreadLibrary 3.07.3

TL;DR: Update OmniThreadLibrary now!

A nasty bug was found in the DSiWin32 library. It causes the DSiTimeGetTime64 function to work incorrectly when called from multiple threads at the same time. As this function is central to time measurement in the OmniThreadLibrary, it was essential to release new, fixed version.

This version also contains two small enhancements.

  • SetTimer method now accepts TProc and TProc timer methods.
  • IOmniTask implements method InvokeOnSelf which can be used to schedule anonymous function execution from a task back to self.  

As usual, you can get OmniThreadLibrary from GitHub (3.07.3HEAD), download the zip, install it with GetIt or with Delphinus.

Damn, multithreading is hard!