How Interpreters and Compilers Process Code

UPI Study › Courses › Introduction to Artificial Intelligence › Free lessons › Lesson 3.3 Free with a free account

How Interpreters and Compilers Process Code

Introduction to Artificial Intelligence · Chapter 3: Programming Foundations and SecuritySection 3.3 · lesson 20 of 6914 min · free with a free account

← Programming Foundations: Writing, Testing, and Fixing CodeNext lesson: Recognizing Threats in Computer Security →

Earn 3 college credits for Introduction to Artificial IntelligenceRecommended for credit by NCCRS · Computer Science 373 · self-paced · one payment, lifetime access

In this lesson

How compilers, interpreters, and bytecode virtual machines turn source code into action.

  • Compare compilers, interpreters, and hybrid bytecode systems with just-in-time compilation
  • Describe the four translation stages: lexing, parsing, code generation, and optimization
  • Explain when syntax, name, runtime, and logic errors are detected
  • Calculate when compiling pays off over interpreting for a given number of runs

Free study notes

Get this lesson's notes by email

The key points and 4 practice questions with answers, in your inbox. One email, free.

One email. Unsubscribe in one click.

Transcript

Everything said in the video, section by section (1,964 words). Read along, or search it.

Opening Question

Translator or Interpreter for Code

A person can read the line, total equals price times 3, plus 2, and know at once what it means. A processor can't. It only understands very simple instructions, written as patterns of zeros and ones. Something must translate between the two. Think of a speech in a foreign language. You could hire a translator to convert the whole written speech before the event. Or an interpreter, who translates sentence by sentence, as the speaker talks. Computers use the same two ideas, and many systems mix them. So which one runs your code, and why do AI developers so often pick the interpreter?

The Problem

Source Code Versus Machine Code

Source code is the text a programmer writes, with words and symbols designed for people. Machine code is the set of binary instructions one particular processor can carry out. Two facts make translation a real engineering job. Each family of processors has its own machine code, so a program translated for one won't run on another without translating again. And one line of source becomes many machine instructions. That one statement means: fetch the price, multiply, add, and store the result.

Comparison

Compilers Build First, Interpreters Run Directly

A compiler reads the whole program, and translates it into machine code before it runs. The result is a separate file, an executable, that runs again and again with no translator present. It runs fast, it has time to optimize heavily, and it catches many mistakes early. But each build is a wait, and the executable only runs on the processor type it was built for. An interpreter reads the program and carries out each step as it goes, with no machine-code file. There's no build: type a line, and see the result at once. The same source runs anywhere the interpreter is installed. But it runs slower, because translation work repeats while the program runs, and some mistakes appear only when the faulty line is reached.

Hybrid Systems

Bytecode, Virtual Machines, and JIT

Many modern systems combine the two. A compiler first translates the source into bytecode: a compact set of simple instructions that's the same on every computer. Then a program called a virtual machine runs the bytecode. It acts like an imaginary processor that exists only in software. Many virtual machines add just-in-time compilation. They watch which parts run most often, the hot spots, and translate those into real machine code while the program runs. So bytecode is portable, it starts quickly, and the JIT wins back much of compiled speed for the busiest code. One more point: compiled or interpreted describes an implementation, not a language. One language can have both.

Overview

Four Stages of Translation

Whatever the approach, a translator works in stages, each passing its result to the next: lexing, parsing, code generation, and optimization. We'll follow one statement through all of them, with real output from Python's own tools: total equals price times, open bracket, 1 plus 2, close bracket, plus 4.

Stage One

Lexing Cuts Text Into Tokens

Stage one, lexing. To the translator, the source starts as one long string of characters. Lexing cuts it into tokens: the smallest pieces that carry meaning. Ask Python's tokenizer. Names, like total and price. The equals sign, and the operators. The brackets. And the numbers, 1, 2, and 4. That's eleven tokens, plus three that Python adds for its own bookkeeping: the file's encoding, the end of the line, and the end of the file. Spaces are thrown away. A lexer finds only the simplest mistakes, like a text string that's never closed.

Error Example

An Unterminated String Literal

Here's one. A string that opens with a quote, and never closes. Python stops before running anything: an unterminated string literal, found while cutting the text into tokens.

Stage Two

Parsing Builds a Syntax Tree

Stage two, parsing. Tokens are a flat list. Parsing checks them against the grammar, the rules of the language, and builds a syntax tree that shows how they group. Ask Python's parser for the tree of the right-hand side. At the top, an addition: something, plus 4. Its left side is a multiplication: price, times another addition. And at the very bottom, 1 plus 2. The brackets put it lowest, so it's worked out first. Notice that the tree still holds 1 plus 2. Working it out in advance is a later stage's job.

Error Example

A Bracket That Was Never Closed

If the tokens break the grammar, the parser reports a syntax error. Drop the closing bracket, and Python says the bracket was never closed. After parsing, translators often run meaning checks too, like: is every name defined? Can these two values be added together?

Stage Three

Generating Stack Machine Instructions

Stage three, code generation. It walks the tree and writes simple instructions. A compiler writes machine code. A hybrid writes bytecode. Many first write a middle form, an intermediate representation. For a simple imaginary stack machine, our statement becomes eight instructions. Load price. Push 1, push 2, and add them. Multiply price by that sum. Push 4, add it. And store the result under the name total.

Stage Four

Constant Folding and Other Optimizations

Stage four, optimization. It rewrites the instructions to run faster, or use less memory or energy, without changing the result. Here, 1 plus 2 involves only fixed numbers, so it can be worked out in advance. That's constant folding, and the list shrinks from eight instructions to six. Other common tricks: dead-code removal drops code that can never run. Moving unchanging work out of a loop does one multiplication instead of a thousand. Sharing a repeated product computes it once. And inlining pastes in a tiny helper. Optimizing has a cost, though: it takes the translator longer, and rearranged code no longer lines up neatly with the original text.

Real Output

CPython 3.12 Bytecode for One Statement

Real hybrid systems do exactly this. Here's the bytecode that CPython 3.12 makes for our statement, using Python's disassembler. Load the name price. Load the constant 3: 1 plus 2, already worked out. Multiply. Load 4, and add. And store the name total. The shape matches our simple version. So even a language called interpreted runs lexing, parsing, code generation, and a little optimization, before the first line executes.

Comparison

Where Each Stage Happens

Where each stage happens differs. A compiler lexes and parses once, before running, optimizes extensively, and the processor runs its machine code directly. An interpreter reads code each time, including every line typed in an interactive session, optimizes little, to keep start-up fast, and performs each step itself. A hybrid parses once, when it makes bytecode, optimizes lightly at first, then more for hot spots, and its virtual machine runs the bytecode.

Error Timing

When Different Mistakes Surface

Different mistakes surface at different times. Lexical and syntax errors are caught when the code is read, before it runs, even by an interpreter. A meaning error, like a name that was never defined, is often caught at build time by a compiler. An interpreter often finds it only when that line runs. Here, start prints first. Only then does Python reach the misspelled name, and stop: name totl is not defined. It even asks, did you mean total? Runtime errors, like dividing by zero, appear while running, in both. And logic errors, like the wrong formula, are never reported at all. A translator checks that code is well-formed, not that it's correct.

Quick Check

Python Parses the Whole File First

Quick check. This three-line file has one missing bracket, on line two. Python is an interpreter, at least in name. When you run it, what appears first? Pause, and predict. Only a SyntaxError. Nothing prints, not even one. Python lexes and parses the whole file before it runs a single line, and the parse fails at line two. One, then an error, is what you'd expect if it translated strictly line by line. But that's not how Python works.

Performance

Translation Time Versus Run Time

Now performance. A program's total time has two parts: time to translate, and time to run. Compiled code pays a large one-time cost up front, then runs fast. Every extra run makes that build cost matter less. Interpreted code pays nothing up front, but every run pays for the extra work on each step: decoding the instruction, looking up each name. On tight arithmetic loops, it's often cited as ten to a hundred times slower. And a JIT starts quickly, then speeds up as hot spots get compiled. The slow start, while it learns what's busy, is called warm-up.

Worked Example

Break-Even at Six Runs

When does compiling pay off? Say a build takes 30 seconds, and a compiled run takes 1 second. An interpreted run takes 6, with no build. After n runs, compiling costs 30 plus n, and interpreting costs 6 n. They're equal when 30 plus n equals 6 n: at n equals 6, 36 seconds each. From the seventh run on, compiling is ahead: 37 seconds against 42. Use the program only two or three times, and the interpreter wins.

Quick Check

A Tie Is Not Ahead

Quick check, with new numbers. A build takes 20 seconds, and a compiled run takes 2. An interpreted run takes 7, with no build. From which run does compiling come out ahead? Pause, and work it out. From the fifth run. Twenty plus 2 n equals 7 n at n equals 4: 28 seconds each, a tie. At run five, compiling totals 30 against 35, and stays ahead after that. The fourth run is the tempting answer, but a tie isn't ahead.

Debugging

How Each Approach Shapes Debugging

The approach also shapes debugging. With an interpreter it's interactive: run a line, look at the values, try a fix. Errors show a stack trace, the chain of calls that led there. But errors in rarely used code can stay hidden. A compiler catches many errors early, but every fix needs a rebuild, and optimized code is hard to follow in a debugger. So developers use a debug build while working, and a release build to deliver. A hybrid mixes both. Its errors point back to the original source lines, and the virtual machine usually offers good inspection tools.

AI Connection

Why AI Code Is Often Interpreted

So why is so much AI code written in interpreted languages, when AI needs huge amounts of computing? First, AI work is experimental: hundreds of trials a day, often in notebooks, where each one should be instant. Second, and this is the key: the heavy lifting isn't done by the interpreter. Multiplying huge tables of numbers, or training a network, runs in compiled libraries tuned for the processor or the GPU. The interpreted code is a thin top layer that directs them. In one measurement, adding up ten million numbers, a single library call was many times faster than a loop in interpreted code. So keep the loops inside the libraries. Third, the code is short and readable. Fourth, a long history: one of the first AI languages, from the late 1950s, was built around an interactive loop. And fifth, a huge shared ecosystem that runs anywhere.

Trade-Offs

When to Compile or Move Work to Libraries

When should the choice change? If a program spends its time in its own loops over big data, the interpreter becomes the bottleneck. Move that part into a library routine, or compile it. Small or time-critical devices, like phones, robots, and cars, usually get a trained model converted to a compact, optimized form. And many AI frameworks now compile a model's calculations just in time for the GPU. Above all, measure first. A profiler shows where time is really spent. And the useful question is never which approach is best, but best for what, and at what cost.

Key Takeaways

Compilers, Interpreters, and Hybrids Summed Up

To sum up. Processors run only machine code. A compiler translates everything first, an interpreter translates as it runs, and a hybrid compiles to bytecode for a virtual machine, often with a JIT. Translation runs in four stages: lexing, parsing, code generation, and optimization. Translators catch badly formed code, never wrong logic. And AI code is often interpreted, because the heavy work runs in compiled libraries.

Reflection

Code for a Small Toy Chip

Something to think about. A team is building a program that will run on a small chip inside a toy, where it must respond in a fraction of a second, and memory is tight. Which parts of the work would you do with an interpreter? And what would you switch to before shipping, and why?

About Introduction to Artificial Intelligence at UPI Study

Introduction to Artificial Intelligence (Computer Science 373) is a self-paced online course of 69 video lessons in 9 chapters, from intelligent agents and search to game strategy, neural networks, logic and reasoning, machine learning, language, robotics and AI ethics. It carries a NCCRS credit recommendation for 3 semester credits.

Every lesson transcript is free on pages like this one, and the videos are free with a free UPI Study account. Enrolling adds a practice quiz after each lesson, the graded work and final exam that earn the credit, lifetime access, and an official transcript on completion. UPI Study has helped over 130,000 students with college credits. ACE and NCCRS have over 2,100 cooperating colleges that will consider accepting credits; the final decision is with the universities.

Compare: AI vs Current Trends in CS and IT

Why take it here

Why students take Introduction to Artificial Intelligence with UPI Study

How machines search, reason and learnIntroduction to Artificial Intelligence covers how AI systems are built: intelligent agents, search and heuristics, game strategy, logic, neural networks, machine learning, language and perception, and the ethics of AI. It is a common upper-level course in computer science degrees.
Credit at a fraction of the priceThe same 3 credits can cost $750 or more at a US college. Here it is one payment, self-paced, with lifetime access.
Finish your degree soonerTransfer credits reduce the courses you still owe, so you can graduate earlier or lighten a heavy semester.
Strengthen an applicationA completed college-level course on an official transcript shows admissions and scholarship committees you can do the work.
Study on your own scheduleNo start dates, no deadlines. Watch the lessons, practice, and take the final when you are ready.
130,000+students helped with college creditsACE and NCCRS have over 2,100 cooperating colleges that will consider accepting credits; the final decision is with the universities.

Where the credit goes

Universities that work with NCCRS

Introduction to Artificial Intelligence carries a NCCRS credit recommendation. These universities work with NCCRS; some are UPI Study's signed partners. ACE and NCCRS have over 2,100 cooperating colleges that will consider accepting credits; the final decision is with the universities.

Find my college → Not listed? Ask Athena in the corner of this page, or book a 15-minute call.

FAQ

Questions students ask us

About How Interpreters and Compilers Process Code

What is the difference between a compiler and an interpreter?
A compiler translates a whole program into machine code before it runs, while an interpreter carries out the program step by step without producing a machine-code file. Compiled executables run fast and are heavily optimized but must be rebuilt for each processor type. Interpreted code starts instantly and runs anywhere the interpreter is installed, but it runs slower because translation work repeats during execution.
Is Python compiled or interpreted?
The standard Python implementation, CPython, is a hybrid: it compiles source code into bytecode and then a virtual machine runs that bytecode. It lexes and parses the whole file before running any line, so a missing bracket on line two produces only a SyntaxError, with no output from line one. Compiled or interpreted describes an implementation, not a language, so one language can have both.
What are the stages of translating source code?
The main stages are lexing, parsing, code generation, and optimization. Lexing cuts the text into tokens, parsing checks tokens against the grammar and builds a syntax tree, code generation writes simple instructions such as bytecode or machine code, and optimization rewrites them to run faster without changing the result. Constant folding, for example, works out 1 + 2 in advance as 3.
Why is so much AI code written in interpreted languages like Python?
Much AI code is written in interpreted languages because the heavy computation runs in compiled libraries, not in the interpreter itself. Matrix math and network training happen in routines tuned for the processor or GPU, while the interpreted code is a thin layer directing them. Interpreters also suit experimental work with many quick trials, code stays short and readable, and a large shared ecosystem runs on many machines.

About the Introduction to Artificial Intelligence course

How many college credits is Introduction to Artificial Intelligence?
Introduction to Artificial Intelligence (Computer Science 373) carries a NCCRS credit recommendation for 3 semester credits. ACE and NCCRS have over 2,100 cooperating colleges that will consider accepting credits; the final decision is with the universities.
How much does Introduction to Artificial Intelligence cost and what is included?
$250, paid once, with lifetime access: all 69 video lessons, a practice quiz after each, the graded work and final exam, and an official transcript when you finish. Students who want several courses choose UPI Study PRO instead.
Which universities accept UPI Study credits?
UPI Study has signed partner agreements with universities such as Thomas Edison State University, University of the People and Charter Oak State College, and works with universities such as Penn State, SNHU and SUNY. ACE and NCCRS have over 2,100 cooperating colleges that will consider accepting credits; the final decision is with the universities. Use "Find my college" on this page to check yours.
How long does Introduction to Artificial Intelligence take?
It is self-paced with no deadlines. The 69 lessons total about 16 hours of video; most students add reading and practice time and finish in a few weeks to a few months, on their own schedule.
How are the exams done?
Quizzes and assignments are online in the course. The final exam is taken online with proctoring; a person on the UPI Study team checks assignments, usually within two days.
How do my credits reach my college?
When the course shows 100% complete, request the official transcript from your dashboard. It is sent to the college you name, and you can send it to more than one. Check your college first with "Find my college" on this page, or ask Athena.

Ready for the full course? Earn 3 credits in Introduction to Artificial Intelligence.

69 video lessons, a quiz after each one, and the graded work that earns the credit. Recommended for credit by NCCRS.

Introduction to Artificial Intelligence
3 credits · NCCRS
Enroll →