blob: 7d403d9621e104477d97297c7a34cd29dc66d31b [file] [log] [blame]
Chris Lattner2e902042007-10-22 07:01:42 +00001<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
2 "http://www.w3.org/TR/html4/strict.dtd">
3
4<html>
5<head>
6 <title>Kaleidoscope: Implementing code generation to LLVM IR</title>
7 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
8 <meta name="author" content="Chris Lattner">
9 <link rel="stylesheet" href="../llvm.css" type="text/css">
10</head>
11
12<body>
13
14<div class="doc_title">Kaleidoscope: Code generation to LLVM IR</div>
15
16<div class="doc_author">
17 <p>Written by <a href="mailto:sabre@nondot.org">Chris Lattner</a></p>
18</div>
19
20<!-- *********************************************************************** -->
21<div class="doc_section"><a name="intro">Part 3 Introduction</a></div>
22<!-- *********************************************************************** -->
23
24<div class="doc_text">
25
26<p>Welcome to part 3 of the "<a href="index.html">Implementing a language with
27LLVM</a>" tutorial. This chapter shows you how to transform the <a
28href="LangImpl2.html">Abstract Syntax Tree built in Chapter 2</a> into LLVM IR.
29This will teach you a little bit about how LLVM does things, as well as
30demonstrate how easy it is to use. It's much more work to build a lexer and
31parser than it is to generate LLVM IR code.
32</p>
33
34</div>
35
36<!-- *********************************************************************** -->
37<div class="doc_section"><a name="basics">Code Generation setup</a></div>
38<!-- *********************************************************************** -->
39
40<div class="doc_text">
41
42<p>
43In order to generate LLVM IR, we want some simple setup to get started. First,
44we define virtual codegen methods in each AST class:</p>
45
46<div class="doc_code">
47<pre>
48/// ExprAST - Base class for all expression nodes.
49class ExprAST {
50public:
51 virtual ~ExprAST() {}
52 virtual Value *Codegen() = 0;
53};
54
55/// NumberExprAST - Expression class for numeric literals like "1.0".
56class NumberExprAST : public ExprAST {
57 double Val;
58public:
59 NumberExprAST(double val) : Val(val) {}
60 virtual Value *Codegen();
61};
62...
63</pre>
64</div>
65
66<p>"Value" is the class used to represent a "register" in LLVM. The Codegen()
67method says to emit IR for that AST node and all things it depends on. The
68second thing we want is an "Error" method like we used for parser, which will
69be used to report errors found during code generation (for example, use of an
70undeclared parameter):</p>
71
72<div class="doc_code">
73<pre>
74Value *ErrorV(const char *Str) { Error(Str); return 0; }
75
76static Module *TheModule;
77static LLVMBuilder Builder;
78static std::map&lt;std::string, Value*&gt; NamedValues;
79</pre>
80</div>
81
82<p>The static variables will be used during code generation. <tt>TheModule</tt>
83is the LLVM construct that contains all of the functions and global variables in
84a chunk of code. In many ways, it is the top-level structure that the LLVM IR
85uses to contain code.</p>
86
87<p>The <tt>Builder</tt> object is a helper object that makes it easy to generate
88LLVM instructions. The <tt>Builder</tt> keeps track of the current place to
89insert instructions and has methods to create new instructions.</p>
90
91<p>The <tt>NamedValues</tt> map keeps track of which values are defined in the
92current scope and what their LLVM representation is. In this form of
93Kaleidoscope, the only things that can be referenced are function parameters.
94As such, function parameters will be in this map when generating code for their
95function body.</p>
96
97<p>
98With these basics in place, we can start talking about how to generate code for
99each expression. Note that this assumes that the <tt>Builder</tt> has been set
100up to generate code <em>into</em> something. For now, we'll assume that this
101has already been done, and we'll just use it to emit code.
102</p>
103
104</div>
105
106<!-- *********************************************************************** -->
107<div class="doc_section"><a name="exprs">Expression Code Generation</a></div>
108<!-- *********************************************************************** -->
109
110<div class="doc_text">
111
112<p>Generating LLVM code for expression nodes is very straight-forward: less
113than 45 lines of commented code for all four of our expression nodes. First,
114we'll do numeric literals:</p>
115
116<div class="doc_code">
117<pre>
118Value *NumberExprAST::Codegen() {
119 return ConstantFP::get(Type::DoubleTy, APFloat(Val));
120}
121</pre>
122</div>
123
124<p>In the LLVM IR, numeric constants are represented with the ConstantFP class,
125which holds the numeric value in an APFloat internally (APFloat has the
126capability of holding floating point constants of arbitrary precision). This
127code basically just creates and returns a ConstantFP. Note that in the LLVM IR
128that constants are all uniqued together and shared. For this reason, the API
129uses "the foo::get(...)" idiom instead of a "create" method or "new foo".</p>
130
131<div class="doc_code">
132<pre>
133Value *VariableExprAST::Codegen() {
134 // Look this variable up in the function.
135 Value *V = NamedValues[Name];
136 return V ? V : ErrorV("Unknown variable name");
137}
138</pre>
139</div>
140
141<p>References to variables is also quite simple here. In our system, we assume
142that the variable has already been emited somewhere and its value is available.
143In practice, the only values in the NamedValues map will be arguments. This
144code simply checks to see that the specified name is in the map (if not, an
145unknown variable is being referenced) and returns the value for it.</p>
146
147<div class="doc_code">
148<pre>
149Value *BinaryExprAST::Codegen() {
150 Value *L = LHS-&gt;Codegen();
151 Value *R = RHS-&gt;Codegen();
152 if (L == 0 || R == 0) return 0;
153
154 switch (Op) {
155 case '+': return Builder.CreateAdd(L, R, "addtmp");
156 case '-': return Builder.CreateSub(L, R, "subtmp");
157 case '*': return Builder.CreateMul(L, R, "multmp");
158 case '&lt;':
159 L = Builder.CreateFCmpULT(L, R, "multmp");
160 // Convert bool 0/1 to double 0.0 or 1.0
161 return Builder.CreateUIToFP(L, Type::DoubleTy, "booltmp");
162 default: return ErrorV("invalid binary operator");
163 }
164}
165</pre>
166</div>
167
168
169
170<div class="doc_code">
171<pre>
172Value *CallExprAST::Codegen() {
173 // Look up the name in the global module table.
174 Function *CalleeF = TheModule-&gt;getFunction(Callee);
175 if (CalleeF == 0)
176 return ErrorV("Unknown function referenced");
177
178 // If argument mismatch error.
179 if (CalleeF-&gt;arg_size() != Args.size())
180 return ErrorV("Incorrect # arguments passed");
181
182 std::vector&lt;Value*&gt; ArgsV;
183 for (unsigned i = 0, e = Args.size(); i != e; ++i) {
184 ArgsV.push_back(Args[i]-&gt;Codegen());
185 if (ArgsV.back() == 0) return 0;
186 }
187
188 return Builder.CreateCall(CalleeF, ArgsV.begin(), ArgsV.end(), "calltmp");
189}
190</pre>
191</div>
192
193<h1> more todo</h1>
194
195</div>
196
197<!-- *********************************************************************** -->
198<div class="doc_section"><a name="code">Conclusions and the Full Code</a></div>
199<!-- *********************************************************************** -->
200
201<div class="doc_text">
202
203<div class="doc_code">
204<pre>
205// To build this:
206// g++ -g toy.cpp `llvm-config --cppflags` `llvm-config --ldflags` \
207// `llvm-config --libs core` -I ~/llvm/include/
208// ./a.out
209// See example below.
210
211#include "llvm/DerivedTypes.h"
212#include "llvm/Module.h"
213#include "llvm/Support/LLVMBuilder.h"
214#include &lt;cstdio&gt;
215#include &lt;string&gt;
216#include &lt;map&gt;
217#include &lt;vector&gt;
218using namespace llvm;
219
220//===----------------------------------------------------------------------===//
221// Lexer
222//===----------------------------------------------------------------------===//
223
224// The lexer returns tokens [0-255] if it is an unknown character, otherwise one
225// of these for known things.
226enum Token {
227 tok_eof = -1,
228
229 // commands
230 tok_def = -2, tok_extern = -3,
231
232 // primary
233 tok_identifier = -4, tok_number = -5,
234};
235
236static std::string IdentifierStr; // Filled in if tok_identifier
237static double NumVal; // Filled in if tok_number
238
239/// gettok - Return the next token from standard input.
240static int gettok() {
241 static int LastChar = ' ';
242
243 // Skip any whitespace.
244 while (isspace(LastChar))
245 LastChar = getchar();
246
247 if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]*
248 IdentifierStr = LastChar;
249 while (isalnum((LastChar = getchar())))
250 IdentifierStr += LastChar;
251
252 if (IdentifierStr == "def") return tok_def;
253 if (IdentifierStr == "extern") return tok_extern;
254 return tok_identifier;
255 }
256
257 if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+
258 std::string NumStr;
259 do {
260 NumStr += LastChar;
261 LastChar = getchar();
262 } while (isdigit(LastChar) || LastChar == '.');
263
264 NumVal = strtod(NumStr.c_str(), 0);
265 return tok_number;
266 }
267
268 if (LastChar == '#') {
269 // Comment until end of line.
270 do LastChar = getchar();
271 while (LastChar != EOF &amp;&amp; LastChar != '\n' &amp; LastChar != '\r');
272
273 if (LastChar != EOF)
274 return gettok();
275 }
276
277 // Check for end of file. Don't eat the EOF.
278 if (LastChar == EOF)
279 return tok_eof;
280
281 // Otherwise, just return the character as its ascii value.
282 int ThisChar = LastChar;
283 LastChar = getchar();
284 return ThisChar;
285}
286
287//===----------------------------------------------------------------------===//
288// Abstract Syntax Tree (aka Parse Tree)
289//===----------------------------------------------------------------------===//
290
291/// ExprAST - Base class for all expression nodes.
292class ExprAST {
293public:
294 virtual ~ExprAST() {}
295 virtual Value *Codegen() = 0;
296};
297
298/// NumberExprAST - Expression class for numeric literals like "1.0".
299class NumberExprAST : public ExprAST {
300 double Val;
301public:
302 NumberExprAST(double val) : Val(val) {}
303 virtual Value *Codegen();
304};
305
306/// VariableExprAST - Expression class for referencing a variable, like "a".
307class VariableExprAST : public ExprAST {
308 std::string Name;
309public:
310 VariableExprAST(const std::string &amp;name) : Name(name) {}
311 virtual Value *Codegen();
312};
313
314/// BinaryExprAST - Expression class for a binary operator.
315class BinaryExprAST : public ExprAST {
316 char Op;
317 ExprAST *LHS, *RHS;
318public:
319 BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs)
320 : Op(op), LHS(lhs), RHS(rhs) {}
321 virtual Value *Codegen();
322};
323
324/// CallExprAST - Expression class for function calls.
325class CallExprAST : public ExprAST {
326 std::string Callee;
327 std::vector&lt;ExprAST*&gt; Args;
328public:
329 CallExprAST(const std::string &amp;callee, std::vector&lt;ExprAST*&gt; &amp;args)
330 : Callee(callee), Args(args) {}
331 virtual Value *Codegen();
332};
333
334/// PrototypeAST - This class represents the "prototype" for a function,
335/// which captures its argument names as well as if it is an operator.
336class PrototypeAST {
337 std::string Name;
338 std::vector&lt;std::string&gt; Args;
339public:
340 PrototypeAST(const std::string &amp;name, const std::vector&lt;std::string&gt; &amp;args)
341 : Name(name), Args(args) {}
342
343 Function *Codegen();
344};
345
346/// FunctionAST - This class represents a function definition itself.
347class FunctionAST {
348 PrototypeAST *Proto;
349 ExprAST *Body;
350public:
351 FunctionAST(PrototypeAST *proto, ExprAST *body)
352 : Proto(proto), Body(body) {}
353
354 Function *Codegen();
355};
356
357//===----------------------------------------------------------------------===//
358// Parser
359//===----------------------------------------------------------------------===//
360
361/// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current
362/// token the parser it looking at. getNextToken reads another token from the
363/// lexer and updates CurTok with its results.
364static int CurTok;
365static int getNextToken() {
366 return CurTok = gettok();
367}
368
369/// BinopPrecedence - This holds the precedence for each binary operator that is
370/// defined.
371static std::map&lt;char, int&gt; BinopPrecedence;
372
373/// GetTokPrecedence - Get the precedence of the pending binary operator token.
374static int GetTokPrecedence() {
375 if (!isascii(CurTok))
376 return -1;
377
378 // Make sure it's a declared binop.
379 int TokPrec = BinopPrecedence[CurTok];
380 if (TokPrec &lt;= 0) return -1;
381 return TokPrec;
382}
383
384/// Error* - These are little helper functions for error handling.
385ExprAST *Error(const char *Str) { fprintf(stderr, "Error: %s\n", Str);return 0;}
386PrototypeAST *ErrorP(const char *Str) { Error(Str); return 0; }
387FunctionAST *ErrorF(const char *Str) { Error(Str); return 0; }
388
389static ExprAST *ParseExpression();
390
391/// identifierexpr
392/// ::= identifer
393/// ::= identifer '(' expression* ')'
394static ExprAST *ParseIdentifierExpr() {
395 std::string IdName = IdentifierStr;
396
397 getNextToken(); // eat identifer.
398
399 if (CurTok != '(') // Simple variable ref.
400 return new VariableExprAST(IdName);
401
402 // Call.
403 getNextToken(); // eat (
404 std::vector&lt;ExprAST*&gt; Args;
405 while (1) {
406 ExprAST *Arg = ParseExpression();
407 if (!Arg) return 0;
408 Args.push_back(Arg);
409
410 if (CurTok == ')') break;
411
412 if (CurTok != ',')
413 return Error("Expected ')'");
414 getNextToken();
415 }
416
417 // Eat the ')'.
418 getNextToken();
419
420 return new CallExprAST(IdName, Args);
421}
422
423/// numberexpr ::= number
424static ExprAST *ParseNumberExpr() {
425 ExprAST *Result = new NumberExprAST(NumVal);
426 getNextToken(); // consume the number
427 return Result;
428}
429
430/// parenexpr ::= '(' expression ')'
431static ExprAST *ParseParenExpr() {
432 getNextToken(); // eat (.
433 ExprAST *V = ParseExpression();
434 if (!V) return 0;
435
436 if (CurTok != ')')
437 return Error("expected ')'");
438 getNextToken(); // eat ).
439 return V;
440}
441
442/// primary
443/// ::= identifierexpr
444/// ::= numberexpr
445/// ::= parenexpr
446static ExprAST *ParsePrimary() {
447 switch (CurTok) {
448 default: return Error("unknown token when expecting an expression");
449 case tok_identifier: return ParseIdentifierExpr();
450 case tok_number: return ParseNumberExpr();
451 case '(': return ParseParenExpr();
452 }
453}
454
455/// binoprhs
456/// ::= ('+' primary)*
457static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) {
458 // If this is a binop, find its precedence.
459 while (1) {
460 int TokPrec = GetTokPrecedence();
461
462 // If this is a binop that binds at least as tightly as the current binop,
463 // consume it, otherwise we are done.
464 if (TokPrec &lt; ExprPrec)
465 return LHS;
466
467 // Okay, we know this is a binop.
468 int BinOp = CurTok;
469 getNextToken(); // eat binop
470
471 // Parse the primary expression after the binary operator.
472 ExprAST *RHS = ParsePrimary();
473 if (!RHS) return 0;
474
475 // If BinOp binds less tightly with RHS than the operator after RHS, let
476 // the pending operator take RHS as its LHS.
477 int NextPrec = GetTokPrecedence();
478 if (TokPrec &lt; NextPrec) {
479 RHS = ParseBinOpRHS(TokPrec+1, RHS);
480 if (RHS == 0) return 0;
481 }
482
483 // Merge LHS/RHS.
484 LHS = new BinaryExprAST(BinOp, LHS, RHS);
485 }
486}
487
488/// expression
489/// ::= primary binoprhs
490///
491static ExprAST *ParseExpression() {
492 ExprAST *LHS = ParsePrimary();
493 if (!LHS) return 0;
494
495 return ParseBinOpRHS(0, LHS);
496}
497
498/// prototype
499/// ::= id '(' id* ')'
500static PrototypeAST *ParsePrototype() {
501 if (CurTok != tok_identifier)
502 return ErrorP("Expected function name in prototype");
503
504 std::string FnName = IdentifierStr;
505 getNextToken();
506
507 if (CurTok != '(')
508 return ErrorP("Expected '(' in prototype");
509
510 std::vector&lt;std::string&gt; ArgNames;
511 while (getNextToken() == tok_identifier)
512 ArgNames.push_back(IdentifierStr);
513 if (CurTok != ')')
514 return ErrorP("Expected ')' in prototype");
515
516 // success.
517 getNextToken(); // eat ')'.
518
519 return new PrototypeAST(FnName, ArgNames);
520}
521
522/// definition ::= 'def' prototype expression
523static FunctionAST *ParseDefinition() {
524 getNextToken(); // eat def.
525 PrototypeAST *Proto = ParsePrototype();
526 if (Proto == 0) return 0;
527
528 if (ExprAST *E = ParseExpression())
529 return new FunctionAST(Proto, E);
530 return 0;
531}
532
533/// toplevelexpr ::= expression
534static FunctionAST *ParseTopLevelExpr() {
535 if (ExprAST *E = ParseExpression()) {
536 // Make an anonymous proto.
537 PrototypeAST *Proto = new PrototypeAST("", std::vector&lt;std::string&gt;());
538 return new FunctionAST(Proto, E);
539 }
540 return 0;
541}
542
543/// external ::= 'extern' prototype
544static PrototypeAST *ParseExtern() {
545 getNextToken(); // eat extern.
546 return ParsePrototype();
547}
548
549//===----------------------------------------------------------------------===//
550// Code Generation
551//===----------------------------------------------------------------------===//
552
553static Module *TheModule;
554static LLVMBuilder Builder;
555static std::map&lt;std::string, Value*&gt; NamedValues;
556
557Value *ErrorV(const char *Str) { Error(Str); return 0; }
558
559Value *NumberExprAST::Codegen() {
560 return ConstantFP::get(Type::DoubleTy, APFloat(Val));
561}
562
563Value *VariableExprAST::Codegen() {
564 // Look this variable up in the function.
565 Value *V = NamedValues[Name];
566 return V ? V : ErrorV("Unknown variable name");
567}
568
569Value *BinaryExprAST::Codegen() {
570 Value *L = LHS-&gt;Codegen();
571 Value *R = RHS-&gt;Codegen();
572 if (L == 0 || R == 0) return 0;
573
574 switch (Op) {
575 case '+': return Builder.CreateAdd(L, R, "addtmp");
576 case '-': return Builder.CreateSub(L, R, "subtmp");
577 case '*': return Builder.CreateMul(L, R, "multmp");
578 case '&lt;':
579 L = Builder.CreateFCmpULT(L, R, "multmp");
580 // Convert bool 0/1 to double 0.0 or 1.0
581 return Builder.CreateUIToFP(L, Type::DoubleTy, "booltmp");
582 default: return ErrorV("invalid binary operator");
583 }
584}
585
586Value *CallExprAST::Codegen() {
587 // Look up the name in the global module table.
588 Function *CalleeF = TheModule-&gt;getFunction(Callee);
589 if (CalleeF == 0)
590 return ErrorV("Unknown function referenced");
591
592 // If argument mismatch error.
593 if (CalleeF-&gt;arg_size() != Args.size())
594 return ErrorV("Incorrect # arguments passed");
595
596 std::vector&lt;Value*&gt; ArgsV;
597 for (unsigned i = 0, e = Args.size(); i != e; ++i) {
598 ArgsV.push_back(Args[i]-&gt;Codegen());
599 if (ArgsV.back() == 0) return 0;
600 }
601
602 return Builder.CreateCall(CalleeF, ArgsV.begin(), ArgsV.end(), "calltmp");
603}
604
605Function *PrototypeAST::Codegen() {
606 // Make the function type: double(double,double) etc.
607 FunctionType *FT =
608 FunctionType::get(Type::DoubleTy, std::vector&lt;const Type*&gt;(Args.size(),
609 Type::DoubleTy),
610 false);
611
612 Function *F = new Function(FT, Function::ExternalLinkage, Name, TheModule);
613
614 // If F conflicted, there was already something named 'Name'. If it has a
615 // body, don't allow redefinition or reextern.
616 if (F-&gt;getName() != Name) {
617 // Delete the one we just made and get the existing one.
618 F-&gt;eraseFromParent();
619 F = TheModule-&gt;getFunction(Name);
620
621 // If F already has a body, reject this.
622 if (!F-&gt;empty()) {
623 ErrorF("redefinition of function");
624 return 0;
625 }
626
627 // If F took a different number of args, reject.
628 if (F-&gt;arg_size() != Args.size()) {
629 ErrorF("redefinition of function with different # args");
630 return 0;
631 }
632 }
633
634 // Set names for all arguments.
635 unsigned Idx = 0;
636 for (Function::arg_iterator AI = F-&gt;arg_begin(); Idx != Args.size();
637 ++AI, ++Idx) {
638 AI-&gt;setName(Args[Idx]);
639
640 // Add arguments to variable symbol table.
641 NamedValues[Args[Idx]] = AI;
642 }
643
644 return F;
645}
646
647Function *FunctionAST::Codegen() {
648 NamedValues.clear();
649
650 Function *TheFunction = Proto-&gt;Codegen();
651 if (TheFunction == 0)
652 return 0;
653
654 // Create a new basic block to start insertion into.
655 Builder.SetInsertPoint(new BasicBlock("entry", TheFunction));
656
657 if (Value *RetVal = Body-&gt;Codegen()) {
658 // Finish off the function.
659 Builder.CreateRet(RetVal);
660 return TheFunction;
661 }
662
663 // Error reading body, remove function.
664 TheFunction-&gt;eraseFromParent();
665 return 0;
666}
667
668//===----------------------------------------------------------------------===//
669// Top-Level parsing and JIT Driver
670//===----------------------------------------------------------------------===//
671
672static void HandleDefinition() {
673 if (FunctionAST *F = ParseDefinition()) {
674 if (Function *LF = F-&gt;Codegen()) {
675 fprintf(stderr, "Read function definition:");
676 LF-&gt;dump();
677 }
678 } else {
679 // Skip token for error recovery.
680 getNextToken();
681 }
682}
683
684static void HandleExtern() {
685 if (PrototypeAST *P = ParseExtern()) {
686 if (Function *F = P-&gt;Codegen()) {
687 fprintf(stderr, "Read extern: ");
688 F-&gt;dump();
689 }
690 } else {
691 // Skip token for error recovery.
692 getNextToken();
693 }
694}
695
696static void HandleTopLevelExpression() {
697 // Evaluate a top level expression into an anonymous function.
698 if (FunctionAST *F = ParseTopLevelExpr()) {
699 if (Function *LF = F-&gt;Codegen()) {
700 fprintf(stderr, "Read top-level expression:");
701 LF-&gt;dump();
702 }
703 } else {
704 // Skip token for error recovery.
705 getNextToken();
706 }
707}
708
709/// top ::= definition | external | expression | ';'
710static void MainLoop() {
711 while (1) {
712 fprintf(stderr, "ready&gt; ");
713 switch (CurTok) {
714 case tok_eof: return;
715 case ';': getNextToken(); break; // ignore top level semicolons.
716 case tok_def: HandleDefinition(); break;
717 case tok_extern: HandleExtern(); break;
718 default: HandleTopLevelExpression(); break;
719 }
720 }
721}
722
723
724
725//===----------------------------------------------------------------------===//
726// "Library" functions that can be "extern'd" from user code.
727//===----------------------------------------------------------------------===//
728
729/// putchard - putchar that takes a double and returns 0.
730extern "C"
731double putchard(double X) {
732 putchar((char)X);
733 return 0;
734}
735
736//===----------------------------------------------------------------------===//
737// Main driver code.
738//===----------------------------------------------------------------------===//
739
740int main() {
741 TheModule = new Module("my cool jit");
742
743 // Install standard binary operators.
744 // 1 is lowest precedence.
745 BinopPrecedence['&lt;'] = 10;
746 BinopPrecedence['+'] = 20;
747 BinopPrecedence['-'] = 20;
748 BinopPrecedence['*'] = 40; // highest.
749
750 // Prime the first token.
751 fprintf(stderr, "ready&gt; ");
752 getNextToken();
753
754 MainLoop();
755 TheModule-&gt;dump();
756 return 0;
757}
758
759/* Examples:
760
761def fib(x)
762 if (x &lt; 3) then
763 1
764 else
765 fib(x-1)+fib(x-2);
766
767fib(10);
768
769*/
770</pre>
771</div>
772</div>
773
774<!-- *********************************************************************** -->
775<hr>
776<address>
777 <a href="http://jigsaw.w3.org/css-validator/check/referer"><img
778 src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"></a>
779 <a href="http://validator.w3.org/check/referer"><img
780 src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /></a>
781
782 <a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
783 <a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
784 Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $
785</address>
786</body>
787</html>