blob: 4dc917e3f06f3293bac74f00c35913c877e3c9b2 [file] [log] [blame]
Lang Hamesbcdb9942016-09-19 23:00:27 +00001#include "llvm/ADT/STLExtras.h"
Eugene Zelenkoae7ac952016-11-18 21:57:58 +00002#include <algorithm>
Will Dietz981af002013-10-12 00:55:57 +00003#include <cctype>
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +00004#include <cstdio>
Eugene Zelenkof981ec42016-05-19 01:08:04 +00005#include <cstdlib>
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +00006#include <map>
David Blaikie96a9d8c2015-11-03 16:23:21 +00007#include <memory>
Chandler Carruth605e30e2012-12-04 10:16:57 +00008#include <string>
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +00009#include <vector>
10
11//===----------------------------------------------------------------------===//
12// Lexer
13//===----------------------------------------------------------------------===//
14
15// The lexer returns tokens [0-255] if it is an unknown character, otherwise one
16// of these for known things.
17enum Token {
18 tok_eof = -1,
19
20 // commands
Lang Hames59b0da82015-08-19 18:15:58 +000021 tok_def = -2,
22 tok_extern = -3,
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +000023
24 // primary
Lang Hames59b0da82015-08-19 18:15:58 +000025 tok_identifier = -4,
26 tok_number = -5
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +000027};
28
Lang Hames59b0da82015-08-19 18:15:58 +000029static std::string IdentifierStr; // Filled in if tok_identifier
30static double NumVal; // Filled in if tok_number
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +000031
32/// gettok - Return the next token from standard input.
33static int gettok() {
34 static int LastChar = ' ';
35
36 // Skip any whitespace.
37 while (isspace(LastChar))
38 LastChar = getchar();
39
40 if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]*
41 IdentifierStr = LastChar;
42 while (isalnum((LastChar = getchar())))
43 IdentifierStr += LastChar;
44
Lang Hames59b0da82015-08-19 18:15:58 +000045 if (IdentifierStr == "def")
46 return tok_def;
47 if (IdentifierStr == "extern")
48 return tok_extern;
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +000049 return tok_identifier;
50 }
51
Lang Hames59b0da82015-08-19 18:15:58 +000052 if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +000053 std::string NumStr;
54 do {
55 NumStr += LastChar;
56 LastChar = getchar();
57 } while (isdigit(LastChar) || LastChar == '.');
58
Hans Wennborgcc9deb42015-09-29 18:02:48 +000059 NumVal = strtod(NumStr.c_str(), nullptr);
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +000060 return tok_number;
61 }
62
63 if (LastChar == '#') {
64 // Comment until end of line.
Lang Hames59b0da82015-08-19 18:15:58 +000065 do
66 LastChar = getchar();
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +000067 while (LastChar != EOF && LastChar != '\n' && LastChar != '\r');
Lang Hames59b0da82015-08-19 18:15:58 +000068
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +000069 if (LastChar != EOF)
70 return gettok();
71 }
Lang Hames59b0da82015-08-19 18:15:58 +000072
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +000073 // Check for end of file. Don't eat the EOF.
74 if (LastChar == EOF)
75 return tok_eof;
76
77 // Otherwise, just return the character as its ascii value.
78 int ThisChar = LastChar;
79 LastChar = getchar();
80 return ThisChar;
81}
82
83//===----------------------------------------------------------------------===//
84// Abstract Syntax Tree (aka Parse Tree)
85//===----------------------------------------------------------------------===//
Eugene Zelenkoae7ac952016-11-18 21:57:58 +000086
Juergen Ributzka05c5a932013-11-19 03:08:35 +000087namespace {
Eugene Zelenkoae7ac952016-11-18 21:57:58 +000088
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +000089/// ExprAST - Base class for all expression nodes.
90class ExprAST {
91public:
Eugene Zelenkoae7ac952016-11-18 21:57:58 +000092 virtual ~ExprAST() = default;
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +000093};
94
95/// NumberExprAST - Expression class for numeric literals like "1.0".
96class NumberExprAST : public ExprAST {
Lang Hames59b0da82015-08-19 18:15:58 +000097 double Val;
98
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +000099public:
Lang Hames59b0da82015-08-19 18:15:58 +0000100 NumberExprAST(double Val) : Val(Val) {}
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000101};
102
103/// VariableExprAST - Expression class for referencing a variable, like "a".
104class VariableExprAST : public ExprAST {
105 std::string Name;
Lang Hames59b0da82015-08-19 18:15:58 +0000106
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000107public:
Lang Hames09bf4c12015-08-18 18:11:06 +0000108 VariableExprAST(const std::string &Name) : Name(Name) {}
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000109};
110
111/// BinaryExprAST - Expression class for a binary operator.
112class BinaryExprAST : public ExprAST {
Lang Hames59b0da82015-08-19 18:15:58 +0000113 char Op;
114 std::unique_ptr<ExprAST> LHS, RHS;
115
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000116public:
Lang Hames09bf4c12015-08-18 18:11:06 +0000117 BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
Lang Hames59b0da82015-08-19 18:15:58 +0000118 std::unique_ptr<ExprAST> RHS)
119 : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000120};
121
122/// CallExprAST - Expression class for function calls.
123class CallExprAST : public ExprAST {
124 std::string Callee;
Lang Hames09bf4c12015-08-18 18:11:06 +0000125 std::vector<std::unique_ptr<ExprAST>> Args;
Lang Hames59b0da82015-08-19 18:15:58 +0000126
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000127public:
Lang Hames09bf4c12015-08-18 18:11:06 +0000128 CallExprAST(const std::string &Callee,
129 std::vector<std::unique_ptr<ExprAST>> Args)
Lang Hames59b0da82015-08-19 18:15:58 +0000130 : Callee(Callee), Args(std::move(Args)) {}
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000131};
132
133/// PrototypeAST - This class represents the "prototype" for a function,
134/// which captures its name, and its argument names (thus implicitly the number
135/// of arguments the function takes).
136class PrototypeAST {
137 std::string Name;
138 std::vector<std::string> Args;
Lang Hames59b0da82015-08-19 18:15:58 +0000139
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000140public:
Lang Hames09bf4c12015-08-18 18:11:06 +0000141 PrototypeAST(const std::string &Name, std::vector<std::string> Args)
Lang Hames59b0da82015-08-19 18:15:58 +0000142 : Name(Name), Args(std::move(Args)) {}
Mehdi Aminibb6805d2017-02-11 21:26:52 +0000143
144 const std::string &getName() const { return Name; }
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000145};
146
147/// FunctionAST - This class represents a function definition itself.
148class FunctionAST {
Lang Hames59b0da82015-08-19 18:15:58 +0000149 std::unique_ptr<PrototypeAST> Proto;
150 std::unique_ptr<ExprAST> Body;
151
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000152public:
Lang Hames09bf4c12015-08-18 18:11:06 +0000153 FunctionAST(std::unique_ptr<PrototypeAST> Proto,
Lang Hames59b0da82015-08-19 18:15:58 +0000154 std::unique_ptr<ExprAST> Body)
155 : Proto(std::move(Proto)), Body(std::move(Body)) {}
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000156};
Eugene Zelenkoae7ac952016-11-18 21:57:58 +0000157
Juergen Ributzka05c5a932013-11-19 03:08:35 +0000158} // end anonymous namespace
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000159
160//===----------------------------------------------------------------------===//
161// Parser
162//===----------------------------------------------------------------------===//
163
164/// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current
165/// token the parser is looking at. getNextToken reads another token from the
166/// lexer and updates CurTok with its results.
167static int CurTok;
Lang Hames59b0da82015-08-19 18:15:58 +0000168static int getNextToken() { return CurTok = gettok(); }
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000169
170/// BinopPrecedence - This holds the precedence for each binary operator that is
171/// defined.
172static std::map<char, int> BinopPrecedence;
173
174/// GetTokPrecedence - Get the precedence of the pending binary operator token.
175static int GetTokPrecedence() {
176 if (!isascii(CurTok))
177 return -1;
Lang Hames59b0da82015-08-19 18:15:58 +0000178
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000179 // Make sure it's a declared binop.
180 int TokPrec = BinopPrecedence[CurTok];
Lang Hames59b0da82015-08-19 18:15:58 +0000181 if (TokPrec <= 0)
182 return -1;
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000183 return TokPrec;
184}
185
Lang Hames5d045a92016-03-25 17:41:26 +0000186/// LogError* - These are little helper functions for error handling.
187std::unique_ptr<ExprAST> LogError(const char *Str) {
Lang Hames09bf4c12015-08-18 18:11:06 +0000188 fprintf(stderr, "Error: %s\n", Str);
189 return nullptr;
190}
Lang Hames5d045a92016-03-25 17:41:26 +0000191std::unique_ptr<PrototypeAST> LogErrorP(const char *Str) {
192 LogError(Str);
Lang Hames09bf4c12015-08-18 18:11:06 +0000193 return nullptr;
194}
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000195
Lang Hames09bf4c12015-08-18 18:11:06 +0000196static std::unique_ptr<ExprAST> ParseExpression();
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000197
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000198/// numberexpr ::= number
Lang Hames09bf4c12015-08-18 18:11:06 +0000199static std::unique_ptr<ExprAST> ParseNumberExpr() {
Lang Hamesbcdb9942016-09-19 23:00:27 +0000200 auto Result = llvm::make_unique<NumberExprAST>(NumVal);
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000201 getNextToken(); // consume the number
Lang Hames09bf4c12015-08-18 18:11:06 +0000202 return std::move(Result);
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000203}
204
205/// parenexpr ::= '(' expression ')'
Lang Hames09bf4c12015-08-18 18:11:06 +0000206static std::unique_ptr<ExprAST> ParseParenExpr() {
Lang Hames59b0da82015-08-19 18:15:58 +0000207 getNextToken(); // eat (.
Lang Hames09bf4c12015-08-18 18:11:06 +0000208 auto V = ParseExpression();
209 if (!V)
210 return nullptr;
Lang Hames59b0da82015-08-19 18:15:58 +0000211
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000212 if (CurTok != ')')
Lang Hames5d045a92016-03-25 17:41:26 +0000213 return LogError("expected ')'");
Lang Hames59b0da82015-08-19 18:15:58 +0000214 getNextToken(); // eat ).
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000215 return V;
216}
217
Lang Hames59b0da82015-08-19 18:15:58 +0000218/// identifierexpr
219/// ::= identifier
220/// ::= identifier '(' expression* ')'
221static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
222 std::string IdName = IdentifierStr;
223
224 getNextToken(); // eat identifier.
225
226 if (CurTok != '(') // Simple variable ref.
Lang Hamesbcdb9942016-09-19 23:00:27 +0000227 return llvm::make_unique<VariableExprAST>(IdName);
Lang Hames59b0da82015-08-19 18:15:58 +0000228
229 // Call.
230 getNextToken(); // eat (
231 std::vector<std::unique_ptr<ExprAST>> Args;
232 if (CurTok != ')') {
Eugene Zelenkof981ec42016-05-19 01:08:04 +0000233 while (true) {
Lang Hames59b0da82015-08-19 18:15:58 +0000234 if (auto Arg = ParseExpression())
235 Args.push_back(std::move(Arg));
236 else
237 return nullptr;
238
239 if (CurTok == ')')
240 break;
241
242 if (CurTok != ',')
Lang Hames5d045a92016-03-25 17:41:26 +0000243 return LogError("Expected ')' or ',' in argument list");
Lang Hames59b0da82015-08-19 18:15:58 +0000244 getNextToken();
245 }
246 }
247
248 // Eat the ')'.
249 getNextToken();
250
Lang Hamesbcdb9942016-09-19 23:00:27 +0000251 return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
Lang Hames59b0da82015-08-19 18:15:58 +0000252}
253
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000254/// primary
255/// ::= identifierexpr
256/// ::= numberexpr
257/// ::= parenexpr
Lang Hames09bf4c12015-08-18 18:11:06 +0000258static std::unique_ptr<ExprAST> ParsePrimary() {
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000259 switch (CurTok) {
Lang Hames59b0da82015-08-19 18:15:58 +0000260 default:
Lang Hames5d045a92016-03-25 17:41:26 +0000261 return LogError("unknown token when expecting an expression");
Lang Hames59b0da82015-08-19 18:15:58 +0000262 case tok_identifier:
263 return ParseIdentifierExpr();
264 case tok_number:
265 return ParseNumberExpr();
266 case '(':
267 return ParseParenExpr();
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000268 }
269}
270
271/// binoprhs
272/// ::= ('+' primary)*
Lang Hames09bf4c12015-08-18 18:11:06 +0000273static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
274 std::unique_ptr<ExprAST> LHS) {
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000275 // If this is a binop, find its precedence.
Eugene Zelenkof981ec42016-05-19 01:08:04 +0000276 while (true) {
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000277 int TokPrec = GetTokPrecedence();
Lang Hames59b0da82015-08-19 18:15:58 +0000278
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000279 // If this is a binop that binds at least as tightly as the current binop,
280 // consume it, otherwise we are done.
281 if (TokPrec < ExprPrec)
282 return LHS;
Lang Hames59b0da82015-08-19 18:15:58 +0000283
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000284 // Okay, we know this is a binop.
285 int BinOp = CurTok;
Lang Hames59b0da82015-08-19 18:15:58 +0000286 getNextToken(); // eat binop
287
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000288 // Parse the primary expression after the binary operator.
Lang Hames09bf4c12015-08-18 18:11:06 +0000289 auto RHS = ParsePrimary();
Lang Hames59b0da82015-08-19 18:15:58 +0000290 if (!RHS)
291 return nullptr;
292
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000293 // If BinOp binds less tightly with RHS than the operator after RHS, let
294 // the pending operator take RHS as its LHS.
295 int NextPrec = GetTokPrecedence();
296 if (TokPrec < NextPrec) {
Lang Hames59b0da82015-08-19 18:15:58 +0000297 RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS));
298 if (!RHS)
299 return nullptr;
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000300 }
Lang Hames59b0da82015-08-19 18:15:58 +0000301
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000302 // Merge LHS/RHS.
Lang Hamesbcdb9942016-09-19 23:00:27 +0000303 LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS),
304 std::move(RHS));
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000305 }
306}
307
308/// expression
309/// ::= primary binoprhs
310///
Lang Hames09bf4c12015-08-18 18:11:06 +0000311static std::unique_ptr<ExprAST> ParseExpression() {
312 auto LHS = ParsePrimary();
Lang Hames59b0da82015-08-19 18:15:58 +0000313 if (!LHS)
314 return nullptr;
315
Lang Hames09bf4c12015-08-18 18:11:06 +0000316 return ParseBinOpRHS(0, std::move(LHS));
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000317}
318
319/// prototype
320/// ::= id '(' id* ')'
Lang Hames09bf4c12015-08-18 18:11:06 +0000321static std::unique_ptr<PrototypeAST> ParsePrototype() {
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000322 if (CurTok != tok_identifier)
Lang Hames5d045a92016-03-25 17:41:26 +0000323 return LogErrorP("Expected function name in prototype");
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000324
325 std::string FnName = IdentifierStr;
326 getNextToken();
Lang Hames59b0da82015-08-19 18:15:58 +0000327
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000328 if (CurTok != '(')
Lang Hames5d045a92016-03-25 17:41:26 +0000329 return LogErrorP("Expected '(' in prototype");
Lang Hames59b0da82015-08-19 18:15:58 +0000330
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000331 std::vector<std::string> ArgNames;
332 while (getNextToken() == tok_identifier)
333 ArgNames.push_back(IdentifierStr);
334 if (CurTok != ')')
Lang Hames5d045a92016-03-25 17:41:26 +0000335 return LogErrorP("Expected ')' in prototype");
Lang Hames59b0da82015-08-19 18:15:58 +0000336
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000337 // success.
Lang Hames59b0da82015-08-19 18:15:58 +0000338 getNextToken(); // eat ')'.
339
Lang Hamesbcdb9942016-09-19 23:00:27 +0000340 return llvm::make_unique<PrototypeAST>(FnName, std::move(ArgNames));
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000341}
342
343/// definition ::= 'def' prototype expression
Lang Hames09bf4c12015-08-18 18:11:06 +0000344static std::unique_ptr<FunctionAST> ParseDefinition() {
Lang Hames59b0da82015-08-19 18:15:58 +0000345 getNextToken(); // eat def.
Lang Hames09bf4c12015-08-18 18:11:06 +0000346 auto Proto = ParsePrototype();
Lang Hames59b0da82015-08-19 18:15:58 +0000347 if (!Proto)
348 return nullptr;
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000349
Lang Hames09bf4c12015-08-18 18:11:06 +0000350 if (auto E = ParseExpression())
Lang Hamesbcdb9942016-09-19 23:00:27 +0000351 return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
Lang Hames09bf4c12015-08-18 18:11:06 +0000352 return nullptr;
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000353}
354
355/// toplevelexpr ::= expression
Lang Hames09bf4c12015-08-18 18:11:06 +0000356static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
357 if (auto E = ParseExpression()) {
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000358 // Make an anonymous proto.
Lang Hamesbcdb9942016-09-19 23:00:27 +0000359 auto Proto = llvm::make_unique<PrototypeAST>("__anon_expr",
360 std::vector<std::string>());
361 return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000362 }
Lang Hames09bf4c12015-08-18 18:11:06 +0000363 return nullptr;
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000364}
365
366/// external ::= 'extern' prototype
Lang Hames09bf4c12015-08-18 18:11:06 +0000367static std::unique_ptr<PrototypeAST> ParseExtern() {
Lang Hames59b0da82015-08-19 18:15:58 +0000368 getNextToken(); // eat extern.
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000369 return ParsePrototype();
370}
371
372//===----------------------------------------------------------------------===//
373// Top-Level parsing
374//===----------------------------------------------------------------------===//
375
376static void HandleDefinition() {
377 if (ParseDefinition()) {
378 fprintf(stderr, "Parsed a function definition.\n");
379 } else {
380 // Skip token for error recovery.
381 getNextToken();
382 }
383}
384
385static void HandleExtern() {
386 if (ParseExtern()) {
387 fprintf(stderr, "Parsed an extern\n");
388 } else {
389 // Skip token for error recovery.
390 getNextToken();
391 }
392}
393
394static void HandleTopLevelExpression() {
395 // Evaluate a top-level expression into an anonymous function.
396 if (ParseTopLevelExpr()) {
397 fprintf(stderr, "Parsed a top-level expr\n");
398 } else {
399 // Skip token for error recovery.
400 getNextToken();
401 }
402}
403
404/// top ::= definition | external | expression | ';'
405static void MainLoop() {
Eugene Zelenkof981ec42016-05-19 01:08:04 +0000406 while (true) {
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000407 fprintf(stderr, "ready> ");
408 switch (CurTok) {
Lang Hames59b0da82015-08-19 18:15:58 +0000409 case tok_eof:
410 return;
411 case ';': // ignore top-level semicolons.
412 getNextToken();
413 break;
414 case tok_def:
415 HandleDefinition();
416 break;
417 case tok_extern:
418 HandleExtern();
419 break;
420 default:
421 HandleTopLevelExpression();
422 break;
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000423 }
424 }
425}
426
427//===----------------------------------------------------------------------===//
428// Main driver code.
429//===----------------------------------------------------------------------===//
430
431int main() {
432 // Install standard binary operators.
433 // 1 is lowest precedence.
434 BinopPrecedence['<'] = 10;
435 BinopPrecedence['+'] = 20;
436 BinopPrecedence['-'] = 20;
Lang Hames59b0da82015-08-19 18:15:58 +0000437 BinopPrecedence['*'] = 40; // highest.
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000438
439 // Prime the first token.
440 fprintf(stderr, "ready> ");
441 getNextToken();
442
443 // Run the main "interpreter loop" now.
444 MainLoop();
445
446 return 0;
447}