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/lower.cpp | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'source/slang/lower.cpp') diff --git a/source/slang/lower.cpp b/source/slang/lower.cpp index bbbfe724b..127ef75ca 100644 --- a/source/slang/lower.cpp +++ b/source/slang/lower.cpp @@ -1628,6 +1628,41 @@ struct LoweringVisitor lowerForStmtCommon(new UnscopedForStmt(), stmt); } + void visitCompileTimeForStmt(CompileTimeForStmt* stmt) + { + // We can either lower this here, so that emit logic doesn't have to deal with it, + // or else just translate it and then let emit deal with it. + // + // The right answer is really to lower it here, I guess. + + auto rangeBeginVal = GetIntVal(stmt->rangeBeginVal); + auto rangeEndVal = GetIntVal(stmt->rangeEndVal); + + if (rangeBeginVal >= rangeEndVal) + return; + + auto varDecl = stmt->varDecl; + + auto varType = lowerType(varDecl->Type); + + for (IntegerLiteralValue ii = rangeBeginVal; ii < rangeEndVal; ++ii) + { + RefPtr constExpr = new ConstantExpressionSyntaxNode(); + constExpr->Type.type = varType.type; + constExpr->ConstType = ConstantExpressionSyntaxNode::ConstantType::Int; + constExpr->integerValue = ii; + + RefPtr loweredVarDecl = new VaryingTupleVarDecl(); + loweredVarDecl->Position = varDecl->Position; + loweredVarDecl->Type = varType; + loweredVarDecl->Expr = constExpr; + + shared->loweredDecls[varDecl] = loweredVarDecl; + + lowerStmtImpl(stmt->body); + } + } + void visitWhileStatementSyntaxNode(WhileStatementSyntaxNode* stmt) { RefPtr loweredStmt = new WhileStatementSyntaxNode(); -- cgit v1.2.3