1/*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef SKSL_TOKEN
9#define SKSL_TOKEN
10
11#include "SkSLPosition.h"
12#include "SkSLUtil.h"
13
14namespace SkSL {
15
16#undef IN
17#undef OUT
18#undef CONST
19
20/**
21 * Represents a lexical analysis token. Token is generally only used during the parse process, but
22 * Token::Kind is also used to represent operator kinds.
23 */
24struct Token {
25    enum Kind {
26        END_OF_FILE,
27        IDENTIFIER,
28        INT_LITERAL,
29        FLOAT_LITERAL,
30        TRUE_LITERAL,
31        FALSE_LITERAL,
32        LPAREN,
33        RPAREN,
34        LBRACE,
35        RBRACE,
36        LBRACKET,
37        RBRACKET,
38        DOT,
39        COMMA,
40        PLUSPLUS,
41        MINUSMINUS,
42        PLUS,
43        MINUS,
44        STAR,
45        SLASH,
46        PERCENT,
47        SHL,
48        SHR,
49        BITWISEOR,
50        BITWISEXOR,
51        BITWISEAND,
52        BITWISENOT,
53        LOGICALOR,
54        LOGICALXOR,
55        LOGICALAND,
56        LOGICALNOT,
57        QUESTION,
58        COLON,
59        EQ,
60        EQEQ,
61        NEQ,
62        GT,
63        LT,
64        GTEQ,
65        LTEQ,
66        PLUSEQ,
67        MINUSEQ,
68        STAREQ,
69        SLASHEQ,
70        PERCENTEQ,
71        SHLEQ,
72        SHREQ,
73        BITWISEOREQ,
74        BITWISEXOREQ,
75        BITWISEANDEQ,
76        LOGICALOREQ,
77        LOGICALXOREQ,
78        LOGICALANDEQ,
79        SEMICOLON,
80        IF,
81        ELSE,
82        FOR,
83        WHILE,
84        DO,
85        SWITCH,
86        CASE,
87        DEFAULT,
88        RETURN,
89        BREAK,
90        CONTINUE,
91        DISCARD,
92        IN,
93        OUT,
94        INOUT,
95        CONST,
96        LOWP,
97        MEDIUMP,
98        HIGHP,
99        UNIFORM,
100        FLAT,
101        NOPERSPECTIVE,
102        READONLY,
103        WRITEONLY,
104        COHERENT,
105        VOLATILE,
106        RESTRICT,
107        STRUCT,
108        LAYOUT,
109        DIRECTIVE,
110        PRECISION,
111        LOCATION,
112        OFFSET,
113        BINDING,
114        INDEX,
115        SET,
116        BUILTIN,
117        INPUT_ATTACHMENT_INDEX,
118        ORIGIN_UPPER_LEFT,
119        OVERRIDE_COVERAGE,
120        BLEND_SUPPORT_ALL_EQUATIONS,
121        PUSH_CONSTANT,
122        POINTS,
123        LINES,
124        LINE_STRIP,
125        LINES_ADJACENCY,
126        TRIANGLES,
127        TRIANGLE_STRIP,
128        TRIANGLES_ADJACENCY,
129        MAX_VERTICES,
130        INVOCATIONS,
131        INVALID_TOKEN
132    };
133
134    static SkString OperatorName(Kind kind) {
135        switch (kind) {
136            case Token::PLUS:         return SkString("+");
137            case Token::MINUS:        return SkString("-");
138            case Token::STAR:         return SkString("*");
139            case Token::SLASH:        return SkString("/");
140            case Token::PERCENT:      return SkString("%");
141            case Token::SHL:          return SkString("<<");
142            case Token::SHR:          return SkString(">>");
143            case Token::LOGICALNOT:   return SkString("!");
144            case Token::LOGICALAND:   return SkString("&&");
145            case Token::LOGICALOR:    return SkString("||");
146            case Token::LOGICALXOR:   return SkString("^^");
147            case Token::BITWISENOT:   return SkString("~");
148            case Token::BITWISEAND:   return SkString("&");
149            case Token::BITWISEOR:    return SkString("|");
150            case Token::BITWISEXOR:   return SkString("^");
151            case Token::EQ:           return SkString("=");
152            case Token::EQEQ:         return SkString("==");
153            case Token::NEQ:          return SkString("!=");
154            case Token::LT:           return SkString("<");
155            case Token::GT:           return SkString(">");
156            case Token::LTEQ:         return SkString("<=");
157            case Token::GTEQ:         return SkString(">=");
158            case Token::PLUSEQ:       return SkString("+=");
159            case Token::MINUSEQ:      return SkString("-=");
160            case Token::STAREQ:       return SkString("*=");
161            case Token::SLASHEQ:      return SkString("/=");
162            case Token::PERCENTEQ:    return SkString("%=");
163            case Token::SHLEQ:        return SkString("<<=");
164            case Token::SHREQ:        return SkString(">>=");
165            case Token::LOGICALANDEQ: return SkString("&&=");
166            case Token::LOGICALOREQ:  return SkString("||=");
167            case Token::LOGICALXOREQ: return SkString("^^=");
168            case Token::BITWISEANDEQ: return SkString("&=");
169            case Token::BITWISEOREQ:  return SkString("|=");
170            case Token::BITWISEXOREQ: return SkString("^=");
171            case Token::PLUSPLUS:     return SkString("++");
172            case Token::MINUSMINUS:   return SkString("--");
173            default:
174                ABORT("unsupported operator: %d\n", kind);
175        }
176    }
177
178    Token() {
179    }
180
181    Token(Position position, Kind kind, SkString text)
182    : fPosition(position)
183    , fKind(kind)
184    , fText(std::move(text)) {}
185
186    static bool IsAssignment(Token::Kind op) {
187        switch (op) {
188            case Token::EQ:           // fall through
189            case Token::PLUSEQ:       // fall through
190            case Token::MINUSEQ:      // fall through
191            case Token::STAREQ:       // fall through
192            case Token::SLASHEQ:      // fall through
193            case Token::PERCENTEQ:    // fall through
194            case Token::SHLEQ:        // fall through
195            case Token::SHREQ:        // fall through
196            case Token::BITWISEOREQ:  // fall through
197            case Token::BITWISEXOREQ: // fall through
198            case Token::BITWISEANDEQ: // fall through
199            case Token::LOGICALOREQ:  // fall through
200            case Token::LOGICALXOREQ: // fall through
201            case Token::LOGICALANDEQ:
202                return true;
203            default:
204                return false;
205        }
206    }
207
208    Position fPosition;
209    Kind fKind;
210    // will be the empty string unless the token has variable text content (identifiers, numeric
211    // literals, and directives)
212    SkString fText;
213};
214
215} // namespace
216#endif
217