Code Generation for a New Programming Language

Code Generation is the final step of the journey through Grammars, Parsers, Semantics and Compilers. In this article, I will discuss with you the implementation I made of a Code Generation module, as part of the Compiler I wrote for a new programming language that I designed. Let’s also briefly review what we’ve learnt so far in this course about Compilers and Programming Languages. We went into the details of many central subjects as well as some side-topics that are useful to understand the whole picture. [Read More]

Design of a New Context-Free Grammar

We studied Formal Grammars in some of the previous articles in this course, What is a Grammar in programming languages and How to design formal Grammars. The most important concepts we learned are: There are 4 types of Grammar in the Chomsky hierarchy. Type-2 Grammars, also said Context-Free Grammars, are the ones used to design new programming languages. One must avoid many pitfalls while creating a new Grammar, for example left-recursion and ambiguity. [Read More]

Do Compilers Depend on the Computer Architecture?

In all previous articles in this course, I tried to emphasize equally all steps in the compilation: Lexical Analysis Parsing Semantic Analysis Optimization Code Generation For some reason, though, I noticed that the first three steps receive a lot of attention, usually much more than the last two. Moreover, the first three steps form what’s usually called front-end compilation, as opposed to the back-end compilation that if formed by the last two. [Read More]

How Compilers Optimize the Source Code (Part I)

A previous aricle of this course was entirely devoted to an overview of Optimization in Compilers. Reading that article is a clear prerequisite for this one (see the references at the end). We did study the following concepts: What Compilers optimize. When Compilers optimize, that is, at which point in the compilation process. Where they optimize, that is, what parts of the code. In this article I want to study How Compilers Optimize source code. [Read More]

How Compilers Optimize the Source Code (Part II)

In Part I of this class we learned a great deal about how Compilers do Local Optimization. Local Optimization is the process of improving the performance of each basic block of code, isolated from the rest of the code. A basic block is a subset of the program that doesn’t contain label, except possibly in the first instruction, and doesn’t contain jump, except possibly in the last instruction. In Part II of the class on How Compilers Optimize the Source code, we will be studying Global Optimization and Data-Flow Analysis. [Read More]

Implementation of a Recursive Descent Parser

We learned a great deal about Parsing algorithms in previous articles of this course. In one sentence, a Parser is a software that receives a list of Token objects and decide whether such a list fulfills the constraints given by a Formal Grammar. In other words, within a Compiler, the Parser is the element that makes sure the grammatical rules are respected. At the organization level, the Parser is the second step in front-end compilation, after Lexical Analysis, but before Semantic Analysis. [Read More]

Implementation of Semantic Analysis

This article is part of my course on Compilers, Formal Grammars and Programming Languages. Up to this point we have studied: What is a Compiler. What are the several stages of the compilation process. What is a Formal Grammar, and several existing types of Grammars. A real design example of a new Context-Free Grammar, for a new Turing-complete programming language. What is Parsing, the second stage of compilation. A real implementation of a Recursive Descent Parser, made for the new programming language mentioned above. [Read More]

How do Compilers Manage Garbage Collection?

A Garbage Collector is the module of a programming language that takes care of cleaning the memory during the program’s execution. Even though we are used to it, Garbage Collection (also called Automatic Memory Management) is a relatively recent innovation in programming languages. In the good old days, programming languages such as C and C++ asked the developer to take care of every bit of memory. For example, in C the developer should: [Read More]

Source Code Optimization in Compilers

The strongest Compilers out there do not limit their work to direct compilation of the source code. They also modify the original source code in order to optimize performances. The first concepts we must study are: What they optimize. When they optimize, that is, at which point in the compilation process. Where they optimize, that is, what parts of the code. What do Compilers Optimize? Software applications vary over a very broad range. [Read More]

Why Are Some Programming Languages Faster?

Thanks to “Compilers” being the main keyword for this course, we also learned a great deal about Programming Language. In a previous article I described what features can differentiate a programming language from the others. In particular: General Purpose vs Domain Specific Language. High vs Low Level Language. Interpreted vs Compiled Language. Procedural vs Functional vs Object Oriented Language. Typed vs Untyped Language. Statically vs Dynamically Typed Language. Static vs Dynamic Scope. [Read More]