Académique Documents
Professionnel Documents
Culture Documents
Intermediate languages are with us for quite a long time. Most of the
compilers employ them in one-way or another. The way of using
intermediate languages have also sometimes contributed to the
success of the languages like Pascal, Java and recently C# (with .NET
initiative in general). Even some tools like MS-Word makes use of an
intermediate language (p-code). Intermediate languages have made a
big difference in achieving portability of code. This article explores the
concept of intermediate languages and their use in achieving complete
portability and language interoperability.
As already stated, writing compilers for the languages that are meant
for interpretation is sometimes not possible. In such cases, it is
possible to bundle the source code with the whole interpreter as an
executable file and distribute it. Java Native Interface (JNI) follows a
similar approach by embedding a Java interpreter in an executable
code created by a C/C++ source code, and run the Java code through
it. This solution is feasible because the Java interpreter’s size is not
very big.
The very popular and widely used approach that combines the
compilation and interpretation is making use of intermediate code
directly. Since its use in Java this approach seems to have received
widespread acceptance, even though its idea was used long back in
Pascal and in many other languages. Languages following this
approach are sometimes referred to as p-code languages since p-code
of Pascal is one of the first intermediate codes to follow this approach
successfully. Few of important p-code languages are Python, Perl, Java
and now, C# (.NET framework). The idea is to use a compiler to
generate the intermediate language code. The intermediate code can
be moved on to other platforms or even across the network where an
interpreter (also called as virtual machine) for that platform will take
over to interpret the code.
The difference is that previously most of the compilers hid the use of
intermediate languages as ‘implementation details’. But now, to make
the best use of them, they are extended, exposed and used in
conjunction with interpretation.
High-level ILs takes more effort to get the code converted to the
native code, but are sufficiently high-level that it can represent rich
features of various source languages directly. So it is possible to
retarget new languages to high-level ILs. However, more effort is
needed in converting the intermediate code to native code. On another
extreme, low-level ILs make the translation to native code easier, but
it is generally hard to retarget other high-level languages than that it
is originally intended for.
Three-address code
R1 := R2 + R3
And the general syntax is.
X := Y op Z
Object files
Tree representations
Stack-based machines
Since stack based machines are one of the most successful ones and is
gaining widespread acceptance in recent times, let us discuss few
implementations based on that in detail here.
P-code:
However, this steps need to be done only in initial steps. Later the
compiler can be modified to generate native code, and once, the
Pascal compiler itself is given as input for the Pascal compiler in p-
code, the compiler becomes available in native code. This process is
referred to as 'bootstrapping', that is generally used in porting
compilers to new environments. But the point here is that this
'bootstrapping' process becomes easy and elegant with the p-code
approach. This let to the popularity and widespread use of Pascal
compilers.
Java bytecodes:
To illustrate, for each and every class or interface defined, a class file
is generated. Every method is compiled into byte codes - the
instructions for the hypothetical microprocessor. For example:
int a = b + 2;
iadd // pop two integer values from stack, add them, push the result back.
istore_2 // pop the int value from the stack and store it in variable 2 // (int type)
All the information that you give inside the class definition are
converted and get stored to form an intermediate class file.
Virtual machine plays a major role in Java technology. All the Java
virtual machines have the same behavior, as defined by SUN, but the
implementation differs. It forms a layer over the physical machine in
the memory.
Even though the Java technology provides the basis for achieving full
portability, Java’s design aids to make it architectural neutral. To
illustrate, lets compare it with a C design consideration with that of
Java. C gives much importance to efficiency and for that, it leaves size
of its data types (except char) to be implementation-dependent. But
Java primitive types are of predetermined size, independent of the
implementation. In general, Java improves upon C by removing the
constructs having various behavioral types in C by having well defined
behavior instead.
.NET Architecture
With .NET you can write a class in C#, extend it in VB and instantiate
it in managed C++. This gives you the ability to work in diversified
languages depending on your requirement and still benefit from the
unified platform to which the code for any .NET compliant language is
compiled into.
Summary
The benefits of using intermediate languages are well known, and the
current trend is towards achieving fully portable code and language
interoperability. To understand the concept of portable code
compilation, the understanding of the conventional translation
technology and their advantages/disadvantages needs to be known.
There are many issues involved in intermediate code design and
understanding them shall enable us to appreciate the various efforts to
generate portable code.
Way back in 1950s itself, the first effort towards achieving portability
was taken through UNCOL initiative. Later, during 1970-80s, Pascal in
the form of p-code picked up the idea. In 1995s Java came as a
revolution to capture the imagination of the language world. Now it
is .NET’s turn with the age-old concept of language interoperability.
Thanks to such technological advances, achieving 100% portable code
with language interoperability is no more a dream. It is clear that the
concept of intermediate languages is here to stay for a long time and
we are not far from having a universal intermediate language.
References:
Sidebar 1:
Sidebar - 2