1*0a6a1f1dSLionel Sambuc #include "llvm/IR/Verifier.h"
2f4a2713aSLionel Sambuc #include "llvm/IR/DerivedTypes.h"
3f4a2713aSLionel Sambuc #include "llvm/IR/IRBuilder.h"
4f4a2713aSLionel Sambuc #include "llvm/IR/LLVMContext.h"
5f4a2713aSLionel Sambuc #include "llvm/IR/Module.h"
6f4a2713aSLionel Sambuc #include <cctype>
7f4a2713aSLionel Sambuc #include <cstdio>
8f4a2713aSLionel Sambuc #include <map>
9f4a2713aSLionel Sambuc #include <string>
10f4a2713aSLionel Sambuc #include <vector>
11f4a2713aSLionel Sambuc using namespace llvm;
12f4a2713aSLionel Sambuc 
13f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
14f4a2713aSLionel Sambuc // Lexer
15f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
16f4a2713aSLionel Sambuc 
17f4a2713aSLionel Sambuc // The lexer returns tokens [0-255] if it is an unknown character, otherwise one
18f4a2713aSLionel Sambuc // of these for known things.
19f4a2713aSLionel Sambuc enum Token {
20f4a2713aSLionel Sambuc   tok_eof = -1,
21f4a2713aSLionel Sambuc 
22f4a2713aSLionel Sambuc   // commands
23f4a2713aSLionel Sambuc   tok_def = -2, tok_extern = -3,
24f4a2713aSLionel Sambuc 
25f4a2713aSLionel Sambuc   // primary
26f4a2713aSLionel Sambuc   tok_identifier = -4, tok_number = -5
27f4a2713aSLionel Sambuc };
28f4a2713aSLionel Sambuc 
29f4a2713aSLionel Sambuc static std::string IdentifierStr;  // Filled in if tok_identifier
30f4a2713aSLionel Sambuc static double NumVal;              // Filled in if tok_number
31f4a2713aSLionel Sambuc 
32f4a2713aSLionel Sambuc /// gettok - Return the next token from standard input.
gettok()33f4a2713aSLionel Sambuc static int gettok() {
34f4a2713aSLionel Sambuc   static int LastChar = ' ';
35f4a2713aSLionel Sambuc 
36f4a2713aSLionel Sambuc   // Skip any whitespace.
37f4a2713aSLionel Sambuc   while (isspace(LastChar))
38f4a2713aSLionel Sambuc     LastChar = getchar();
39f4a2713aSLionel Sambuc 
40f4a2713aSLionel Sambuc   if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]*
41f4a2713aSLionel Sambuc     IdentifierStr = LastChar;
42f4a2713aSLionel Sambuc     while (isalnum((LastChar = getchar())))
43f4a2713aSLionel Sambuc       IdentifierStr += LastChar;
44f4a2713aSLionel Sambuc 
45f4a2713aSLionel Sambuc     if (IdentifierStr == "def") return tok_def;
46f4a2713aSLionel Sambuc     if (IdentifierStr == "extern") return tok_extern;
47f4a2713aSLionel Sambuc     return tok_identifier;
48f4a2713aSLionel Sambuc   }
49f4a2713aSLionel Sambuc 
50f4a2713aSLionel Sambuc   if (isdigit(LastChar) || LastChar == '.') {   // Number: [0-9.]+
51f4a2713aSLionel Sambuc     std::string NumStr;
52f4a2713aSLionel Sambuc     do {
53f4a2713aSLionel Sambuc       NumStr += LastChar;
54f4a2713aSLionel Sambuc       LastChar = getchar();
55f4a2713aSLionel Sambuc     } while (isdigit(LastChar) || LastChar == '.');
56f4a2713aSLionel Sambuc 
57f4a2713aSLionel Sambuc     NumVal = strtod(NumStr.c_str(), 0);
58f4a2713aSLionel Sambuc     return tok_number;
59f4a2713aSLionel Sambuc   }
60f4a2713aSLionel Sambuc 
61f4a2713aSLionel Sambuc   if (LastChar == '#') {
62f4a2713aSLionel Sambuc     // Comment until end of line.
63f4a2713aSLionel Sambuc     do LastChar = getchar();
64f4a2713aSLionel Sambuc     while (LastChar != EOF && LastChar != '\n' && LastChar != '\r');
65f4a2713aSLionel Sambuc 
66f4a2713aSLionel Sambuc     if (LastChar != EOF)
67f4a2713aSLionel Sambuc       return gettok();
68f4a2713aSLionel Sambuc   }
69f4a2713aSLionel Sambuc 
70f4a2713aSLionel Sambuc   // Check for end of file.  Don't eat the EOF.
71f4a2713aSLionel Sambuc   if (LastChar == EOF)
72f4a2713aSLionel Sambuc     return tok_eof;
73f4a2713aSLionel Sambuc 
74f4a2713aSLionel Sambuc   // Otherwise, just return the character as its ascii value.
75f4a2713aSLionel Sambuc   int ThisChar = LastChar;
76f4a2713aSLionel Sambuc   LastChar = getchar();
77f4a2713aSLionel Sambuc   return ThisChar;
78f4a2713aSLionel Sambuc }
79f4a2713aSLionel Sambuc 
80f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
81f4a2713aSLionel Sambuc // Abstract Syntax Tree (aka Parse Tree)
82f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
83f4a2713aSLionel Sambuc namespace {
84f4a2713aSLionel Sambuc /// ExprAST - Base class for all expression nodes.
85f4a2713aSLionel Sambuc class ExprAST {
86f4a2713aSLionel Sambuc public:
~ExprAST()87f4a2713aSLionel Sambuc   virtual ~ExprAST() {}
88f4a2713aSLionel Sambuc   virtual Value *Codegen() = 0;
89f4a2713aSLionel Sambuc };
90f4a2713aSLionel Sambuc 
91f4a2713aSLionel Sambuc /// NumberExprAST - Expression class for numeric literals like "1.0".
92f4a2713aSLionel Sambuc class NumberExprAST : public ExprAST {
93f4a2713aSLionel Sambuc   double Val;
94f4a2713aSLionel Sambuc public:
NumberExprAST(double val)95f4a2713aSLionel Sambuc   NumberExprAST(double val) : Val(val) {}
96f4a2713aSLionel Sambuc   virtual Value *Codegen();
97f4a2713aSLionel Sambuc };
98f4a2713aSLionel Sambuc 
99f4a2713aSLionel Sambuc /// VariableExprAST - Expression class for referencing a variable, like "a".
100f4a2713aSLionel Sambuc class VariableExprAST : public ExprAST {
101f4a2713aSLionel Sambuc   std::string Name;
102f4a2713aSLionel Sambuc public:
VariableExprAST(const std::string & name)103f4a2713aSLionel Sambuc   VariableExprAST(const std::string &name) : Name(name) {}
104f4a2713aSLionel Sambuc   virtual Value *Codegen();
105f4a2713aSLionel Sambuc };
106f4a2713aSLionel Sambuc 
107f4a2713aSLionel Sambuc /// BinaryExprAST - Expression class for a binary operator.
108f4a2713aSLionel Sambuc class BinaryExprAST : public ExprAST {
109f4a2713aSLionel Sambuc   char Op;
110f4a2713aSLionel Sambuc   ExprAST *LHS, *RHS;
111f4a2713aSLionel Sambuc public:
BinaryExprAST(char op,ExprAST * lhs,ExprAST * rhs)112f4a2713aSLionel Sambuc   BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs)
113f4a2713aSLionel Sambuc     : Op(op), LHS(lhs), RHS(rhs) {}
114f4a2713aSLionel Sambuc   virtual Value *Codegen();
115f4a2713aSLionel Sambuc };
116f4a2713aSLionel Sambuc 
117f4a2713aSLionel Sambuc /// CallExprAST - Expression class for function calls.
118f4a2713aSLionel Sambuc class CallExprAST : public ExprAST {
119f4a2713aSLionel Sambuc   std::string Callee;
120f4a2713aSLionel Sambuc   std::vector<ExprAST*> Args;
121f4a2713aSLionel Sambuc public:
CallExprAST(const std::string & callee,std::vector<ExprAST * > & args)122f4a2713aSLionel Sambuc   CallExprAST(const std::string &callee, std::vector<ExprAST*> &args)
123f4a2713aSLionel Sambuc     : Callee(callee), Args(args) {}
124f4a2713aSLionel Sambuc   virtual Value *Codegen();
125f4a2713aSLionel Sambuc };
126f4a2713aSLionel Sambuc 
127f4a2713aSLionel Sambuc /// PrototypeAST - This class represents the "prototype" for a function,
128f4a2713aSLionel Sambuc /// which captures its name, and its argument names (thus implicitly the number
129f4a2713aSLionel Sambuc /// of arguments the function takes).
130f4a2713aSLionel Sambuc class PrototypeAST {
131f4a2713aSLionel Sambuc   std::string Name;
132f4a2713aSLionel Sambuc   std::vector<std::string> Args;
133f4a2713aSLionel Sambuc public:
PrototypeAST(const std::string & name,const std::vector<std::string> & args)134f4a2713aSLionel Sambuc   PrototypeAST(const std::string &name, const std::vector<std::string> &args)
135f4a2713aSLionel Sambuc     : Name(name), Args(args) {}
136f4a2713aSLionel Sambuc 
137f4a2713aSLionel Sambuc   Function *Codegen();
138f4a2713aSLionel Sambuc };
139f4a2713aSLionel Sambuc 
140f4a2713aSLionel Sambuc /// FunctionAST - This class represents a function definition itself.
141f4a2713aSLionel Sambuc class FunctionAST {
142f4a2713aSLionel Sambuc   PrototypeAST *Proto;
143f4a2713aSLionel Sambuc   ExprAST *Body;
144f4a2713aSLionel Sambuc public:
FunctionAST(PrototypeAST * proto,ExprAST * body)145f4a2713aSLionel Sambuc   FunctionAST(PrototypeAST *proto, ExprAST *body)
146f4a2713aSLionel Sambuc     : Proto(proto), Body(body) {}
147f4a2713aSLionel Sambuc 
148f4a2713aSLionel Sambuc   Function *Codegen();
149f4a2713aSLionel Sambuc };
150f4a2713aSLionel Sambuc } // end anonymous namespace
151f4a2713aSLionel Sambuc 
152f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
153f4a2713aSLionel Sambuc // Parser
154f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
155f4a2713aSLionel Sambuc 
156f4a2713aSLionel Sambuc /// CurTok/getNextToken - Provide a simple token buffer.  CurTok is the current
157f4a2713aSLionel Sambuc /// token the parser is looking at.  getNextToken reads another token from the
158f4a2713aSLionel Sambuc /// lexer and updates CurTok with its results.
159f4a2713aSLionel Sambuc static int CurTok;
getNextToken()160f4a2713aSLionel Sambuc static int getNextToken() {
161f4a2713aSLionel Sambuc   return CurTok = gettok();
162f4a2713aSLionel Sambuc }
163f4a2713aSLionel Sambuc 
164f4a2713aSLionel Sambuc /// BinopPrecedence - This holds the precedence for each binary operator that is
165f4a2713aSLionel Sambuc /// defined.
166f4a2713aSLionel Sambuc static std::map<char, int> BinopPrecedence;
167f4a2713aSLionel Sambuc 
168f4a2713aSLionel Sambuc /// GetTokPrecedence - Get the precedence of the pending binary operator token.
GetTokPrecedence()169f4a2713aSLionel Sambuc static int GetTokPrecedence() {
170f4a2713aSLionel Sambuc   if (!isascii(CurTok))
171f4a2713aSLionel Sambuc     return -1;
172f4a2713aSLionel Sambuc 
173f4a2713aSLionel Sambuc   // Make sure it's a declared binop.
174f4a2713aSLionel Sambuc   int TokPrec = BinopPrecedence[CurTok];
175f4a2713aSLionel Sambuc   if (TokPrec <= 0) return -1;
176f4a2713aSLionel Sambuc   return TokPrec;
177f4a2713aSLionel Sambuc }
178f4a2713aSLionel Sambuc 
179f4a2713aSLionel Sambuc /// Error* - These are little helper functions for error handling.
Error(const char * Str)180f4a2713aSLionel Sambuc ExprAST *Error(const char *Str) { fprintf(stderr, "Error: %s\n", Str);return 0;}
ErrorP(const char * Str)181f4a2713aSLionel Sambuc PrototypeAST *ErrorP(const char *Str) { Error(Str); return 0; }
ErrorF(const char * Str)182f4a2713aSLionel Sambuc FunctionAST *ErrorF(const char *Str) { Error(Str); return 0; }
183f4a2713aSLionel Sambuc 
184f4a2713aSLionel Sambuc static ExprAST *ParseExpression();
185f4a2713aSLionel Sambuc 
186f4a2713aSLionel Sambuc /// identifierexpr
187f4a2713aSLionel Sambuc ///   ::= identifier
188f4a2713aSLionel Sambuc ///   ::= identifier '(' expression* ')'
ParseIdentifierExpr()189f4a2713aSLionel Sambuc static ExprAST *ParseIdentifierExpr() {
190f4a2713aSLionel Sambuc   std::string IdName = IdentifierStr;
191f4a2713aSLionel Sambuc 
192f4a2713aSLionel Sambuc   getNextToken();  // eat identifier.
193f4a2713aSLionel Sambuc 
194f4a2713aSLionel Sambuc   if (CurTok != '(') // Simple variable ref.
195f4a2713aSLionel Sambuc     return new VariableExprAST(IdName);
196f4a2713aSLionel Sambuc 
197f4a2713aSLionel Sambuc   // Call.
198f4a2713aSLionel Sambuc   getNextToken();  // eat (
199f4a2713aSLionel Sambuc   std::vector<ExprAST*> Args;
200f4a2713aSLionel Sambuc   if (CurTok != ')') {
201f4a2713aSLionel Sambuc     while (1) {
202f4a2713aSLionel Sambuc       ExprAST *Arg = ParseExpression();
203f4a2713aSLionel Sambuc       if (!Arg) return 0;
204f4a2713aSLionel Sambuc       Args.push_back(Arg);
205f4a2713aSLionel Sambuc 
206f4a2713aSLionel Sambuc       if (CurTok == ')') break;
207f4a2713aSLionel Sambuc 
208f4a2713aSLionel Sambuc       if (CurTok != ',')
209f4a2713aSLionel Sambuc         return Error("Expected ')' or ',' in argument list");
210f4a2713aSLionel Sambuc       getNextToken();
211f4a2713aSLionel Sambuc     }
212f4a2713aSLionel Sambuc   }
213f4a2713aSLionel Sambuc 
214f4a2713aSLionel Sambuc   // Eat the ')'.
215f4a2713aSLionel Sambuc   getNextToken();
216f4a2713aSLionel Sambuc 
217f4a2713aSLionel Sambuc   return new CallExprAST(IdName, Args);
218f4a2713aSLionel Sambuc }
219f4a2713aSLionel Sambuc 
220f4a2713aSLionel Sambuc /// numberexpr ::= number
ParseNumberExpr()221f4a2713aSLionel Sambuc static ExprAST *ParseNumberExpr() {
222f4a2713aSLionel Sambuc   ExprAST *Result = new NumberExprAST(NumVal);
223f4a2713aSLionel Sambuc   getNextToken(); // consume the number
224f4a2713aSLionel Sambuc   return Result;
225f4a2713aSLionel Sambuc }
226f4a2713aSLionel Sambuc 
227f4a2713aSLionel Sambuc /// parenexpr ::= '(' expression ')'
ParseParenExpr()228f4a2713aSLionel Sambuc static ExprAST *ParseParenExpr() {
229f4a2713aSLionel Sambuc   getNextToken();  // eat (.
230f4a2713aSLionel Sambuc   ExprAST *V = ParseExpression();
231f4a2713aSLionel Sambuc   if (!V) return 0;
232f4a2713aSLionel Sambuc 
233f4a2713aSLionel Sambuc   if (CurTok != ')')
234f4a2713aSLionel Sambuc     return Error("expected ')'");
235f4a2713aSLionel Sambuc   getNextToken();  // eat ).
236f4a2713aSLionel Sambuc   return V;
237f4a2713aSLionel Sambuc }
238f4a2713aSLionel Sambuc 
239f4a2713aSLionel Sambuc /// primary
240f4a2713aSLionel Sambuc ///   ::= identifierexpr
241f4a2713aSLionel Sambuc ///   ::= numberexpr
242f4a2713aSLionel Sambuc ///   ::= parenexpr
ParsePrimary()243f4a2713aSLionel Sambuc static ExprAST *ParsePrimary() {
244f4a2713aSLionel Sambuc   switch (CurTok) {
245f4a2713aSLionel Sambuc   default: return Error("unknown token when expecting an expression");
246f4a2713aSLionel Sambuc   case tok_identifier: return ParseIdentifierExpr();
247f4a2713aSLionel Sambuc   case tok_number:     return ParseNumberExpr();
248f4a2713aSLionel Sambuc   case '(':            return ParseParenExpr();
249f4a2713aSLionel Sambuc   }
250f4a2713aSLionel Sambuc }
251f4a2713aSLionel Sambuc 
252f4a2713aSLionel Sambuc /// binoprhs
253f4a2713aSLionel Sambuc ///   ::= ('+' primary)*
ParseBinOpRHS(int ExprPrec,ExprAST * LHS)254f4a2713aSLionel Sambuc static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) {
255f4a2713aSLionel Sambuc   // If this is a binop, find its precedence.
256f4a2713aSLionel Sambuc   while (1) {
257f4a2713aSLionel Sambuc     int TokPrec = GetTokPrecedence();
258f4a2713aSLionel Sambuc 
259f4a2713aSLionel Sambuc     // If this is a binop that binds at least as tightly as the current binop,
260f4a2713aSLionel Sambuc     // consume it, otherwise we are done.
261f4a2713aSLionel Sambuc     if (TokPrec < ExprPrec)
262f4a2713aSLionel Sambuc       return LHS;
263f4a2713aSLionel Sambuc 
264f4a2713aSLionel Sambuc     // Okay, we know this is a binop.
265f4a2713aSLionel Sambuc     int BinOp = CurTok;
266f4a2713aSLionel Sambuc     getNextToken();  // eat binop
267f4a2713aSLionel Sambuc 
268f4a2713aSLionel Sambuc     // Parse the primary expression after the binary operator.
269f4a2713aSLionel Sambuc     ExprAST *RHS = ParsePrimary();
270f4a2713aSLionel Sambuc     if (!RHS) return 0;
271f4a2713aSLionel Sambuc 
272f4a2713aSLionel Sambuc     // If BinOp binds less tightly with RHS than the operator after RHS, let
273f4a2713aSLionel Sambuc     // the pending operator take RHS as its LHS.
274f4a2713aSLionel Sambuc     int NextPrec = GetTokPrecedence();
275f4a2713aSLionel Sambuc     if (TokPrec < NextPrec) {
276f4a2713aSLionel Sambuc       RHS = ParseBinOpRHS(TokPrec+1, RHS);
277f4a2713aSLionel Sambuc       if (RHS == 0) return 0;
278f4a2713aSLionel Sambuc     }
279f4a2713aSLionel Sambuc 
280f4a2713aSLionel Sambuc     // Merge LHS/RHS.
281f4a2713aSLionel Sambuc     LHS = new BinaryExprAST(BinOp, LHS, RHS);
282f4a2713aSLionel Sambuc   }
283f4a2713aSLionel Sambuc }
284f4a2713aSLionel Sambuc 
285f4a2713aSLionel Sambuc /// expression
286f4a2713aSLionel Sambuc ///   ::= primary binoprhs
287f4a2713aSLionel Sambuc ///
ParseExpression()288f4a2713aSLionel Sambuc static ExprAST *ParseExpression() {
289f4a2713aSLionel Sambuc   ExprAST *LHS = ParsePrimary();
290f4a2713aSLionel Sambuc   if (!LHS) return 0;
291f4a2713aSLionel Sambuc 
292f4a2713aSLionel Sambuc   return ParseBinOpRHS(0, LHS);
293f4a2713aSLionel Sambuc }
294f4a2713aSLionel Sambuc 
295f4a2713aSLionel Sambuc /// prototype
296f4a2713aSLionel Sambuc ///   ::= id '(' id* ')'
ParsePrototype()297f4a2713aSLionel Sambuc static PrototypeAST *ParsePrototype() {
298f4a2713aSLionel Sambuc   if (CurTok != tok_identifier)
299f4a2713aSLionel Sambuc     return ErrorP("Expected function name in prototype");
300f4a2713aSLionel Sambuc 
301f4a2713aSLionel Sambuc   std::string FnName = IdentifierStr;
302f4a2713aSLionel Sambuc   getNextToken();
303f4a2713aSLionel Sambuc 
304f4a2713aSLionel Sambuc   if (CurTok != '(')
305f4a2713aSLionel Sambuc     return ErrorP("Expected '(' in prototype");
306f4a2713aSLionel Sambuc 
307f4a2713aSLionel Sambuc   std::vector<std::string> ArgNames;
308f4a2713aSLionel Sambuc   while (getNextToken() == tok_identifier)
309f4a2713aSLionel Sambuc     ArgNames.push_back(IdentifierStr);
310f4a2713aSLionel Sambuc   if (CurTok != ')')
311f4a2713aSLionel Sambuc     return ErrorP("Expected ')' in prototype");
312f4a2713aSLionel Sambuc 
313f4a2713aSLionel Sambuc   // success.
314f4a2713aSLionel Sambuc   getNextToken();  // eat ')'.
315f4a2713aSLionel Sambuc 
316f4a2713aSLionel Sambuc   return new PrototypeAST(FnName, ArgNames);
317f4a2713aSLionel Sambuc }
318f4a2713aSLionel Sambuc 
319f4a2713aSLionel Sambuc /// definition ::= 'def' prototype expression
ParseDefinition()320f4a2713aSLionel Sambuc static FunctionAST *ParseDefinition() {
321f4a2713aSLionel Sambuc   getNextToken();  // eat def.
322f4a2713aSLionel Sambuc   PrototypeAST *Proto = ParsePrototype();
323f4a2713aSLionel Sambuc   if (Proto == 0) return 0;
324f4a2713aSLionel Sambuc 
325f4a2713aSLionel Sambuc   if (ExprAST *E = ParseExpression())
326f4a2713aSLionel Sambuc     return new FunctionAST(Proto, E);
327f4a2713aSLionel Sambuc   return 0;
328f4a2713aSLionel Sambuc }
329f4a2713aSLionel Sambuc 
330f4a2713aSLionel Sambuc /// toplevelexpr ::= expression
ParseTopLevelExpr()331f4a2713aSLionel Sambuc static FunctionAST *ParseTopLevelExpr() {
332f4a2713aSLionel Sambuc   if (ExprAST *E = ParseExpression()) {
333f4a2713aSLionel Sambuc     // Make an anonymous proto.
334f4a2713aSLionel Sambuc     PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>());
335f4a2713aSLionel Sambuc     return new FunctionAST(Proto, E);
336f4a2713aSLionel Sambuc   }
337f4a2713aSLionel Sambuc   return 0;
338f4a2713aSLionel Sambuc }
339f4a2713aSLionel Sambuc 
340f4a2713aSLionel Sambuc /// external ::= 'extern' prototype
ParseExtern()341f4a2713aSLionel Sambuc static PrototypeAST *ParseExtern() {
342f4a2713aSLionel Sambuc   getNextToken();  // eat extern.
343f4a2713aSLionel Sambuc   return ParsePrototype();
344f4a2713aSLionel Sambuc }
345f4a2713aSLionel Sambuc 
346f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
347f4a2713aSLionel Sambuc // Code Generation
348f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
349f4a2713aSLionel Sambuc 
350f4a2713aSLionel Sambuc static Module *TheModule;
351f4a2713aSLionel Sambuc static IRBuilder<> Builder(getGlobalContext());
352f4a2713aSLionel Sambuc static std::map<std::string, Value*> NamedValues;
353f4a2713aSLionel Sambuc 
ErrorV(const char * Str)354f4a2713aSLionel Sambuc Value *ErrorV(const char *Str) { Error(Str); return 0; }
355f4a2713aSLionel Sambuc 
Codegen()356f4a2713aSLionel Sambuc Value *NumberExprAST::Codegen() {
357f4a2713aSLionel Sambuc   return ConstantFP::get(getGlobalContext(), APFloat(Val));
358f4a2713aSLionel Sambuc }
359f4a2713aSLionel Sambuc 
Codegen()360f4a2713aSLionel Sambuc Value *VariableExprAST::Codegen() {
361f4a2713aSLionel Sambuc   // Look this variable up in the function.
362f4a2713aSLionel Sambuc   Value *V = NamedValues[Name];
363f4a2713aSLionel Sambuc   return V ? V : ErrorV("Unknown variable name");
364f4a2713aSLionel Sambuc }
365f4a2713aSLionel Sambuc 
Codegen()366f4a2713aSLionel Sambuc Value *BinaryExprAST::Codegen() {
367f4a2713aSLionel Sambuc   Value *L = LHS->Codegen();
368f4a2713aSLionel Sambuc   Value *R = RHS->Codegen();
369f4a2713aSLionel Sambuc   if (L == 0 || R == 0) return 0;
370f4a2713aSLionel Sambuc 
371f4a2713aSLionel Sambuc   switch (Op) {
372f4a2713aSLionel Sambuc   case '+': return Builder.CreateFAdd(L, R, "addtmp");
373f4a2713aSLionel Sambuc   case '-': return Builder.CreateFSub(L, R, "subtmp");
374f4a2713aSLionel Sambuc   case '*': return Builder.CreateFMul(L, R, "multmp");
375f4a2713aSLionel Sambuc   case '<':
376f4a2713aSLionel Sambuc     L = Builder.CreateFCmpULT(L, R, "cmptmp");
377f4a2713aSLionel Sambuc     // Convert bool 0/1 to double 0.0 or 1.0
378f4a2713aSLionel Sambuc     return Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()),
379f4a2713aSLionel Sambuc                                 "booltmp");
380f4a2713aSLionel Sambuc   default: return ErrorV("invalid binary operator");
381f4a2713aSLionel Sambuc   }
382f4a2713aSLionel Sambuc }
383f4a2713aSLionel Sambuc 
Codegen()384f4a2713aSLionel Sambuc Value *CallExprAST::Codegen() {
385f4a2713aSLionel Sambuc   // Look up the name in the global module table.
386f4a2713aSLionel Sambuc   Function *CalleeF = TheModule->getFunction(Callee);
387f4a2713aSLionel Sambuc   if (CalleeF == 0)
388f4a2713aSLionel Sambuc     return ErrorV("Unknown function referenced");
389f4a2713aSLionel Sambuc 
390f4a2713aSLionel Sambuc   // If argument mismatch error.
391f4a2713aSLionel Sambuc   if (CalleeF->arg_size() != Args.size())
392f4a2713aSLionel Sambuc     return ErrorV("Incorrect # arguments passed");
393f4a2713aSLionel Sambuc 
394f4a2713aSLionel Sambuc   std::vector<Value*> ArgsV;
395f4a2713aSLionel Sambuc   for (unsigned i = 0, e = Args.size(); i != e; ++i) {
396f4a2713aSLionel Sambuc     ArgsV.push_back(Args[i]->Codegen());
397f4a2713aSLionel Sambuc     if (ArgsV.back() == 0) return 0;
398f4a2713aSLionel Sambuc   }
399f4a2713aSLionel Sambuc 
400f4a2713aSLionel Sambuc   return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
401f4a2713aSLionel Sambuc }
402f4a2713aSLionel Sambuc 
Codegen()403f4a2713aSLionel Sambuc Function *PrototypeAST::Codegen() {
404f4a2713aSLionel Sambuc   // Make the function type:  double(double,double) etc.
405f4a2713aSLionel Sambuc   std::vector<Type*> Doubles(Args.size(),
406f4a2713aSLionel Sambuc                              Type::getDoubleTy(getGlobalContext()));
407f4a2713aSLionel Sambuc   FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),
408f4a2713aSLionel Sambuc                                        Doubles, false);
409f4a2713aSLionel Sambuc 
410f4a2713aSLionel Sambuc   Function *F = Function::Create(FT, Function::ExternalLinkage, Name, TheModule);
411f4a2713aSLionel Sambuc 
412f4a2713aSLionel Sambuc   // If F conflicted, there was already something named 'Name'.  If it has a
413f4a2713aSLionel Sambuc   // body, don't allow redefinition or reextern.
414f4a2713aSLionel Sambuc   if (F->getName() != Name) {
415f4a2713aSLionel Sambuc     // Delete the one we just made and get the existing one.
416f4a2713aSLionel Sambuc     F->eraseFromParent();
417f4a2713aSLionel Sambuc     F = TheModule->getFunction(Name);
418f4a2713aSLionel Sambuc 
419f4a2713aSLionel Sambuc     // If F already has a body, reject this.
420f4a2713aSLionel Sambuc     if (!F->empty()) {
421f4a2713aSLionel Sambuc       ErrorF("redefinition of function");
422f4a2713aSLionel Sambuc       return 0;
423f4a2713aSLionel Sambuc     }
424f4a2713aSLionel Sambuc 
425f4a2713aSLionel Sambuc     // If F took a different number of args, reject.
426f4a2713aSLionel Sambuc     if (F->arg_size() != Args.size()) {
427f4a2713aSLionel Sambuc       ErrorF("redefinition of function with different # args");
428f4a2713aSLionel Sambuc       return 0;
429f4a2713aSLionel Sambuc     }
430f4a2713aSLionel Sambuc   }
431f4a2713aSLionel Sambuc 
432f4a2713aSLionel Sambuc   // Set names for all arguments.
433f4a2713aSLionel Sambuc   unsigned Idx = 0;
434f4a2713aSLionel Sambuc   for (Function::arg_iterator AI = F->arg_begin(); Idx != Args.size();
435f4a2713aSLionel Sambuc        ++AI, ++Idx) {
436f4a2713aSLionel Sambuc     AI->setName(Args[Idx]);
437f4a2713aSLionel Sambuc 
438f4a2713aSLionel Sambuc     // Add arguments to variable symbol table.
439f4a2713aSLionel Sambuc     NamedValues[Args[Idx]] = AI;
440f4a2713aSLionel Sambuc   }
441f4a2713aSLionel Sambuc 
442f4a2713aSLionel Sambuc   return F;
443f4a2713aSLionel Sambuc }
444f4a2713aSLionel Sambuc 
Codegen()445f4a2713aSLionel Sambuc Function *FunctionAST::Codegen() {
446f4a2713aSLionel Sambuc   NamedValues.clear();
447f4a2713aSLionel Sambuc 
448f4a2713aSLionel Sambuc   Function *TheFunction = Proto->Codegen();
449f4a2713aSLionel Sambuc   if (TheFunction == 0)
450f4a2713aSLionel Sambuc     return 0;
451f4a2713aSLionel Sambuc 
452f4a2713aSLionel Sambuc   // Create a new basic block to start insertion into.
453f4a2713aSLionel Sambuc   BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
454f4a2713aSLionel Sambuc   Builder.SetInsertPoint(BB);
455f4a2713aSLionel Sambuc 
456f4a2713aSLionel Sambuc   if (Value *RetVal = Body->Codegen()) {
457f4a2713aSLionel Sambuc     // Finish off the function.
458f4a2713aSLionel Sambuc     Builder.CreateRet(RetVal);
459f4a2713aSLionel Sambuc 
460f4a2713aSLionel Sambuc     // Validate the generated code, checking for consistency.
461f4a2713aSLionel Sambuc     verifyFunction(*TheFunction);
462f4a2713aSLionel Sambuc 
463f4a2713aSLionel Sambuc     return TheFunction;
464f4a2713aSLionel Sambuc   }
465f4a2713aSLionel Sambuc 
466f4a2713aSLionel Sambuc   // Error reading body, remove function.
467f4a2713aSLionel Sambuc   TheFunction->eraseFromParent();
468f4a2713aSLionel Sambuc   return 0;
469f4a2713aSLionel Sambuc }
470f4a2713aSLionel Sambuc 
471f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
472f4a2713aSLionel Sambuc // Top-Level parsing and JIT Driver
473f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
474f4a2713aSLionel Sambuc 
HandleDefinition()475f4a2713aSLionel Sambuc static void HandleDefinition() {
476f4a2713aSLionel Sambuc   if (FunctionAST *F = ParseDefinition()) {
477f4a2713aSLionel Sambuc     if (Function *LF = F->Codegen()) {
478f4a2713aSLionel Sambuc       fprintf(stderr, "Read function definition:");
479f4a2713aSLionel Sambuc       LF->dump();
480f4a2713aSLionel Sambuc     }
481f4a2713aSLionel Sambuc   } else {
482f4a2713aSLionel Sambuc     // Skip token for error recovery.
483f4a2713aSLionel Sambuc     getNextToken();
484f4a2713aSLionel Sambuc   }
485f4a2713aSLionel Sambuc }
486f4a2713aSLionel Sambuc 
HandleExtern()487f4a2713aSLionel Sambuc static void HandleExtern() {
488f4a2713aSLionel Sambuc   if (PrototypeAST *P = ParseExtern()) {
489f4a2713aSLionel Sambuc     if (Function *F = P->Codegen()) {
490f4a2713aSLionel Sambuc       fprintf(stderr, "Read extern: ");
491f4a2713aSLionel Sambuc       F->dump();
492f4a2713aSLionel Sambuc     }
493f4a2713aSLionel Sambuc   } else {
494f4a2713aSLionel Sambuc     // Skip token for error recovery.
495f4a2713aSLionel Sambuc     getNextToken();
496f4a2713aSLionel Sambuc   }
497f4a2713aSLionel Sambuc }
498f4a2713aSLionel Sambuc 
HandleTopLevelExpression()499f4a2713aSLionel Sambuc static void HandleTopLevelExpression() {
500f4a2713aSLionel Sambuc   // Evaluate a top-level expression into an anonymous function.
501f4a2713aSLionel Sambuc   if (FunctionAST *F = ParseTopLevelExpr()) {
502f4a2713aSLionel Sambuc     if (Function *LF = F->Codegen()) {
503f4a2713aSLionel Sambuc       fprintf(stderr, "Read top-level expression:");
504f4a2713aSLionel Sambuc       LF->dump();
505f4a2713aSLionel Sambuc     }
506f4a2713aSLionel Sambuc   } else {
507f4a2713aSLionel Sambuc     // Skip token for error recovery.
508f4a2713aSLionel Sambuc     getNextToken();
509f4a2713aSLionel Sambuc   }
510f4a2713aSLionel Sambuc }
511f4a2713aSLionel Sambuc 
512f4a2713aSLionel Sambuc /// top ::= definition | external | expression | ';'
MainLoop()513f4a2713aSLionel Sambuc static void MainLoop() {
514f4a2713aSLionel Sambuc   while (1) {
515f4a2713aSLionel Sambuc     fprintf(stderr, "ready> ");
516f4a2713aSLionel Sambuc     switch (CurTok) {
517f4a2713aSLionel Sambuc     case tok_eof:    return;
518f4a2713aSLionel Sambuc     case ';':        getNextToken(); break;  // ignore top-level semicolons.
519f4a2713aSLionel Sambuc     case tok_def:    HandleDefinition(); break;
520f4a2713aSLionel Sambuc     case tok_extern: HandleExtern(); break;
521f4a2713aSLionel Sambuc     default:         HandleTopLevelExpression(); break;
522f4a2713aSLionel Sambuc     }
523f4a2713aSLionel Sambuc   }
524f4a2713aSLionel Sambuc }
525f4a2713aSLionel Sambuc 
526f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
527f4a2713aSLionel Sambuc // "Library" functions that can be "extern'd" from user code.
528f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
529f4a2713aSLionel Sambuc 
530f4a2713aSLionel Sambuc /// putchard - putchar that takes a double and returns 0.
531f4a2713aSLionel Sambuc extern "C"
putchard(double X)532f4a2713aSLionel Sambuc double putchard(double X) {
533f4a2713aSLionel Sambuc   putchar((char)X);
534f4a2713aSLionel Sambuc   return 0;
535f4a2713aSLionel Sambuc }
536f4a2713aSLionel Sambuc 
537f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
538f4a2713aSLionel Sambuc // Main driver code.
539f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
540f4a2713aSLionel Sambuc 
main()541f4a2713aSLionel Sambuc int main() {
542f4a2713aSLionel Sambuc   LLVMContext &Context = getGlobalContext();
543f4a2713aSLionel Sambuc 
544f4a2713aSLionel Sambuc   // Install standard binary operators.
545f4a2713aSLionel Sambuc   // 1 is lowest precedence.
546f4a2713aSLionel Sambuc   BinopPrecedence['<'] = 10;
547f4a2713aSLionel Sambuc   BinopPrecedence['+'] = 20;
548f4a2713aSLionel Sambuc   BinopPrecedence['-'] = 20;
549f4a2713aSLionel Sambuc   BinopPrecedence['*'] = 40;  // highest.
550f4a2713aSLionel Sambuc 
551f4a2713aSLionel Sambuc   // Prime the first token.
552f4a2713aSLionel Sambuc   fprintf(stderr, "ready> ");
553f4a2713aSLionel Sambuc   getNextToken();
554f4a2713aSLionel Sambuc 
555f4a2713aSLionel Sambuc   // Make the module, which holds all the code.
556f4a2713aSLionel Sambuc   TheModule = new Module("my cool jit", Context);
557f4a2713aSLionel Sambuc 
558f4a2713aSLionel Sambuc   // Run the main "interpreter loop" now.
559f4a2713aSLionel Sambuc   MainLoop();
560f4a2713aSLionel Sambuc 
561f4a2713aSLionel Sambuc   // Print out all of the generated code.
562f4a2713aSLionel Sambuc   TheModule->dump();
563f4a2713aSLionel Sambuc 
564f4a2713aSLionel Sambuc   return 0;
565f4a2713aSLionel Sambuc }
566