jitcraft/AST.h
author David Anderson <dvander@alliedmods.net>
Sun Jul 01 16:36:39 2012 -0700 (2012-07-01)
changeset 22 765ab1b672a3
parent 21 af5d8e985502
child 23 8a31742781c1
permissions -rw-r--r--
Added support for fused math-assign ops (+=, etc).
dvander@0
     1
/*
dvander@0
     2
 * Copyright (C) 2012 David Anderson
dvander@0
     3
 *
dvander@0
     4
 * This file is part of JITCraft.
dvander@0
     5
 *
dvander@0
     6
 * JITCraft is free software: you can redistribute it and/or modify it under
dvander@0
     7
 * the terms of the GNU General Public License as published by the Free
dvander@0
     8
 * Software Foundation, either version 3 of the License, or (at your option)
dvander@0
     9
 * any later version.
dvander@0
    10
 * 
dvander@0
    11
 * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
dvander@0
    12
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
dvander@0
    13
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
dvander@0
    14
 *
dvander@0
    15
 * You should have received a copy of the GNU General Public License along with
dvander@0
    16
 * JITCraft. If not, see http://www.gnu.org/licenses/.
dvander@0
    17
 */
dvander@0
    18
#ifndef _include_jitcraft_ast_h_
dvander@0
    19
#define _include_jitcraft_ast_h_
dvander@0
    20
dvander@0
    21
#include "PoolAllocator.h"
dvander@0
    22
#include "Token.h"
dvander@0
    23
#include "StringPool.h"
dvander@0
    24
#include "NameBinding.h"
dvander@0
    25
dvander@0
    26
namespace jc {
dvander@0
    27
dvander@0
    28
#define ASTKINDS(_)             \
dvander@0
    29
    _(VariableDeclaration)      \
dvander@0
    30
    _(ForStatement)             \
dvander@0
    31
    _(ReturnStatement)          \
dvander@4
    32
    _(IntegerLiteral)           \
dvander@4
    33
    _(FloatLiteral)             \
dvander@21
    34
    _(StringLiteral)            \
dvander@0
    35
    _(BinaryExpression)         \
dvander@0
    36
    _(BlockStatement)           \
dvander@0
    37
    _(Assignment)               \
dvander@0
    38
    _(NameProxy)                \
dvander@0
    39
    _(ExpressionStatement)      \
dvander@0
    40
    _(FunctionStatement)        \
dvander@0
    41
    _(CallExpression)           \
dvander@0
    42
    _(IfStatement)              \
dvander@2
    43
    _(IndexExpression)          \
dvander@9
    44
    _(EnumStatement)            \
dvander@10
    45
    _(WhileStatement)           \
dvander@10
    46
    _(BreakStatement)           \
dvander@10
    47
    _(ContinueStatement)
dvander@0
    48
dvander@0
    49
// Forward declarations.
dvander@0
    50
#define _(name) class name;
dvander@0
    51
ASTKINDS(_)
dvander@0
    52
#undef _
dvander@0
    53
dvander@0
    54
class AstVisitor;
dvander@0
    55
dvander@0
    56
// Interface for AST nodes.
dvander@0
    57
class AstNode : public PoolObject
dvander@0
    58
{
dvander@0
    59
  public:
dvander@0
    60
    enum Kind {
dvander@0
    61
#       define _(name) k##name,
dvander@0
    62
        ASTKINDS(_)
dvander@0
    63
#       undef _
dvander@0
    64
        AstKind_Invalid
dvander@0
    65
    };
dvander@0
    66
    
dvander@0
    67
    virtual Kind kind() const = 0;
dvander@0
    68
dvander@0
    69
#define _(name)     bool is##name() { return kind() == k##name; }                   \
dvander@0
    70
                    name *to##name() { assert(is##name()); return (name *)this; }
dvander@0
    71
    ASTKINDS(_)
dvander@0
    72
#undef _
dvander@0
    73
dvander@0
    74
    virtual void accept(AstVisitor *visitor) = 0;
dvander@0
    75
};
dvander@0
    76
dvander@0
    77
class AstVisitor
dvander@0
    78
{
dvander@0
    79
  public:
dvander@0
    80
#define _(name) virtual void visit(name *node) = 0;
dvander@0
    81
    ASTKINDS(_)
dvander@0
    82
#undef _
dvander@0
    83
};
dvander@0
    84
dvander@0
    85
class NameLocation
dvander@0
    86
{
dvander@0
    87
  public:
dvander@0
    88
    enum Kind {
dvander@0
    89
        LOCAL
dvander@0
    90
    };
dvander@0
    91
dvander@0
    92
    static NameLocation Local(VariableDeclaration *decl) {
dvander@0
    93
        NameLocation loc;
dvander@0
    94
        loc.kind_ = LOCAL;
dvander@0
    95
        loc.u_.decl = decl;
dvander@0
    96
        return loc;
dvander@0
    97
    }
dvander@0
    98
dvander@0
    99
    Kind kind() const {
dvander@0
   100
        return kind_;
dvander@0
   101
    }
dvander@0
   102
dvander@0
   103
    VariableDeclaration *local() const {
dvander@0
   104
        assert(kind() == LOCAL);
dvander@0
   105
        return u_.decl;
dvander@0
   106
    }
dvander@0
   107
dvander@0
   108
  private:
dvander@0
   109
    Kind kind_;
dvander@0
   110
    union {
dvander@0
   111
        VariableDeclaration *decl;
dvander@0
   112
    } u_;
dvander@0
   113
};
dvander@0
   114
dvander@0
   115
class Statement : public AstNode
dvander@0
   116
{
dvander@0
   117
};
dvander@0
   118
dvander@0
   119
class Expression : public AstNode
dvander@0
   120
{
dvander@0
   121
    Type *type_;
dvander@0
   122
dvander@0
   123
  public:
dvander@0
   124
    Expression()
dvander@0
   125
      : type_(NULL)
dvander@0
   126
    {
dvander@0
   127
    }
dvander@0
   128
dvander@0
   129
    void setType(Type *type) {
dvander@0
   130
        type_ = type;
dvander@0
   131
    }
dvander@0
   132
    Type *type() const {
dvander@0
   133
        return type_;
dvander@0
   134
    }
dvander@0
   135
};
dvander@0
   136
dvander@0
   137
class Declaration : public Statement
dvander@0
   138
{
dvander@0
   139
};
dvander@0
   140
dvander@0
   141
typedef PoolList<Statement *> StatementList;
dvander@0
   142
typedef std::vector<Expression *> ExpressionList;
dvander@0
   143
dvander@0
   144
class VariableDeclaration : public Declaration
dvander@0
   145
{
dvander@0
   146
    Variable *variable_;
dvander@0
   147
    Expression *initialization_;
dvander@0
   148
    ExpressionList *postDimensions_;
dvander@4
   149
    Name *tag_;
dvander@0
   150
dvander@0
   151
  public:
dvander@4
   152
    VariableDeclaration(Variable *var, Name *tag, ExpressionList *postDimensions, Expression *initialization)
dvander@0
   153
      : variable_(var),
dvander@0
   154
        postDimensions_(postDimensions),
dvander@4
   155
        initialization_(initialization),
dvander@4
   156
        tag_(tag)
dvander@0
   157
    {
dvander@0
   158
    }
dvander@0
   159
dvander@4
   160
    Name *tag() const {
dvander@4
   161
        return tag_;
dvander@4
   162
    }
dvander@0
   163
    Kind kind() const {
dvander@0
   164
        return kVariableDeclaration;
dvander@0
   165
    }
dvander@0
   166
    Variable *variable() const {
dvander@0
   167
        return variable_;
dvander@0
   168
    }
dvander@0
   169
    Expression *initialization() const {
dvander@0
   170
        return initialization_;
dvander@0
   171
    }
dvander@0
   172
    ExpressionList *postDimensions() const {
dvander@0
   173
        return postDimensions_;
dvander@0
   174
    }
dvander@0
   175
    void accept(AstVisitor *visitor) {
dvander@0
   176
        visitor->visit(this);
dvander@0
   177
    }
dvander@0
   178
};
dvander@0
   179
dvander@14
   180
class Parameter : public PoolObject
dvander@14
   181
{
dvander@14
   182
    Variable *variable_;
dvander@14
   183
    Name *tag_;
dvander@14
   184
    bool reference_;
dvander@14
   185
dvander@14
   186
  public:
dvander@14
   187
    Parameter(Variable *var, Name *tag, bool reference)
dvander@14
   188
      : variable_(var),
dvander@14
   189
        tag_(tag),
dvander@14
   190
        reference_(reference)
dvander@14
   191
    {
dvander@14
   192
    }
dvander@14
   193
dvander@14
   194
    Name *tag() const {
dvander@14
   195
        return tag_;
dvander@14
   196
    }
dvander@14
   197
    Variable *variable() const {
dvander@14
   198
        return variable_;
dvander@14
   199
    }
dvander@14
   200
    bool reference() const {
dvander@14
   201
        return reference_;
dvander@14
   202
    }
dvander@14
   203
};
dvander@14
   204
dvander@0
   205
class NameProxy : public Expression
dvander@0
   206
{
dvander@0
   207
    Name *name_;
dvander@0
   208
    BoundName *binding_;
dvander@0
   209
dvander@0
   210
  public:
dvander@0
   211
    NameProxy(Name *name, BoundName *binding)
dvander@0
   212
      : name_(name),
dvander@0
   213
        binding_(binding)
dvander@0
   214
    {
dvander@0
   215
    }
dvander@0
   216
dvander@0
   217
    Kind kind() const {
dvander@0
   218
        return kNameProxy;
dvander@0
   219
    }
dvander@0
   220
    Name *name() const {
dvander@0
   221
        return name_;
dvander@0
   222
    }
dvander@0
   223
    void accept(AstVisitor *visitor) {
dvander@0
   224
        visitor->visit(this);
dvander@0
   225
    }
dvander@0
   226
    BoundName *binding() const {
dvander@0
   227
        return binding_;
dvander@0
   228
    }
dvander@0
   229
    void bind(BoundName *name) {
dvander@0
   230
        assert(!binding());
dvander@0
   231
        binding_ = name;
dvander@0
   232
    }
dvander@0
   233
};
dvander@0
   234
dvander@4
   235
class IntegerLiteral : public Expression
dvander@0
   236
{
dvander@0
   237
    int value_;
dvander@0
   238
dvander@0
   239
  public:
dvander@4
   240
    IntegerLiteral(int value)
dvander@0
   241
      : value_(value)
dvander@0
   242
    {
dvander@0
   243
    }
dvander@0
   244
dvander@0
   245
    Kind kind() const {
dvander@4
   246
        return kIntegerLiteral;
dvander@0
   247
    }
dvander@0
   248
    int value() const {
dvander@0
   249
        return value_;
dvander@0
   250
    }
dvander@0
   251
    void accept(AstVisitor *visitor) {
dvander@0
   252
        visitor->visit(this);
dvander@0
   253
    }
dvander@0
   254
};
dvander@0
   255
dvander@4
   256
class FloatLiteral : public Expression
dvander@4
   257
{
dvander@4
   258
    double value_;
dvander@4
   259
dvander@4
   260
  public:
dvander@4
   261
    FloatLiteral(double value)
dvander@4
   262
      : value_(value)
dvander@4
   263
    {
dvander@4
   264
    }
dvander@4
   265
dvander@4
   266
    Kind kind() const {
dvander@4
   267
        return kFloatLiteral;
dvander@4
   268
    }
dvander@4
   269
    double value() const {
dvander@4
   270
        return value_;
dvander@4
   271
    }
dvander@4
   272
    void accept(AstVisitor *visitor) {
dvander@4
   273
        visitor->visit(this);
dvander@4
   274
    }
dvander@4
   275
};
dvander@4
   276
dvander@21
   277
class StringLiteral : public Expression
dvander@21
   278
{
dvander@21
   279
    ByteArray *string_;
dvander@21
   280
dvander@21
   281
  public:
dvander@21
   282
    StringLiteral(ByteArray *array)
dvander@21
   283
      : string_(array)
dvander@21
   284
    {
dvander@21
   285
    }
dvander@21
   286
dvander@21
   287
    Kind kind() const {
dvander@21
   288
        return kStringLiteral;
dvander@21
   289
    }
dvander@21
   290
    ByteArray *string() const {
dvander@21
   291
        return string_;
dvander@21
   292
    }
dvander@21
   293
    void accept(AstVisitor *visitor) {
dvander@21
   294
        visitor->visit(this);
dvander@21
   295
    }
dvander@21
   296
};
dvander@21
   297
dvander@0
   298
class BinaryExpression : public Expression
dvander@0
   299
{
dvander@0
   300
    Expression *left_;
dvander@0
   301
    Expression *right_;
dvander@0
   302
    TokenKind token_;
dvander@0
   303
dvander@0
   304
  public:
dvander@0
   305
    BinaryExpression(TokenKind token, Expression *left, Expression *right)
dvander@0
   306
      : token_(token),
dvander@0
   307
        left_(left),
dvander@0
   308
        right_(right)
dvander@0
   309
    {
dvander@0
   310
    }
dvander@0
   311
dvander@0
   312
    Kind kind() const {
dvander@0
   313
        return kBinaryExpression;
dvander@0
   314
    }
dvander@0
   315
    Expression *left() const {
dvander@0
   316
        return left_;
dvander@0
   317
    }
dvander@0
   318
    Expression *right() const {
dvander@0
   319
        return right_;
dvander@0
   320
    }
dvander@0
   321
    TokenKind token() const {
dvander@0
   322
        return token_;
dvander@0
   323
    }
dvander@0
   324
    void accept(AstVisitor *visitor) {
dvander@0
   325
        visitor->visit(this);
dvander@0
   326
    }
dvander@0
   327
};
dvander@0
   328
dvander@0
   329
class IndexExpression : public Expression
dvander@0
   330
{
dvander@0
   331
    Expression *left_;
dvander@0
   332
    Expression *right_;
dvander@0
   333
dvander@0
   334
  public:
dvander@0
   335
    IndexExpression(Expression *left, Expression *right)
dvander@0
   336
      : left_(left),
dvander@0
   337
        right_(right)
dvander@0
   338
    {
dvander@0
   339
    }
dvander@0
   340
dvander@0
   341
    Kind kind() const {
dvander@0
   342
        return kIndexExpression;
dvander@0
   343
    }
dvander@0
   344
    Expression *left() const {
dvander@0
   345
        return left_;
dvander@0
   346
    }
dvander@0
   347
    Expression *right() const {
dvander@0
   348
        return right_;
dvander@0
   349
    }
dvander@0
   350
    void accept(AstVisitor *visitor) {
dvander@0
   351
        visitor->visit(this);
dvander@0
   352
    }
dvander@0
   353
};
dvander@0
   354
dvander@0
   355
class CallExpression : public Expression
dvander@0
   356
{
dvander@0
   357
    Expression *callee_;
dvander@0
   358
    ExpressionList *arguments_;
dvander@0
   359
dvander@0
   360
  public:
dvander@0
   361
    CallExpression(Expression *callee, ExpressionList *arguments)
dvander@0
   362
      : callee_(callee),
dvander@0
   363
        arguments_(arguments)
dvander@0
   364
    {
dvander@0
   365
    }
dvander@0
   366
dvander@0
   367
    Kind kind() const {
dvander@0
   368
        return kCallExpression;
dvander@0
   369
    }
dvander@0
   370
    Expression *callee() const {
dvander@0
   371
        return callee_;
dvander@0
   372
    }
dvander@0
   373
    ExpressionList *arguments() const {
dvander@0
   374
        return arguments_;
dvander@0
   375
    }
dvander@0
   376
    void accept(AstVisitor *visitor) {
dvander@0
   377
        visitor->visit(this);
dvander@0
   378
    }
dvander@0
   379
};
dvander@0
   380
dvander@0
   381
class ForStatement : public Statement
dvander@0
   382
{
dvander@0
   383
    Scope *scope_;
dvander@22
   384
    Statement *initialization_;
dvander@0
   385
    Expression *condition_;
dvander@0
   386
    Statement *update_;
dvander@0
   387
    Statement *body_;
dvander@0
   388
dvander@0
   389
  public:
dvander@22
   390
    ForStatement(Scope *scope, Statement *initialization,
dvander@0
   391
                 Expression *condition, Statement *update, Statement *body)
dvander@0
   392
      : scope_(scope),
dvander@22
   393
        initialization_(initialization),
dvander@0
   394
        condition_(condition),
dvander@0
   395
        update_(update),
dvander@0
   396
        body_(body)
dvander@0
   397
    {
dvander@0
   398
    }
dvander@0
   399
dvander@0
   400
    Kind kind() const {
dvander@0
   401
        return kForStatement;
dvander@0
   402
    }
dvander@22
   403
    Statement *initialization() const {
dvander@22
   404
        return initialization_;
dvander@0
   405
    }
dvander@0
   406
    Scope *scope() const {
dvander@0
   407
        return scope_;
dvander@0
   408
    }
dvander@0
   409
    Expression *condition() const {
dvander@0
   410
        return condition_;
dvander@0
   411
    }
dvander@0
   412
    Statement *update() const {
dvander@0
   413
        return update_;
dvander@0
   414
    }
dvander@0
   415
    Statement *body() const {
dvander@0
   416
        return body_;
dvander@0
   417
    }
dvander@0
   418
    void accept(AstVisitor *visitor) {
dvander@0
   419
        visitor->visit(this);
dvander@0
   420
    }
dvander@0
   421
};
dvander@0
   422
dvander@9
   423
class WhileStatement : public Statement
dvander@9
   424
{
dvander@9
   425
    TokenKind token_;
dvander@9
   426
    Expression *condition_;
dvander@9
   427
    Statement *body_;
dvander@9
   428
dvander@9
   429
  public:
dvander@9
   430
    WhileStatement(TokenKind kind, Expression *condition, Statement *body)
dvander@9
   431
      : token_(kind),
dvander@9
   432
        condition_(condition),
dvander@9
   433
        body_(body)
dvander@9
   434
    {
dvander@9
   435
    }
dvander@9
   436
    
dvander@9
   437
    Kind kind() const {
dvander@9
   438
        return kWhileStatement;
dvander@9
   439
    }
dvander@9
   440
    TokenKind token() const {
dvander@9
   441
        return token_;
dvander@9
   442
    }
dvander@9
   443
    Expression *condition() const {
dvander@9
   444
        return condition_;
dvander@9
   445
    }
dvander@9
   446
    Statement *body() const {
dvander@9
   447
        return body_;
dvander@9
   448
    }
dvander@9
   449
    void accept(AstVisitor *visitor) {
dvander@9
   450
        visitor->visit(this);
dvander@9
   451
    }
dvander@9
   452
};
dvander@9
   453
dvander@0
   454
class ReturnStatement : public Statement
dvander@0
   455
{
dvander@0
   456
    Expression *expression_;
dvander@0
   457
dvander@0
   458
  public:
dvander@0
   459
    ReturnStatement(Expression *expression)
dvander@0
   460
      : expression_(expression)
dvander@0
   461
    {
dvander@0
   462
    }
dvander@0
   463
dvander@0
   464
    Kind kind() const {
dvander@0
   465
        return kReturnStatement;
dvander@0
   466
    }
dvander@0
   467
    Expression *expression() const {
dvander@0
   468
        return expression_;
dvander@0
   469
    }
dvander@0
   470
    void accept(AstVisitor *visitor) {
dvander@0
   471
        visitor->visit(this);
dvander@0
   472
    }
dvander@0
   473
};
dvander@0
   474
dvander@10
   475
class BreakStatement : public Statement
dvander@10
   476
{
dvander@10
   477
  public:
dvander@10
   478
    BreakStatement()
dvander@10
   479
    {
dvander@10
   480
    }
dvander@10
   481
dvander@10
   482
    Kind kind() const {
dvander@10
   483
        return kBreakStatement;
dvander@10
   484
    }
dvander@10
   485
    void accept(AstVisitor *visitor) {
dvander@10
   486
        visitor->visit(this);
dvander@10
   487
    }
dvander@10
   488
};
dvander@10
   489
dvander@10
   490
class ContinueStatement : public Statement
dvander@10
   491
{
dvander@10
   492
  public:
dvander@10
   493
    ContinueStatement()
dvander@10
   494
    {
dvander@10
   495
    }
dvander@10
   496
dvander@10
   497
    Kind kind() const {
dvander@10
   498
        return kContinueStatement;
dvander@10
   499
    }
dvander@10
   500
    void accept(AstVisitor *visitor) {
dvander@10
   501
        visitor->visit(this);
dvander@10
   502
    }
dvander@10
   503
};
dvander@10
   504
dvander@0
   505
class Assignment : public Expression
dvander@0
   506
{
dvander@22
   507
    TokenKind token_;
dvander@0
   508
    Expression *lvalue_;
dvander@0
   509
    Expression *expression_;
dvander@0
   510
dvander@0
   511
  public:
dvander@22
   512
    Assignment(TokenKind token, Expression *left, Expression *right)
dvander@22
   513
      : token_(token),
dvander@22
   514
        lvalue_(left),
dvander@0
   515
        expression_(right)
dvander@0
   516
    {
dvander@0
   517
    }
dvander@0
   518
dvander@0
   519
    Kind kind() const {
dvander@0
   520
        return kAssignment;
dvander@0
   521
    }
dvander@22
   522
    TokenKind token() const {
dvander@22
   523
        return token_;
dvander@22
   524
    }
dvander@0
   525
    Expression *lvalue() const {
dvander@0
   526
        return lvalue_;
dvander@0
   527
    }
dvander@0
   528
    Expression *expression() const {
dvander@0
   529
        return expression_;
dvander@0
   530
    }
dvander@0
   531
    void accept(AstVisitor *visitor) {
dvander@0
   532
        visitor->visit(this);
dvander@0
   533
    }
dvander@0
   534
};
dvander@0
   535
dvander@0
   536
class ExpressionStatement : public Statement
dvander@0
   537
{
dvander@0
   538
    Expression *expression_;
dvander@0
   539
dvander@0
   540
  public:
dvander@0
   541
    ExpressionStatement(Expression *expression)
dvander@0
   542
      : expression_(expression)
dvander@0
   543
    {
dvander@0
   544
    }
dvander@0
   545
dvander@0
   546
    Kind kind() const {
dvander@0
   547
        return kExpressionStatement;
dvander@0
   548
    }
dvander@0
   549
    Expression *expression() const {
dvander@0
   550
        return expression_;
dvander@0
   551
    }
dvander@0
   552
    void accept(AstVisitor *visitor) {
dvander@0
   553
        visitor->visit(this);
dvander@0
   554
    }
dvander@0
   555
};
dvander@0
   556
dvander@0
   557
class BlockStatement : public Statement
dvander@0
   558
{
dvander@0
   559
    Scope *scope_;
dvander@0
   560
    StatementList *statements_;
dvander@0
   561
dvander@0
   562
  public:
dvander@0
   563
    BlockStatement(Scope *scope, StatementList *statements)
dvander@0
   564
      : scope_(scope),
dvander@0
   565
        statements_(statements)
dvander@0
   566
    {
dvander@0
   567
    }
dvander@0
   568
dvander@0
   569
    Kind kind() const {
dvander@0
   570
        return kBlockStatement;
dvander@0
   571
    }
dvander@0
   572
    Scope *scope() const {
dvander@0
   573
        return scope_;
dvander@0
   574
    }
dvander@0
   575
    StatementList *statements() const {
dvander@0
   576
        return statements_;
dvander@0
   577
    }
dvander@0
   578
    void accept(AstVisitor *visitor) {
dvander@0
   579
        visitor->visit(this);
dvander@0
   580
    }
dvander@0
   581
};
dvander@0
   582
dvander@14
   583
typedef std::vector<Parameter *> ParameterList;
dvander@14
   584
dvander@0
   585
class FunctionStatement : public Statement
dvander@0
   586
{
dvander@0
   587
    Scope *scope_;
dvander@0
   588
    NamedFunction *fun_;
dvander@0
   589
    Statement *body_;
dvander@14
   590
    ParameterList *parameters_;
dvander@0
   591
dvander@0
   592
  public:
dvander@14
   593
    FunctionStatement(Scope *scope, NamedFunction *fun, Statement *body, ParameterList *parameters)
dvander@0
   594
      : scope_(scope),
dvander@0
   595
        fun_(fun),
dvander@14
   596
        body_(body),
dvander@14
   597
        parameters_(parameters)
dvander@0
   598
    {
dvander@0
   599
    }
dvander@0
   600
dvander@0
   601
    Kind kind() const {
dvander@0
   602
        return kFunctionStatement;
dvander@0
   603
    }
dvander@0
   604
    Scope *scope() const {
dvander@0
   605
        return scope_;
dvander@0
   606
    }
dvander@0
   607
    NamedFunction *fun() const {
dvander@0
   608
        return fun_;
dvander@0
   609
    }
dvander@0
   610
    Statement *body() const {
dvander@0
   611
        return body_;
dvander@0
   612
    }
dvander@14
   613
    ParameterList *parameters() const {
dvander@14
   614
        return parameters_;
dvander@14
   615
    }
dvander@0
   616
    void accept(AstVisitor *visitor) {
dvander@0
   617
        visitor->visit(this);
dvander@0
   618
    }
dvander@0
   619
};
dvander@0
   620
dvander@0
   621
class IfStatement : public Statement
dvander@0
   622
{
dvander@0
   623
    Expression *condition_;
dvander@0
   624
    Statement *ifTrue_;
dvander@0
   625
    Statement *ifFalse_;
dvander@0
   626
dvander@0
   627
  public:
dvander@0
   628
    IfStatement(Expression *condition, Statement *ifTrue)
dvander@0
   629
      : condition_(condition),
dvander@0
   630
        ifTrue_(ifTrue),
dvander@0
   631
        ifFalse_(NULL)
dvander@0
   632
    {
dvander@0
   633
    }
dvander@0
   634
dvander@0
   635
    Kind kind() const {
dvander@0
   636
        return kIfStatement;
dvander@0
   637
    }
dvander@0
   638
    Expression *condition() const {
dvander@0
   639
        return condition_;
dvander@0
   640
    }
dvander@0
   641
    Statement *ifTrue() const {
dvander@0
   642
        return ifTrue_;
dvander@0
   643
    }
dvander@0
   644
    Statement *ifFalse() const {
dvander@0
   645
        return ifFalse_;
dvander@0
   646
    }
dvander@0
   647
    void setIfFalse(Statement *ifFalse) {
dvander@0
   648
        ifFalse_ = ifFalse;
dvander@0
   649
    }
dvander@0
   650
    void accept(AstVisitor *visitor) {
dvander@0
   651
        visitor->visit(this);
dvander@0
   652
    }
dvander@0
   653
};
dvander@0
   654
dvander@2
   655
class EnumStatement : public Statement
dvander@2
   656
{
dvander@2
   657
    Name *name_;
dvander@2
   658
dvander@2
   659
  public:
dvander@2
   660
    struct Entry {
dvander@2
   661
        NamedConstant *name;
dvander@2
   662
        Expression *expr;
dvander@2
   663
dvander@2
   664
        Entry(NamedConstant *name, Expression *expr)
dvander@2
   665
          : name(name),
dvander@2
   666
            expr(expr)
dvander@2
   667
        {
dvander@2
   668
        }
dvander@2
   669
    };
dvander@2
   670
dvander@2
   671
    typedef std::vector<Entry> EntryList;
dvander@2
   672
dvander@2
   673
  public:
dvander@2
   674
    EnumStatement(Name *name, EntryList *entries)
dvander@2
   675
      : name_(name),
dvander@2
   676
        entries_(entries)
dvander@2
   677
    {
dvander@2
   678
    }
dvander@2
   679
dvander@2
   680
    Kind kind() const {
dvander@2
   681
        return kEnumStatement;
dvander@2
   682
    }
dvander@2
   683
    Name *name() const {
dvander@2
   684
        return name_;
dvander@2
   685
    }
dvander@2
   686
    EntryList *entries() const {
dvander@2
   687
        return entries_;
dvander@2
   688
    }
dvander@2
   689
    void accept(AstVisitor *visitor) {
dvander@2
   690
        visitor->visit(this);
dvander@2
   691
    }
dvander@2
   692
dvander@2
   693
  private:
dvander@2
   694
    EntryList *entries_;
dvander@2
   695
};
dvander@2
   696
dvander@0
   697
class Scope;
dvander@0
   698
dvander@0
   699
typedef std::vector<NameProxy *> NameProxyList;
dvander@0
   700
dvander@0
   701
class ParseTree : public PoolObject
dvander@0
   702
{
dvander@0
   703
    StatementList *statements_;
dvander@0
   704
    Scope *scope_;
dvander@0
   705
    NameProxyList *unbound_;
dvander@0
   706
dvander@0
   707
  public:
dvander@0
   708
    ParseTree(Scope *scope, StatementList *statements, NameProxyList *unbound)
dvander@0
   709
      : statements_(statements),
dvander@0
   710
        scope_(scope),
dvander@0
   711
        unbound_(unbound)
dvander@0
   712
    {
dvander@0
   713
    }
dvander@0
   714
dvander@0
   715
    void dump(FILE *fp);
dvander@0
   716
dvander@0
   717
    StatementList *statements() const {
dvander@0
   718
        return statements_;
dvander@0
   719
    }
dvander@0
   720
    Scope *scope() const {
dvander@0
   721
        return scope_;
dvander@0
   722
    }
dvander@0
   723
    NameProxyList *unbound() const {
dvander@0
   724
        return unbound_;
dvander@0
   725
    }
dvander@0
   726
};
dvander@0
   727
dvander@0
   728
}
dvander@0
   729
dvander@0
   730
#endif // _include_jitcraft_ast_h_