brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.2 KiB · a89462c Raw
138 lines · cpp
1//=== LexHLSLRootSignature.cpp - Lex Root Signature -----------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "clang/Lex/LexHLSLRootSignature.h"10 11namespace clang {12namespace hlsl {13 14using TokenKind = RootSignatureToken::Kind;15 16// Lexer Definitions17 18static bool isNumberChar(char C) {19  return isdigit(C)                                      // integer support20         || C == '.'                                     // float support21         || C == 'e' || C == 'E' || C == '-' || C == '+' // exponent support22         || C == 'f' || C == 'F'; // explicit float support23}24 25RootSignatureToken RootSignatureLexer::lexToken() {26  // Discard any leading whitespace27  advanceBuffer(Buffer.take_while(isspace).size());28 29  if (isEndOfBuffer())30    return RootSignatureToken(TokenKind::end_of_stream, LocOffset);31 32  // Record where this token is in the text for usage in parser diagnostics33  RootSignatureToken Result(LocOffset);34 35  char C = Buffer.front();36 37  // Punctuators38  switch (C) {39#define PUNCTUATOR(X, Y)                                                       \40  case Y: {                                                                    \41    Result.TokKind = TokenKind::pu_##X;                                        \42    advanceBuffer();                                                           \43    return Result;                                                             \44  }45#include "clang/Lex/HLSLRootSignatureTokenKinds.def"46  default:47    break;48  }49 50  // Number literal51  if (isdigit(C) || C == '.') {52    Result.NumSpelling = Buffer.take_while(isNumberChar);53 54    // If all values are digits then we have an int literal55    bool IsInteger = Result.NumSpelling.find_if_not(isdigit) == StringRef::npos;56 57    Result.TokKind =58        IsInteger ? TokenKind::int_literal : TokenKind::float_literal;59    advanceBuffer(Result.NumSpelling.size());60    return Result;61  }62 63  // All following tokens require at least one additional character64  if (Buffer.size() <= 1) {65    Result = RootSignatureToken(TokenKind::invalid, LocOffset);66    return Result;67  }68 69  // Peek at the next character to deteremine token type70  char NextC = Buffer[1];71 72  // Registers: [tsub][0-9+]73  if ((C == 't' || C == 's' || C == 'u' || C == 'b') && isdigit(NextC)) {74    // Convert character to the register type.75    switch (C) {76    case 'b':77      Result.TokKind = TokenKind::bReg;78      break;79    case 't':80      Result.TokKind = TokenKind::tReg;81      break;82    case 'u':83      Result.TokKind = TokenKind::uReg;84      break;85    case 's':86      Result.TokKind = TokenKind::sReg;87      break;88    default:89      llvm_unreachable("Switch for an expected token was not provided");90    }91 92    advanceBuffer();93 94    // Lex the integer literal95    Result.NumSpelling = Buffer.take_while(isNumberChar);96    advanceBuffer(Result.NumSpelling.size());97 98    return Result;99  }100 101  // Keywords and Enums:102  StringRef TokSpelling =103      Buffer.take_while([](char C) { return isalnum(C) || C == '_'; });104 105  // Define a large string switch statement for all the keywords and enums106  auto Switch = llvm::StringSwitch<TokenKind>(TokSpelling);107#define KEYWORD(NAME) Switch.CaseLower(#NAME, TokenKind::kw_##NAME);108#define ENUM(NAME, LIT) Switch.CaseLower(LIT, TokenKind::en_##NAME);109#include "clang/Lex/HLSLRootSignatureTokenKinds.def"110 111  // Then attempt to retreive a string from it112  Result.TokKind = Switch.Default(TokenKind::invalid);113  advanceBuffer(TokSpelling.size());114  return Result;115}116 117RootSignatureToken RootSignatureLexer::consumeToken() {118  // If we previously peeked then just return the previous value over119  if (NextToken && NextToken->TokKind != TokenKind::end_of_stream) {120    RootSignatureToken Result = *NextToken;121    NextToken = std::nullopt;122    return Result;123  }124  return lexToken();125}126 127RootSignatureToken RootSignatureLexer::peekNextToken() {128  // Already peeked from the current token129  if (NextToken)130    return *NextToken;131 132  NextToken = lexToken();133  return *NextToken;134}135 136} // namespace hlsl137} // namespace clang138