From a01c09c3934d3f859bf4bea6b4e583f25291b643 Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Thu, 9 Apr 2020 15:43:09 -0400 Subject: Literal folding on other operators (#1314) * Fold prefix operators if they prefix an int literal. * Make test case a bit more convoluted. * Remove ++ and -- as not appropriate for folding of literals. * Set output buffer name. --- source/slang/slang-parser.cpp | 61 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 13 deletions(-) (limited to 'source/slang') diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp index 4ce4c49b5..170178932 100644 --- a/source/slang/slang-parser.cpp +++ b/source/slang/slang-parser.cpp @@ -4706,29 +4706,63 @@ namespace Slang } } + static IRIntegerValue _foldIntegerPrefixOp(TokenType tokenType, IRIntegerValue value) + { + switch (tokenType) + { + case TokenType::OpNot: return !value; + case TokenType::OpBitNot: return ~value; + case TokenType::OpAdd: return value; + case TokenType::OpSub: return -value; + default: + { + SLANG_ASSERT(!"Unexpected op"); + return value; + } + } + } + + static IRFloatingPointValue _foldFloatPrefixOp(TokenType tokenType, IRFloatingPointValue value) + { + switch (tokenType) + { + case TokenType::OpNot: return !value; + case TokenType::OpAdd: return value; + case TokenType::OpSub: return -value; + default: + { + SLANG_ASSERT(!"Unexpected op"); + return value; + } + } + } + static RefPtr parsePrefixExpr(Parser* parser) { - switch( peekTokenType(parser) ) + auto tokenType = peekTokenType(parser); + switch( tokenType ) { default: return parsePostfixExpr(parser); + case TokenType::OpInc: case TokenType::OpDec: + { + RefPtr prefixExpr = new PrefixExpr(); + parser->FillPosition(prefixExpr.Ptr()); + prefixExpr->FunctionExpr = parseOperator(parser); + + auto arg = parsePrefixExpr(parser); + + prefixExpr->Arguments.add(arg); + return prefixExpr; + } case TokenType::OpNot: case TokenType::OpBitNot: case TokenType::OpAdd: - { - RefPtr prefixExpr = new PrefixExpr(); - parser->FillPosition(prefixExpr.Ptr()); - prefixExpr->FunctionExpr = parseOperator(parser); - prefixExpr->Arguments.add(parsePrefixExpr(parser)); - return prefixExpr; - } case TokenType::OpSub: { - // Special case prefix sub (aka neg), so if it's on a literal, it produces a new literal - RefPtr prefixExpr = new PrefixExpr(); parser->FillPosition(prefixExpr.Ptr()); prefixExpr->FunctionExpr = parseOperator(parser); @@ -4739,7 +4773,7 @@ namespace Slang { RefPtr newLiteral = new IntegerLiteralExpr(*intLit); - IRIntegerValue value = -newLiteral->value; + IRIntegerValue value = _foldIntegerPrefixOp(tokenType, newLiteral->value); // Need to get the basic type, so we can fit to underlying type if (auto basicExprType = as(intLit->type.type)) @@ -4753,13 +4787,14 @@ namespace Slang else if (auto floatLit = as(arg)) { RefPtr newLiteral = new FloatingPointLiteralExpr(*floatLit); - newLiteral->value = -newLiteral->value; + newLiteral->value = _foldFloatPrefixOp(tokenType, floatLit->value); return newLiteral; } - + prefixExpr->Arguments.add(arg); return prefixExpr; } + break; } } -- cgit v1.2.3