An undergraduate compilers course poses significant challenges to students, in both the conceptual richness of the major components and in the programming effort necessary to implement them. In this paper, I argue that a related architecture, the interpreter, serves as an effective conceptual framework in which to teach some of the later stages of the compiler pipeline. This framework can serve both to unify some of the major concepts that are taught in a typical undergraduate course and to structure the implementation of a semester-long compiler project.
From a theoretical perspective, it is well known that both semantic analysis and code generation are closely related to a language's interpreter , the former a simulation of program execution on abstract value domains @cite_6 and the latter a specialization of the interpreter with respect to a program's source code @cite_9 . It is therefore unsurprising that the implementation of an interpreter shares many structural characteristics with the implementation of both the semantic analysis and code generation phases. However, the details of these correspondences are likely inaccessible to the typical undergraduate student, and moreover, they are a distraction. An undergraduate course in compiler construction generally focuses on a narrow range of language features, emphasizing instead many real-world concerns such as efficient symbol table construction, separation of front and back ends through an intermediate representation, call stack frames, and (time permitting) various code-improving transformation techniques. As a consequence, interpreters, if they are included at all, generally serve as a foil for the superior performance of compiled code @cite_13 @cite_1 , or else as material for a more breadth-based course on general language implementation @cite_8 @cite_5 .
@cite_8 @cite_9 @cite_1 @cite_6 @cite_5 @cite_13
1556604985 570548980 1963705166 109232922 2230980491
Functions, types and expressions programming languages and their operational semantics compilation partial evaluation of a flow chart languages partial evaluation of a first-order functional languages the view from Olympus partial evaluation of the Lambda calculus partial evaluation of prolog aspects of Similix - a partial evaluator for a subset of scheme partial evaluation of C applications of partial evaluation termination of partial evaluation program analysis more general program transformation guide to the literature the self-applicable scheme specializer. 1. Introduction 2. Language Processors 3. Compilation 4. Syntactic Analysis 5. Contextual Analysis 6. Run-time Organization 7. Code Generation 8. Interpretation 9. Conclusion Starting from a denotational semantics of the eager untyped lambda-calculus with explicit runtime errors, the standard collecting semantics is defined as specifying the strongest program properties. By a first abstraction, a new sound type collecting semantics is derived in compositional fix-point form. Then by successive (semi-dual) Galois connection based abstractions, type systems and or type inference algorithms are designed as abstract semantics or abstract interpreters approximating the type collecting semantics. This leads to a hierarchy of type systems, which is part of the lattice of abstract interpretations of the untyped lambda-calculus. This hierarchy includes two new � la Church Curry polytype systems. Abstractions of this polytype semantics lead to classical Milner Mycroft and Damas Milner polymorphic type schemes, Church Curry monotypes and Hindley principal typing algorithm. This shows that types are abstract interpretations. As a textbook suitable for the classroom or self-study, Michael Scott's Programming Language Pragmatics provides a worthy tour of the theory and practice of how programming languages are run on today's computers. Clearly organized and filled with a wide-ranging perspective on over 40 different languages, this book will be appreciated for its depth and breadth of coverage on an essential topic in computer science. With references to dozens of programming languages, from Ada to Turing and everything in between (including C, C++, Java, and Perl), this book is a truly in-depth guide to how code is compiled (or interpreted) and executed on computer hardware. Early chapters tend to be slightly more theoretical (with coverage of regular expressions and context-free grammars) and will be most valuable to the computer science student, but much of this book is accessible to anyone seeking to widen their knowledge (especially since recent standards surrounding XML make use of some of the same vocabulary presented here). The book has a comprehensive discussion of compilation and linking, as well as how data types are implemented in memory. Sections on functional and logical programming (illustrated with Scheme and Prolog, which are often used in AI research) can expand your understanding of how programming languages work. Final sections on the advantages--and complexities--of concurrent processing, plus a nice treatment of code optimization techniques, round out the text here. Each chapter provides numerous exercises, so you can try out the ideas on your own. Students will benefit from the practical examples here, drawn from a wide range of languages. If you are a self-taught developer, the very approachable tutorial can give you perspective on the formal definitions of many computer languages, which can help you master new ones more effectively. --Richard Dragan Topics covered: A survey of today's programming languages, compilation vs. interpretation, the compilation process, regular expression and context-free grammars, scanners and parsers, names, scopes and bindings, scope rules, overloading, semantic analysis, introduction to computer architecture, representing data, instruction sets, 680x0 and MIPs architectures, control flow and expression evaluation, iteration and recursion, data types, type checking, records, arrays, strings, sets, pointers, lists, file I O, subroutines, calling sequences and parameter passing, exception handling, coroutines, compile back-end processing, code generation, linking, object-oriented programming basics, encapsulation and inheritance, late binding, multiple inheritance, functional and logical languages, Scheme and Prolog, programming with concurrency, shared memory and message passing, and code optimization techniques. Long-awaited revision to a unique guide that covers both compilers and interpreters Revised, updated, and now focusing on Java instead of C++, this long-awaited, latest edition of this popular book teaches programmers and software engineering students how to write compilers and interpreters using Java. You?ll write compilers and interpreters as case studies, generating general assembly code for a Java Virtual Machine that takes advantage of the Java Collections Framework to shorten and simplify the code. In addition, coverage includes Java Collections Framework, UML modeling, object-oriented programming with design patterns, working with XML intermediate code, and more.