blob: f5a2c5f3ce117405c61947fafffd677a2360584f [file] [log] [blame]
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_READER_WGSL_TOKEN_H_
#define SRC_READER_WGSL_TOKEN_H_
#include <stddef.h>
#include <ostream>
#include <string>
#include "src/source.h"
namespace tint {
namespace reader {
namespace wgsl {
/// Stores tokens generated by the Lexer
class Token {
public:
/// The type of the parsed token
enum class Type {
/// Error result
kError = -2,
/// Reserved keyword
kReservedKeyword = -1,
/// Uninitialized token
kUninitialized = 0,
/// End of input string reached
kEOF,
/// An identifier
kIdentifier,
/// A string value
kStringLiteral,
/// A float value
kFloatLiteral,
/// An int value
kIntLiteral,
/// A uint value
kUintLiteral,
/// A '&'
kAnd,
/// A '&&'
kAndAnd,
/// A '->'
kArrow,
/// A '[['
kAttrLeft,
/// A ']]'
kAttrRight,
/// A '/'
kForwardSlash,
/// A '!'
kBang,
/// A '['
kBracketLeft,
/// A ']'
kBracketRight,
/// A '{'
kBraceLeft,
/// A '}'
kBraceRight,
/// A ':'
kColon,
/// A ','
kComma,
/// A '='
kEqual,
/// A '=='
kEqualEqual,
/// A '>'
kGreaterThan,
/// A '>='
kGreaterThanEqual,
/// A '<'
kLessThan,
/// A '<='
kLessThanEqual,
/// A '%'
kMod,
/// A '-'
kMinus,
/// A '::'
kNamespace,
/// A '!='
kNotEqual,
/// A '.'
kPeriod,
/// A '+'
kPlus,
/// A '|'
kOr,
/// A '||'
kOrOr,
/// A '('
kParenLeft,
/// A ')'
kParenRight,
/// A ';'
kSemicolon,
/// A '*'
kStar,
/// A '^'
kXor,
/// A 'array'
kArray,
/// A 'as'
kAs,
/// A 'binding'
kBinding,
/// A 'bool'
kBool,
/// A 'block'
kBlock,
/// A 'break'
kBreak,
/// A 'builtin'
kBuiltin,
/// A 'case'
kCase,
/// A 'cast'
kCast,
/// A 'compute'
kCompute,
/// A 'const'
kConst,
/// A 'continue'
kContinue,
/// A 'continuing'
kContinuing,
/// A 'default'
kDefault,
/// A 'else'
kElse,
/// A 'elseif'
kElseIf,
/// A 'entry_point'
kEntryPoint,
/// A 'f32'
kF32,
/// A 'fallthrough'
kFallthrough,
/// A 'false'
kFalse,
/// A 'fn'
kFn,
/// A 'fragment'
kFragment,
/// A 'function'
kFunction,
/// A 'i32'
kI32,
/// A 'if'
kIf,
/// A 'image'
kImage,
/// A 'import'
kImport,
/// A 'in'
kIn,
/// A 'kill'
kKill,
/// A 'location'
kLocation,
/// A 'loop'
kLoop,
/// A 'mat2x2'
kMat2x2,
/// A 'mat2x3'
kMat2x3,
/// A 'mat2x4'
kMat2x4,
/// A 'mat3x2'
kMat3x2,
/// A 'mat3x3'
kMat3x3,
/// A 'mat3x4'
kMat3x4,
/// A 'mat4x2'
kMat4x2,
/// A 'mat4x3'
kMat4x3,
/// A 'mat4x4'
kMat4x4,
/// A 'offset'
kOffset,
/// A 'out'
kOut,
/// A 'premerge'
kPremerge,
/// A 'private'
kPrivate,
/// A 'ptr'
kPtr,
/// A 'regardless'
kRegardless,
/// A 'return'
kReturn,
/// A 'set'
kSet,
/// A 'storage_buffer'
kStorageBuffer,
/// A 'struct'
kStruct,
/// A 'switch'
kSwitch,
/// A 'true'
kTrue,
/// A 'type'
kType,
/// A 'u32'
kU32,
/// A 'uniform'
kUniform,
/// A 'uniform_constant'
kUniformConstant,
/// A 'unless'
kUnless,
/// A 'var'
kVar,
/// A 'vec2'
kVec2,
/// A 'vec3'
kVec3,
/// A 'vec4'
kVec4,
/// A 'vertex'
kVertex,
/// A 'void'
kVoid,
/// A 'workgroup'
kWorkgroup
};
/// Converts a token type to a name
/// @param type the type to convert
/// @returns the token type as as string
static std::string TypeToName(Type type);
/// Creates an uninitialized token
Token();
/// Create a Token
/// @param type the Token::Type of the token
/// @param source the source of the token
Token(Type type, const Source& source);
/// Create a string Token
/// @param type the Token::Type of the token
/// @param source the source of the token
/// @param val the source string for the token
Token(Type type, const Source& source, const std::string& val);
/// Create a unsigned integer Token
/// @param source the source of the token
/// @param val the source unsigned for the token
Token(const Source& source, uint32_t val);
/// Create a signed integer Token
/// @param source the source of the token
/// @param val the source integer for the token
Token(const Source& source, int32_t val);
/// Create a float Token
/// @param source the source of the token
/// @param val the source float for the token
Token(const Source& source, float val);
/// Move constructor
Token(Token&&);
/// Copy constructor
Token(const Token&);
~Token();
/// Assignment operator
/// @param b the token to copy
/// @return Token
Token& operator=(const Token& b);
/// Returns true if the token is of the given type
/// @param t the type to check against.
/// @returns true if the token is of type |t|
bool Is(Type t) const { return type_ == t; }
/// @returns true if the token is uninitialized
bool IsUninitialized() const { return type_ == Type::kUninitialized; }
/// @returns true if the token is reserved
bool IsReservedKeyword() const { return type_ == Type::kReservedKeyword; }
/// @returns true if the token is an error
bool IsError() const { return type_ == Type::kError; }
/// @returns true if the token is EOF
bool IsEof() const { return type_ == Type::kEOF; }
/// @returns true if the token is an identifier
bool IsIdentifier() const { return type_ == Type::kIdentifier; }
/// @returns true if the token is a string
bool IsStringLiteral() const { return type_ == Type::kStringLiteral; }
/// @returns true if the token is a float
bool IsFloatLiteral() const { return type_ == Type::kFloatLiteral; }
/// @returns true if the token is an int
bool IsIntLiteral() const { return type_ == Type::kIntLiteral; }
/// @returns true if the token is a unsigned int
bool IsUintLiteral() const { return type_ == Type::kUintLiteral; }
/// @returns true if token is a '&'
bool IsAnd() const { return type_ == Type::kAnd; }
/// @returns true if token is a '&&'
bool IsAndAnd() const { return type_ == Type::kAndAnd; }
/// @returns true if token is a '->'
bool IsArrow() const { return type_ == Type::kArrow; }
/// @returns true if token is a '[['
bool IsAttrLeft() const { return type_ == Type::kAttrLeft; }
/// @returns true if token is a ']]'
bool IsAttrRight() const { return type_ == Type::kAttrRight; }
/// @returns true if token is a '/'
bool IsForwardSlash() const { return type_ == Type::kForwardSlash; }
/// @returns true if token is a '!'
bool IsBang() const { return type_ == Type::kBang; }
/// @returns true if token is a '['
bool IsBracketLeft() const { return type_ == Type::kBracketLeft; }
/// @returns true if token is a ']'
bool IsBracketRight() const { return type_ == Type::kBracketRight; }
/// @returns true if token is a '{'
bool IsBraceLeft() const { return type_ == Type::kBraceLeft; }
/// @returns true if token is a '}'
bool IsBraceRight() const { return type_ == Type::kBraceRight; }
/// @returns true if token is a ':'
bool IsColon() const { return type_ == Type::kColon; }
/// @returns true if token is a ','
bool IsComma() const { return type_ == Type::kComma; }
/// @returns true if token is a '='
bool IsEqual() const { return type_ == Type::kEqual; }
/// @returns true if token is a '=='
bool IsEqualEqual() const { return type_ == Type::kEqualEqual; }
/// @returns true if token is a '>'
bool IsGreaterThan() const { return type_ == Type::kGreaterThan; }
/// @returns true if token is a '>='
bool IsGreaterThanEqual() const { return type_ == Type::kGreaterThanEqual; }
/// @returns true if token is a '<'
bool IsLessThan() const { return type_ == Type::kLessThan; }
/// @returns true if token is a '<='
bool IsLessThanEqual() const { return type_ == Type::kLessThanEqual; }
/// @returns true if token is a '%'
bool IsMod() const { return type_ == Type::kMod; }
/// @returns true if token is a '-'
bool IsMinus() const { return type_ == Type::kMinus; }
/// @returns true if token is a '::'
bool IsNamespace() const { return type_ == Type::kNamespace; }
/// @returns true if token is a '!='
bool IsNotEqual() const { return type_ == Type::kNotEqual; }
/// @returns true if token is a '.'
bool IsPeriod() const { return type_ == Type::kPeriod; }
/// @returns true if token is a '+'
bool IsPlus() const { return type_ == Type::kPlus; }
/// @returns true if token is a '|'
bool IsOr() const { return type_ == Type::kOr; }
/// @returns true if token is a '||'
bool IsOrOr() const { return type_ == Type::kOrOr; }
/// @returns true if token is a '('
bool IsParenLeft() const { return type_ == Type::kParenLeft; }
/// @returns true if token is a ')'
bool IsParenRight() const { return type_ == Type::kParenRight; }
/// @returns true if token is a ';'
bool IsSemicolon() const { return type_ == Type::kSemicolon; }
/// @returns true if token is a '*'
bool IsStar() const { return type_ == Type::kStar; }
/// @returns true if token is a '^'
bool IsXor() const { return type_ == Type::kXor; }
/// @returns true if token is a 'array'
bool IsArray() const { return type_ == Type::kArray; }
/// @returns true if token is a 'as'
bool IsAs() const { return type_ == Type::kAs; }
/// @returns true if token is a 'binding'
bool IsBinding() const { return type_ == Type::kBinding; }
/// @returns true if token is a 'block'
bool IsBlock() const { return type_ == Type::kBlock; }
/// @returns true if token is a 'bool'
bool IsBool() const { return type_ == Type::kBool; }
/// @returns true if token is a 'break'
bool IsBreak() const { return type_ == Type::kBreak; }
/// @returns true if token is a 'builtin'
bool IsBuiltin() const { return type_ == Type::kBuiltin; }
/// @returns true if token is a 'case'
bool IsCase() const { return type_ == Type::kCase; }
/// @returns true if token is a 'cast'
bool IsCast() const { return type_ == Type::kCast; }
/// @returns true if token is a 'compute'
bool IsCompute() const { return type_ == Type::kCompute; }
/// @returns true if token is a 'const'
bool IsConst() const { return type_ == Type::kConst; }
/// @returns true if token is a 'continue'
bool IsContinue() const { return type_ == Type::kContinue; }
/// @returns true if token is a 'continuing'
bool IsContinuing() const { return type_ == Type::kContinuing; }
/// @returns true if token is a 'default'
bool IsDefault() const { return type_ == Type::kDefault; }
/// @returns true if token is a 'else'
bool IsElse() const { return type_ == Type::kElse; }
/// @returns true if token is a 'elseif'
bool IsElseIf() const { return type_ == Type::kElseIf; }
/// @returns true if token is a 'entry_point'
bool IsEntryPoint() const { return type_ == Type::kEntryPoint; }
/// @returns true if token is a 'f32'
bool IsF32() const { return type_ == Type::kF32; }
/// @returns true if token is a 'fallthrough'
bool IsFallthrough() const { return type_ == Type::kFallthrough; }
/// @returns true if token is a 'false'
bool IsFalse() const { return type_ == Type::kFalse; }
/// @returns true if token is a 'fn'
bool IsFn() const { return type_ == Type::kFn; }
/// @returns true if token is a 'fragment'
bool IsFragment() const { return type_ == Type::kFragment; }
/// @returns true if token is a 'function'
bool IsFunction() const { return type_ == Type::kFunction; }
/// @returns true if token is a 'i32'
bool IsI32() const { return type_ == Type::kI32; }
/// @returns true if token is a 'if'
bool IsIf() const { return type_ == Type::kIf; }
/// @returns true if token is a 'image'
bool IsImage() const { return type_ == Type::kImage; }
/// @returns true if token is a 'import'
bool IsImport() const { return type_ == Type::kImport; }
/// @returns true if token is a 'in'
bool IsIn() const { return type_ == Type::kIn; }
/// @returns true if token is a 'kill'
bool IsKill() const { return type_ == Type::kKill; }
/// @returns true if token is a 'location'
bool IsLocation() const { return type_ == Type::kLocation; }
/// @returns true if token is a 'loop'
bool IsLoop() const { return type_ == Type::kLoop; }
/// @returns true if token is a 'mat2x2'
bool IsMat2x2() const { return type_ == Type::kMat2x2; }
/// @returns true if token is a 'mat2x3'
bool IsMat2x3() const { return type_ == Type::kMat2x3; }
/// @returns true if token is a 'mat2x4'
bool IsMat2x4() const { return type_ == Type::kMat2x4; }
/// @returns true if token is a 'mat3x2'
bool IsMat3x2() const { return type_ == Type::kMat3x2; }
/// @returns true if token is a 'mat3x3'
bool IsMat3x3() const { return type_ == Type::kMat3x3; }
/// @returns true if token is a 'mat3x4'
bool IsMat3x4() const { return type_ == Type::kMat3x4; }
/// @returns true if token is a 'mat4x2'
bool IsMat4x2() const { return type_ == Type::kMat4x2; }
/// @returns true if token is a 'mat4x3'
bool IsMat4x3() const { return type_ == Type::kMat4x3; }
/// @returns true if token is a 'mat4x4'
bool IsMat4x4() const { return type_ == Type::kMat4x4; }
/// @returns true if token is a 'offset'
bool IsOffset() const { return type_ == Type::kOffset; }
/// @returns true if token is a 'out'
bool IsOut() const { return type_ == Type::kOut; }
/// @returns true if token is a 'private'
bool IsPrivate() const { return type_ == Type::kPrivate; }
/// @returns true if token is a 'ptr'
bool IsPtr() const { return type_ == Type::kPtr; }
/// @returns true if token is a 'return'
bool IsReturn() const { return type_ == Type::kReturn; }
/// @returns true if token is a 'set'
bool IsSet() const { return type_ == Type::kSet; }
/// @returns true if token is a 'storage_buffer'
bool IsStorageBuffer() const { return type_ == Type::kStorageBuffer; }
/// @returns true if token is a 'struct'
bool IsStruct() const { return type_ == Type::kStruct; }
/// @returns true if token is a 'switch'
bool IsSwitch() const { return type_ == Type::kSwitch; }
/// @returns true if token is a 'true'
bool IsTrue() const { return type_ == Type::kTrue; }
/// @returns true if token is a 'type'
bool IsType() const { return type_ == Type::kType; }
/// @returns true if token is a 'u32'
bool IsU32() const { return type_ == Type::kU32; }
/// @returns true if token is a 'uniform'
bool IsUniform() const { return type_ == Type::kUniform; }
/// @returns true if token is a 'uniform_constant'
bool IsUniformConstant() const { return type_ == Type::kUniformConstant; }
/// @returns true if token is a 'unless'
bool IsUnless() const { return type_ == Type::kUnless; }
/// @returns true if token is a 'var'
bool IsVar() const { return type_ == Type::kVar; }
/// @returns true if token is a 'vec2'
bool IsVec2() const { return type_ == Type::kVec2; }
/// @returns true if token is a 'vec3'
bool IsVec3() const { return type_ == Type::kVec3; }
/// @returns true if token is a 'vec4'
bool IsVec4() const { return type_ == Type::kVec4; }
/// @returns true if token is a 'vertex'
bool IsVertex() const { return type_ == Type::kVertex; }
/// @returns true if token is a 'void'
bool IsVoid() const { return type_ == Type::kVoid; }
/// @returns true if token is a 'workgroup'
bool IsWorkgroup() const { return type_ == Type::kWorkgroup; }
/// @returns the source line of the token
size_t line() const { return source_.line; }
/// @returns the source column of the token
size_t column() const { return source_.column; }
/// @returns the source information for this token
Source source() const { return source_; }
/// Returns the string value of the token
/// @return const std::string&
std::string to_str() const;
/// Returns the float value of the token. 0 is returned if the token does not
/// contain a float value.
/// @return float
float to_f32() const;
/// Returns the uint32 value of the token. 0 is returned if the token does not
/// contain a unsigned integer value.
/// @return uint32_t
uint32_t to_u32() const;
/// Returns the int32 value of the token. 0 is returned if the token does not
/// contain a signed integer value.
/// @return int32_t
int32_t to_i32() const;
/// @returns the token type as string
std::string to_name() const { return Token::TypeToName(type_); }
private:
/// The Token::Type of the token
Type type_ = Type::kError;
/// The source where the token appeared
Source source_;
/// The string represented by the token
std::string val_str_;
/// The signed integer represented by the token
int32_t val_int_ = 0;
/// The unsigned integer represented by the token
uint32_t val_uint_ = 0;
/// The float value represented by the token
float val_float_ = 0.0;
};
#ifndef NDEBUG
inline std::ostream& operator<<(std::ostream& out, Token::Type type) {
out << Token::TypeToName(type);
return out;
}
#endif // NDEBUG
} // namespace wgsl
} // namespace reader
} // namespace tint
#endif // SRC_READER_WGSL_TOKEN_H_