11.1 - Programming Languages & Translators
Computer languages and the need for translation
Computers process instructions only in a form they can understand, which requires translating programming languages into machine-readable code. Programming languages are sets of instructions used to create software, and they fall into two main categories: high-level and low-level.
High-level languages
High-level languages are designed to be easy for humans to read and write, using syntax similar to natural language. Examples include Python and C++.
Key features of high-level languages
- They use English-like commands, making them accessible for programmers.
- A single high-level instruction can represent multiple machine code instructions, simplifying complex tasks.
- Code written in these languages is portable, meaning it can run on different machines without major changes.
- Programmers can use data structures like lists and arrays without needing to manage memory details directly.
High-level languages must be translated into machine code before execution, as computers cannot run them natively.
Example of high-level code
Here is a simple Python example to print a message:
Low-level languages
Low-level languages are closer to the computer's hardware and are more difficult for humans to use. They include machine code and assembly language.
Types of low-level languages
- Machine code - This is binary code (sequences of 0s and 1s) that the computer's central processing unit (CPU) can execute directly. It is specific to the processor and hard to read.
- Assembly language - This uses mnemonic codes (short abbreviations) for instructions, making it slightly more human-readable than machine code. It still requires knowledge of the CPU's structure.
Example of machine code
000000 00101 00110 00111 00000 100000
This binary string represents a single instruction but is challenging for humans to interpret.
Example of assembly language
ADD r1, r2, r3
Here, ADD is the operation code (opcode) for addition, and r1, r2, r3 specifies the registers involved. Assembly code typically translates to one machine code instruction.
Low-level languages allow precise control over hardware but demand detailed understanding of memory and CPU operations.
Advantages and disadvantages of high-level and low-level languages
Choosing between high-level and low-level languages depends on the programming needs, such as efficiency or ease of use.
Advantages of high-level languages
- Easier to read, write, and maintain due to English-like syntax
- Faster development time as complex operations can be expressed simply
- Portable across different computer systems
- Built-in error checking and debugging features
Disadvantages of high-level languages
- Programs run slower as they require translation
- Less control over hardware and memory management
- Larger file sizes after compilation
Advantages of low-level languages
- Programs execute faster with optimal performance
- Direct control over hardware and memory
- Smaller executable file sizes
- No translation overhead during execution
Disadvantages of low-level languages
- Difficult to read, write, and maintain
- Time-consuming development process
- Not portable between different processor types
- Requires detailed knowledge of computer architecture
High-level languages are preferred for most applications due to their simplicity, while low-level languages are used for tasks requiring optimal performance, like system software or embedded systems.
The need for translating high-level and assembly languages
Computers can only execute instructions in machine code, so high-level languages and assembly languages require translation. This converts human-readable code into binary instructions the CPU can process.
Translation bridges the gap between programmer-friendly code and hardware execution. There are two main types of translators: compilers and interpreters.
Compilers as translators
A compiler is a translator that converts the entire high-level source code into machine code at once, producing an executable file. Source code is the original program written by the programmer.
How compilers work
- The compiler scans the whole program and translates it into machine code.
- It generates an executable file that can run independently without the compiler.
- If errors are found, it lists all of them after compilation, aiding in debugging the entire program.
Compilers are efficient for completed programs, as compilation happens once, and the resulting executable runs quickly. However, the initial compilation can be time-consuming for large programs.
Interpreters as translators
An interpreter is a translator that processes high-level source code one instruction at a time, without creating an executable file. Instead, it executes each line by calling pre-written machine code subroutines.
How interpreters work
- The interpreter reads and translates one instruction.
- It executes that instruction immediately.
- If an error occurs, it stops and reports the first error found, which is helpful for step-by-step debugging.
- The process repeats for each line every time the program runs.
Interpreters are useful during development for quick testing, but programs run slower because translation happens during execution. They must be present each time the program is run.
Comparing compilers and interpreters
The choice between a compiler and an interpreter depends on the programming language, integrated development environment (IDE) - a software tool for writing and testing code - and the project's needs.
Advantages of compilers
- Faster program execution once compiled
- No need for the translator during program execution
- Source code is protected as only executable files are distributed
- Better optimization of code for performance
Advantages of interpreters
- Faster development cycle with immediate testing
- Better error reporting during development
- Cross-platform compatibility without recompilation
- Interactive programming and debugging capabilities
Compilers suit production software, while interpreters aid in development and scripting.
The role of linkers in program execution
When a program is spread across multiple source code files, a linker is used after compilation. A linker is a tool that combines separate compiled machine code files into a single executable program.
How linkers work
- It resolves references between files, such as function calls from one file to another.
- The result is a unified executable that can run as a complete program.
Linkers ensure modular programs - those built in separate parts for better organisation - function seamlessly.