|
|
1 | (12) |
|
1.1 Files for This Chapter |
|
|
1 | (1) |
|
1.2 Meta Language and Object Language |
|
|
1 | (1) |
|
1.3 A Simple Language of Expressions |
|
|
2 | (3) |
|
1.3.1 Expressions Without Variables |
|
|
2 | (1) |
|
1.3.2 Expressions with Variables |
|
|
3 | (2) |
|
|
5 | (1) |
|
1.5 Representing Expressions by Objects |
|
|
6 | (2) |
|
1.6 The History of Programming Languages |
|
|
8 | (1) |
|
|
9 | (4) |
|
|
12 | (1) |
|
2 Interpreters and Compilers |
|
|
13 | (18) |
|
2.1 Files for This Chapter |
|
|
13 | (1) |
|
2.2 Interpreters and Compilers |
|
|
13 | (1) |
|
2.3 Scope and Bound and Free Variables |
|
|
14 | (6) |
|
2.3.1 Expressions with Let-Bindings and Static Scope |
|
|
15 | (1) |
|
|
16 | (1) |
|
2.3.3 The Set of Free Variables |
|
|
17 | (1) |
|
2.3.4 Substitution: Replacing Variables by Expressions |
|
|
17 | (3) |
|
2.4 Integer Addresses Instead of Names |
|
|
20 | (2) |
|
2.5 Stack Machines for Expression Evaluation |
|
|
22 | (1) |
|
2.6 Postscript, a Stack-Based Language |
|
|
23 | (2) |
|
2.7 Compiling Expressions to Stack Machine Code |
|
|
25 | (1) |
|
2.8 Implementing an Abstract Machine in Java |
|
|
26 | (1) |
|
2.9 History and Literature |
|
|
26 | (1) |
|
|
26 | (5) |
|
|
29 | (2) |
|
3 From Concrete Syntax to Abstract Syntax |
|
|
31 | (28) |
|
|
31 | (1) |
|
3.2 Lexers, Parsers, and Generators |
|
|
32 | (1) |
|
3.3 Regular Expressions in Lexer Specifications |
|
|
33 | (1) |
|
3.4 Grammars in Parser Specifications |
|
|
34 | (1) |
|
3.5 Working with F# Modules |
|
|
35 | (1) |
|
3.6 Using fslex and fsyacc |
|
|
36 | (11) |
|
3.6.1 Installing and Using fslex and fsyacc |
|
|
37 | (1) |
|
3.6.2 Parser Specification for Expressions |
|
|
37 | (1) |
|
3.6.3 Lexer Specification for Expressions |
|
|
38 | (3) |
|
3.6.4 The ExprPar.fsyacc.output File Generated by fsyacc |
|
|
41 | (3) |
|
3.6.5 Exercising the Parser Automaton |
|
|
44 | (1) |
|
3.6.6 Shift/Reduce Conflicts |
|
|
45 | (2) |
|
3.7 Lexer and Parser Specification Examples |
|
|
47 | (1) |
|
3.7.1 A Small Functional Language |
|
|
47 | (1) |
|
3.7.2 Lexer and Parser Specifications for Micro-SQL |
|
|
48 | (1) |
|
3.8 A Handwritten Recursive Descent Parser |
|
|
48 | (2) |
|
3.9 JavaCC: Lexer-, Parser-, and Tree Generator |
|
|
50 | (3) |
|
3.10 History and Literature |
|
|
53 | (2) |
|
|
55 | (4) |
|
|
57 | (2) |
|
4 A First-Order Functional Language |
|
|
59 | (22) |
|
4.1 Files for This Chapter |
|
|
59 | (1) |
|
4.2 Examples and Abstract Syntax |
|
|
60 | (1) |
|
4.3 Run-Time Values: Integers and Closures |
|
|
61 | (1) |
|
4.4 A Simple Environment Implementation |
|
|
62 | (1) |
|
4.5 Evaluating the Functional Language |
|
|
62 | (2) |
|
4.6 Evaluation Rules for Micro-ML |
|
|
64 | (2) |
|
4.7 Static Scope and Dynamic Scope |
|
|
66 | (2) |
|
4.8 Type-Checking an Explicitly Typed Language |
|
|
68 | (2) |
|
4.9 Type Rules for Monomorphic Types |
|
|
70 | (2) |
|
4.10 Static Typing and Dynamic Typing |
|
|
72 | (2) |
|
4.10.1 Dynamic Typing in Java and C# Array Assignment |
|
|
73 | (1) |
|
4.10.2 Dynamic Typing in Non-generic Collection Classes |
|
|
74 | (1) |
|
4.11 History and Literature |
|
|
74 | (1) |
|
|
75 | (6) |
|
|
78 | (3) |
|
|
81 | (16) |
|
5.1 Files for This Chapter |
|
|
81 | (1) |
|
5.2 Higher-Order Functions in F# |
|
|
81 | (1) |
|
5.3 Higher-Order Functions in the Mainstream |
|
|
82 | (4) |
|
5.3.1 Higher-Order Functions in Java 5 |
|
|
82 | (2) |
|
5.3.2 Higher-Order Functions in Java 8 |
|
|
84 | (1) |
|
5.3.3 Higher-Order Functions in C# |
|
|
85 | (1) |
|
|
86 | (1) |
|
5.4 A Higher-Order Functional Language |
|
|
86 | (1) |
|
5.5 Eager and Lazy Evaluation |
|
|
87 | (1) |
|
|
88 | (3) |
|
5.7 History and Literature |
|
|
91 | (1) |
|
|
91 | (6) |
|
|
96 | (1) |
|
|
97 | (22) |
|
6.1 Files for This Chapter |
|
|
97 | (1) |
|
6.2 ML-Style Polymorphic Types |
|
|
97 | (4) |
|
6.2.1 Informal Explanation of ML Type Inference |
|
|
98 | (2) |
|
6.2.2 Which Type Parameters May Be Generalized |
|
|
100 | (1) |
|
6.3 Type Rules for Polymorphic Types |
|
|
101 | (2) |
|
6.4 Implementing ML Type Inference |
|
|
103 | (5) |
|
6.4.1 Type Equation Solving by Unification |
|
|
106 | (1) |
|
6.4.2 The Union-Find Algorithm |
|
|
106 | (1) |
|
6.4.3 The Complexity of ML-Style Type Inference |
|
|
107 | (1) |
|
6.5 Generic Types in Java and C# |
|
|
108 | (2) |
|
6.6 Co-Variance and Contra-Variance |
|
|
110 | (4) |
|
|
111 | (1) |
|
6.6.2 C# Variance Declarations |
|
|
112 | (1) |
|
6.6.3 The Variance Mechanisms of Java and C# |
|
|
113 | (1) |
|
6.7 History and Literature |
|
|
114 | (1) |
|
|
114 | (5) |
|
|
117 | (2) |
|
|
119 | (22) |
|
7.1 Files for This Chapter |
|
|
119 | (1) |
|
7.2 A Naive Imperative Language |
|
|
120 | (1) |
|
7.3 Environment and Store |
|
|
121 | (1) |
|
7.4 Parameter Passing Mechanisms |
|
|
122 | (2) |
|
7.5 The C Programming Language |
|
|
124 | (3) |
|
7.5.1 Integers, Pointers and Arrays in C |
|
|
124 | (2) |
|
7.5.2 Type Declarations in C |
|
|
126 | (1) |
|
|
127 | (7) |
|
7.6.1 Interpreting Micro-C |
|
|
129 | (1) |
|
7.6.2 Example Programs in Micro-C |
|
|
129 | (1) |
|
7.6.3 Lexer Specification for Micrb-C |
|
|
130 | (2) |
|
7.6.4 Parser Specification for Micro-C |
|
|
132 | (2) |
|
7.7 Notes on Strachey's Fundamental Concepts |
|
|
134 | (3) |
|
7.8 History and Literature |
|
|
137 | (1) |
|
|
137 | (4) |
|
|
140 | (1) |
|
|
141 | (20) |
|
8.1 Files for This Chapter |
|
|
141 | (1) |
|
8.2 An Abstract Stack Machine |
|
|
142 | (5) |
|
8.2.1 The State of the Abstract Machine |
|
|
142 | (1) |
|
8.2.2 The Abstract Machine Instruction Set |
|
|
143 | (2) |
|
8.2.3 The Symbolic Machine Code |
|
|
145 | (1) |
|
8.2.4 The Abstract Machine Implemented in Java |
|
|
145 | (2) |
|
8.2.5 The Abstract Machine Implemented in C |
|
|
147 | (1) |
|
8.3 The Structure of the Stack at Run-Time |
|
|
147 | (1) |
|
8.4 Compiling Micro-C to Abstract Machine Code |
|
|
148 | (1) |
|
8.5 Compilation Schemes for Micro-C |
|
|
149 | (1) |
|
8.6 Compilation of Statements |
|
|
150 | (3) |
|
8.7 Compilation of Expressions |
|
|
153 | (1) |
|
8.8 Compilation of Access Expressions |
|
|
154 | (1) |
|
8.9 Compilation to Real Machine Code |
|
|
155 | (1) |
|
8.10 History and Literature |
|
|
155 | (1) |
|
|
156 | (5) |
|
|
159 | (2) |
|
9 Real-World Abstract Machines |
|
|
161 | (22) |
|
9.1 Files for This Chapter |
|
|
161 | (1) |
|
9.2 An Overview of Abstract Machines |
|
|
161 | (2) |
|
9.3 The Java Virtual Machine (JVM) |
|
|
163 | (6) |
|
9.3.1 The JVM Run-Time State |
|
|
163 | (2) |
|
|
165 | (1) |
|
9.3.3 The Contents of JVM Class Files |
|
|
165 | (4) |
|
9.3.4 Bytecode Verification |
|
|
169 | (1) |
|
9.4 The Common Language Infrastructure (CLI) |
|
|
169 | (3) |
|
9.5 Generic Types in CLI and JVM |
|
|
172 | (3) |
|
9.5.1 A Generic Class in Bytecode |
|
|
173 | (1) |
|
9.5.2 Consequences for Java |
|
|
174 | (1) |
|
9.6 Decompilers for Java and C# |
|
|
175 | (1) |
|
9.7 Just-in-Time Compilation |
|
|
176 | (1) |
|
9.8 History and Literature |
|
|
177 | (1) |
|
|
178 | (5) |
|
|
180 | (3) |
|
|
183 | (26) |
|
10.1 Files for This Chapter |
|
|
183 | (1) |
|
10.2 Predictable Lifetime and Stack Allocation |
|
|
183 | (1) |
|
10.3 Unpredictable Lifetime and Heap Allocation |
|
|
184 | (1) |
|
10.4 Allocation in a Heap |
|
|
185 | (1) |
|
10.5 Garbage Collection Techniques |
|
|
186 | (7) |
|
10.5.1 The Heap and the Freelist |
|
|
187 | (1) |
|
10.5.2 Garbage Collection by Reference Counting |
|
|
187 | (1) |
|
10.5.3 Mark-Sweep Collection |
|
|
188 | (1) |
|
10.5.4 Two-Space Stop-and-Copy Collection |
|
|
189 | (2) |
|
10.5.5 Generational Garbage Collection |
|
|
191 | (1) |
|
10.5.6 Conservative Garbage Collection |
|
|
192 | (1) |
|
10.5.7 Garbage Collectors Used in Existing Systems |
|
|
192 | (1) |
|
10.6 Programming with a Garbage Collector |
|
|
193 | (2) |
|
|
193 | (1) |
|
|
194 | (1) |
|
10.6.3 Calling the Garbage Collector |
|
|
194 | (1) |
|
10.7 Implementing a Garbage Collector in C |
|
|
195 | (7) |
|
10.7.1 The List-C Language |
|
|
195 | (3) |
|
10.7.2 The List-C Machine |
|
|
198 | (1) |
|
10.7.3 Distinguishing References from Integers |
|
|
198 | (1) |
|
10.7.4 Memory Structures in the Garbage Collector |
|
|
199 | (1) |
|
10.7.5 Actions of the Garbage Collector |
|
|
200 | (2) |
|
10.8 History and Literature |
|
|
202 | (1) |
|
|
202 | (7) |
|
|
207 | (2) |
|
|
209 | (24) |
|
11.1 Files for This Chapter |
|
|
209 | (1) |
|
11.2 Tail-Calls and Tail-Recursive Functions |
|
|
210 | (2) |
|
11.2.1 A Recursive but Not Tail-Recursive Function |
|
|
210 | (1) |
|
11.2.2 A Tail-Recursive Function |
|
|
210 | (2) |
|
11.2.3 Which Calls Are Tail Calls? |
|
|
212 | (1) |
|
11.3 Continuations and Continuation-Passing Style |
|
|
212 | (3) |
|
11.3.1 Writing a Function in Continuation-Passing Style |
|
|
213 | (1) |
|
11.3.2 Continuations and Accumulating Parameters |
|
|
214 | (1) |
|
11.3.3 The CPS Transformation |
|
|
214 | (1) |
|
11.4 Interpreters in Continuation-Passing Style |
|
|
215 | (4) |
|
11.4.1 A Continuation-Based Functional Interpreter |
|
|
215 | (2) |
|
11.4.2 Tail Position and Continuation-Based Interpreters |
|
|
217 | (1) |
|
11.4.3 A Continuation-Based Imperative Interpreter |
|
|
217 | (2) |
|
11.5 The Frame Stack and Continuations |
|
|
219 | (1) |
|
11.6 Exception Handling in a Stack Machine |
|
|
220 | (1) |
|
11.7 Continuations and Tail Calls |
|
|
221 | (2) |
|
11.8 Callcc: Call with Current Continuation |
|
|
223 | (1) |
|
11.9 Continuations and Backtracking |
|
|
224 | (3) |
|
11.9.1 Expressions in Icon |
|
|
224 | (1) |
|
11.9.2 Using Continuations to Implement Backtracking |
|
|
225 | (2) |
|
11.10 History and Literature |
|
|
227 | (1) |
|
|
228 | (5) |
|
|
231 | (2) |
|
12 A Locally Optimizing Compiler |
|
|
233 | (20) |
|
12.1 Files for This Chapter |
|
|
233 | (1) |
|
12.2 Generating Optimized Code Backwards |
|
|
233 | (1) |
|
12.3 Backwards Compilation Functions |
|
|
234 | (12) |
|
12.3.1 Optimizing Expression Code While Generating It |
|
|
236 | (2) |
|
12.3.2 The Old Compilation of Jumps |
|
|
238 | (1) |
|
12.3.3 Optimizing a Jump While Generating It |
|
|
238 | (2) |
|
12.3.4 Optimizing Logical Expression Code |
|
|
240 | (2) |
|
12.3.5 Eliminating bead Code |
|
|
242 | (1) |
|
12.3.6 Optimizing Tail Calls |
|
|
242 | (3) |
|
12.3.7 Remaining Deficiencies of the Generated Code |
|
|
245 | (1) |
|
|
246 | (1) |
|
12.5 A Command Line Compiler for Micro-C |
|
|
247 | (1) |
|
12.6 History and Literature |
|
|
248 | (1) |
|
|
248 | (5) |
|
|
251 | (2) |
|
|
253 | (30) |
|
13.1 Files for This Chapter |
|
|
253 | (1) |
|
13.2 Grammar for Micro-SML |
|
|
254 | (5) |
|
|
255 | (1) |
|
|
256 | (1) |
|
|
256 | (1) |
|
|
257 | (1) |
|
|
258 | (1) |
|
13.3 Type Inference for Micro-SML |
|
|
259 | (4) |
|
13.3.1 Type Inference Implementation |
|
|
261 | (2) |
|
13.3.2 Annotated Type Information |
|
|
263 | (1) |
|
13.4 Interpreting Micro-SML |
|
|
263 | (6) |
|
|
266 | (1) |
|
|
267 | (1) |
|
|
267 | (1) |
|
|
268 | (1) |
|
|
269 | (10) |
|
13.5.1 Extensions to Abstract Machine Instruction Set |
|
|
269 | (3) |
|
13.5.2 Compilation of Primitive Micro-SML Expressions |
|
|
272 | (1) |
|
13.5.3 Compilation of Variable Access |
|
|
273 | (1) |
|
13.5.4 Compilation of Value Declarations |
|
|
274 | (3) |
|
13.5.5 Compilation of Let Expressions and Functions |
|
|
277 | (1) |
|
13.5.6 Compilation of Exceptions |
|
|
278 | (1) |
|
|
279 | (4) |
|
|
281 | (2) |
|
|
283 | (24) |
|
14.1 Files for This Chapter |
|
|
283 | (1) |
|
14.2 The x86 Processor Family |
|
|
284 | (6) |
|
14.2.1 Evolution of the x86 Processor Family |
|
|
284 | (1) |
|
14.2.2 Registers of the x86 Architecture |
|
|
285 | (2) |
|
14.2.3 The x86 Instruction Set |
|
|
287 | (1) |
|
14.2.4 The x86 Stack Layout |
|
|
288 | (1) |
|
14.2.5 An Assembly Code Example |
|
|
288 | (2) |
|
14.3 Compiling Micro-C to x86 Code |
|
|
290 | (5) |
|
14.3.1 Compilation Strategy |
|
|
291 | (1) |
|
14.3.2 Representing x86 Machine Code in the Compiler |
|
|
292 | (1) |
|
14.3.3 Stack Layout for Micro-C x86 Code |
|
|
293 | (2) |
|
14.4 The micro-C x86 Compiler |
|
|
295 | (2) |
|
14.5 Compilation Schemes for Micro-C '296 |
|
|
|
14.6 Compilation of Statements |
|
|
297 | (1) |
|
14.7 Compilation of Expressions |
|
|
297 | (3) |
|
14.8 Compilation of Access Expressions |
|
|
300 | (1) |
|
14.9 Choosing Target Registers |
|
|
301 | (1) |
|
14.10 Improving the Compiler |
|
|
302 | (1) |
|
14.11 History and Literature |
|
|
303 | (1) |
|
|
303 | (4) |
|
|
305 | (2) |
Appendix A Crash Course in F# |
|
307 | (26) |
Index |
|
333 | |