diff options
| author | Tim Foley <tfoley@nvidia.com> | 2017-07-12 11:56:02 -0700 |
|---|---|---|
| committer | Tim Foley <tfoley@nvidia.com> | 2017-07-12 11:56:02 -0700 |
| commit | 11f12cd3a1d53f988d4c9726ac4301f35dc7f01f (patch) | |
| tree | d011ac9ff264a4585072022d43a878c0b82fc49d /source/slang/lower.cpp | |
| parent | 6101e483ae8ea9e10db2b5a9423af3cc7fafb710 (diff) | |
Add tuple lowering logic for assignment
- When assigning tuples `(a0, ...) = (b0, ...)` generate a tuple of assignments `(a0 = b0, ...)`
- Given an expression statement on a tuple `(a0, ...);` generate a sequence of statements `a0; ...`
Diffstat (limited to 'source/slang/lower.cpp')
| -rw-r--r-- | source/slang/lower.cpp | 80 |
1 files changed, 78 insertions, 2 deletions
diff --git a/source/slang/lower.cpp b/source/slang/lower.cpp index 02da47ccb..c7278201a 100644 --- a/source/slang/lower.cpp +++ b/source/slang/lower.cpp @@ -631,6 +631,69 @@ struct LoweringVisitor return loweredExpr; } + RefPtr<ExpressionSyntaxNode> createAssignExpr( + RefPtr<ExpressionSyntaxNode> leftExpr, + RefPtr<ExpressionSyntaxNode> rightExpr) + { + auto leftTuple = leftExpr.As<TupleExpr>(); + auto rightTuple = rightExpr.As<TupleExpr>(); + if (leftTuple && rightTuple) + { + RefPtr<TupleExpr> resultTuple = new TupleExpr(); + resultTuple->Type = leftExpr->Type; + + if (leftTuple->primaryExpr) + { + assert(rightTuple->primaryExpr); + + resultTuple->primaryExpr = createAssignExpr( + leftTuple->primaryExpr, + rightTuple->primaryExpr); + } + + auto elementCount = leftTuple->tupleElements.Count(); + assert(elementCount == rightTuple->tupleElements.Count()); + for (UInt ee = 0; ee < elementCount; ++ee) + { + auto leftElement = leftTuple->tupleElements[ee]; + auto rightElement = rightTuple->tupleElements[ee]; + + TupleExpr::Element resultElement; + + resultElement.tupleFieldDeclRef = leftElement.tupleFieldDeclRef; + resultElement.expr = createAssignExpr( + leftElement.expr, + rightElement.expr); + + resultTuple->tupleElements.Add(resultElement); + } + + return resultTuple; + } + else + { + assert(!leftTuple && !rightTuple); + } + + + RefPtr<AssignExpr> loweredExpr = new AssignExpr(); + loweredExpr->Type = leftExpr->Type; + loweredExpr->left = leftExpr; + loweredExpr->right = rightExpr; + return loweredExpr; + } + + RefPtr<ExpressionSyntaxNode> visitAssignExpr( + AssignExpr* expr) + { + auto leftExpr = lowerExpr(expr->left); + auto rightExpr = lowerExpr(expr->right); + + auto loweredExpr = createAssignExpr(leftExpr, rightExpr); + lowerExprCommon(loweredExpr, expr); + return loweredExpr; + } + void addArgs( InvokeExpressionSyntaxNode* callExpr, RefPtr<ExpressionSyntaxNode> argExpr) @@ -917,8 +980,21 @@ struct LoweringVisitor void addExprStmt( RefPtr<ExpressionSyntaxNode> expr) { - // TODO: handle cases where the `expr` cannot be directly - // represented as a single statement + // Desugar tuples in statement position + if (auto tupleExpr = expr.As<TupleExpr>()) + { + if (tupleExpr->primaryExpr) + { + addExprStmt(tupleExpr->primaryExpr); + } + for (auto ee : tupleExpr->tupleElements) + { + addExprStmt(ee.expr); + } + return; + } + + // TODO: could also desugar "operator comma" here RefPtr<ExpressionStatementSyntaxNode> stmt = new ExpressionStatementSyntaxNode(); stmt->Expression = expr; |
