What code is: source, interpreters and compilers
Code is text written in a programming language, so people can read and write it. A CPU cannot read text: it only runs machine code, instructions stored as numbers. Follow a two-line Python program, print('Hello, world!') and print('Goodbye!'), through a compiler, an interpreter and CPython's bytecode, and see why one missing bracket stops the whole program before it starts.
5 quick questions
Pick an answer to see why. Your score saves with your progress.
01What is the only kind of program a CPU can run directly?
A CPU only runs machine code: instructions stored as numbers, for its own CPU family. Source code and bytecode must first go through a translator.
02What does a compiler do?
A compiler translates everything first and saves the result as a file of machine code. Later the CPU runs that file directly; C, Go and Rust usually work this way.
03How does CPython, the usual Python, run your file?
CPython first compiles the whole file into bytecode, simple instructions for a virtual machine. Then the virtual machine, a program running on the CPU, carries them out one at a time.
04Line 2 is print('Goodbye!' with the closing bracket missing. What happens when you run the file?
Python compiles the whole file before running any of it. The syntax error stops the compile, so no bytecode is made and not even line 1 runs.
05What does print('Hello, world!') do?
print shows the value inside its brackets as text on the screen. The quotes mark where the text starts and ends; they are not printed.
Glossary
- Source code
- The text of a program, written in a programming language so people can read and change it.
- Machine code
- Instructions stored as numbers (bytes) for one family of CPUs. It is the only thing a CPU can run.
- Compiler
- A program that translates a whole program ahead of time, usually into a machine-code file you can run later.
- Interpreter
- A program that reads code and carries it out as it goes, without saving a machine-code file first.
- Bytecode
- Simple instructions made by CPython from your file, run by the Python virtual machine rather than by the CPU.
- Virtual machine
- A pretend computer made of software. CPython's virtual machine reads bytecode and does each instruction.
- Syntax
- The exact rules for how code in a language must be written, such as matching brackets and quotes.
- Syntax error
- A mistake in those rules. Python finds it before running anything and reports where it is.
Notes and sources
- Compiled and interpreted are two ends of a range, not two boxes. Java also compiles to bytecode, and some interpreters compile busy parts of a program to machine code while it runs (a JIT); CPython 3.13 added an experimental one.
- The bytecode card shows three instructions of line 1 from python3 -m dis (Python 3.14); a few, such as PUSH_NULL, are left out. Bytecode is a detail of CPython and changes between versions. CPython saves it in .pyc files for imported modules, so they start faster next time.
- The machine-code card holds real x86-64 bytes: B8 01 00 00 00 is mov eax, 1 (Linux system call 1, write), BF 01 00 00 00 is mov edi, 1 (standard output), and 0F 05 is syscall. A whole Hello, world program needs a few more, to say where the text is and how long it is.
- A C, Go or Rust compiler builds one file for one kind of CPU and operating system; to run it elsewhere you compile again for that machine. The figure draws the compiler and the interpreter as one block, because both are translators.
- The message SyntaxError: '(' was never closed is the wording of Python 3.10 and later. Older versions said less, such as "unexpected EOF while parsing".
- Python Glossary: bytecode
- Python Glossary: interpreted
- Python Library Reference: dis, disassembler for Python bytecode
- Python Tutorial: Errors and Exceptions (Syntax Errors)
- What's New in Python 3.10: better error messages
- Python Library Reference: print()
- The Rust Programming Language, 1.2 Hello, World! (ahead-of-time compilation)
- Go documentation: How to Write Go Code
- GCC manual: Options Controlling the Kind of Output
- Intel 64 and IA-32 Architectures Software Developer's Manuals (Vol. 2: MOV, SYSCALL)
- Linux kernel: x86-64 system call table
- Linux man-pages: syscall(2)
- PEP 744: JIT Compilation
- Harvard CS50x 2024, Lecture 1 notes (source code, compilers, machine code)
Quiz Unlocks after the last step.