Compiler design

In this section, you will understand the concept of a compiler in brief. It is recommended that everyone who codes in Dynamics NAV should understand the basics of compiler design.

The main aim of a compiler is to convert a high-level language such as C# and JAVA to a low-level language like machine-level language. The question is, Why do you need to do that? The reason is that we are not comfortable writing a problem in 0's and 1's, which is the form in which a computer system understands the commands. The figure shown in the Assembler section explains how the whole compilation process can be sliced into different entities, which handle different operations, leading to the transformation of a high-level language into machine-level bits. The first layer in most of the high-level development environments is the preprocessors.

Preprocessor

A preprocessor is nothing but a language-specific program, which processes the input high-level code into the output code that can be passed on to the compiler. It basically breaks down the complex chunk of code for the convenience of the compiler. Here, in the C/SIDE development environment, you can take the preprocessor as the code that converts C/AL code, and converts it into a C sharp equivalent code. Actually, this is not real compilation. It is just changing the form of the code. The output of the preprocessor is transferred to the compiler.

Compiler

A compiler is also a computer program or programs, which work together to transform the output source code of a preprocessor into another form, usually into another computer language. Here I am taking the preprocessor as the first layer, but in many cases, the source code is directly passed on to the compiler. In most cases, the output of the compiler is assembly code, and the code is passed on to another layer called the assembler.

Assembler

An assembler is the entity which translates assembly-level language into object files or machine code bits. The basic functions used in assembly language are basic arithmetic operations, because a computer just knows how to compute. The operations are add, subtract, move, compare, shift, and so on. This is the last layer where there is some user-readable form of code. The output of the assembler is the bit of 0's and 1's, which is binary programming language, also called machine-level language.

A computer only understands binary language, because it can be then transformed into the electrical form, 1 for electrical potential and 0 for no electrical potential, and then the processor can carry out operations at the hardware level. Hence, whatever be the output of the operations, it is again converted back into a user-readable format, and the user is able to see the result.

Note

The main intention behind explaining these core terminologies is to give the reader a very brief knowledge about code transformations thus providing knowledge about the system and the implications of very complex code, which can make system response time slower.

The next diagram explains how high level languages are broken down into chunks of bits when it passes through different processing units such as the preprocessor, compiler, and assemblers. Some of them have their own context free grammars (CFG) which they use as the tool while breaking the code that is meaningful to the humans into relevant machine level codes and vice versa:

Assembler

Now let us examine the internal structure of a compiler, since all of the major operations such as lexical analysis, syntax analysis, and semantic analysis are carried out by different programs which are a part of the main compiler program set.

Whenever any code is passed on to the compiler, it is converted into tokens or a stream of tokens. Tokens are nothing but strings with an identified meaning. Every compiler has a set of strings in its dictionary. In the next layer, these tokens are matched with the strings in the predefined dictionary. But in this layer, the code is just converted into small chunks of tokens, and passed on to the syntax analyzer.

A syntax analyzer is also called a parser. The compiler contains the rules and grammar. It arranges the tokens into a parse tree so that in the later part it can be checked for its correct grammar and rules. The parse tree is then passed on to the semantic analysis process.

Semantic analysis is the process of relating the parse tree with the phrases where the compiler understands the meaning of the code. It also verifies for correct grammar and correct semantics of the code (parse tree). This then passes through other layers where the code gets reduced in size, and where the comment section is truncated from the actual code, making the code ready to be converted into assembly-level code. Finally, the assembly-level code is generated.

Tip

This preceding process is the same such as when you translate a non-English language into English: you first break down the words, and then arrange the words as per the meaning and its semantics, and finally, understand the meaning of those arrangements.

The following figure explains the internal structure of different layers that we examined in the previous section. Here we can see how difference processes are carried out inside the compiler to break the high-level code into assembly level code:

Assembler

Hence, the code is processed and checked. There are many layers which perform different tasks. It is important to understand how the C/SIDE development environment does all this for a programmer.

Preprocessing into C# code

Whenever you write C/AL code in Dynamics NAV, you must understand that the ultimate goal is to provide the command to the computer to perform operations like add, subtract, move, and many such basic operations. C/Side just provides an additional layer of simplicity over C# code compilation. We all must understand that all C/AL codes are ultimately converted into C# codes, and then processed accordingly. We will now examine how we can see the C# code for the corresponding C/AL code. For this, we need to make some changes to our configuration file so that the system can generate a C# code, which is nothing but the counterpart of the C/AL code.

Perform the following steps to get the corresponding C sharp code:

  1. Go to the following address in the system where Dynamics NAV is installed:

    C:Program FilesMicrosoft Dynamics NAV90Service and find the file named CustomSettings.config.

  2. Open the file, and search for the EnableDebugging key.
  3. Change the value of Key to True:

    Preprocessing into C# code

  4. Save the file.
  5. Restart the service from Services.Msc.

    For this, open the Run command (Ctrl + R ), and type services.msc. Locate the Microsoft Dynamics NAV 2016 Service, and restart it as shown in the following screenshot:

    Preprocessing into C# code

  6. Now run the Role Tailored client of Microsoft Dynamics NAV 2016.

Locate the folder C:ProgramDataMicrosoftMicrosoft Dynamics NAV90ServerMicrosoftDynamicsNavServer$DynamicsNAV90source:

Preprocessing into C# code

The folders seen in the preceding screenshot are those which contain the CS file, which contain the corresponding C# code. Microsoft Dynamics NAV 2016 has come a long way since the code started preprocessing into C#, which was first introduced in version 2009. The following screenshot is the C# equivalent code for Page 48: Sales Orders, which is not that easy to understand. But if you take a look at the earliest version of C# code of the same page, then it will be easy to understand for the sake of this discussion. So, I will try to explain this concept with the help of a C# code of Microsoft Dynamics NAV 2009 (RTC):

Preprocessing into C# code

Let us examine the C sharp code for the release function, which is present in Page 9305 Sales Order List:

Preprocessing into C# code

In the last screenshot, we can easily see that a function performManualRelease is being called by passing Record as the parameter. Now we will examine the C# code for the same page in Dynamics NAV 2009 to make things clearer. Even in version 2009, the process of generating C sharp code and the location is similar to what is shown in the following screenshot:

Preprocessing into C# code

Now let's open the code, search for the PerformManualRelease function, and examine the code:

Preprocessing into C# code

It is clear that the C/AL code has been commented out, and the corresponding C Sharp code is generated. Now it is clear how the complexity of different concepts has been simplified into a single line of C/AL code, which is another reason for the success of Microsoft Dynamics NAV. Since the year 2009, Microsoft has been working to optimize the code and make it more secure. Thus, the present version of the code, which is more robust and efficient, has evolved. If you want to know more, then try this with version 2009 and then relate it to Version 2016.