diff options
| author | Tim Foley <tfoley@nvidia.com> | 2017-07-18 14:51:12 -0700 |
|---|---|---|
| committer | Tim Foley <tfoley@nvidia.com> | 2017-07-18 14:51:12 -0700 |
| commit | 2476c035ec15d3ee22239ebd1fe10e6e8c1e01e3 (patch) | |
| tree | 30e1bf209e232d7f8d6723959db68b2c0cb015dd /source/slang/check.cpp | |
| parent | 3d313d963f29f6ca6a8d12bd5c403a70c49aca2a (diff) | |
Add a compile-time loop construct to Slang
The basic syntax is:
$for(i in Range(0,99))
{
/* stuff goes here */
}
Note that the exact form is very restrictive. All that you are allowed to change is `i`, `0`, `99` or `/* stuff goes here */`.
As a tiny bit of syntax sugar, the following should work:
$for(i in Range(99))
{
/* stuff goes here */
}
Note that the range given is half-open (C++ iterator `[begin,end)` style).
Both the beginning and end of the range must be compile-time constant expressions that Slang knows how to constant-fold.
The implementation will basically generate code for `/* stuff goes here */` N times, once for each value in the half-open range.
Each time, the variable `i` will be replaced with a different compile-time-constant expression.
While I was working on a test case for this, I also found that our build of glslang had an issue with resource limits, so I fixed that.
Clients will need to build a new glslang to use the fix.
Diffstat (limited to 'source/slang/check.cpp')
| -rw-r--r-- | source/slang/check.cpp | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/source/slang/check.cpp b/source/slang/check.cpp index 1c1c6d5d3..26d28d495 100644 --- a/source/slang/check.cpp +++ b/source/slang/check.cpp @@ -1735,6 +1735,48 @@ namespace Slang PopOuterStmt(stmt); } + + RefPtr<ExpressionSyntaxNode> checkExpressionAndExpectIntegerConstant(RefPtr<ExpressionSyntaxNode> expr, RefPtr<IntVal>* outIntVal) + { + expr = CheckExpr(expr); + auto intVal = CheckIntegerConstantExpression(expr); + if (outIntVal) + *outIntVal = intVal; + return expr; + } + + void visitCompileTimeForStmt(CompileTimeForStmt* stmt) + { + PushOuterStmt(stmt); + + stmt->varDecl->Type.type = ExpressionType::GetInt(); + addModifier(stmt->varDecl, new ConstModifier()); + + RefPtr<IntVal> rangeBeginVal; + RefPtr<IntVal> rangeEndVal; + + if (stmt->rangeBeginExpr) + { + stmt->rangeBeginExpr = checkExpressionAndExpectIntegerConstant(stmt->rangeBeginExpr, &rangeBeginVal); + } + else + { + RefPtr<ConstantIntVal> rangeBeginConst = new ConstantIntVal(); + rangeBeginConst->value = 0; + rangeBeginVal = rangeBeginConst; + } + + stmt->rangeEndExpr = checkExpressionAndExpectIntegerConstant(stmt->rangeEndExpr, &rangeEndVal); + + stmt->rangeBeginVal = rangeBeginVal; + stmt->rangeEndVal = rangeEndVal; + + checkStmt(stmt->body); + + + PopOuterStmt(stmt); + } + void visitSwitchStmt(SwitchStmt* stmt) { PushOuterStmt(stmt); |
