| Misha Brukman | 3669299 | 2004-05-12 19:52:00 +0000 | [diff] [blame] | 1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" | 
 | 2 |                       "http://www.w3.org/TR/html4/strict.dtd"> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 3 | <html> | 
 | 4 | <head> | 
| Misha Brukman | 3669299 | 2004-05-12 19:52:00 +0000 | [diff] [blame] | 5 |   <title>Stacker: An Example Of Using LLVM</title> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 6 |   <link rel="stylesheet" href="llvm.css" type="text/css"> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 7 |   <style> | 
 | 8 |     table, tr, td { border: 2px solid gray } | 
| Misha Brukman | fd90f88 | 2004-05-13 00:37:23 +0000 | [diff] [blame] | 9 |     table { border-collapse: collapse; margin-bottom: 2em } | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 10 |   </style> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 11 | </head> | 
 | 12 | <body> | 
| Misha Brukman | 3669299 | 2004-05-12 19:52:00 +0000 | [diff] [blame] | 13 |  | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 14 | <div class="doc_title">Stacker: An Example Of Using LLVM</div> | 
| Misha Brukman | 3669299 | 2004-05-12 19:52:00 +0000 | [diff] [blame] | 15 |  | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 16 | <ol> | 
 | 17 |   <li><a href="#abstract">Abstract</a></li> | 
 | 18 |   <li><a href="#introduction">Introduction</a></li> | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 19 |   <li><a href="#lessons">Lessons I Learned About LLVM</a> | 
 | 20 |     <ol> | 
 | 21 |       <li><a href="#value">Everything's a Value!</a></li> | 
 | 22 |       <li><a href="#terminate">Terminate Those Blocks!</a></li> | 
 | 23 |       <li><a href="#blocks">Concrete Blocks</a></li> | 
 | 24 |       <li><a href="#push_back">push_back Is Your Friend</a></li> | 
 | 25 |       <li><a href="#gep">The Wily GetElementPtrInst</a></li> | 
 | 26 |       <li><a href="#linkage">Getting Linkage Types Right</a></li> | 
 | 27 |       <li><a href="#constants">Constants Are Easier Than That!</a></li> | 
| Misha Brukman | 3669299 | 2004-05-12 19:52:00 +0000 | [diff] [blame] | 28 |     </ol></li> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 29 |   <li><a href="#lexicon">The Stacker Lexicon</a> | 
 | 30 |     <ol> | 
| Misha Brukman | 3669299 | 2004-05-12 19:52:00 +0000 | [diff] [blame] | 31 |       <li><a href="#stack">The Stack</a></li> | 
 | 32 |       <li><a href="#punctuation">Punctuation</a></li> | 
 | 33 |       <li><a href="#comments">Comments</a></li> | 
 | 34 |       <li><a href="#literals">Literals</a></li> | 
 | 35 |       <li><a href="#words">Words</a></li> | 
| Misha Brukman | 4fcfaa5 | 2004-06-03 23:47:34 +0000 | [diff] [blame] | 36 |       <li><a href="#style">Standard Style</a></li> | 
| Misha Brukman | 3669299 | 2004-05-12 19:52:00 +0000 | [diff] [blame] | 37 |       <li><a href="#builtins">Built-Ins</a></li> | 
 | 38 |     </ol></li> | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 39 |   <li><a href="#example">Prime: A Complete Example</a></li> | 
 | 40 |   <li><a href="#internal">Internal Code Details</a> | 
 | 41 |     <ol> | 
 | 42 |       <li><a href="#directory">The Directory Structure </a></li> | 
 | 43 |       <li><a href="#lexer">The Lexer</a></li> | 
 | 44 |       <li><a href="#parser">The Parser</a></li> | 
 | 45 |       <li><a href="#compiler">The Compiler</a></li> | 
 | 46 |       <li><a href="#runtime">The Runtime</a></li> | 
 | 47 |       <li><a href="#driver">Compiler Driver</a></li> | 
 | 48 |       <li><a href="#tests">Test Programs</a></li> | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 49 |       <li><a href="#exercise">Exercise</a></li> | 
 | 50 |       <li><a href="#todo">Things Remaining To Be Done</a></li> | 
| Misha Brukman | 3669299 | 2004-05-12 19:52:00 +0000 | [diff] [blame] | 51 |     </ol></li> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 52 | </ol> | 
| Misha Brukman | 3669299 | 2004-05-12 19:52:00 +0000 | [diff] [blame] | 53 |  | 
| Chris Lattner | 7911ce2 | 2004-05-23 21:07:27 +0000 | [diff] [blame] | 54 | <div class="doc_author"> | 
 | 55 |   <p>Written by <a href="mailto:rspencer@x10sys.com">Reid Spencer</a></p> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 56 | </div> | 
| Misha Brukman | 3669299 | 2004-05-12 19:52:00 +0000 | [diff] [blame] | 57 |  | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 58 | <!-- ======================================================================= --> | 
| Misha Brukman | 3669299 | 2004-05-12 19:52:00 +0000 | [diff] [blame] | 59 | <div class="doc_section"><a name="abstract">Abstract</a></div> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 60 | <div class="doc_text"> | 
 | 61 | <p>This document is another way to learn about LLVM. Unlike the  | 
 | 62 | <a href="LangRef.html">LLVM Reference Manual</a> or  | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 63 | <a href="ProgrammersManual.html">LLVM Programmer's Manual</a>, here we learn | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 64 | about LLVM through the experience of creating a simple programming language | 
 | 65 | named Stacker.  Stacker was invented specifically as a demonstration of | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 66 | LLVM. The emphasis in this document is not on describing the | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 67 | intricacies of LLVM itself but on how to use it to build your own | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 68 | compiler system.</p> | 
 | 69 | </div> | 
 | 70 | <!-- ======================================================================= --> | 
 | 71 | <div class="doc_section"> <a name="introduction">Introduction</a> </div> | 
 | 72 | <div class="doc_text"> | 
 | 73 | <p>Amongst other things, LLVM is a platform for compiler writers. | 
 | 74 | Because of its exceptionally clean and small IR (intermediate | 
 | 75 | representation), compiler writing with LLVM is much easier than with | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 76 | other system. As proof, I wrote the entire compiler (language definition,  | 
 | 77 | lexer, parser, code generator, etc.) in about <em>four days</em>!  | 
 | 78 | That's important to know because it shows how quickly you can get a new | 
 | 79 | language running when using LLVM. Furthermore, this was the <em >first</em>  | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 80 | language the author ever created using LLVM. The learning curve is  | 
 | 81 | included in that four days.</p> | 
 | 82 | <p>The language described here, Stacker, is Forth-like. Programs | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 83 | are simple collections of word definitions, and the only thing definitions | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 84 | can do is manipulate a stack or generate I/O.  Stacker is not a "real"  | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 85 | programming language; it's very simple.  Although it is computationally  | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 86 | complete, you wouldn't use it for your next big project. However,  | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 87 | the fact that it is complete, it's simple, and it <em>doesn't</em> have  | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 88 | a C-like syntax make it useful for demonstration purposes. It shows | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 89 | that LLVM could be applied to a wide variety of languages.</p> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 90 | <p>The basic notions behind stacker is very simple. There's a stack of  | 
 | 91 | integers (or character pointers) that the program manipulates. Pretty  | 
 | 92 | much the only thing the program can do is manipulate the stack and do  | 
 | 93 | some limited I/O operations. The language provides you with several  | 
 | 94 | built-in words that manipulate the stack in interesting ways. To get  | 
 | 95 | your feet wet, here's how you write the traditional "Hello, World"  | 
 | 96 | program in Stacker:</p> | 
 | 97 | <p><code>: hello_world "Hello, World!" >s DROP CR ;<br> | 
 | 98 | : MAIN hello_world ;<br></code></p> | 
 | 99 | <p>This has two "definitions" (Stacker manipulates words, not | 
 | 100 | functions and words have definitions): <code>MAIN</code> and <code> | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 101 | hello_world</code>. The <code>MAIN</code> definition is standard; it | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 102 | tells Stacker where to start. Here, <code>MAIN</code> is defined to  | 
 | 103 | simply invoke the word <code>hello_world</code>. The | 
 | 104 | <code>hello_world</code> definition tells stacker to push the  | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 105 | <code>"Hello, World!"</code> string on to the stack, print it out  | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 106 | (<code>>s</code>), pop it off the stack (<code>DROP</code>), and | 
 | 107 | finally print a carriage return (<code>CR</code>). Although  | 
 | 108 | <code>hello_world</code> uses the stack, its net effect is null. Well | 
 | 109 | written Stacker definitions have that characteristic. </p> | 
 | 110 | <p>Exercise for the reader: how could you make this a one line program?</p> | 
 | 111 | </div> | 
 | 112 | <!-- ======================================================================= --> | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 113 | <div class="doc_section"><a name="lessons"></a>Lessons I Learned About LLVM</div> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 114 | <div class="doc_text"> | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 115 | <p>Stacker was written for two purposes: </p> | 
 | 116 | <ol> | 
 | 117 |     <li>to get the author over the learning curve, and</li> | 
 | 118 |     <li>to provide a simple example of how to write a compiler using LLVM.</li> | 
 | 119 | </ol> | 
 | 120 | <p>During the development of Stacker, many lessons about LLVM were | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 121 | learned. Those lessons are described in the following subsections.<p> | 
 | 122 | </div> | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 123 | <!-- ======================================================================= --> | 
 | 124 | <div class="doc_subsection"><a name="value"></a>Everything's a Value!</div> | 
 | 125 | <div class="doc_text"> | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 126 | <p>Although I knew that LLVM uses a Single Static Assignment (SSA) format,  | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 127 | it wasn't obvious to me how prevalent this idea was in LLVM until I really | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 128 | started using it.  Reading the <a href="ProgrammersManual.html"> | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 129 | Programmer's Manual</a> and <a href="LangRef.html">Language Reference</a>, | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 130 | I noted that most of the important LLVM IR (Intermediate Representation) C++  | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 131 | classes were derived from the Value class. The full power of that simple | 
 | 132 | design only became fully understood once I started constructing executable | 
 | 133 | expressions for Stacker.</p> | 
 | 134 | <p>This really makes your programming go faster. Think about compiling code | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 135 | for the following C/C++ expression: <code>(a|b)*((x+1)/(y+1))</code>. Assuming | 
 | 136 | the values are on the stack in the order a, b, x, y, this could be | 
 | 137 | expressed in stacker as: <code>1 + SWAP 1 + / ROT2 OR *</code>. | 
 | 138 | You could write a function using LLVM that computes this expression like this: </p> | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 139 | <pre><code> | 
 | 140 | Value*  | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 141 | expression(BasicBlock* bb, Value* a, Value* b, Value* x, Value* y ) | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 142 | { | 
 | 143 |     Instruction* tail = bb->getTerminator(); | 
 | 144 |     ConstantSInt* one = ConstantSInt::get( Type::IntTy, 1); | 
 | 145 |     BinaryOperator* or1 =  | 
| Chris Lattner | 0b404c8 | 2003-11-25 01:44:27 +0000 | [diff] [blame] | 146 | 	BinaryOperator::create( Instruction::Or, a, b, "", tail ); | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 147 |     BinaryOperator* add1 =  | 
| Chris Lattner | 0b404c8 | 2003-11-25 01:44:27 +0000 | [diff] [blame] | 148 | 	BinaryOperator::create( Instruction::Add, x, one, "", tail ); | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 149 |     BinaryOperator* add2 = | 
| Chris Lattner | 0b404c8 | 2003-11-25 01:44:27 +0000 | [diff] [blame] | 150 | 	BinaryOperator::create( Instruction::Add, y, one, "", tail ); | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 151 |     BinaryOperator* div1 =  | 
| Chris Lattner | 0b404c8 | 2003-11-25 01:44:27 +0000 | [diff] [blame] | 152 | 	BinaryOperator::create( Instruction::Div, add1, add2, "", tail); | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 153 |     BinaryOperator* mult1 =  | 
| Chris Lattner | 0b404c8 | 2003-11-25 01:44:27 +0000 | [diff] [blame] | 154 | 	BinaryOperator::create( Instruction::Mul, or1, div1, "", tail ); | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 155 |  | 
 | 156 |     return mult1; | 
 | 157 | } | 
 | 158 | </code></pre> | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 159 | <p>"Okay, big deal," you say?  It is a big deal. Here's why. Note that I didn't | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 160 | have to tell this function which kinds of Values are being passed in. They could be | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 161 | <code>Instruction</code>s, <code>Constant</code>s, <code>GlobalVariable</code>s, or | 
 | 162 | any of the other subclasses of <code>Value</code> that LLVM supports. | 
 | 163 | Furthermore, if you specify Values that are incorrect for this sequence of  | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 164 | operations, LLVM will either notice right away (at compilation time) or the LLVM  | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 165 | Verifier will pick up the inconsistency when the compiler runs. In either case  | 
 | 166 | LLVM prevents you from making a type error that gets passed through to the  | 
 | 167 | generated program.  This <em>really</em> helps you write a compiler that  | 
 | 168 | always generates correct code!<p> | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 169 | <p>The second point is that we don't have to worry about branching, registers, | 
 | 170 | stack variables, saving partial results, etc. The instructions we create  | 
 | 171 | <em>are</em> the values we use. Note that all that was created in the above | 
 | 172 | code is a Constant value and five operators. Each of the instructions <em>is</em>  | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 173 | the resulting value of that instruction. This saves a lot of time.</p> | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 174 | <p>The lesson is this: <em>SSA form is very powerful: there is no difference | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 175 | between a value and the instruction that created it.</em> This is fully | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 176 | enforced by the LLVM IR. Use it to your best advantage.</p> | 
 | 177 | </div> | 
 | 178 | <!-- ======================================================================= --> | 
 | 179 | <div class="doc_subsection"><a name="terminate"></a>Terminate Those Blocks!</div> | 
 | 180 | <div class="doc_text"> | 
 | 181 | <p>I had to learn about terminating blocks the hard way: using the debugger  | 
 | 182 | to figure out what the LLVM verifier was trying to tell me and begging for | 
 | 183 | help on the LLVMdev mailing list. I hope you avoid this experience.</p> | 
 | 184 | <p>Emblazon this rule in your mind:</p> | 
 | 185 | <ul> | 
 | 186 |     <li><em>All</em> <code>BasicBlock</code>s in your compiler <b>must</b> be | 
 | 187 | 	terminated with a terminating instruction (branch, return, etc.). | 
 | 188 |     </li> | 
 | 189 | </ul> | 
 | 190 | <p>Terminating instructions are a semantic requirement of the LLVM IR. There | 
 | 191 | is no facility for implicitly chaining together blocks placed into a function | 
 | 192 | in the order they occur. Indeed, in the general case, blocks will not be | 
 | 193 | added to the function in the order of execution because of the recursive | 
 | 194 | way compilers are written.</p> | 
 | 195 | <p>Furthermore, if you don't terminate your blocks, your compiler code will  | 
 | 196 | compile just fine. You won't find out about the problem until you're running  | 
 | 197 | the compiler and the module you just created fails on the LLVM Verifier.</p> | 
 | 198 | </div> | 
 | 199 | <!-- ======================================================================= --> | 
 | 200 | <div class="doc_subsection"><a name="blocks"></a>Concrete Blocks</div> | 
 | 201 | <div class="doc_text"> | 
 | 202 | <p>After a little initial fumbling around, I quickly caught on to how blocks | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 203 | should be constructed. In general, here's what I learned: | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 204 | <ol> | 
 | 205 |     <li><em>Create your blocks early.</em> While writing your compiler, you  | 
 | 206 |     will encounter several situations where you know apriori that you will | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 207 |     need several blocks. For example, if-then-else, switch, while, and for | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 208 |     statements in C/C++ all need multiple blocks for expression in LVVM.  | 
 | 209 |     The rule is, create them early.</li> | 
 | 210 |     <li><em>Terminate your blocks early.</em> This just reduces the chances  | 
 | 211 |     that you forget to terminate your blocks which is required (go  | 
 | 212 |     <a href="#terminate">here</a> for more).  | 
 | 213 |     <li><em>Use getTerminator() for instruction insertion.</em> I noticed early on | 
 | 214 |     that many of the constructors for the Instruction classes take an optional | 
 | 215 |     <code>insert_before</code> argument. At first, I thought this was a mistake | 
 | 216 |     because clearly the normal mode of inserting instructions would be one at | 
 | 217 |     a time <em>after</em> some other instruction, not <em>before</em>. However, | 
 | 218 |     if you hold on to your terminating instruction (or use the handy dandy | 
 | 219 |     <code>getTerminator()</code> method on a <code>BasicBlock</code>), it can | 
 | 220 |     always be used as the <code>insert_before</code> argument to your instruction | 
 | 221 |     constructors. This causes the instruction to automatically be inserted in  | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 222 |     the RightPlace™ place, just before the terminating instruction. The  | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 223 |     nice thing about this design is that you can pass blocks around and insert  | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 224 |     new instructions into them without ever knowing what instructions came  | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 225 |     before. This makes for some very clean compiler design.</li> | 
 | 226 | </ol> | 
 | 227 | <p>The foregoing is such an important principal, its worth making an idiom:</p> | 
| Misha Brukman | 3669299 | 2004-05-12 19:52:00 +0000 | [diff] [blame] | 228 | <pre> | 
 | 229 | BasicBlock* bb = new BasicBlock(); | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 230 | bb->getInstList().push_back( new Branch( ... ) ); | 
 | 231 | new Instruction(..., bb->getTerminator() ); | 
| Misha Brukman | 3669299 | 2004-05-12 19:52:00 +0000 | [diff] [blame] | 232 | </pre> | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 233 | <p>To make this clear, consider the typical if-then-else statement | 
 | 234 | (see StackerCompiler::handle_if() method).  We can set this up | 
 | 235 | in a single function using LLVM in the following way: </p> | 
 | 236 | <pre> | 
 | 237 | using namespace llvm; | 
 | 238 | BasicBlock* | 
 | 239 | MyCompiler::handle_if( BasicBlock* bb, SetCondInst* condition ) | 
 | 240 | { | 
 | 241 |     // Create the blocks to contain code in the structure of if/then/else | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 242 |     BasicBlock* then_bb = new BasicBlock();  | 
 | 243 |     BasicBlock* else_bb = new BasicBlock(); | 
 | 244 |     BasicBlock* exit_bb = new BasicBlock(); | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 245 |  | 
 | 246 |     // Insert the branch instruction for the "if" | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 247 |     bb->getInstList().push_back( new BranchInst( then_bb, else_bb, condition ) ); | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 248 |  | 
 | 249 |     // Set up the terminating instructions | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 250 |     then->getInstList().push_back( new BranchInst( exit_bb ) ); | 
 | 251 |     else->getInstList().push_back( new BranchInst( exit_bb ) ); | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 252 |  | 
 | 253 |     // Fill in the then part .. details excised for brevity | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 254 |     this->fill_in( then_bb ); | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 255 |  | 
 | 256 |     // Fill in the else part .. details excised for brevity | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 257 |     this->fill_in( else_bb ); | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 258 |  | 
 | 259 |     // Return a block to the caller that can be filled in with the code | 
 | 260 |     // that follows the if/then/else construct. | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 261 |     return exit_bb; | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 262 | } | 
 | 263 | </pre> | 
 | 264 | <p>Presumably in the foregoing, the calls to the "fill_in" method would add  | 
 | 265 | the instructions for the "then" and "else" parts. They would use the third part | 
 | 266 | of the idiom almost exclusively (inserting new instructions before the  | 
 | 267 | terminator). Furthermore, they could even recurse back to <code>handle_if</code>  | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 268 | should they encounter another if/then/else statement, and it will just work.</p> | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 269 | <p>Note how cleanly this all works out. In particular, the push_back methods on | 
 | 270 | the <code>BasicBlock</code>'s instruction list. These are lists of type  | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 271 | <code>Instruction</code> (which is also of type <code>Value</code>). To create  | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 272 | the "if" branch we merely instantiate a <code>BranchInst</code> that takes as  | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 273 | arguments the blocks to branch to and the condition to branch on. The  | 
 | 274 | <code>BasicBlock</code> objects act like branch labels! This new  | 
 | 275 | <code>BranchInst</code> terminates the <code>BasicBlock</code> provided  | 
 | 276 | as an argument. To give the caller a way to keep inserting after calling  | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 277 | <code>handle_if</code>, we create an <code>exit_bb</code> block which is | 
 | 278 | returned  | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 279 | to the caller.  Note that the <code>exit_bb</code> block is used as the  | 
 | 280 | terminator for both the <code>then_bb</code> and the <code>else_bb</code> | 
 | 281 | blocks. This guarantees that no matter what else <code>handle_if</code> | 
 | 282 | or <code>fill_in</code> does, they end up at the <code>exit_bb</code> block. | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 283 | </p> | 
 | 284 | </div> | 
 | 285 | <!-- ======================================================================= --> | 
 | 286 | <div class="doc_subsection"><a name="push_back"></a>push_back Is Your Friend</div> | 
 | 287 | <div class="doc_text"> | 
 | 288 | <p> | 
 | 289 | One of the first things I noticed is the frequent use of the "push_back" | 
 | 290 | method on the various lists. This is so common that it is worth mentioning. | 
 | 291 | The "push_back" inserts a value into an STL list, vector, array, etc. at the | 
 | 292 | end. The method might have also been named "insert_tail" or "append". | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 293 | Although I've used STL quite frequently, my use of push_back wasn't very | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 294 | high in other programs. In LLVM, you'll use it all the time. | 
 | 295 | </p> | 
 | 296 | </div> | 
 | 297 | <!-- ======================================================================= --> | 
 | 298 | <div class="doc_subsection"><a name="gep"></a>The Wily GetElementPtrInst</div> | 
 | 299 | <div class="doc_text"> | 
 | 300 | <p> | 
 | 301 | It took a little getting used to and several rounds of postings to the LLVM | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 302 | mailing list to wrap my head around this instruction correctly. Even though I had | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 303 | read the Language Reference and Programmer's Manual a couple times each, I still | 
 | 304 | missed a few <em>very</em> key points: | 
 | 305 | </p> | 
 | 306 | <ul> | 
| Misha Brukman | 3669299 | 2004-05-12 19:52:00 +0000 | [diff] [blame] | 307 | <li>GetElementPtrInst gives you back a Value for the last thing indexed.</li> | 
 | 308 | <li>All global variables in LLVM  are <em>pointers</em>.</li> | 
 | 309 | <li>Pointers must also be dereferenced with the GetElementPtrInst | 
 | 310 | instruction.</li> | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 311 | </ul> | 
 | 312 | <p>This means that when you look up an element in the global variable (assuming | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 313 | it's a struct or array), you <em>must</em> deference the pointer first! For many | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 314 | things, this leads to the idiom: | 
 | 315 | </p> | 
| Misha Brukman | 3669299 | 2004-05-12 19:52:00 +0000 | [diff] [blame] | 316 | <pre> | 
 | 317 | std::vector<Value*> index_vector; | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 318 | index_vector.push_back( ConstantSInt::get( Type::LongTy, 0 ); | 
 | 319 | // ... push other indices ... | 
 | 320 | GetElementPtrInst* gep = new GetElementPtrInst( ptr, index_vector ); | 
| Misha Brukman | 3669299 | 2004-05-12 19:52:00 +0000 | [diff] [blame] | 321 | </pre> | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 322 | <p>For example, suppose we have a global variable whose type is [24 x int]. The | 
 | 323 | variable itself represents a <em>pointer</em> to that array. To subscript the | 
 | 324 | array, we need two indices, not just one. The first index (0) dereferences the | 
 | 325 | pointer. The second index subscripts the array. If you're a "C" programmer, this | 
 | 326 | will run against your grain because you'll naturally think of the global array | 
 | 327 | variable and the address of its first element as the same. That tripped me up | 
 | 328 | for a while until I realized that they really do differ .. by <em>type</em>. | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 329 | Remember that LLVM is strongly typed. Everything has a type.   | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 330 | The "type" of the global variable is [24 x int]*. That is, it's | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 331 | a pointer to an array of 24 ints.  When you dereference that global variable with | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 332 | a single (0) index, you now have a "[24 x int]" type.  Although | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 333 | the pointer value of the dereferenced global and the address of the zero'th element | 
 | 334 | in the array will be the same, they differ in their type. The zero'th element has | 
 | 335 | type "int" while the pointer value has type "[24 x int]".</p> | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 336 | <p>Get this one aspect of LLVM right in your head, and you'll save yourself | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 337 | a lot of compiler writing headaches down the road.</p> | 
 | 338 | </div> | 
 | 339 | <!-- ======================================================================= --> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 340 | <div class="doc_subsection"><a name="linkage"></a>Getting Linkage Types Right</div> | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 341 | <div class="doc_text"> | 
 | 342 | <p>Linkage types in LLVM can be a little confusing, especially if your compiler | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 343 | writing mind has affixed firm concepts to particular words like "weak", | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 344 | "external", "global", "linkonce", etc. LLVM does <em>not</em> use the precise | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 345 | definitions of, say, ELF or GCC, even though they share common terms. To be fair, | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 346 | the concepts are related and similar but not precisely the same. This can lead | 
 | 347 | you to think you know what a linkage type represents but in fact it is slightly | 
 | 348 | different. I recommend you read the  | 
 | 349 | <a href="LangRef.html#linkage"> Language Reference on this topic</a> very  | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 350 | carefully. Then, read it again.<p> | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 351 | <p>Here are some handy tips that I discovered along the way:</p> | 
 | 352 | <ul> | 
| Alkis Evlogimenos | 0744b5f | 2004-03-11 10:14:21 +0000 | [diff] [blame] | 353 |     <li><em>Uninitialized means external.</em> That is, the symbol is declared in the current | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 354 |     module and can be used by that module, but it is not defined by that module.</li> | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 355 |     <li><em>Setting an initializer changes a global' linkage type.</em> Setting an  | 
 | 356 |     initializer changes a global's linkage type from whatever it was to a normal,  | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 357 |     defined global (not external). You'll need to call the setLinkage() method to  | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 358 |     reset it if you specify the initializer after the GlobalValue has been constructed.  | 
 | 359 |     This is important for LinkOnce and Weak linkage types.</li>  | 
 | 360 |     <li><em>Appending linkage can keep track of things.</em> Appending linkage can  | 
 | 361 |     be used to keep track of compilation information at runtime. It could be used,  | 
 | 362 |     for example, to build a full table of all the C++ virtual tables or hold the  | 
 | 363 |     C++ RTTI data, or whatever. Appending linkage can only be applied to arrays.  | 
 | 364 |     All arrays with the same name in each module are concatenated together at link  | 
 | 365 |     time.</li> | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 366 | </ul> | 
 | 367 | </div> | 
 | 368 | <!-- ======================================================================= --> | 
 | 369 | <div class="doc_subsection"><a name="constants"></a>Constants Are Easier Than That!</div> | 
 | 370 | <div class="doc_text"> | 
 | 371 | <p> | 
 | 372 | Constants in LLVM took a little getting used to until I discovered a few utility | 
 | 373 | functions in the LLVM IR that make things easier. Here's what I learned: </p> | 
 | 374 | <ul> | 
 | 375 |  <li>Constants are Values like anything else and can be operands of instructions</li> | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 376 |  <li>Integer constants, frequently needed, can be created using the static "get" | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 377 |  methods of the ConstantInt, ConstantSInt, and ConstantUInt classes. The nice thing | 
 | 378 |  about these is that you can "get" any kind of integer quickly.</li> | 
 | 379 |  <li>There's a special method on Constant class which allows you to get the null  | 
 | 380 |  constant for <em>any</em> type. This is really handy for initializing large  | 
 | 381 |  arrays or structures, etc.</li> | 
 | 382 | </ul> | 
 | 383 | </div> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 384 | <!-- ======================================================================= --> | 
 | 385 | <div class="doc_section"> <a name="lexicon">The Stacker Lexicon</a></div> | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 386 | <div class="doc_text"><p>This section describes the Stacker language</p></div> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 387 | <div class="doc_subsection"><a name="stack"></a>The Stack</div> | 
 | 388 | <div class="doc_text"> | 
 | 389 | <p>Stacker definitions define what they do to the global stack. Before | 
 | 390 | proceeding, a few words about the stack are in order. The stack is simply | 
 | 391 | a global array of 32-bit integers or pointers. A global index keeps track | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 392 | of the location of the top of the stack. All of this is hidden from the  | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 393 | programmer, but it needs to be noted because it is the foundation of the  | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 394 | conceptual programming model for Stacker. When you write a definition, | 
 | 395 | you are, essentially, saying how you want that definition to manipulate | 
 | 396 | the global stack.</p> | 
 | 397 | <p>Manipulating the stack can be quite hazardous. There is no distinction | 
 | 398 | given and no checking for the various types of values that can be placed | 
 | 399 | on the stack. Automatic coercion between types is performed. In many  | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 400 | cases, this is useful. For example, a boolean value placed on the stack | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 401 | can be interpreted as an integer with good results. However, using a | 
 | 402 | word that interprets that boolean value as a pointer to a string to | 
 | 403 | print out will almost always yield a crash. Stacker simply leaves it | 
 | 404 | to the programmer to get it right without any interference or hindering | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 405 | on interpretation of the stack values. You've been warned. :) </p> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 406 | </div> | 
 | 407 | <!-- ======================================================================= --> | 
 | 408 | <div class="doc_subsection"> <a name="punctuation"></a>Punctuation</div> | 
 | 409 | <div class="doc_text"> | 
 | 410 | <p>Punctuation in Stacker is very simple. The colon and semi-colon  | 
 | 411 | characters are used to introduce and terminate a definition | 
 | 412 | (respectively). Except for <em>FORWARD</em> declarations, definitions  | 
 | 413 | are all you can specify in Stacker.  Definitions are read left to right.  | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 414 | Immediately after the colon comes the name of the word being defined.  | 
 | 415 | The remaining words in the definition specify what the word does. The definition | 
 | 416 | is terminated by a semi-colon.</p> | 
 | 417 | <p>So, your typical definition will have the form:</p> | 
 | 418 | <pre><code>: name ... ;</code></pre> | 
 | 419 | <p>The <code>name</code> is up to you but it must start with a letter and contain | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 420 | only letters, numbers, and underscore. Names are case sensitive and must not be | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 421 | the same as the name of a built-in word. The <code>...</code> is replaced by | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 422 | the stack manipulating words that you wish to define <code>name</code> as. <p> | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 423 | </div> | 
 | 424 | <!-- ======================================================================= --> | 
 | 425 | <div class="doc_subsection"><a name="comments"></a>Comments</div> | 
 | 426 | <div class="doc_text"> | 
 | 427 |     <p>Stacker supports two types of comments. A hash mark (#) starts a comment | 
 | 428 |     that extends to the end of the line. It is identical to the kind of comments | 
 | 429 |     commonly used in shell scripts. A pair of parentheses also surround a comment. | 
 | 430 |     In both cases, the content of the comment is ignored by the Stacker compiler. The | 
 | 431 |     following does nothing in Stacker. | 
 | 432 |     </p> | 
 | 433 | <pre><code> | 
 | 434 | # This is a comment to end of line | 
 | 435 | ( This is an enclosed comment ) | 
 | 436 | </code></pre> | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 437 | <p>See the <a href="#example">example</a> program to see comments in use in  | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 438 | a real program.</p> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 439 | </div> | 
 | 440 | <!-- ======================================================================= --> | 
 | 441 | <div class="doc_subsection"><a name="literals"></a>Literals</div> | 
 | 442 | <div class="doc_text"> | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 443 |     <p>There are three kinds of literal values in Stacker: Integers, Strings, | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 444 |     and Booleans. In each case, the stack operation is to simply push the | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 445 |     value on to the stack. So, for example:<br/> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 446 |     <code> 42 " is the answer." TRUE </code><br/> | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 447 |     will push three values on to the stack: the integer 42, the | 
 | 448 |     string " is the answer.", and the boolean TRUE.</p> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 449 | </div> | 
 | 450 | <!-- ======================================================================= --> | 
 | 451 | <div class="doc_subsection"><a name="words"></a>Words</div> | 
 | 452 | <div class="doc_text"> | 
 | 453 | <p>Each definition in Stacker is composed of a set of words. Words are | 
 | 454 | read and executed in order from left to right. There is very little | 
 | 455 | checking in Stacker to make sure you're doing the right thing with  | 
 | 456 | the stack. It is assumed that the programmer knows how the stack  | 
 | 457 | transformation he applies will affect the program.</p> | 
 | 458 | <p>Words in a definition come in two flavors: built-in and programmer | 
 | 459 | defined. Simply mentioning the name of a previously defined or declared | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 460 | programmer-defined word causes that word's stack actions to be invoked. It | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 461 | is somewhat like a function call in other languages. The built-in | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 462 | words have various effects, described <a href="#builtins">below</a>.</p> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 463 | <p>Sometimes you need to call a word before it is defined. For this, you can | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 464 | use the <code>FORWARD</code> declaration. It looks like this:</p> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 465 | <p><code>FORWARD name ;</code></p> | 
 | 466 | <p>This simply states to Stacker that "name" is the name of a definition | 
 | 467 | that is defined elsewhere. Generally it means the definition can be found | 
 | 468 | "forward" in the file. But, it doesn't have to be in the current compilation | 
 | 469 | unit. Anything declared with <code>FORWARD</code> is an external symbol for | 
 | 470 | linking.</p> | 
 | 471 | </div> | 
 | 472 | <!-- ======================================================================= --> | 
| Misha Brukman | 4fcfaa5 | 2004-06-03 23:47:34 +0000 | [diff] [blame] | 473 | <div class="doc_subsection"><a name="style"></a>Standard Style</div> | 
 | 474 | <div class="doc_text"> | 
 | 475 | <p>TODO</p> | 
 | 476 | </div> | 
 | 477 | <!-- ======================================================================= --> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 478 | <div class="doc_subsection"><a name="builtins"></a>Built In Words</div> | 
 | 479 | <div class="doc_text"> | 
 | 480 | <p>The built-in words of the Stacker language are put in several groups  | 
 | 481 | depending on what they do. The groups are as follows:</p> | 
 | 482 | <ol>  | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 483 |     <li><em>Logical</em>: These words provide the logical operations for | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 484 |     comparing stack operands.<br/>The words are: < > <= >=  | 
 | 485 |     = <> true false.</li> | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 486 |     <li><em>Bitwise</em>: These words perform bitwise computations on  | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 487 |     their operands. <br/> The words are: << >> XOR AND NOT</li> | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 488 |     <li><em>Arithmetic</em>: These words perform arithmetic computations on | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 489 |     their operands. <br/> The words are: ABS NEG + - * / MOD */ ++ -- MIN MAX</li> | 
 | 490 |     <li><em>Stack</em>These words manipulate the stack directly by moving | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 491 |     its elements around.<br/> The words are: DROP DROP2 NIP NIP2 DUP DUP2  | 
 | 492 |     SWAP SWAP2 OVER OVER2 ROT ROT2 RROT RROT2 TUCK TUCK2 PICK SELECT ROLL</li> | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 493 |     <li><em>Memory</em>These words allocate, free, and manipulate memory | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 494 |     areas outside the stack.<br/>The words are: MALLOC FREE GET PUT</li> | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 495 |     <li><em>Control</em>: These words alter the normal left to right flow | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 496 |     of execution.<br/>The words are: IF ELSE ENDIF WHILE END RETURN EXIT RECURSE</li> | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 497 |     <li><em>I/O</em>: These words perform output on the standard output | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 498 |     and input on the standard input. No other I/O is possible in Stacker. | 
 | 499 |     <br/>The words are: SPACE TAB CR >s >d >c <s <d <c.</li> | 
 | 500 | </ol> | 
 | 501 | <p>While you may be familiar with many of these operations from other | 
 | 502 | programming languages, a careful review of their semantics is important | 
 | 503 | for correct programming in Stacker. Of most importance is the effect  | 
 | 504 | that each of these built-in words has on the global stack. The effect is | 
 | 505 | not always intuitive. To better describe the effects, we'll borrow from Forth the idiom of | 
 | 506 | describing the effect on the stack with:</p> | 
 | 507 | <p><code> BEFORE -- AFTER </code></p>  | 
 | 508 | <p>That is, to the left of the -- is a representation of the stack before | 
 | 509 | the operation. To the right of the -- is a representation of the stack | 
 | 510 | after the operation. In the table below that describes the operation of | 
 | 511 | each of the built in words, we will denote the elements of the stack  | 
 | 512 | using the following construction:</p> | 
 | 513 | <ol> | 
 | 514 |     <li><em>b</em> - a boolean truth value</li> | 
 | 515 |     <li><em>w</em> - a normal integer valued word.</li> | 
 | 516 |     <li><em>s</em> - a pointer to a string value</li> | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 517 |     <li><em>p</em> - a pointer to a malloc'd memory block</li> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 518 | </ol> | 
 | 519 | </div> | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 520 | <div class="doc_text" > | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 521 |     <table class="doc_table"> | 
 | 522 | <tr class="doc_table"><td colspan="4">Definition Of Operation Of Built In Words</td></tr> | 
 | 523 | <tr class="doc_table"><td colspan="4"><b>LOGICAL OPERATIONS</b></td></tr> | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 524 | <tr class="doc_table"> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 525 |     <td>Word</td> | 
 | 526 |     <td>Name</td> | 
 | 527 |     <td>Operation</td> | 
 | 528 |     <td>Description</td> | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 529 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 530 | <tr class="doc_table"> | 
 | 531 |     <td><</td> | 
 | 532 |     <td>LT</td> | 
 | 533 |     <td>w1 w2 -- b</td> | 
 | 534 |     <td>Two values (w1 and w2) are popped off the stack and | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 535 |     compared. If w1 is less than w2, TRUE is pushed back on | 
 | 536 |     the stack, otherwise FALSE is pushed back on the stack.</td> | 
 | 537 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 538 | <tr><td>></td> | 
 | 539 |     <td>GT</td> | 
 | 540 |     <td>w1 w2 -- b</td> | 
 | 541 |     <td>Two values (w1 and w2) are popped off the stack and | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 542 |     compared. If w1 is greater than w2, TRUE is pushed back on | 
 | 543 |     the stack, otherwise FALSE is pushed back on the stack.</td> | 
 | 544 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 545 | <tr><td>>=</td> | 
 | 546 |     <td>GE</td> | 
 | 547 |     <td>w1 w2 -- b</td> | 
 | 548 |     <td>Two values (w1 and w2) are popped off the stack and | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 549 |     compared. If w1 is greater than or equal to w2, TRUE is  | 
 | 550 |     pushed back on the stack, otherwise FALSE is pushed back  | 
 | 551 |     on the stack.</td> | 
 | 552 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 553 | <tr><td><=</td> | 
 | 554 |     <td>LE</td> | 
 | 555 |     <td>w1 w2 -- b</td> | 
 | 556 |     <td>Two values (w1 and w2) are popped off the stack and | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 557 |     compared. If w1 is less than or equal to w2, TRUE is  | 
 | 558 |     pushed back on the stack, otherwise FALSE is pushed back  | 
 | 559 |     on the stack.</td> | 
 | 560 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 561 | <tr><td>=</td> | 
 | 562 |     <td>EQ</td> | 
 | 563 |     <td>w1 w2 -- b</td> | 
 | 564 |     <td>Two values (w1 and w2) are popped off the stack and | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 565 |     compared. If w1 is equal to w2, TRUE is  | 
 | 566 |     pushed back on the stack, otherwise FALSE is pushed back  | 
 | 567 |     </td> | 
 | 568 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 569 | <tr><td><></td> | 
 | 570 |     <td>NE</td> | 
 | 571 |     <td>w1 w2 -- b</td> | 
 | 572 |     <td>Two values (w1 and w2) are popped off the stack and | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 573 |     compared. If w1 is equal to w2, TRUE is  | 
 | 574 |     pushed back on the stack, otherwise FALSE is pushed back  | 
 | 575 |     </td> | 
 | 576 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 577 | <tr><td>FALSE</td> | 
 | 578 |     <td>FALSE</td> | 
 | 579 |     <td> -- b</td> | 
 | 580 |     <td>The boolean value FALSE (0) is pushed on to the stack.</td> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 581 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 582 | <tr><td>TRUE</td> | 
 | 583 |     <td>TRUE</td> | 
 | 584 |     <td> -- b</td> | 
 | 585 |     <td>The boolean value TRUE (-1) is pushed on to the stack.</td> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 586 | </tr> | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 587 | <tr><td colspan="4"><b>BITWISE OPERATORS</b></td></tr> | 
 | 588 | <tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 589 |     <td>Word</td> | 
 | 590 |     <td>Name</td> | 
 | 591 |     <td>Operation</td> | 
 | 592 |     <td>Description</td> | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 593 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 594 | <tr><td><<</td> | 
 | 595 |     <td>SHL</td> | 
 | 596 |     <td>w1 w2 -- w1<<w2</td> | 
 | 597 |     <td>Two values (w1 and w2) are popped off the stack. The w2 | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 598 |     operand is shifted left by the number of bits given by the | 
 | 599 |     w1 operand. The result is pushed back to the stack.</td> | 
 | 600 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 601 | <tr><td>>></td> | 
 | 602 |     <td>SHR</td> | 
 | 603 |     <td>w1 w2 -- w1>>w2</td> | 
 | 604 |     <td>Two values (w1 and w2) are popped off the stack. The w2 | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 605 |     operand is shifted right by the number of bits given by the | 
 | 606 |     w1 operand. The result is pushed back to the stack.</td> | 
 | 607 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 608 | <tr><td>OR</td> | 
 | 609 |     <td>OR</td> | 
 | 610 |     <td>w1 w2 -- w2|w1</td> | 
 | 611 |     <td>Two values (w1 and w2) are popped off the stack. The values | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 612 |     are bitwise OR'd together and pushed back on the stack. This is  | 
 | 613 |     not a logical OR. The sequence 1 2 OR yields 3 not 1.</td> | 
 | 614 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 615 | <tr><td>AND</td> | 
 | 616 |     <td>AND</td> | 
 | 617 |     <td>w1 w2 -- w2&w1</td> | 
 | 618 |     <td>Two values (w1 and w2) are popped off the stack. The values | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 619 |     are bitwise AND'd together and pushed back on the stack. This is  | 
 | 620 |     not a logical AND. The sequence 1 2 AND yields 0 not 1.</td> | 
 | 621 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 622 | <tr><td>XOR</td> | 
 | 623 |     <td>XOR</td> | 
 | 624 |     <td>w1 w2 -- w2^w1</td> | 
 | 625 |     <td>Two values (w1 and w2) are popped off the stack. The values | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 626 |     are bitwise exclusive OR'd together and pushed back on the stack.  | 
 | 627 |     For example, The sequence 1 3 XOR yields 2.</td> | 
 | 628 | </tr> | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 629 | <tr><td colspan="4"><b>ARITHMETIC OPERATORS</b></td></tr> | 
 | 630 | <tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 631 |     <td>Word</td> | 
 | 632 |     <td>Name</td> | 
 | 633 |     <td>Operation</td> | 
 | 634 |     <td>Description</td> | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 635 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 636 | <tr><td>ABS</td> | 
 | 637 |     <td>ABS</td> | 
 | 638 |     <td>w -- |w|</td> | 
 | 639 |     <td>One value s popped off the stack; its absolute value is computed | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 640 |     and then pushed on to the stack. If w1 is -1 then w2 is 1. If w1 is | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 641 |     1 then w2 is also 1.</td> | 
 | 642 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 643 | <tr><td>NEG</td> | 
 | 644 |     <td>NEG</td> | 
 | 645 |     <td>w -- -w</td> | 
 | 646 |     <td>One value is popped off the stack which is negated and then | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 647 |     pushed back on to the stack. If w1 is -1 then w2 is 1. If w1 is | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 648 |     1 then w2 is -1.</td> | 
 | 649 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 650 | <tr><td> + </td> | 
 | 651 |     <td>ADD</td> | 
 | 652 |     <td>w1 w2 -- w2+w1</td> | 
 | 653 |     <td>Two values are popped off the stack. Their sum is pushed back | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 654 |     on to the stack</td> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 655 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 656 | <tr><td> - </td> | 
 | 657 |     <td>SUB</td> | 
 | 658 |     <td>w1 w2 -- w2-w1</td> | 
 | 659 |     <td>Two values are popped off the stack. Their difference is pushed back | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 660 |     on to the stack</td> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 661 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 662 | <tr><td> * </td> | 
 | 663 |     <td>MUL</td> | 
 | 664 |     <td>w1 w2 -- w2*w1</td> | 
 | 665 |     <td>Two values are popped off the stack. Their product is pushed back | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 666 |     on to the stack</td> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 667 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 668 | <tr><td> / </td> | 
 | 669 |     <td>DIV</td> | 
 | 670 |     <td>w1 w2 -- w2/w1</td> | 
 | 671 |     <td>Two values are popped off the stack. Their quotient is pushed back | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 672 |     on to the stack</td> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 673 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 674 | <tr><td>MOD</td> | 
 | 675 |     <td>MOD</td> | 
 | 676 |     <td>w1 w2 -- w2%w1</td> | 
 | 677 |     <td>Two values are popped off the stack. Their remainder after division | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 678 |     of w1 by w2 is pushed back on to the stack</td> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 679 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 680 | <tr><td> */ </td> | 
 | 681 |     <td>STAR_SLAH</td> | 
 | 682 |     <td>w1 w2 w3 -- (w3*w2)/w1</td> | 
 | 683 |     <td>Three values are popped off the stack. The product of w1 and w2 is | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 684 |     divided by w3. The result is pushed back on to the stack.</td> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 685 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 686 | <tr><td> ++ </td> | 
 | 687 |     <td>INCR</td> | 
 | 688 |     <td>w -- w+1</td> | 
 | 689 |     <td>One value is popped off the stack. It is incremented by one and then | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 690 |     pushed back on to the stack.</td> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 691 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 692 | <tr><td> -- </td> | 
 | 693 |     <td>DECR</td> | 
 | 694 |     <td>w -- w-1</td> | 
 | 695 |     <td>One value is popped off the stack. It is decremented by one and then | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 696 |     pushed back on to the stack.</td> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 697 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 698 | <tr><td>MIN</td> | 
 | 699 |     <td>MIN</td> | 
 | 700 |     <td>w1 w2 -- (w2<w1?w2:w1)</td> | 
 | 701 |     <td>Two values are popped off the stack. The larger one is pushed back | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 702 |     on to the stack.</td> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 703 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 704 | <tr><td>MAX</td> | 
 | 705 |     <td>MAX</td> | 
 | 706 |     <td>w1 w2 -- (w2>w1?w2:w1)</td> | 
 | 707 |     <td>Two values are popped off the stack. The larger value is pushed back | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 708 | 	on to the stack.</td> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 709 | </tr> | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 710 | <tr><td colspan="4"><b>STACK MANIPULATION OPERATORS</b></td></tr> | 
 | 711 | <tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 712 |     <td>Word</td> | 
 | 713 |     <td>Name</td> | 
 | 714 |     <td>Operation</td> | 
 | 715 |     <td>Description</td> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 716 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 717 | <tr><td>DROP</td> | 
 | 718 |     <td>DROP</td> | 
 | 719 |     <td>w -- </td> | 
 | 720 |     <td>One value is popped off the stack.</td> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 721 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 722 | <tr><td>DROP2</td> | 
 | 723 |     <td>DROP2</td> | 
 | 724 |     <td>w1 w2 -- </td> | 
 | 725 |     <td>Two values are popped off the stack.</td> | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 726 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 727 | <tr><td>NIP</td> | 
 | 728 |     <td>NIP</td> | 
 | 729 |     <td>w1 w2 -- w2</td> | 
 | 730 |     <td>The second value on the stack is removed from the stack. That is, | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 731 | 	a value is popped off the stack and retained. Then a second value is | 
 | 732 | 	popped and the retained value is pushed.</td> | 
 | 733 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 734 | <tr><td>NIP2</td> | 
 | 735 |     <td>NIP2</td> | 
 | 736 |     <td>w1 w2 w3 w4 -- w3 w4</td> | 
 | 737 |     <td>The third and fourth values on the stack are removed from it. That is, | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 738 | 	two values are popped and retained. Then two more values are popped and | 
 | 739 | 	the two retained values are pushed back on.</td> | 
 | 740 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 741 | <tr><td>DUP</td> | 
 | 742 |     <td>DUP</td> | 
 | 743 |     <td>w1 -- w1 w1</td> | 
 | 744 |     <td>One value is popped off the stack. That value is then pushed on to | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 745 | 	the stack twice to duplicate the top stack vaue.</td> | 
 | 746 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 747 | <tr><td>DUP2</td> | 
 | 748 |     <td>DUP2</td> | 
 | 749 |     <td>w1 w2 -- w1 w2 w1 w2</td> | 
 | 750 |     <td>The top two values on the stack are duplicated. That is, two vaues | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 751 | 	are popped off the stack. They are alternately pushed back on the | 
 | 752 | 	stack twice each.</td> | 
 | 753 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 754 | <tr><td>SWAP</td> | 
 | 755 |     <td>SWAP</td> | 
 | 756 |     <td>w1 w2 -- w2 w1</td> | 
 | 757 |     <td>The top two stack items are reversed in their order. That is, two | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 758 | 	values are popped off the stack and pushed back on to the stack in | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 759 | 	the opposite order they were popped.</td> | 
 | 760 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 761 | <tr><td>SWAP2</td> | 
 | 762 |     <td>SWAP2</td> | 
 | 763 |     <td>w1 w2 w3 w4 -- w3 w4 w2 w1</td> | 
 | 764 |     <td>The top four stack items are swapped in pairs. That is, two values | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 765 | 	are popped and retained. Then, two more values are popped and retained. | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 766 | 	The values are pushed back on to the stack in the reverse order but | 
| Misha Brukman | 3669299 | 2004-05-12 19:52:00 +0000 | [diff] [blame] | 767 | 	in pairs.</td> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 768 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 769 | <tr><td>OVER</td> | 
 | 770 |     <td>OVER</td> | 
 | 771 |     <td>w1 w2-- w1 w2 w1</td> | 
 | 772 |     <td>Two values are popped from the stack. They are pushed back | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 773 | 	on to the stack in the order w1 w2 w1. This seems to cause the | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 774 | 	top stack element to be duplicated "over" the next value.</td> | 
 | 775 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 776 | <tr><td>OVER2</td> | 
 | 777 |     <td>OVER2</td> | 
 | 778 |     <td>w1 w2 w3 w4 -- w1 w2 w3 w4 w1 w2</td> | 
 | 779 |     <td>The third and fourth values on the stack are replicated on to the | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 780 | 	top of the stack</td> | 
 | 781 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 782 | <tr><td>ROT</td> | 
 | 783 |     <td>ROT</td> | 
 | 784 |     <td>w1 w2 w3 -- w2 w3 w1</td> | 
 | 785 |     <td>The top three values are rotated. That is, three value are popped | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 786 | 	off the stack. They are pushed back on to the stack in the order | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 787 | 	w1 w3 w2.</td> | 
 | 788 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 789 | <tr><td>ROT2</td> | 
 | 790 |     <td>ROT2</td> | 
 | 791 |     <td>w1 w2 w3 w4 w5 w6 -- w3 w4 w5 w6 w1 w2</td> | 
 | 792 |     <td>Like ROT but the rotation is done using three pairs instead of | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 793 | 	three singles.</td> | 
 | 794 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 795 | <tr><td>RROT</td> | 
 | 796 |     <td>RROT</td> | 
 | 797 |     <td>w1 w2 w3 -- w2 w3 w1</td> | 
 | 798 |     <td>Reverse rotation. Like ROT, but it rotates the other way around. | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 799 | 	Essentially, the third element on the stack is moved to the top | 
 | 800 | 	of the stack.</td> | 
 | 801 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 802 | <tr><td>RROT2</td> | 
 | 803 |     <td>RROT2</td> | 
 | 804 |     <td>w1 w2 w3 w4 w5 w6 -- w3 w4 w5 w6 w1 w2</td> | 
 | 805 |     <td>Double reverse rotation. Like RROT but the rotation is done using  | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 806 | 	three pairs instead of three singles. The fifth and sixth stack  | 
 | 807 | 	elements are moved to the first and second positions</td> | 
 | 808 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 809 | <tr><td>TUCK</td> | 
 | 810 |     <td>TUCK</td> | 
 | 811 |     <td>w1 w2 -- w2 w1 w2</td> | 
 | 812 |     <td>Similar to OVER except that the second operand is being  | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 813 | 	replicated. Essentially, the first operand is being "tucked" | 
 | 814 | 	in between two instances of the second operand. Logically, two | 
 | 815 | 	values are popped off the stack. They are placed back on the | 
 | 816 | 	stack in the order w2 w1 w2.</td> | 
 | 817 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 818 | <tr><td>TUCK2</td> | 
 | 819 |     <td>TUCK2</td> | 
 | 820 |     <td>w1 w2 w3 w4 -- w3 w4 w1 w2 w3 w4</td> | 
 | 821 |     <td>Like TUCK but a pair of elements is tucked over two pairs. | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 822 | 	That is, the top two elements of the stack are duplicated and | 
 | 823 | 	inserted into the stack at the fifth and positions.</td> | 
 | 824 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 825 | <tr><td>PICK</td> | 
 | 826 |     <td>PICK</td> | 
 | 827 |     <td>x0 ... Xn n -- x0 ... Xn x0</td> | 
 | 828 |     <td>The top of the stack is used as an index into the remainder of | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 829 | 	the stack. The element at the nth position replaces the index  | 
 | 830 | 	(top of stack). This is useful for cycling through a set of  | 
 | 831 | 	values. Note that indexing is zero based. So, if n=0 then you | 
 | 832 | 	get the second item on the stack. If n=1 you get the third, etc. | 
 | 833 | 	Note also that the index is replaced by the n'th value. </td> | 
 | 834 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 835 | <tr><td>SELECT</td> | 
 | 836 |     <td>SELECT</td> | 
 | 837 |     <td>m n X0..Xm Xm+1 .. Xn -- Xm</td> | 
 | 838 |     <td>This is like PICK but the list is removed and you need to specify | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 839 | 	both the index and the size of the list. Careful with this one, | 
 | 840 | 	the wrong value for n can blow away a huge amount of the stack.</td> | 
 | 841 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 842 | <tr><td>ROLL</td> | 
 | 843 |     <td>ROLL</td> | 
 | 844 |     <td>x0 x1 .. xn n -- x1 .. xn x0</td> | 
 | 845 |     <td><b>Not Implemented</b>. This one has been left as an exercise to | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 846 | 	the student. See <a href="#exercise">Exercise</a>. ROLL requires  | 
 | 847 |     a value, "n", to be on the top of the stack. This value specifies how  | 
 | 848 |     far into the stack to "roll". The n'th value is <em>moved</em> (not | 
 | 849 |     copied) from its location and replaces the "n" value on the top of the | 
 | 850 |     stack. In this way, all the values between "n" and x0 roll up the stack. | 
 | 851 |     The operation of ROLL is a generalized ROT.  The "n" value specifies  | 
 | 852 |     how much to rotate. That is, ROLL with n=1 is the same as ROT and  | 
 | 853 |     ROLL with n=2 is the same as ROT2.</td> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 854 | </tr> | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 855 | <tr><td colspan="4"><b>MEMORY OPERATORS</b></td></tr> | 
 | 856 | <tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 857 |     <td>Word</td> | 
 | 858 |     <td>Name</td> | 
 | 859 |     <td>Operation</td> | 
 | 860 |     <td>Description</td> | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 861 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 862 | <tr><td>MALLOC</td> | 
 | 863 |     <td>MALLOC</td> | 
 | 864 |     <td>w1 -- p</td> | 
 | 865 |     <td>One value is popped off the stack. The value is used as the size | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 866 | 	of a memory block to allocate. The size is in bytes, not words. | 
 | 867 |         The memory allocation is completed and the address of the memory | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 868 | 	block is pushed on to the stack.</td> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 869 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 870 | <tr><td>FREE</td> | 
 | 871 |     <td>FREE</td> | 
 | 872 |     <td>p -- </td> | 
 | 873 |     <td>One pointer value is popped off the stack. The value should be | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 874 | 	the address of a memory block created by the MALLOC operation. The | 
 | 875 | 	associated memory block is freed. Nothing is pushed back on the | 
 | 876 | 	stack. Many bugs can be created by attempting to FREE something | 
 | 877 | 	that isn't a pointer to a MALLOC allocated memory block. Make | 
 | 878 | 	sure you know what's on the stack.  One way to do this is with | 
 | 879 | 	the following idiom:<br/> | 
 | 880 | 	<code>64 MALLOC DUP DUP (use ptr) DUP (use ptr) ...  FREE</code> | 
 | 881 | 	<br/>This ensures that an extra copy of the pointer is placed on | 
 | 882 | 	the stack (for the FREE at the end) and that every use of the | 
 | 883 | 	pointer is preceded by a DUP to retain the copy for FREE.</td> | 
 | 884 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 885 | <tr><td>GET</td> | 
 | 886 |     <td>GET</td> | 
 | 887 |     <td>w1 p -- w2 p</td> | 
 | 888 |     <td>An integer index and a pointer to a memory block are popped of | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 889 | 	the block. The index is used to index one byte from the memory | 
 | 890 | 	block. That byte value is retained, the pointer is pushed again | 
 | 891 | 	and the retained value is pushed. Note that the pointer value | 
 | 892 | 	s essentially retained in its position so this doesn't count | 
 | 893 | 	as a "use ptr" in the FREE idiom.</td> | 
 | 894 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 895 | <tr><td>PUT</td> | 
 | 896 |     <td>PUT</td> | 
 | 897 |     <td>w1 w2 p -- p </td> | 
 | 898 |     <td>An integer value is popped of the stack. This is the value to | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 899 | 	be put into a memory block. Another integer value is popped of | 
 | 900 | 	the stack. This is the indexed byte in the memory block. A | 
 | 901 | 	pointer to the memory block is popped off the stack. The | 
 | 902 | 	first value (w1) is then converted to a byte and written | 
 | 903 | 	to the element of the memory block(p) at the index given | 
 | 904 | 	by the second value (w2). The pointer to the memory block is | 
 | 905 | 	pushed back on the stack so this doesn't count as a "use ptr" | 
 | 906 | 	in the FREE idiom.</td> | 
 | 907 | </tr> | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 908 | <tr><td colspan="4"><b>CONTROL FLOW OPERATORS</b></td></tr> | 
 | 909 | <tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 910 |     <td>Word</td> | 
 | 911 |     <td>Name</td> | 
 | 912 |     <td>Operation</td> | 
 | 913 |     <td>Description</td> | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 914 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 915 | <tr><td>RETURN</td> | 
 | 916 |     <td>RETURN</td> | 
 | 917 |     <td> --  </td> | 
 | 918 |     <td>The currently executing definition returns immediately to its caller. | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 919 | 	Note that there is an implicit <code>RETURN</code> at the end of each | 
 | 920 | 	definition, logically located at the semi-colon. The sequence  | 
 | 921 | 	<code>RETURN ;</code>  is valid but redundant.</td> | 
 | 922 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 923 | <tr><td>EXIT</td> | 
 | 924 |     <td>EXIT</td> | 
 | 925 |     <td>w1 -- </td> | 
 | 926 |     <td>A return value for the program is popped off the stack. The program is | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 927 | 	then immediately terminated. This is normally an abnormal exit from the | 
 | 928 | 	program. For a normal exit (when <code>MAIN</code> finishes), the exit | 
 | 929 | 	code will always be zero in accordance with UNIX conventions.</td> | 
 | 930 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 931 | <tr><td>RECURSE</td> | 
 | 932 |     <td>RECURSE</td> | 
 | 933 |     <td> -- </td> | 
 | 934 |     <td>The currently executed definition is called again. This operation is  | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 935 | 	needed since the definition of a word doesn't exist until the semi colon | 
 | 936 | 	is reacher. Attempting something like:<br/> | 
 | 937 | 	<code> : recurser recurser ; </code><br/> will yield and error saying that  | 
 | 938 | 	"recurser" is not defined yet. To accomplish the same thing, change this | 
 | 939 | 	to:<br/> | 
 | 940 | 	<code> : recurser RECURSE ; </code></td> | 
 | 941 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 942 | <tr><td>IF (words...) ENDIF</td> | 
 | 943 |     <td>IF (words...) ENDIF</td> | 
 | 944 |     <td>b -- </td> | 
 | 945 |     <td>A boolean value is popped of the stack. If it is non-zero then the "words..."  | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 946 | 	are executed. Otherwise, execution continues immediately following the ENDIF.</td> | 
 | 947 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 948 | <tr><td>IF (words...) ELSE (words...) ENDIF</td> | 
 | 949 |     <td>IF (words...) ELSE (words...) ENDIF</td> | 
 | 950 |     <td>b -- </td> | 
 | 951 |     <td>A boolean value is popped of the stack. If it is non-zero then the "words..." | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 952 | 	between IF and ELSE are executed. Otherwise the words between ELSE and ENDIF are | 
 | 953 | 	executed. In either case, after the (words....) have executed, execution continues | 
 | 954 |         immediately following the ENDIF. </td> | 
 | 955 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 956 | <tr><td>WHILE (words...) END</td> | 
 | 957 |     <td>WHILE (words...) END</td> | 
 | 958 |     <td>b -- b </td> | 
 | 959 |     <td>The boolean value on the top of the stack is examined. If it is non-zero then the  | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 960 | 	"words..." between WHILE and END are executed. Execution then begins again at the WHILE where another | 
 | 961 | 	boolean is popped off the stack. To prevent this operation from eating up the entire | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 962 | 	stack, you should push on to the stack (just before the END) a boolean value that indicates | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 963 | 	whether to terminate. Note that since booleans and integers can be coerced you can | 
 | 964 | 	use the following "for loop" idiom:<br/> | 
 | 965 | 	<code>(push count) WHILE (words...) -- END</code><br/> | 
 | 966 | 	For example:<br/> | 
 | 967 | 	<code>10 WHILE DUP >d -- END</code><br/> | 
 | 968 | 	This will print the numbers from 10 down to 1. 10 is pushed on the stack. Since that is | 
 | 969 | 	non-zero, the while loop is entered. The top of the stack (10) is duplicated and then | 
 | 970 | 	printed out with >d. The top of the stack is decremented, yielding 9 and control is | 
 | 971 | 	transfered back to the WHILE keyword. The process starts all over again and repeats until | 
 | 972 | 	the top of stack is decremented to 0 at which the WHILE test fails and control is | 
 | 973 | 	transfered to the word after the END.</td> | 
 | 974 | </tr> | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 975 | <tr><td colspan="4"><b>INPUT & OUTPUT OPERATORS</b></td></tr> | 
 | 976 | <tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 977 |     <td>Word</td> | 
 | 978 |     <td>Name</td> | 
 | 979 |     <td>Operation</td> | 
 | 980 |     <td>Description</td> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 981 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 982 | <tr><td>SPACE</td> | 
 | 983 |     <td>SPACE</td> | 
 | 984 |     <td> --  </td> | 
 | 985 |     <td>A space character is put out. There is no stack effect.</td> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 986 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 987 | <tr><td>TAB</td> | 
 | 988 |     <td>TAB</td> | 
 | 989 |     <td> --  </td> | 
 | 990 |     <td>A tab character is put out. There is no stack effect.</td> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 991 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 992 | <tr><td>CR</td> | 
 | 993 |     <td>CR</td> | 
 | 994 |     <td> --  </td> | 
 | 995 |     <td>A carriage return character is put out. There is no stack effect.</td> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 996 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 997 | <tr><td>>s</td> | 
 | 998 |     <td>OUT_STR</td> | 
 | 999 |     <td> -- </td> | 
 | 1000 |     <td>A string pointer is popped from the stack. It is put out.</td> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1001 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 1002 | <tr><td>>d</td> | 
 | 1003 |     <td>OUT_STR</td> | 
 | 1004 |     <td> -- </td> | 
 | 1005 |     <td>A value is popped from the stack. It is put out as a decimal | 
 | 1006 |     integer.</td> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1007 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 1008 | <tr><td>>c</td> | 
 | 1009 |     <td>OUT_CHR</td> | 
 | 1010 |     <td> -- </td> | 
 | 1011 |     <td>A value is popped from the stack. It is put out as an ASCII | 
 | 1012 |     character.</td> | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 1013 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 1014 | <tr><td><s</td> | 
 | 1015 |     <td>IN_STR</td> | 
 | 1016 |     <td> -- s </td> | 
 | 1017 |     <td>A string is read from the input via the scanf(3) format string " %as". | 
 | 1018 |     The resulting string is pushed on to the stack.</td> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1019 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 1020 | <tr><td><d</td> | 
 | 1021 |     <td>IN_STR</td> | 
 | 1022 |     <td> -- w </td> | 
 | 1023 |     <td>An integer is read from the input via the scanf(3) format string " %d". | 
 | 1024 |     The resulting value is pushed on to the stack</td> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1025 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 1026 | <tr><td><c</td> | 
 | 1027 |     <td>IN_CHR</td> | 
 | 1028 |     <td> -- w </td> | 
 | 1029 |     <td>A single character is read from the input via the scanf(3) format string | 
 | 1030 |     " %c". The value is converted to an integer and pushed on to the stack.</td> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1031 | </tr> | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 1032 | <tr><td>DUMP</td> | 
 | 1033 |     <td>DUMP</td> | 
 | 1034 |     <td> -- </td> | 
 | 1035 |     <td>The stack contents are dumped to standard output. This is useful for | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1036 | 	debugging your definitions. Put DUMP at the beginning and end of a definition | 
 | 1037 | 	to see instantly the net effect of the definition.</td> | 
 | 1038 | </tr> | 
 | 1039 | </table> | 
| Misha Brukman | fd90f88 | 2004-05-13 00:37:23 +0000 | [diff] [blame] | 1040 |  | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1041 | </div> | 
 | 1042 | <!-- ======================================================================= --> | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 1043 | <div class="doc_section"> <a name="example">Prime: A Complete Example</a></div> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1044 | <div class="doc_text"> | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 1045 | <p>The following fully documented program highlights many features of both | 
 | 1046 | the Stacker language and what is possible with LLVM. The program has two modes | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 1047 | of operation. If you provide numeric arguments to the program, it checks to see | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 1048 | if those arguments are prime numbers and prints out the results. Without any  | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 1049 | arguments, the program prints out any prime numbers it finds between 1 and one  | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 1050 | million (there's a lot of them!). The source code comments below tell the  | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 1051 | remainder of the story. | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1052 | </p> | 
 | 1053 | </div> | 
 | 1054 | <div class="doc_text"> | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 1055 | <pre><code> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1056 | ################################################################################ | 
 | 1057 | # | 
 | 1058 | # Brute force prime number generator | 
 | 1059 | # | 
 | 1060 | # This program is written in classic Stacker style, that being the style of a  | 
 | 1061 | # stack. Start at the bottom and read your way up ! | 
 | 1062 | # | 
 | 1063 | # Reid Spencer - Nov 2003  | 
 | 1064 | ################################################################################ | 
 | 1065 | # Utility definitions | 
 | 1066 | ################################################################################ | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 1067 | : print >d CR ; | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1068 | : it_is_a_prime TRUE ; | 
 | 1069 | : it_is_not_a_prime FALSE ; | 
 | 1070 | : continue_loop TRUE ; | 
 | 1071 | : exit_loop FALSE; | 
 | 1072 |      | 
 | 1073 | ################################################################################ | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 1074 | # This definition tries an actual division of a candidate prime number. It | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1075 | # determines whether the division loop on this candidate should continue or | 
 | 1076 | # not. | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 1077 | # STACK<: | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1078 | #    div - the divisor to try | 
 | 1079 | #    p   - the prime number we are working on | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 1080 | # STACK>: | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1081 | #    cont - should we continue the loop ? | 
 | 1082 | #    div - the next divisor to try | 
 | 1083 | #    p   - the prime number we are working on | 
 | 1084 | ################################################################################ | 
 | 1085 | : try_dividing | 
 | 1086 |     DUP2			( save div and p ) | 
 | 1087 |     SWAP			( swap to put divisor second on stack) | 
 | 1088 |     MOD 0 = 			( get remainder after division and test for 0 ) | 
 | 1089 |     IF  | 
 | 1090 |         exit_loop		( remainder = 0, time to exit ) | 
 | 1091 |     ELSE | 
 | 1092 |         continue_loop		( remainder != 0, keep going ) | 
 | 1093 |     ENDIF | 
 | 1094 | ; | 
 | 1095 |  | 
 | 1096 | ################################################################################ | 
 | 1097 | # This function tries one divisor by calling try_dividing. But, before doing | 
 | 1098 | # that it checks to see if the value is 1. If it is, it does not bother with | 
 | 1099 | # the division because prime numbers are allowed to be divided by one. The | 
 | 1100 | # top stack value (cont) is set to determine if the loop should continue on | 
 | 1101 | # this prime number or not. | 
 | 1102 | # STACK<: | 
 | 1103 | #    cont - should we continue the loop (ignored)? | 
 | 1104 | #    div - the divisor to try | 
 | 1105 | #    p   - the prime number we are working on | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 1106 | # STACK>: | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1107 | #    cont - should we continue the loop ? | 
 | 1108 | #    div - the next divisor to try | 
 | 1109 | #    p   - the prime number we are working on | 
 | 1110 | ################################################################################ | 
 | 1111 | : try_one_divisor | 
 | 1112 |     DROP			( drop the loop continuation ) | 
 | 1113 |     DUP				( save the divisor ) | 
 | 1114 |     1 = IF			( see if divisor is == 1 ) | 
 | 1115 |         exit_loop		( no point dividing by 1 ) | 
 | 1116 |     ELSE | 
 | 1117 |         try_dividing		( have to keep going ) | 
 | 1118 |     ENDIF | 
 | 1119 |     SWAP			( get divisor on top ) | 
 | 1120 |     --				( decrement it ) | 
 | 1121 |     SWAP			( put loop continuation back on top ) | 
 | 1122 | ; | 
 | 1123 |  | 
 | 1124 | ################################################################################ | 
 | 1125 | # The number on the stack (p) is a candidate prime number that we must test to  | 
 | 1126 | # determine if it really is a prime number. To do this, we divide it by every  | 
 | 1127 | # number from one p-1 to 1. The division is handled in the try_one_divisor  | 
 | 1128 | # definition which returns a loop continuation value (which we also seed with | 
 | 1129 | # the value 1).  After the loop, we check the divisor. If it decremented all | 
 | 1130 | # the way to zero then we found a prime, otherwise we did not find one. | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 1131 | # STACK<: | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1132 | #   p - the prime number to check | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 1133 | # STACK>: | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 1134 | #   yn - boolean indicating if its a prime or not | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1135 | #   p - the prime number checked | 
 | 1136 | ################################################################################ | 
 | 1137 | : try_harder | 
 | 1138 |     DUP 			( duplicate to get divisor value ) ) | 
 | 1139 |     --				( first divisor is one less than p ) | 
 | 1140 |     1				( continue the loop ) | 
 | 1141 |     WHILE | 
 | 1142 |        try_one_divisor		( see if its prime ) | 
 | 1143 |     END | 
 | 1144 |     DROP			( drop the continuation value ) | 
 | 1145 |     0 = IF			( test for divisor == 1 ) | 
 | 1146 |        it_is_a_prime		( we found one ) | 
 | 1147 |     ELSE | 
 | 1148 |        it_is_not_a_prime	( nope, this one is not a prime ) | 
 | 1149 |     ENDIF | 
 | 1150 | ; | 
 | 1151 |  | 
 | 1152 | ################################################################################ | 
 | 1153 | # This definition determines if the number on the top of the stack is a prime  | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 1154 | # or not. It does this by testing if the value is degenerate (<= 3) and  | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1155 | # responding with yes, its a prime. Otherwise, it calls try_harder to actually  | 
 | 1156 | # make some calculations to determine its primeness. | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 1157 | # STACK<: | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1158 | #    p - the prime number to check | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 1159 | # STACK>: | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1160 | #    yn - boolean indicating if its a prime or not | 
 | 1161 | #    p  - the prime number checked | 
 | 1162 | ################################################################################ | 
 | 1163 | : is_prime  | 
 | 1164 |     DUP 			( save the prime number ) | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 1165 |     3 >= IF			( see if its <= 3 ) | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1166 |         it_is_a_prime  		( its <= 3 just indicate its prime ) | 
 | 1167 |     ELSE  | 
 | 1168 |         try_harder 		( have to do a little more work ) | 
 | 1169 |     ENDIF  | 
 | 1170 | ; | 
 | 1171 |  | 
 | 1172 | ################################################################################ | 
 | 1173 | # This definition is called when it is time to exit the program, after we have  | 
 | 1174 | # found a sufficiently large number of primes. | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 1175 | # STACK<: ignored | 
 | 1176 | # STACK>: exits | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1177 | ################################################################################ | 
 | 1178 | : done  | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 1179 |     "Finished" >s CR 		( say we are finished ) | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1180 |     0 EXIT 			( exit nicely ) | 
 | 1181 | ; | 
 | 1182 |  | 
 | 1183 | ################################################################################ | 
 | 1184 | # This definition checks to see if the candidate is greater than the limit. If  | 
 | 1185 | # it is, it terminates the program by calling done. Otherwise, it increments  | 
 | 1186 | # the value and calls is_prime to determine if the candidate is a prime or not.  | 
 | 1187 | # If it is a prime, it prints it. Note that the boolean result from is_prime is | 
 | 1188 | # gobbled by the following IF which returns the stack to just contining the | 
 | 1189 | # prime number just considered. | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 1190 | # STACK<:  | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1191 | #    p - one less than the prime number to consider | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 1192 | # STAC>K | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1193 | #    p+1 - the prime number considered | 
 | 1194 | ################################################################################ | 
 | 1195 | : consider_prime  | 
 | 1196 |     DUP 			( save the prime number to consider ) | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 1197 |     1000000 < IF 		( check to see if we are done yet ) | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1198 |         done 			( we are done, call "done" ) | 
 | 1199 |     ENDIF  | 
 | 1200 |     ++ 				( increment to next prime number ) | 
 | 1201 |     is_prime 			( see if it is a prime ) | 
 | 1202 |     IF  | 
 | 1203 |        print 			( it is, print it ) | 
 | 1204 |     ENDIF  | 
 | 1205 | ; | 
 | 1206 |  | 
 | 1207 | ################################################################################ | 
 | 1208 | # This definition starts at one, prints it out and continues into a loop calling | 
 | 1209 | # consider_prime on each iteration. The prime number candidate we are looking at | 
 | 1210 | # is incremented by consider_prime. | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 1211 | # STACK<: empty | 
 | 1212 | # STACK>: empty | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1213 | ################################################################################ | 
 | 1214 | : find_primes  | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 1215 |     "Prime Numbers: " >s CR	( say hello ) | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1216 |     DROP			( get rid of that pesky string ) | 
 | 1217 |     1 				( stoke the fires ) | 
 | 1218 |     print			( print the first one, we know its prime ) | 
 | 1219 |     WHILE  			( loop while the prime to consider is non zero ) | 
 | 1220 |         consider_prime 		( consider one prime number ) | 
 | 1221 |     END  | 
 | 1222 | ;  | 
 | 1223 |  | 
 | 1224 | ################################################################################ | 
 | 1225 | # | 
 | 1226 | ################################################################################ | 
 | 1227 | : say_yes | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 1228 |     >d				( Print the prime number ) | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1229 |     " is prime."		( push string to output ) | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 1230 |     >s				( output it ) | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1231 |     CR				( print carriage return ) | 
 | 1232 |     DROP			( pop string ) | 
 | 1233 | ; | 
 | 1234 |  | 
 | 1235 | : say_no | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 1236 |     >d				( Print the prime number ) | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1237 |     " is NOT prime."		( push string to put out ) | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 1238 |     >s				( put out the string ) | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1239 |     CR				( print carriage return ) | 
 | 1240 |     DROP			( pop string ) | 
 | 1241 | ; | 
 | 1242 |  | 
 | 1243 | ################################################################################ | 
 | 1244 | # This definition processes a single command line argument and determines if it | 
 | 1245 | # is a prime number or not. | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 1246 | # STACK<: | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1247 | #    n - number of arguments | 
 | 1248 | #    arg1 - the prime numbers to examine | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 1249 | # STACK>: | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1250 | #    n-1 - one less than number of arguments | 
 | 1251 | #    arg2 - we processed one argument | 
 | 1252 | ################################################################################ | 
 | 1253 | : do_one_argument | 
 | 1254 |     --				( decrement loop counter ) | 
 | 1255 |     SWAP			( get the argument value  ) | 
 | 1256 |     is_prime IF			( determine if its prime ) | 
 | 1257 |         say_yes			( uhuh ) | 
 | 1258 |     ELSE | 
 | 1259 |         say_no			( nope ) | 
 | 1260 |     ENDIF | 
 | 1261 |     DROP			( done with that argument ) | 
 | 1262 | ; | 
 | 1263 |  | 
 | 1264 | ################################################################################ | 
 | 1265 | # The MAIN program just prints a banner and processes its arguments. | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 1266 | # STACK<: | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1267 | #    n - number of arguments | 
 | 1268 | #    ... - the arguments | 
 | 1269 | ################################################################################ | 
 | 1270 | : process_arguments | 
 | 1271 |     WHILE			( while there are more arguments ) | 
 | 1272 |        do_one_argument		( process one argument ) | 
 | 1273 |     END | 
 | 1274 | ; | 
 | 1275 |      | 
 | 1276 | ################################################################################ | 
 | 1277 | # The MAIN program just prints a banner and processes its arguments. | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 1278 | # STACK<: arguments | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1279 | ################################################################################ | 
 | 1280 | : MAIN  | 
 | 1281 |     NIP				( get rid of the program name ) | 
 | 1282 |     --				( reduce number of arguments ) | 
 | 1283 |     DUP				( save the arg counter ) | 
| Misha Brukman | f39d5d6 | 2004-05-13 00:24:43 +0000 | [diff] [blame] | 1284 |     1 <= IF			( See if we got an argument ) | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1285 |         process_arguments	( tell user if they are prime ) | 
 | 1286 |     ELSE | 
 | 1287 |         find_primes		( see how many we can find ) | 
 | 1288 |     ENDIF | 
 | 1289 |     0				( push return code ) | 
 | 1290 | ; | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1291 | </code> | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 1292 | </pre> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1293 | </div> | 
 | 1294 | <!-- ======================================================================= --> | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 1295 | <div class="doc_section"> <a name="internal">Internals</a></div> | 
 | 1296 | <div class="doc_text"> | 
 | 1297 |  <p><b>This section is under construction.</b> | 
 | 1298 |  <p>In the mean time, you can always read the code! It has comments!</p> | 
 | 1299 | </div> | 
 | 1300 | <!-- ======================================================================= --> | 
 | 1301 | <div class="doc_subsection"> <a name="directory">Directory Structure</a></div> | 
 | 1302 | <div class="doc_text"> | 
 | 1303 | <p>The source code, test programs, and sample programs can all be found | 
 | 1304 | under the LLVM "projects" directory. You will need to obtain the LLVM sources | 
 | 1305 | to find it (either via anonymous CVS or a tarball. See the  | 
 | 1306 | <a href="GettingStarted.html">Getting Started</a> document).</p> | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 1307 | <p>Under the "projects" directory there is a directory named "Stacker". That | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 1308 | directory contains everything, as follows:</p> | 
 | 1309 | <ul> | 
 | 1310 |     <li><em>lib</em> - contains most of the source code | 
 | 1311 |     <ul> | 
 | 1312 | 	<li><em>lib/compiler</em> - contains the compiler library | 
 | 1313 | 	<li><em>lib/runtime</em> - contains the runtime library | 
 | 1314 |     </ul></li> | 
 | 1315 |     <li><em>test</em> - contains the test programs</li> | 
 | 1316 |     <li><em>tools</em> - contains the Stacker compiler main program, stkrc | 
 | 1317 |     <ul> | 
 | 1318 | 	<li><em>lib/stkrc</em> - contains the Stacker compiler main program | 
 | 1319 |     </ul</li> | 
 | 1320 |     <li><em>sample</em> - contains the sample programs</li> | 
 | 1321 | </ul> | 
 | 1322 | </div> | 
 | 1323 | <!-- ======================================================================= --> | 
 | 1324 | <div class="doc_subsection"><a name="lexer"></a>The Lexer</div> | 
 | 1325 | <div class="doc_text"> | 
 | 1326 | <p>See projects/Stacker/lib/compiler/Lexer.l</p> | 
| Misha Brukman | 3669299 | 2004-05-12 19:52:00 +0000 | [diff] [blame] | 1327 | </div> | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 1328 | <!-- ======================================================================= --> | 
 | 1329 | <div class="doc_subsection"><a name="parser"></a>The Parser</div> | 
 | 1330 | <div class="doc_text"> | 
 | 1331 | <p>See projects/Stacker/lib/compiler/StackerParser.y</p> | 
| Misha Brukman | 3669299 | 2004-05-12 19:52:00 +0000 | [diff] [blame] | 1332 | </div> | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 1333 | <!-- ======================================================================= --> | 
 | 1334 | <div class="doc_subsection"><a name="compiler"></a>The Compiler</div> | 
 | 1335 | <div class="doc_text"> | 
 | 1336 | <p>See projects/Stacker/lib/compiler/StackerCompiler.cpp</p> | 
| Misha Brukman | 3669299 | 2004-05-12 19:52:00 +0000 | [diff] [blame] | 1337 | </div> | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 1338 | <!-- ======================================================================= --> | 
 | 1339 | <div class="doc_subsection"><a name="runtime"></a>The Runtime</div> | 
 | 1340 | <div class="doc_text"> | 
 | 1341 | <p>See projects/Stacker/lib/runtime/stacker_rt.c</p> | 
| Misha Brukman | 3669299 | 2004-05-12 19:52:00 +0000 | [diff] [blame] | 1342 | </div> | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 1343 | <!-- ======================================================================= --> | 
 | 1344 | <div class="doc_subsection"><a name="driver"></a>Compiler Driver</div> | 
 | 1345 | <div class="doc_text"> | 
 | 1346 | <p>See projects/Stacker/tools/stkrc/stkrc.cpp</p> | 
| Misha Brukman | 3669299 | 2004-05-12 19:52:00 +0000 | [diff] [blame] | 1347 | </div> | 
| Brian Gaeke | 07e89e4 | 2003-11-24 17:03:38 +0000 | [diff] [blame] | 1348 | <!-- ======================================================================= --> | 
 | 1349 | <div class="doc_subsection"><a name="tests"></a>Test Programs</div> | 
 | 1350 | <div class="doc_text"> | 
 | 1351 | <p>See projects/Stacker/test/*.st</p> | 
| Misha Brukman | 3669299 | 2004-05-12 19:52:00 +0000 | [diff] [blame] | 1352 | </div> | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1353 | <!-- ======================================================================= --> | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 1354 | <div class="doc_subsection"> <a name="exercise">Exercise</a></div> | 
 | 1355 | <div class="doc_text"> | 
 | 1356 | <p>As you may have noted from a careful inspection of the Built-In word | 
 | 1357 | definitions, the ROLL word is not implemented. This word was left out of  | 
 | 1358 | Stacker on purpose so that it can be an exercise for the student.  The exercise  | 
 | 1359 | is to implement the ROLL functionality (in your own workspace) and build a test  | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 1360 | program for it.  If you can implement ROLL, you understand Stacker and probably  | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 1361 | a fair amount about LLVM since this is one of the more complicated Stacker  | 
 | 1362 | operations. The work will almost be completely limited to the  | 
 | 1363 | <a href="#compiler">compiler</a>.   | 
 | 1364 | <p>The ROLL word is already recognized by both the lexer and parser but ignored  | 
 | 1365 | by the compiler. That means you don't have to futz around with figuring out how | 
 | 1366 | to get the keyword recognized. It already is.  The part of the compiler that | 
 | 1367 | you need to implement is the <code>ROLL</code> case in the  | 
| Misha Brukman | fe22af6 | 2004-04-16 16:20:07 +0000 | [diff] [blame] | 1368 | <code>StackerCompiler::handle_word(int)</code> method.</p> See the | 
 | 1369 | implementations of PICK and SELECT in the same method to get some hints about | 
 | 1370 | how to complete this exercise.<p> | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 1371 | <p>Good luck!</p> | 
 | 1372 | </div> | 
 | 1373 | <!-- ======================================================================= --> | 
| Misha Brukman | fe22af6 | 2004-04-16 16:20:07 +0000 | [diff] [blame] | 1374 | <div class="doc_subsection"><a name="todo">Things Remaining To Be Done</a></div> | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 1375 | <div class="doc_text"> | 
 | 1376 | <p>The initial implementation of Stacker has several deficiencies. If you're | 
 | 1377 | interested, here are some things that could be implemented better:</p> | 
 | 1378 | <ol> | 
 | 1379 |     <li>Write an LLVM pass to compute the correct stack depth needed by the | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 1380 |     program. Currently the stack is set to a fixed number which means programs | 
 | 1381 |     with large numbers of definitions might fail.</li> | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 1382 |     <li>Write an LLVM pass to optimize the use of the global stack. The code | 
 | 1383 |     emitted currently is somewhat wasteful. It gets cleaned up a lot by existing | 
 | 1384 |     passes but more could be done.</li> | 
 | 1385 |     <li>Add -O -O1 -O2 and -O3 optimization switches to the compiler driver to | 
| John Criswell | d000e1d | 2003-12-18 16:43:17 +0000 | [diff] [blame] | 1386 |     allow LLVM optimization without using "opt."</li> | 
| Misha Brukman | fe22af6 | 2004-04-16 16:20:07 +0000 | [diff] [blame] | 1387 |     <li>Make the compiler driver use the LLVM linking facilities (with IPO) | 
 | 1388 |     before depending on GCC to do the final link.</li> | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 1389 |     <li>Clean up parsing. It doesn't handle errors very well.</li> | 
 | 1390 |     <li>Rearrange the StackerCompiler.cpp code to make better use of inserting | 
 | 1391 |     instructions before a block's terminating instruction. I didn't figure this | 
| Misha Brukman | fe22af6 | 2004-04-16 16:20:07 +0000 | [diff] [blame] | 1392 |     technique out until I was nearly done with LLVM. As it is, its a bad example | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 1393 |     of how to insert instructions!</li> | 
 | 1394 |     <li>Provide for I/O to arbitrary files instead of just stdin/stdout.</li> | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 1395 |     <li>Write additional built-in words; with inspiration from FORTH</li> | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 1396 |     <li>Write additional sample Stacker programs.</li> | 
| Chris Lattner | 45ab10c | 2003-12-18 06:40:22 +0000 | [diff] [blame] | 1397 |     <li>Add your own compiler writing experiences and tips in the  | 
 | 1398 |     <a href="#lessons">Lessons I Learned About LLVM</a> section.</li> | 
| Chris Lattner | e46d601 | 2003-11-25 01:35:06 +0000 | [diff] [blame] | 1399 | </ol> | 
 | 1400 | </div> | 
| Misha Brukman | 3669299 | 2004-05-12 19:52:00 +0000 | [diff] [blame] | 1401 |  | 
 | 1402 | <!-- *********************************************************************** --> | 
 | 1403 |  | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1404 | <hr> | 
| Misha Brukman | 3669299 | 2004-05-12 19:52:00 +0000 | [diff] [blame] | 1405 | <address> | 
 | 1406 |   <a href="http://jigsaw.w3.org/css-validator/check/referer"><img | 
 | 1407 |   src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"></a> | 
 | 1408 |   <a href="http://validator.w3.org/check/referer"><img | 
 | 1409 |   src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!"></a> | 
 | 1410 |  | 
 | 1411 |   <a href="mailto:rspencer@x10sys.com">Reid Spencer</a><br> | 
 | 1412 |   <a href="http://llvm.cs.uiuc.edu">LLVM Compiler Infrastructure</a><br> | 
 | 1413 |   Last modified: $Date$ | 
 | 1414 | </address> | 
 | 1415 |  | 
| Brian Gaeke | 9018148 | 2003-11-24 02:52:51 +0000 | [diff] [blame] | 1416 | </body> | 
 | 1417 | </html> |