summaryrefslogtreecommitdiff
path: root/source/slang/slang-ast-stmt.h
blob: 2edc844c63c0869b43bf93e7bff4fab4459bc9ec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
// slang-ast-stmt.h

#pragma once

#include "slang-ast-base.h"

namespace Slang {

// Syntax class definitions for statements.

class ScopeStmt : public Stmt 
{
    SLANG_ABSTRACT_AST_CLASS(ScopeStmt)

    ScopeDecl* scopeDecl = nullptr;
};

// A sequence of statements, treated as a single statement
class SeqStmt : public Stmt 
{
    SLANG_AST_CLASS(SeqStmt)

    List<Stmt*> stmts;
};

// The simplest kind of scope statement: just a `{...}` block
class BlockStmt : public ScopeStmt 
{
    SLANG_AST_CLASS(BlockStmt)

        /// TODO(JS): Having ranges of sourcelocs might be a good addition to AST nodes in general.
    SourceLoc closingSourceLoc;         ///< The source location of the closing brace

    Stmt* body = nullptr;
};

// A statement that we aren't going to parse or check, because
// we want to let a downstream compiler handle any issues
class UnparsedStmt : public Stmt 
{
    SLANG_AST_CLASS(UnparsedStmt)

    // The tokens that were contained between `{` and `}`
    List<Token> tokens;
};

class EmptyStmt : public Stmt 
{
    SLANG_AST_CLASS(EmptyStmt)
};

class DiscardStmt : public Stmt 
{
    SLANG_AST_CLASS(DiscardStmt)
};

class DeclStmt : public Stmt 
{
    SLANG_AST_CLASS(DeclStmt)

    DeclBase* decl = nullptr;
};

class IfStmt : public Stmt 
{
    SLANG_AST_CLASS(IfStmt)

    Expr* predicate = nullptr;
    Stmt* positiveStatement = nullptr;
    Stmt* negativeStatement = nullptr;
};

// A statement that can be escaped with a `break`
class BreakableStmt : public ScopeStmt 
{
    SLANG_ABSTRACT_AST_CLASS(BreakableStmt)

};

class SwitchStmt : public BreakableStmt 
{
    SLANG_AST_CLASS(SwitchStmt)

    Expr* condition = nullptr;
    Stmt* body = nullptr;
};

// A statement that is expected to appear lexically nested inside
// some other construct, and thus needs to keep track of the
// outer statement that it is associated with...
class ChildStmt : public Stmt 
{
    SLANG_ABSTRACT_AST_CLASS(ChildStmt)

    Stmt* parentStmt = nullptr;
};

// a `case` or `default` statement inside a `switch`
//
// Note(tfoley): A correct AST for a C-like language would treat
// these as a labelled statement, and so they would contain a
// sub-statement. I'm leaving that out for now for simplicity.
class CaseStmtBase : public ChildStmt 
{
    SLANG_ABSTRACT_AST_CLASS(CaseStmtBase)

};

// a `case` statement inside a `switch`
class CaseStmt : public CaseStmtBase 
{
    SLANG_AST_CLASS(CaseStmt)

    Expr* expr = nullptr;
};

// a `default` statement inside a `switch`
class DefaultStmt : public CaseStmtBase 
{
    SLANG_AST_CLASS(DefaultStmt)
};

// a `default` statement inside a `switch`
class GpuForeachStmt : public ScopeStmt 
{
    SLANG_AST_CLASS(GpuForeachStmt)

    Expr* device = nullptr;
    Expr* gridDims = nullptr;
    VarDecl* dispatchThreadID = nullptr;
    Expr* kernelCall = nullptr;
};

// A statement that represents a loop, and can thus be escaped with a `continue`
class LoopStmt : public BreakableStmt 
{
    SLANG_ABSTRACT_AST_CLASS(LoopStmt)

};

// A `for` statement
class ForStmt : public LoopStmt 
{
    SLANG_AST_CLASS(ForStmt)

    Stmt* initialStatement = nullptr;
    Expr* sideEffectExpression = nullptr;
    Expr* predicateExpression = nullptr;
    Stmt* statement = nullptr;
};

// A `for` statement in a language that doesn't restrict the scope
// of the loop variable to the body.
class UnscopedForStmt : public ForStmt 
{
    SLANG_AST_CLASS(UnscopedForStmt)
;
};

class WhileStmt : public LoopStmt 
{
    SLANG_AST_CLASS(WhileStmt)

    Expr* predicate = nullptr;
    Stmt* statement = nullptr;
};

class DoWhileStmt : public LoopStmt 
{
    SLANG_AST_CLASS(DoWhileStmt)

    Stmt* statement = nullptr;
    Expr* predicate = nullptr;
};

// A compile-time, range-based `for` loop, which will not appear in the output code
class CompileTimeForStmt : public ScopeStmt 
{
    SLANG_AST_CLASS(CompileTimeForStmt)

    VarDecl* varDecl = nullptr;
    Expr* rangeBeginExpr = nullptr;
    Expr* rangeEndExpr = nullptr;
    Stmt* body = nullptr;
    IntVal* rangeBeginVal = nullptr;
    IntVal* rangeEndVal = nullptr;
};

// The case of child statements that do control flow relative
// to their parent statement.
class JumpStmt : public ChildStmt 
{
    SLANG_ABSTRACT_AST_CLASS(JumpStmt)
};

class BreakStmt : public JumpStmt 
{
    SLANG_AST_CLASS(BreakStmt)
};

class ContinueStmt : public JumpStmt 
{
    SLANG_AST_CLASS(ContinueStmt)
};

class ReturnStmt : public Stmt 
{
    SLANG_AST_CLASS(ReturnStmt)

    Expr* expression = nullptr;
};

class ExpressionStmt : public Stmt 
{
    SLANG_AST_CLASS(ExpressionStmt)

    Expr* expression = nullptr;
};

} // namespace Slang