Home | History | Annotate | Download | only in sksl
      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 
     14 namespace 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  */
     24 struct 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