7 //===----------------------------------------------------------------------===//
9 //===----------------------------------------------------------------------===//
11 // The lexer returns tokens [0-255] if it is an unknown character, otherwise one
12 // of these for known things.
17 tok_def
= -2, tok_extern
= -3,
20 tok_identifier
= -4, tok_number
= -5
23 static std::string IdentifierStr
; // Filled in if tok_identifier
24 static double NumVal
; // Filled in if tok_number
26 /// gettok - Return the next token from standard input.
28 static int LastChar
= ' ';
30 // Skip any whitespace.
31 while (isspace(LastChar
))
34 if (isalpha(LastChar
)) { // identifier: [a-zA-Z][a-zA-Z0-9]*
35 IdentifierStr
= LastChar
;
36 while (isalnum((LastChar
= getchar())))
37 IdentifierStr
+= LastChar
;
39 if (IdentifierStr
== "def") return tok_def
;
40 if (IdentifierStr
== "extern") return tok_extern
;
41 return tok_identifier
;
44 if (isdigit(LastChar
) || LastChar
== '.') { // Number: [0-9.]+
49 } while (isdigit(LastChar
) || LastChar
== '.');
51 NumVal
= strtod(NumStr
.c_str(), 0);
55 if (LastChar
== '#') {
56 // Comment until end of line.
57 do LastChar
= getchar();
58 while (LastChar
!= EOF
&& LastChar
!= '\n' && LastChar
!= '\r');
64 // Check for end of file. Don't eat the EOF.
68 // Otherwise, just return the character as its ascii value.
69 int ThisChar
= LastChar
;
74 //===----------------------------------------------------------------------===//
75 // Abstract Syntax Tree (aka Parse Tree)
76 //===----------------------------------------------------------------------===//
78 /// ExprAST - Base class for all expression nodes.
84 /// NumberExprAST - Expression class for numeric literals like "1.0".
85 class NumberExprAST
: public ExprAST
{
88 NumberExprAST(double val
) : Val(val
) {}
91 /// VariableExprAST - Expression class for referencing a variable, like "a".
92 class VariableExprAST
: public ExprAST
{
95 VariableExprAST(const std::string
&name
) : Name(name
) {}
98 /// BinaryExprAST - Expression class for a binary operator.
99 class BinaryExprAST
: public ExprAST
{
103 BinaryExprAST(char op
, ExprAST
*lhs
, ExprAST
*rhs
)
104 : Op(op
), LHS(lhs
), RHS(rhs
) {}
107 /// CallExprAST - Expression class for function calls.
108 class CallExprAST
: public ExprAST
{
110 std::vector
<ExprAST
*> Args
;
112 CallExprAST(const std::string
&callee
, std::vector
<ExprAST
*> &args
)
113 : Callee(callee
), Args(args
) {}
116 /// PrototypeAST - This class represents the "prototype" for a function,
117 /// which captures its name, and its argument names (thus implicitly the number
118 /// of arguments the function takes).
121 std::vector
<std::string
> Args
;
123 PrototypeAST(const std::string
&name
, const std::vector
<std::string
> &args
)
124 : Name(name
), Args(args
) {}
128 /// FunctionAST - This class represents a function definition itself.
133 FunctionAST(PrototypeAST
*proto
, ExprAST
*body
)
134 : Proto(proto
), Body(body
) {}
138 //===----------------------------------------------------------------------===//
140 //===----------------------------------------------------------------------===//
142 /// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current
143 /// token the parser is looking at. getNextToken reads another token from the
144 /// lexer and updates CurTok with its results.
146 static int getNextToken() {
147 return CurTok
= gettok();
150 /// BinopPrecedence - This holds the precedence for each binary operator that is
152 static std::map
<char, int> BinopPrecedence
;
154 /// GetTokPrecedence - Get the precedence of the pending binary operator token.
155 static int GetTokPrecedence() {
156 if (!isascii(CurTok
))
159 // Make sure it's a declared binop.
160 int TokPrec
= BinopPrecedence
[CurTok
];
161 if (TokPrec
<= 0) return -1;
165 /// Error* - These are little helper functions for error handling.
166 ExprAST
*Error(const char *Str
) { fprintf(stderr
, "Error: %s\n", Str
);return 0;}
167 PrototypeAST
*ErrorP(const char *Str
) { Error(Str
); return 0; }
168 FunctionAST
*ErrorF(const char *Str
) { Error(Str
); return 0; }
170 static ExprAST
*ParseExpression();
174 /// ::= identifier '(' expression* ')'
175 static ExprAST
*ParseIdentifierExpr() {
176 std::string IdName
= IdentifierStr
;
178 getNextToken(); // eat identifier.
180 if (CurTok
!= '(') // Simple variable ref.
181 return new VariableExprAST(IdName
);
184 getNextToken(); // eat (
185 std::vector
<ExprAST
*> Args
;
188 ExprAST
*Arg
= ParseExpression();
192 if (CurTok
== ')') break;
195 return Error("Expected ')' or ',' in argument list");
203 return new CallExprAST(IdName
, Args
);
206 /// numberexpr ::= number
207 static ExprAST
*ParseNumberExpr() {
208 ExprAST
*Result
= new NumberExprAST(NumVal
);
209 getNextToken(); // consume the number
213 /// parenexpr ::= '(' expression ')'
214 static ExprAST
*ParseParenExpr() {
215 getNextToken(); // eat (.
216 ExprAST
*V
= ParseExpression();
220 return Error("expected ')'");
221 getNextToken(); // eat ).
226 /// ::= identifierexpr
229 static ExprAST
*ParsePrimary() {
231 default: return Error("unknown token when expecting an expression");
232 case tok_identifier
: return ParseIdentifierExpr();
233 case tok_number
: return ParseNumberExpr();
234 case '(': return ParseParenExpr();
239 /// ::= ('+' primary)*
240 static ExprAST
*ParseBinOpRHS(int ExprPrec
, ExprAST
*LHS
) {
241 // If this is a binop, find its precedence.
243 int TokPrec
= GetTokPrecedence();
245 // If this is a binop that binds at least as tightly as the current binop,
246 // consume it, otherwise we are done.
247 if (TokPrec
< ExprPrec
)
250 // Okay, we know this is a binop.
252 getNextToken(); // eat binop
254 // Parse the primary expression after the binary operator.
255 ExprAST
*RHS
= ParsePrimary();
258 // If BinOp binds less tightly with RHS than the operator after RHS, let
259 // the pending operator take RHS as its LHS.
260 int NextPrec
= GetTokPrecedence();
261 if (TokPrec
< NextPrec
) {
262 RHS
= ParseBinOpRHS(TokPrec
+1, RHS
);
263 if (RHS
== 0) return 0;
267 LHS
= new BinaryExprAST(BinOp
, LHS
, RHS
);
272 /// ::= primary binoprhs
274 static ExprAST
*ParseExpression() {
275 ExprAST
*LHS
= ParsePrimary();
278 return ParseBinOpRHS(0, LHS
);
282 /// ::= id '(' id* ')'
283 static PrototypeAST
*ParsePrototype() {
284 if (CurTok
!= tok_identifier
)
285 return ErrorP("Expected function name in prototype");
287 std::string FnName
= IdentifierStr
;
291 return ErrorP("Expected '(' in prototype");
293 std::vector
<std::string
> ArgNames
;
294 while (getNextToken() == tok_identifier
)
295 ArgNames
.push_back(IdentifierStr
);
297 return ErrorP("Expected ')' in prototype");
300 getNextToken(); // eat ')'.
302 return new PrototypeAST(FnName
, ArgNames
);
305 /// definition ::= 'def' prototype expression
306 static FunctionAST
*ParseDefinition() {
307 getNextToken(); // eat def.
308 PrototypeAST
*Proto
= ParsePrototype();
309 if (Proto
== 0) return 0;
311 if (ExprAST
*E
= ParseExpression())
312 return new FunctionAST(Proto
, E
);
316 /// toplevelexpr ::= expression
317 static FunctionAST
*ParseTopLevelExpr() {
318 if (ExprAST
*E
= ParseExpression()) {
319 // Make an anonymous proto.
320 PrototypeAST
*Proto
= new PrototypeAST("", std::vector
<std::string
>());
321 return new FunctionAST(Proto
, E
);
326 /// external ::= 'extern' prototype
327 static PrototypeAST
*ParseExtern() {
328 getNextToken(); // eat extern.
329 return ParsePrototype();
332 //===----------------------------------------------------------------------===//
334 //===----------------------------------------------------------------------===//
336 static void HandleDefinition() {
337 if (ParseDefinition()) {
338 fprintf(stderr
, "Parsed a function definition.\n");
340 // Skip token for error recovery.
345 static void HandleExtern() {
347 fprintf(stderr
, "Parsed an extern\n");
349 // Skip token for error recovery.
354 static void HandleTopLevelExpression() {
355 // Evaluate a top-level expression into an anonymous function.
356 if (ParseTopLevelExpr()) {
357 fprintf(stderr
, "Parsed a top-level expr\n");
359 // Skip token for error recovery.
364 /// top ::= definition | external | expression | ';'
365 static void MainLoop() {
367 fprintf(stderr
, "ready> ");
369 case tok_eof
: return;
370 case ';': getNextToken(); break; // ignore top-level semicolons.
371 case tok_def
: HandleDefinition(); break;
372 case tok_extern
: HandleExtern(); break;
373 default: HandleTopLevelExpression(); break;
378 //===----------------------------------------------------------------------===//
380 //===----------------------------------------------------------------------===//
383 // Install standard binary operators.
384 // 1 is lowest precedence.
385 BinopPrecedence
['<'] = 10;
386 BinopPrecedence
['+'] = 20;
387 BinopPrecedence
['-'] = 20;
388 BinopPrecedence
['*'] = 40; // highest.
390 // Prime the first token.
391 fprintf(stderr
, "ready> ");
394 // Run the main "interpreter loop" now.