Chapter Thirteen · How Languages Run

How Languages Run

How a language turns text into running code, followed on one string. Six topics lex, parse, check and evaluate Lantern's query author:"le guin" AND year>1970, then leave Lantern for general-purpose languages: ahead-of-time compilers and their optimizations, and the just-in-time runtimes that explain why the same program runs at different speeds.

6 topics

Computing Foundations from Zero says that code is either compiled or interpreted. This chapter opens that sentence up. Every language implementation, from Lantern's search box to CPython to a C++ compiler, runs the same early stages: group characters into tokens, group tokens into a tree by a grammar, resolve the names in the tree and check that the operations fit. Only after that do implementations part ways, and where they part decides where the price of running code is paid.

The first four topics follow one string through those stages. Lantern's canonical query is lexed into seven tokens, parsed by a four-rule grammar into a tree of three nodes, checked against a table of five fields and evaluated by walking the tree. The code on those pages is a working lexer, parser, checker and evaluator, and every token list, tree and error message shown is what it printed on Python 3.15. CPython's own bytecode appears beside it as the same idea at full scale.

The last two topics leave Lantern. Compilers pay once at build time and optimize for inputs they have never seen. Just-in-time runtimes pay at start-up and optimize for the inputs they are watching. Every topic closes on where its stage costs: at build time, at start-up or on every operation.

One query through the four front stages
Lexcharacters → tokens
→
Parsetokens → tree
→
Checknames and types
→
Runwalk or compile

Topics in This Chapter