From 2476c035ec15d3ee22239ebd1fe10e6e8c1e01e3 Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Tue, 18 Jul 2017 14:51:12 -0700 Subject: 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. --- source/slang/check.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'source/slang/check.cpp') 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 checkExpressionAndExpectIntegerConstant(RefPtr expr, RefPtr* 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 rangeBeginVal; + RefPtr rangeEndVal; + + if (stmt->rangeBeginExpr) + { + stmt->rangeBeginExpr = checkExpressionAndExpectIntegerConstant(stmt->rangeBeginExpr, &rangeBeginVal); + } + else + { + RefPtr 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); -- cgit v1.2.3