blob: 8357c5b63fb70bc99426a7b820a953373c183775 [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)) {}
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000143};
144
145/// FunctionAST - This class represents a function definition itself.
146class FunctionAST {
Lang Hames59b0da82015-08-19 18:15:58 +0000147 std::unique_ptr<PrototypeAST> Proto;
148 std::unique_ptr<ExprAST> Body;
149
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000150public:
Lang Hames09bf4c12015-08-18 18:11:06 +0000151 FunctionAST(std::unique_ptr<PrototypeAST> Proto,
Lang Hames59b0da82015-08-19 18:15:58 +0000152 std::unique_ptr<ExprAST> Body)
153 : Proto(std::move(Proto)), Body(std::move(Body)) {}
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000154};
Eugene Zelenkoae7ac952016-11-18 21:57:58 +0000155
Juergen Ributzka05c5a932013-11-19 03:08:35 +0000156} // end anonymous namespace
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000157
158//===----------------------------------------------------------------------===//
159// Parser
160//===----------------------------------------------------------------------===//
161
162/// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current
163/// token the parser is looking at. getNextToken reads another token from the
164/// lexer and updates CurTok with its results.
165static int CurTok;
Lang Hames59b0da82015-08-19 18:15:58 +0000166static int getNextToken() { return CurTok = gettok(); }
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000167
168/// BinopPrecedence - This holds the precedence for each binary operator that is
169/// defined.
170static std::map<char, int> BinopPrecedence;
171
172/// GetTokPrecedence - Get the precedence of the pending binary operator token.
173static int GetTokPrecedence() {
174 if (!isascii(CurTok))
175 return -1;
Lang Hames59b0da82015-08-19 18:15:58 +0000176
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000177 // Make sure it's a declared binop.
178 int TokPrec = BinopPrecedence[CurTok];
Lang Hames59b0da82015-08-19 18:15:58 +0000179 if (TokPrec <= 0)
180 return -1;
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000181 return TokPrec;
182}
183
Lang Hames5d045a92016-03-25 17:41:26 +0000184/// LogError* - These are little helper functions for error handling.
185std::unique_ptr<ExprAST> LogError(const char *Str) {
Lang Hames09bf4c12015-08-18 18:11:06 +0000186 fprintf(stderr, "Error: %s\n", Str);
187 return nullptr;
188}
Lang Hames5d045a92016-03-25 17:41:26 +0000189std::unique_ptr<PrototypeAST> LogErrorP(const char *Str) {
190 LogError(Str);
Lang Hames09bf4c12015-08-18 18:11:06 +0000191 return nullptr;
192}
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000193
Lang Hames09bf4c12015-08-18 18:11:06 +0000194static std::unique_ptr<ExprAST> ParseExpression();
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000195
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000196/// numberexpr ::= number
Lang Hames09bf4c12015-08-18 18:11:06 +0000197static std::unique_ptr<ExprAST> ParseNumberExpr() {
Lang Hamesbcdb9942016-09-19 23:00:27 +0000198 auto Result = llvm::make_unique<NumberExprAST>(NumVal);
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000199 getNextToken(); // consume the number
Lang Hames09bf4c12015-08-18 18:11:06 +0000200 return std::move(Result);
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000201}
202
203/// parenexpr ::= '(' expression ')'
Lang Hames09bf4c12015-08-18 18:11:06 +0000204static std::unique_ptr<ExprAST> ParseParenExpr() {
Lang Hames59b0da82015-08-19 18:15:58 +0000205 getNextToken(); // eat (.
Lang Hames09bf4c12015-08-18 18:11:06 +0000206 auto V = ParseExpression();
207 if (!V)
208 return nullptr;
Lang Hames59b0da82015-08-19 18:15:58 +0000209
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000210 if (CurTok != ')')
Lang Hames5d045a92016-03-25 17:41:26 +0000211 return LogError("expected ')'");
Lang Hames59b0da82015-08-19 18:15:58 +0000212 getNextToken(); // eat ).
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000213 return V;
214}
215
Lang Hames59b0da82015-08-19 18:15:58 +0000216/// identifierexpr
217/// ::= identifier
218/// ::= identifier '(' expression* ')'
219static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
220 std::string IdName = IdentifierStr;
221
222 getNextToken(); // eat identifier.
223
224 if (CurTok != '(') // Simple variable ref.
Lang Hamesbcdb9942016-09-19 23:00:27 +0000225 return llvm::make_unique<VariableExprAST>(IdName);
Lang Hames59b0da82015-08-19 18:15:58 +0000226
227 // Call.
228 getNextToken(); // eat (
229 std::vector<std::unique_ptr<ExprAST>> Args;
230 if (CurTok != ')') {
Eugene Zelenkof981ec42016-05-19 01:08:04 +0000231 while (true) {
Lang Hames59b0da82015-08-19 18:15:58 +0000232 if (auto Arg = ParseExpression())
233 Args.push_back(std::move(Arg));
234 else
235 return nullptr;
236
237 if (CurTok == ')')
238 break;
239
240 if (CurTok != ',')
Lang Hames5d045a92016-03-25 17:41:26 +0000241 return LogError("Expected ')' or ',' in argument list");
Lang Hames59b0da82015-08-19 18:15:58 +0000242 getNextToken();
243 }
244 }
245
246 // Eat the ')'.
247 getNextToken();
248
Lang Hamesbcdb9942016-09-19 23:00:27 +0000249 return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
Lang Hames59b0da82015-08-19 18:15:58 +0000250}
251
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000252/// primary
253/// ::= identifierexpr
254/// ::= numberexpr
255/// ::= parenexpr
Lang Hames09bf4c12015-08-18 18:11:06 +0000256static std::unique_ptr<ExprAST> ParsePrimary() {
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000257 switch (CurTok) {
Lang Hames59b0da82015-08-19 18:15:58 +0000258 default:
Lang Hames5d045a92016-03-25 17:41:26 +0000259 return LogError("unknown token when expecting an expression");
Lang Hames59b0da82015-08-19 18:15:58 +0000260 case tok_identifier:
261 return ParseIdentifierExpr();
262 case tok_number:
263 return ParseNumberExpr();
264 case '(':
265 return ParseParenExpr();
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000266 }
267}
268
269/// binoprhs
270/// ::= ('+' primary)*
Lang Hames09bf4c12015-08-18 18:11:06 +0000271static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
272 std::unique_ptr<ExprAST> LHS) {
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000273 // If this is a binop, find its precedence.
Eugene Zelenkof981ec42016-05-19 01:08:04 +0000274 while (true) {
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000275 int TokPrec = GetTokPrecedence();
Lang Hames59b0da82015-08-19 18:15:58 +0000276
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000277 // If this is a binop that binds at least as tightly as the current binop,
278 // consume it, otherwise we are done.
279 if (TokPrec < ExprPrec)
280 return LHS;
Lang Hames59b0da82015-08-19 18:15:58 +0000281
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000282 // Okay, we know this is a binop.
283 int BinOp = CurTok;
Lang Hames59b0da82015-08-19 18:15:58 +0000284 getNextToken(); // eat binop
285
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000286 // Parse the primary expression after the binary operator.
Lang Hames09bf4c12015-08-18 18:11:06 +0000287 auto RHS = ParsePrimary();
Lang Hames59b0da82015-08-19 18:15:58 +0000288 if (!RHS)
289 return nullptr;
290
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000291 // If BinOp binds less tightly with RHS than the operator after RHS, let
292 // the pending operator take RHS as its LHS.
293 int NextPrec = GetTokPrecedence();
294 if (TokPrec < NextPrec) {
Lang Hames59b0da82015-08-19 18:15:58 +0000295 RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS));
296 if (!RHS)
297 return nullptr;
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000298 }
Lang Hames59b0da82015-08-19 18:15:58 +0000299
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000300 // Merge LHS/RHS.
Lang Hamesbcdb9942016-09-19 23:00:27 +0000301 LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS),
302 std::move(RHS));
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000303 }
304}
305
306/// expression
307/// ::= primary binoprhs
308///
Lang Hames09bf4c12015-08-18 18:11:06 +0000309static std::unique_ptr<ExprAST> ParseExpression() {
310 auto LHS = ParsePrimary();
Lang Hames59b0da82015-08-19 18:15:58 +0000311 if (!LHS)
312 return nullptr;
313
Lang Hames09bf4c12015-08-18 18:11:06 +0000314 return ParseBinOpRHS(0, std::move(LHS));
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000315}
316
317/// prototype
318/// ::= id '(' id* ')'
Lang Hames09bf4c12015-08-18 18:11:06 +0000319static std::unique_ptr<PrototypeAST> ParsePrototype() {
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000320 if (CurTok != tok_identifier)
Lang Hames5d045a92016-03-25 17:41:26 +0000321 return LogErrorP("Expected function name in prototype");
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000322
323 std::string FnName = IdentifierStr;
324 getNextToken();
Lang Hames59b0da82015-08-19 18:15:58 +0000325
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000326 if (CurTok != '(')
Lang Hames5d045a92016-03-25 17:41:26 +0000327 return LogErrorP("Expected '(' in prototype");
Lang Hames59b0da82015-08-19 18:15:58 +0000328
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000329 std::vector<std::string> ArgNames;
330 while (getNextToken() == tok_identifier)
331 ArgNames.push_back(IdentifierStr);
332 if (CurTok != ')')
Lang Hames5d045a92016-03-25 17:41:26 +0000333 return LogErrorP("Expected ')' in prototype");
Lang Hames59b0da82015-08-19 18:15:58 +0000334
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000335 // success.
Lang Hames59b0da82015-08-19 18:15:58 +0000336 getNextToken(); // eat ')'.
337
Lang Hamesbcdb9942016-09-19 23:00:27 +0000338 return llvm::make_unique<PrototypeAST>(FnName, std::move(ArgNames));
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000339}
340
341/// definition ::= 'def' prototype expression
Lang Hames09bf4c12015-08-18 18:11:06 +0000342static std::unique_ptr<FunctionAST> ParseDefinition() {
Lang Hames59b0da82015-08-19 18:15:58 +0000343 getNextToken(); // eat def.
Lang Hames09bf4c12015-08-18 18:11:06 +0000344 auto Proto = ParsePrototype();
Lang Hames59b0da82015-08-19 18:15:58 +0000345 if (!Proto)
346 return nullptr;
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000347
Lang Hames09bf4c12015-08-18 18:11:06 +0000348 if (auto E = ParseExpression())
Lang Hamesbcdb9942016-09-19 23:00:27 +0000349 return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
Lang Hames09bf4c12015-08-18 18:11:06 +0000350 return nullptr;
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000351}
352
353/// toplevelexpr ::= expression
Lang Hames09bf4c12015-08-18 18:11:06 +0000354static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
355 if (auto E = ParseExpression()) {
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000356 // Make an anonymous proto.
Lang Hamesbcdb9942016-09-19 23:00:27 +0000357 auto Proto = llvm::make_unique<PrototypeAST>("__anon_expr",
358 std::vector<std::string>());
359 return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000360 }
Lang Hames09bf4c12015-08-18 18:11:06 +0000361 return nullptr;
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000362}
363
364/// external ::= 'extern' prototype
Lang Hames09bf4c12015-08-18 18:11:06 +0000365static std::unique_ptr<PrototypeAST> ParseExtern() {
Lang Hames59b0da82015-08-19 18:15:58 +0000366 getNextToken(); // eat extern.
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000367 return ParsePrototype();
368}
369
370//===----------------------------------------------------------------------===//
371// Top-Level parsing
372//===----------------------------------------------------------------------===//
373
374static void HandleDefinition() {
375 if (ParseDefinition()) {
376 fprintf(stderr, "Parsed a function definition.\n");
377 } else {
378 // Skip token for error recovery.
379 getNextToken();
380 }
381}
382
383static void HandleExtern() {
384 if (ParseExtern()) {
385 fprintf(stderr, "Parsed an extern\n");
386 } else {
387 // Skip token for error recovery.
388 getNextToken();
389 }
390}
391
392static void HandleTopLevelExpression() {
393 // Evaluate a top-level expression into an anonymous function.
394 if (ParseTopLevelExpr()) {
395 fprintf(stderr, "Parsed a top-level expr\n");
396 } else {
397 // Skip token for error recovery.
398 getNextToken();
399 }
400}
401
402/// top ::= definition | external | expression | ';'
403static void MainLoop() {
Eugene Zelenkof981ec42016-05-19 01:08:04 +0000404 while (true) {
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000405 fprintf(stderr, "ready> ");
406 switch (CurTok) {
Lang Hames59b0da82015-08-19 18:15:58 +0000407 case tok_eof:
408 return;
409 case ';': // ignore top-level semicolons.
410 getNextToken();
411 break;
412 case tok_def:
413 HandleDefinition();
414 break;
415 case tok_extern:
416 HandleExtern();
417 break;
418 default:
419 HandleTopLevelExpression();
420 break;
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000421 }
422 }
423}
424
425//===----------------------------------------------------------------------===//
426// Main driver code.
427//===----------------------------------------------------------------------===//
428
429int main() {
430 // Install standard binary operators.
431 // 1 is lowest precedence.
432 BinopPrecedence['<'] = 10;
433 BinopPrecedence['+'] = 20;
434 BinopPrecedence['-'] = 20;
Lang Hames59b0da82015-08-19 18:15:58 +0000435 BinopPrecedence['*'] = 40; // highest.
Erick Tryzelaar21e83ea2009-09-22 21:15:19 +0000436
437 // Prime the first token.
438 fprintf(stderr, "ready> ");
439 getNextToken();
440
441 // Run the main "interpreter loop" now.
442 MainLoop();
443
444 return 0;
445}