Muutke küpsiste eelistusi

E-raamat: Programming Language Concepts

  • Formaat - PDF+DRM
  • Hind: 53,09 €*
  • * hind on lõplik, st. muud allahindlused enam ei rakendu
  • Lisa ostukorvi
  • Lisa soovinimekirja
  • See e-raamat on mõeldud ainult isiklikuks kasutamiseks. E-raamatuid ei saa tagastada.

DRM piirangud

  • Kopeerimine (copy/paste):

    ei ole lubatud

  • Printimine:

    ei ole lubatud

  • Kasutamine:

    Digitaalõiguste kaitse (DRM)
    Kirjastus on väljastanud selle e-raamatu krüpteeritud kujul, mis tähendab, et selle lugemiseks peate installeerima spetsiaalse tarkvara. Samuti peate looma endale  Adobe ID Rohkem infot siin. E-raamatut saab lugeda 1 kasutaja ning alla laadida kuni 6'de seadmesse (kõik autoriseeritud sama Adobe ID-ga).

    Vajalik tarkvara
    Mobiilsetes seadmetes (telefon või tahvelarvuti) lugemiseks peate installeerima selle tasuta rakenduse: PocketBook Reader (iOS / Android)

    PC või Mac seadmes lugemiseks peate installima Adobe Digital Editionsi (Seeon tasuta rakendus spetsiaalselt e-raamatute lugemiseks. Seda ei tohi segamini ajada Adober Reader'iga, mis tõenäoliselt on juba teie arvutisse installeeritud )

    Seda e-raamatut ei saa lugeda Amazon Kindle's. 

The full source code for the examples provided in this book aims to encourage innovation and experimentation by a readership that will gain much from the first publication of its kind based on F#. It also covers design and other aspects of Java and C#.



This book uses a functional programming language (F#) as a metalanguage to present all concepts and examples, and thus has an operational flavour, enabling practical experiments and exercises. It includes basic concepts such as abstract syntax, interpretation, stack machines, compilation, type checking, garbage collection, and real machine code. Also included are more advanced topics on polymorphic types, type inference using unification, co- and contravariant types, continuations, and backwards code generation with on-the-fly peephole optimization. 

This second edition includes two new chapters. One describes compilation and type checking of a full functional language, tying together the previous chapters. The other describes how to compile a C subset to real (x86) hardware, as a smooth extension of the previously presented compilers.The examples present several interpreters and compilers for toy languages, including compilers for a small but usable subset of C, abstract machines, a garbage collector, and ML-style polymorphic type inference.  Each chapter has exercises.  

Programming Language Concepts covers practical construction of lexers and parsers, but not regular expressions, automata and grammars, which are well covered already.  It discusses the design and technology of Java and C# to strengthen students’ understanding of these widely used languages.

1 Introduction
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)
1.4 Syntax and Semantics
5(1)
1.5 Representing Expressions by Objects
6(2)
1.6 The History of Programming Languages
8(1)
1.7 Exercises
9(4)
References
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)
2.3.2 Closed Expressions
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)
2.10 Exercises
26(5)
References
29(2)
3 From Concrete Syntax to Abstract Syntax
31(28)
3.1 Preparatory Reading
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)
3.11 Exercises
55(4)
References
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)
4.12 Exercises
75(6)
References
78(3)
5 Higher-Order Functions
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)
5.3.4 Google MapReduce
86(1)
5.4 A Higher-Order Functional Language
86(1)
5.5 Eager and Lazy Evaluation
87(1)
5.6 The Lambda Calculus
88(3)
5.7 History and Literature
91(1)
5.8 Exercises
91(6)
References
96(1)
6 Polymorphic Types
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)
6.6.1 Java Wildcards
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)
6.8 Exercises
114(5)
References
117(2)
7 Imperative Languages
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)
7.6 The Micro-C Language
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)
7.9 Exercises
137(4)
References
140(1)
8 Compiling Micro-C
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)
8.11 Exercises
156(5)
References
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)
9.3.2 The JVM Bytecode
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)
9.9 Exercises
178(5)
References
180(3)
10 Garbage Collection
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)
10.6.1 Memory Leaks
193(1)
10.6.2 Finalizers
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)
10.9 Exercises
202(7)
References
207(2)
11 Continuations
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)
11.11 Exercises
228(5)
References
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)
12.4 Other Optimizations
246(1)
12.5 A Command Line Compiler for Micro-C
247(1)
12.6 History and Literature
248(1)
12.7 Exercises
248(5)
References
251(2)
13 Compiling Micro-SML
253(30)
13.1 Files for This
Chapter
253(1)
13.2 Grammar for Micro-SML
254(5)
13.2.1 Example Programs
255(1)
13.2.2 Abstract Syntax
256(1)
13.2.3 Prettyprinting
256(1)
13.2.4 Tail Calls
257(1)
13.2.5 Free Variables
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)
13.4.1 Continuations
266(1)
13.4.2 Sequence
267(1)
13.4.3 Functions
267(1)
13.4.4 Exceptions
268(1)
13.5 Compiling Micro-SML
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)
13.6 Exercises
279(4)
Reference
281(2)
14 Real Machine Code
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)
14.12 Exercises
303(4)
References
305(2)
Appendix A Crash Course in F# 307(26)
Index 333
Peter Sestoft is professor and head of department at the IT University of Copenhagen. He has 25 years teaching experience and his research interests include functional and object-oriented programming languages, the implementation of such languages, and parallel programming on multicore machines. He is the author or co-author of six books published by MIT Press, Morgan Kaufmann, Prentice-Hall and Springer.