Automatically Achieving Elasticity in the Implementation of Programming Languages Michael Lee Horowitz
Total Page:16
File Type:pdf, Size:1020Kb
Automatically Achieving Elasticity in the Implementation of Programming Languages Michael Lee Horowitz January 1988 CMU-CS-88- I04 Submitted to CarnegieMellon Universityin partial fulf'dlment of the requirements for the degree of Doctor of Philosophy in Computer Science. Department of Computer Science Carnegie Mellon University Pittsburgh, PA 15213 Copyright © 1988 Michael Lee Horowitz. All fights reserved. This research was sponsored by the Defense Advanced Research Projects Agency (DOD), ARPA Order No. 4976 under contract F33615-87-C-1499 and monitored by the: Avionics Laboratory Air Force Wright Aeronautical Laboratories Aeronautical Systems Division (AFSC) Wright-Patterson AFB, OHIO 45433-6543 The views and conclusions contained in this document are those of the authors and should not be interpreted as representing the official policies, either expressed or implied, of the Defense Advanced Research Projects Agency or the US Government. Abstract Several developments in programming language design and software engineering lead to a re- examination of the role of binding times in programming language implementation. We can alleviate problems associated with these developments by using event-driven processing to determine translation binding times. Our ultimate goal is to clarify the effects of different designs on binding times and to reduce binding time concerns in the language design process. Determining the binding time of a translation action involves two concerns: the ordering of the action's execution relative to other actions and the translation phase in which the execution occurs (e.g. compile- time, link-time, or run-time). Some issues that affect these concerns include: how to handle forward references, language designs that require dynamic interpretation, the role of link-time in languages that allow separate compilation, and how to achieve elasticity. Elasticity occurs when similar translation actions may be executed at very different binding times, typically in different translation phases. In particular, the binding time of each translation action is determined individually. Elastic translation, therefore, incurs the costs of late bindings only when language flexibility is used by the programmer. Otherwise, the programmer receives the benefits associated with static binding times (e.g. early error notification and efficient program execution). We can model language translation as an event-driven process. Each semantic action needed to translate a program may be viewed as an event. Each event becomes enabled when its required data becomes available. Event-driven translation progresses by executing those events initially enabled and continuing with those enabled as a result. Since each action is handled individually, event-driven translation naturally determines the proper ordering and phase for executing events and achieves elasticity. We can also generate event-driven translation systems automatically. Automatic generation removes from the language implementor the need to understand the event-driven translation model. In particular, event-driven systems can be generated from a known specification formalism (i.e. attribute grammars). An automatic generator of event-driven translators can also provide useful information about binding times during the language design process. Finally, event-driven systems may have potential in practical language implementations. This thesis describes translation problems, the event-driven translation model, a generator of event-driven translators, a language design based on elasticity, and an evaluation of the model for practical language translation. Elastic translation has particular promise in the design and implementation of programming environments and command languages. Event-driven translation may also provide the means to quantify well-known design "principles" such as avoiding pre-emptive decisions. Acknowledgments If once a man indulges himself in murder, very soon he comes to think little of robbing; and from robbing he comes next to drinking and Sabbath-breaking, and from that to incivility and procrastination. Thomas De Quincey Murder Considered as One of the Fine Arts (1827) I would like to extend my appreciation to the following people: - To my parents, who taught me the discipline necessary for being a student. -To Dr. James Naismith, who created the game of basketball, to the Celtics, the Lakers, WTBS, and ESPN for keeping me sane, and to all the gym rats who provided the competition that kept me fit. - To everyone at the department, who have made, and continue to make, CMU one of the best places in the world, socially as well as technically. -To my colleagues at Formative Technologies, who have expressed confidence in my abilities, particularly the one to finish. - To Mary Shaw, who taught me never to be satisfied with less than my best. - To all of the friends I have made at CS, who never let on that I was procrastinating badly. - To Sharon Burks, who smoothed all administration bumps. -To Richard Cohn, who provided many valuable comments and actually read the thesis in doing so. - To Peter Hibbard, who taught me how to express my ideas better, and to Cynthia Hibbard, who helped me express my ideas better on paper. - To Mario Barbacci, Chuck Eastman, and Maurice Herlihy, my committee, for their support, direction, and valuable advice. - To Roger Dannenberg, my advisor, who never lost hope and helped me polish my concepts. -To my son, Elijah, who has made procrastination ever so sweet and showed me the true meaning of life. - To my wife, Laura Lupovitz, who has been my everything, my anchor in life, and my prime motivator to finish. Table of Contents 1. Introduction 1 1.1. Motivation 2 1.1.1. Language design 2 1.1.2. Separate compilation 3 1.1.3. Relative ordering 3 1.1.4. Programming environments 4 1.1.5. Command languages 5 1.2. Goals 5 1.3. Previous Work 6 1.4. Overview 9 2. Event-driven Translation 11 2.1. Translation as Actions 11 2.2. Translation as Events 13 2.3. Binding Times 14 2.4. Examples 16 2.4.1. Relative ordering 17 2.4.2. Link-time as a significant binding time 19 2.4.3. Achieving elasticity 21 2.5. Generation of Event-driven Translators 24 3. Target Machine and Specification Language 29 3.1. Target Machine 30 3.1.1. Stack Machine 30 3.1.2. Auxiliary Models 32 3.2. Specification Language 34 3.2.1. Attribute Grammars 35 3.2.2. The Specification of Events 37 3.2.3. Specification Example 40 4. ELI Generation System 43 4.1. The Generator 43 4.2. The Intermediate Form 46 4.3. The Translation Engine 48 5. Language Design and Elasticity 55 5.1. Smalltalk 55 5.2. Design Options 59 5.3. Elastic-Smalltalk 64 5.3.1. Syntax of Elastic-Smalltalk 64 5.3.2. Semantics of Elastic-Smalltalk 67 5.4. Review of Specification 75 5.5. Review of Motivations 76 6. Evaluation and Practical Applications 79 6.1. Effectiveness of Model 80 6.2. Criteria of Practicality 81 6.2.1. Ease of specification 811 6.2.2. Ease of generation 82 6.2.3. Code generation 82 6.2.4. Practicality of generated translators 83 6.3. Implementing Modula-2 85 6.4. Other Applications 89 6.4.1. Determining Re-compilation 89 6.4.2. Syntax-directed Editing 92 7. Conclusions 95 7.1. Commonality of Binding Time Determination 95 7.2. Event-driven Translation 96 7.3. Generation of Event-driven Translators 97 7.4. Impact on Language Design 97 7.5. Future Directions 98 7.5.1. Generation of practical translators 99 7.5.2. Language design 100 7.5.3. Other applications 100 7.6. Concluding Thoughts 101 Appendix A. Specification Language Syntax 103 Appendix B. Operation Signatures 105 Appendix C. Elastic-Smalltalk Syntax 107 Appendix D. Elastic-Smalltalk Examples 109 Appendix E. Elastic-Smalltalk Specification 113 Appendix F. Modula-2 Specification 139 List of Figures Figure 2-1: Simple translation 12 Figure 2-2: Forward pointer type reference 18 Figure 2-3: Nested Algol68 blocks [Banatre 79] 18 Figure 2-4: Computing the block number of a closed clause 19 Figure 2-5: Consequence of hidden type representation 20 Figure 2-6: Evaluating typed constant expressions 20 Figure 2-7: Generating iterator loop exit test 22 Figure 2-8: Type checking an assignment statement 23 Figure 2-9: Array access bounds check 23 Figure 2-10: Message lookup when type declarations are allowed 24 Figure 2-11: Form of Classical Translator Generator 25 Figure 3-1: Stack Machine Operations Codes, Part I 31 Figure 3-2: Model Operations, Part 1: Atomic models 33 Figure 3-3: Example Attribute Grammar Production 36 Figure 3-4: Syntax of a Production 38 Figure 3-5: Computational Event Syntax 38 Figure 3-6: Production with Computational Events 40 Figure 3-7: Specification for Based Numbers 41 Figure 4-1: Example of event ordering 45 Figure 4-2: Contents of an Abstract Syntax Tree Node 47 Figure 4-3: The Abstract Syntax Tree component of an Intermediate Form 48 Figure 4-4: An Abstract Syntax Tree component during translation 49 Figure 4-5: Operation of a Phase 50 Figure 4-6: Operation of a Compilation Phase 50 Figure 4-7: Operation of Linking Phase 51 Figure 4-8: Production for Modula-2 WHILE Statement 52 Figure 5-1: The need for Abstract Superclasses 57 Figure 5-2: Class using an Abstract Superclass 58 Figure 5-3: Type Checking Possibilities 62 Figure 5-4: Message Lookup Possibilities 63 Figure 5-5: Interface for SortableList 66 Figure 5-6: Implementation for SortableList 67 Figure 5-7: Production for Method Declaration, Part 1 69 Figure 5-8: Production for RETURN statment 71 Figure 5-9: Assignment Expression Production 72 Figure 5-10: Production