@@ -28,6 +28,7 @@ struct Token
28
28
LPAREN,
29
29
RPAREN,
30
30
PROPERTY_ACCESS,
31
+ EQUALS,
31
32
EOL
32
33
} type;
33
34
@@ -58,8 +59,9 @@ struct SingleToken {
58
59
{ ' *' , Token::OP },
59
60
{ ' /' , Token::OP },
60
61
{ ' %' , Token::OP },
61
- { ' .' , Token::PROPERTY_ACCESS },
62
- { ' ,' , Token::COMMA }// ,
62
+ { ' .' , Token::OP },
63
+ { ' ,' , Token::COMMA },
64
+ { ' =' , Token::EQUALS },
63
65
// { '\n', Token::EOL }
64
66
};
65
67
@@ -216,20 +218,43 @@ namespace ast
216
218
{
217
219
public:
218
220
Identifier (const std::string &name) : name_(name) {}
219
- std::string toString () { return " IDENTIFIER" ; }
221
+ std::string toString () { return std::string ( " IDENTIFIER ( " ) + name_ + " ) " ; }
220
222
221
223
private:
222
224
std::string name_;
223
225
};
224
226
227
+ class PropertyAccess : public Expr
228
+ {
229
+ public:
230
+ PropertyAccess (Expr *owner, Expr *property)
231
+ : owner_(owner), property_(property) {}
232
+ std::string toString ()
233
+ {
234
+ return owner_->toString () + " " + property_->toString ();
235
+ }
236
+
237
+ private:
238
+ Expr *owner_;
239
+ Expr *property_;
240
+ };
241
+
225
242
class Dim : public Node
226
243
{
227
244
public:
228
- Dim (const std::string &name) : name_(name) {}
229
- std::string toString () { return " DIM" ; }
245
+ Dim (const std::string &name, Expr *val)
246
+ : name_(name), val_(val) {}
247
+ std::string toString ()
248
+ {
249
+ if (!val_)
250
+ return " DIM" ;
251
+ else
252
+ return std::string (" DIM " ) + val_->toString ();
253
+ }
230
254
231
255
private:
232
256
std::string name_;
257
+ Expr *val_;
233
258
};
234
259
235
260
class BinaryExpr : public Expr
@@ -249,7 +274,7 @@ namespace ast
249
274
public:
250
275
CallExpr (const std::string &callee, const std::vector<Expr *> &args)
251
276
: callee_(callee), args_(args) {}
252
- std::string toString () { return " CALL" ; }
277
+ std::string toString () { return std::string ( " CALL ( " ) + callee_ + " ) " ; }
253
278
254
279
private:
255
280
std::string callee_;
@@ -259,26 +284,39 @@ namespace ast
259
284
class Function : public Node
260
285
{
261
286
public:
262
- Function (const std::string &name, const std::vector<std::string> &args, Expr *body)
263
- : name_(name), args_(args), body_(body) {}
264
- std::string toString () { return std::string (" FUNCTION\n " ) + " " + body_->toString (); }
287
+ Function (const std::string &name,
288
+ const std::vector<std::string> &args,
289
+ const std::vector<Node *> &body,
290
+ bool sub)
291
+ : name_(name), args_(args), body_(body), sub_(sub) {}
292
+ std::string toString ()
293
+ {
294
+ std::string repr (sub_ ? " SUB\n " : " FUNCTION\n " );
295
+ for (unsigned int i = 0 ; i < body_.size (); i++)
296
+ repr += " " + body_[i]->toString () + " \n " ;
297
+ return repr;
298
+ }
265
299
266
300
private:
267
301
std::string name_;
268
302
std::vector<std::string> args_;
269
- Expr *body_;
303
+ std::vector<Node *> body_;
304
+ bool sub_;
270
305
};
271
306
}
272
307
273
308
typedef std::list<Token *> TokenList;
274
309
typedef TokenList::const_reverse_iterator TokenIt;
275
310
311
+ Token *currentToken (TokenIt &it, const TokenIt &end)
312
+ {
313
+ return it != end ? *it : NULL ;
314
+ }
315
+
276
316
Token *nextToken (TokenIt &it, const TokenIt &end)
277
317
{
278
318
it++;
279
- if (it != end)
280
- return *it;
281
- else return NULL ;
319
+ return currentToken (it, end);
282
320
}
283
321
284
322
ast::Node *errorN (const char *str)
@@ -307,13 +345,27 @@ int opPrecedence(char op)
307
345
binopPrecedence[' %' ] = 10 ;
308
346
binopPrecedence[' /' ] = 40 ;
309
347
binopPrecedence[' *' ] = 40 ; // highest.
348
+ binopPrecedence[' .' ] = 1000 ;
310
349
}
311
350
312
351
int precedence = binopPrecedence[op];
313
352
if (precedence <= 0 ) return -1 ;
314
353
return precedence;
315
354
}
316
355
356
+ #define EXPECT_TOKEN (t, expected, func, error ) \
357
+ { if (!t || t->type != expected) \
358
+ return func (error); }
359
+
360
+ #define EXPECT_TOKEN_N (t, expected, error ) \
361
+ EXPECT_TOKEN (t, expected, errorN, error)
362
+
363
+ #define EXPECT_TOKEN_E (t, expected, error ) \
364
+ EXPECT_TOKEN (t, expected, errorE, error)
365
+
366
+ #define EXPECT_ANY_TOKEN (t, func, error ) \
367
+ { if (!t) return func (error); }
368
+
317
369
ast::Expr *parseLiteral (TokenIt &it, const TokenIt &end)
318
370
{
319
371
ast::Expr *node = new ast::Literal ((*it)->value );
@@ -325,50 +377,71 @@ ast::Expr *parseExpr(TokenIt &it, const TokenIt &end);
325
377
326
378
ast::Expr *parseParenExpr (TokenIt &it, const TokenIt &end)
327
379
{
328
- nextToken (it, end);
380
+ Token *current = nextToken (it, end);
329
381
ast::Expr *node = parseExpr (it, end);
330
- if ((*it)-> type != Token::RPAREN)
331
- return errorE ( " Expected ')'" );
382
+ current = currentToken (it, end);
383
+ EXPECT_TOKEN_E (current, Token::RPAREN, " Expected ')'" );
332
384
333
385
nextToken (it, end);
334
386
return node;
335
387
}
336
388
337
- ast::Expr *parseIdentifer (TokenIt &it, const TokenIt &end)
389
+ ast::Expr *parseIdentifier (TokenIt &it, const TokenIt &end)
338
390
{
339
- std::string identifier = (*it)->value ;
340
- Token *current = nextToken (it, end);
341
- if (!current || current->type != Token::LPAREN)
391
+ Token *current = currentToken (it, end);
392
+ EXPECT_ANY_TOKEN (current, errorE, " Identifier expected" );
393
+
394
+ std::string identifier = current->value ;
395
+ current = nextToken (it, end);
396
+ if (!current || (current->type != Token::LPAREN &&
397
+ current->type != Token::PROPERTY_ACCESS))
342
398
return new ast::Identifier (identifier);
343
399
344
- current = nextToken (it, end);
345
- std::vector<ast::Expr *> args;
346
- if (current->type != Token::RPAREN)
347
- while (1 )
348
- {
349
- ast::Expr *arg = parseExpr (it, end);
350
- if (!arg) return NULL ;
351
- args.push_back (arg);
400
+ if (current->type == Token::LPAREN)
401
+ {
402
+ current = nextToken (it, end);
403
+ EXPECT_ANY_TOKEN (current, errorE, " Expression or ')' expected" );
404
+
405
+ std::vector<ast::Expr *> args;
406
+ if (current->type != Token::RPAREN)
407
+ while (1 )
408
+ {
409
+ ast::Expr *arg = parseExpr (it, end);
410
+ if (!arg) return NULL ;
411
+ args.push_back (arg);
352
412
353
- current = *it;
413
+ current = currentToken (it, end);
414
+ EXPECT_ANY_TOKEN (current, errorE, " Expected ')' or ','" );
354
415
355
- if (current->type == Token::RPAREN)
356
- break ;
357
- else if (current->type != Token::COMMA)
358
- return errorE (" Expected ')' or ','" );
416
+ if (current->type == Token::RPAREN)
417
+ break ;
418
+ else if (current->type != Token::COMMA)
419
+ return errorE (" Expected ')' or ','" );
359
420
360
- current = nextToken (it, end);
361
- }
421
+ current = nextToken (it, end);
422
+ }
362
423
363
- nextToken (it, end);
364
- return new ast::CallExpr (identifier, args);
424
+ nextToken (it, end);
425
+ return new ast::CallExpr (identifier, args);
426
+ }
427
+
428
+ current = nextToken (it, end);
429
+ EXPECT_TOKEN_E (current, Token::IDENTIFIER, " Identifier expected after '.'" );
430
+
431
+ ast::Expr *property = parseIdentifier (it, end);
432
+ // if(!property)
433
+ return errorE (" Identifier expected after '.'" );
434
+ // return new ast::PropertyAccess(identifier, property);
365
435
}
366
436
367
437
ast::Expr *parsePrimary (TokenIt &it, const TokenIt &end)
368
438
{
369
- switch ((*it)->type )
439
+ Token *current = currentToken (it, end);
440
+ EXPECT_ANY_TOKEN (current, errorE, " Expected a primary expression" );
441
+
442
+ switch (current->type )
370
443
{
371
- case Token::IDENTIFIER: return parseIdentifer (it, end);
444
+ case Token::IDENTIFIER: return parseIdentifier (it, end);
372
445
case Token::NUMBER: return parseLiteral (it, end);
373
446
case Token::LPAREN: return parseParenExpr (it, end);
374
447
default : return errorE (" Unexpected token when expecting an expression" );
@@ -378,18 +451,29 @@ ast::Expr *parsePrimary(TokenIt &it, const TokenIt &end)
378
451
ast::Node *parseDim (TokenIt &it, const TokenIt &end)
379
452
{
380
453
Token *current = nextToken (it, end);
381
-
382
- if (!current || current->type != Token::IDENTIFIER)
383
- return errorN (" Expected identifier" );
454
+ EXPECT_TOKEN_N (current, Token::IDENTIFIER, " Expected identifier" );
455
+
456
+ std::string name = current->value ;
457
+
458
+ current = nextToken (it, end);
459
+ // FIXME: Dim foo 5
460
+ if (!current || current->type != Token::EQUALS)
461
+ return new ast::Dim (name, NULL );
384
462
385
- ast::Node *dim = new ast::Dim (current->value );
386
463
nextToken (it, end);
387
- return dim;
464
+ ast::Expr *val = parseExpr (it, end);
465
+ if (!val)
466
+ return errorN (" Expected expression" );
467
+
468
+ return new ast::Dim (name, val);
388
469
}
389
470
390
471
ast::Node *parseStatement (TokenIt &it, const TokenIt &end)
391
472
{
392
- switch ((*it)->type )
473
+ Token *current = currentToken (it, end);
474
+ EXPECT_ANY_TOKEN (current, errorN, " Statement expected" );
475
+
476
+ switch (current->type )
393
477
{
394
478
case Token::DIM: return parseDim (it, end);
395
479
default : return parseExpr (it, end);
@@ -400,7 +484,9 @@ ast::Expr *parseBinOpRHS(int exprPrecendence, ast::Expr *lhs, TokenIt &it, const
400
484
{
401
485
while (1 )
402
486
{
403
- char binOp = it != end ? (*it)->value .c_str ()[0 ] : 0 ;
487
+ Token *current = currentToken (it, end);
488
+
489
+ char binOp = current ? current->value .c_str ()[0 ] : 0 ;
404
490
int precendence = opPrecedence (binOp);
405
491
if (precendence < exprPrecendence)
406
492
return lhs;
@@ -409,7 +495,9 @@ ast::Expr *parseBinOpRHS(int exprPrecendence, ast::Expr *lhs, TokenIt &it, const
409
495
if (!rhs)
410
496
return NULL ;
411
497
412
- int nextPrecedence = opPrecedence (it != end ? (*it)->value .c_str ()[0 ] : 0 );
498
+ current = currentToken (it, end);
499
+
500
+ int nextPrecedence = opPrecedence (current ? current->value .c_str ()[0 ] : 0 );
413
501
if (precendence < nextPrecedence)
414
502
{
415
503
rhs = parseBinOpRHS (precendence + 1 , rhs, it, end);
@@ -429,6 +517,66 @@ ast::Expr *parseExpr(TokenIt &it, const TokenIt &end)
429
517
return parseBinOpRHS (NULL , lhs, it, end);
430
518
}
431
519
520
+ ast::Node *parseFunction (TokenIt &it, const TokenIt &end, bool sub)
521
+ {
522
+ Token *current = nextToken (it, end);
523
+ EXPECT_TOKEN_N (current, Token::IDENTIFIER, " Expected function identifier" );
524
+
525
+ std::string name = current->value ;
526
+
527
+ current = nextToken (it, end);
528
+ EXPECT_TOKEN_N (current, Token::LPAREN, " Expected '('" );
529
+
530
+ std::vector<std::string> args;
531
+ while (1 )
532
+ {
533
+ current = nextToken (it, end);
534
+ if (current && current->type == Token::IDENTIFIER)
535
+ {
536
+ args.push_back (current->value );
537
+ current = nextToken (it, end);
538
+ if (current->type == Token::RPAREN)
539
+ break ;
540
+ EXPECT_TOKEN_N (current, Token::COMMA, " Expected ',' in arg list" );
541
+ }
542
+ else break ;
543
+ }
544
+
545
+ EXPECT_TOKEN_N (current, Token::RPAREN, " Expected ')'" );
546
+ current = nextToken (it, end);
547
+ std::vector<ast::Node *> body;
548
+ while (1 )
549
+ {
550
+ current = currentToken (it, end);
551
+ EXPECT_ANY_TOKEN (current, errorN, " Statement or function end expected" );
552
+
553
+ if (current->type == Token::END)
554
+ break ;
555
+
556
+ if (ast::Node *stmt = parseStatement (it, end))
557
+ body.push_back (stmt);
558
+ else return errorN (" Statement or function end expected" );
559
+ }
560
+
561
+ current = nextToken (it, end);
562
+ EXPECT_TOKEN_N (current, (sub ? Token::SUB : Token::FUNCTION),
563
+ " Function end expected" );
564
+
565
+ nextToken (it, end);
566
+
567
+ return new ast::Function (name, args, body, sub);
568
+ }
569
+
570
+ ast::Node *parseTopLevel (TokenIt &it, const TokenIt &end)
571
+ {
572
+ switch ((*it)->type )
573
+ {
574
+ case Token::FUNCTION: return parseFunction (it, end, false );
575
+ case Token::SUB: return parseFunction (it, end, true );
576
+ default : return parseStatement (it, end);
577
+ }
578
+ }
579
+
432
580
typedef std::list<ast::Node *> ASTNodeList;
433
581
typedef ASTNodeList::reverse_iterator ASTNodeListIt;
434
582
@@ -439,7 +587,7 @@ ASTNodeList *generateAST(const TokenList &tokens)
439
587
TokenIt it = tokens.rbegin (), end = tokens.rend ();
440
588
while (it != end)
441
589
{
442
- node = parseStatement (it, end);
590
+ node = parseTopLevel (it, end);
443
591
if (node)
444
592
ast->push_back (node);
445
593
else break ;
@@ -473,6 +621,7 @@ int main(int /*argc*/, char */*argv*/[])
473
621
474
622
std::cin.clear ();
475
623
} while (tokens.size ());
476
-
624
+
625
+ std::cout << std::endl;
477
626
return 0 ;
478
627
}
0 commit comments