logo

const enum

compiler::Token

sys::Obj
  sys::Enum
    compiler::Token
   1  //
   2  // Copyright (c) 2006, Brian Frank and Andy Frank
   3  // Licensed under the Academic Free License version 3.0
   4  //
   5  // History:
   6  //   16 Apr 06  Brian Frank  Creation
   7  //
   8  
   9  **
  10  ** Token is the enum for all the token types.
  11  **
  12  enum Token
  13  {
  14  
  15  //////////////////////////////////////////////////////////////////////////
  16  // Enum
  17  //////////////////////////////////////////////////////////////////////////
  18  
  19    // identifer/literals
  20    identifier      ("identifier"),
  21    strLiteral      ("Str literal"),
  22    intLiteral      ("Int literal"),
  23    floatLiteral    ("Float literal"),
  24    durationLiteral ("Duration literal"),
  25    uriLiteral      ("Uri literal"),
  26  
  27    // operators
  28    dot("."),
  29    semicolon     (";"),
  30    comma         (","),
  31    colon         (":"),
  32    doubleColon   ("::"),
  33    plus          ("+"),
  34    minus         ("-"),
  35    star          ("*"),
  36    slash         ("/"),
  37    percent       ("%"),
  38    pound         ("#"),
  39    increment     ("++"),
  40    decrement     ("--"),
  41    bang          ("!"),
  42    question      ("?"),
  43    tilde         ("~"),
  44    pipe          ("|"),
  45    amp           ("&"),
  46    caret         ("^"),
  47    at            ("@"),
  48    doublePipe    ("||"),
  49    doubleAmp     ("&&"),
  50    same          ("==="),
  51    notSame       ("!=="),
  52    eq            ("=="),
  53    notEq         ("!="),
  54    cmp           ("<=>"),
  55    lt            ("<"),
  56    ltEq          ("<="),
  57    gt            (">"),
  58    gtEq          (">="),
  59    lshift        ("<<"),
  60    rshift        (">>"),
  61    lbrace        ("{"),
  62    rbrace        ("}"),
  63    lparen        ("("),
  64    rparen        (")"),
  65    lbracket      ("["),
  66    rbracket      ("]"),
  67    dotDot        (".."),
  68    dotDotDot     ("..."),
  69    defAssign     (":="),
  70    assign        ("="),
  71    assignPlus    ("+="),
  72    assignMinus   ("-="),
  73    assignStar    ("*="),
  74    assignSlash   ("/="),
  75    assignPercent ("%="),
  76    assignAmp     ("&="),
  77    assignPipe    ("|="),
  78    assignCaret   ("^="),
  79    assignLshift  ("<<="),
  80    assignRshift  (">>="),
  81    arrow         ("->"),
  82    docComment    ("**"),
  83  
  84    // keywords
  85    abstractKeyword,
  86    asKeyword,
  87    assertKeyword,
  88    breakKeyword,
  89    caseKeyword,
  90    catchKeyword,
  91    classKeyword,
  92    constKeyword,
  93    continueKeyword,
  94    defaultKeyword,
  95    doKeyword,
  96    elseKeyword,
  97    enumKeyword,
  98    falseKeyword,
  99    finalKeyword,
 100    finallyKeyword,
 101    forKeyword,
 102    foreachKeyword,
 103    gotoKeyword,
 104    ifKeyword,
 105    internalKeyword,
 106    isKeyword,
 107    mixinKeyword,
 108    nativeKeyword,
 109    newKeyword,
 110    nullKeyword,
 111    overrideKeyword,
 112    privateKeyword,
 113    protectedKeyword,
 114    publicKeyword,
 115    readonlyKeyword,
 116    returnKeyword,
 117    staticKeyword,
 118    superKeyword,
 119    switchKeyword,
 120    thisKeyword,
 121    throwKeyword,
 122    trueKeyword,
 123    tryKeyword,
 124    usingKeyword,
 125    virtualKeyword,
 126    volatileKeyword,
 127    voidKeyword,
 128    whileKeyword,
 129  
 130    // misc
 131    eof("eof");
 132  
 133    // potential keywords:
 134    //   async, checked, contract, decimal, duck, def, isnot,
 135    //   namespace, once, unchecked, unless, when,  var, with
 136  
 137  //////////////////////////////////////////////////////////////////////////
 138  // Constructor
 139  //////////////////////////////////////////////////////////////////////////
 140  
 141    **
 142    ** Construct with symbol str, or null symbol for keyword.
 143    **
 144    private new make(Str symbol := null)
 145    {
 146      if (symbol == null)
 147      {
 148        if (!name.endsWith("Keyword")) throw Err.make(name)
 149        this.symbol   = name[0..-8]
 150        this.keyword  = true
 151        this.isAssign = false
 152      }
 153      else
 154      {
 155        this.symbol   = symbol
 156        this.keyword  = false
 157        this.isAssign = name.startsWith("assign") ||
 158                        name == "increment" ||
 159                        name == "decrement"
 160      }
 161    }
 162  
 163  //////////////////////////////////////////////////////////////////////////
 164  // Methods
 165  //////////////////////////////////////////////////////////////////////////
 166  
 167    **
 168    ** Get this Token as a ExprId or throw Err.
 169    **
 170    ExprId toExprId()
 171    {
 172      switch (this)
 173      {
 174        // unary
 175        case bang:       return ExprId.boolNot
 176  
 177        // binary
 178        case assign:     return ExprId.assign
 179        case doubleAmp:  return ExprId.boolAnd
 180        case doublePipe: return ExprId.boolOr
 181        case same:       return ExprId.same
 182        case notSame:    return ExprId.notSame
 183        case asKeyword:  return ExprId.asExpr
 184        case isKeyword:  return ExprId.isExpr
 185  
 186        // default
 187        default: throw Err.make(toStr)
 188      }
 189    }
 190  
 191    /**
 192  
 193  
 194  
 195    ShortcutOp toShortcutOp(Int degree)
 196    {
 197      switch (this)
 198      {
 199        case plus:           return ShortcutOp.plus      // a + b
 200        case minus:          return degree == 1 ? ShortcutOp.negate : ShortcutOp.minus  // -a; a - b
 201        case star:           return ShortcutOp.star      // a * b
 202        case slash:          return ShortcutOp.slash     // a / b
 203        case percent:        return ShortcutOp.percent   // a % b
 204        case lshift:         return ShortcutOp.lshift    // a << b
 205        case rshift:         return ShortcutOp.rshift    // a >> b
 206        case amp:            return ShortcutOp.amp       // a & b
 207        case pipe:           return ShortcutOp.pipe      // a | b
 208        case caret:          return ShortcutOp.caret     // a ^ b
 209        case tilde:          return ShortcutOp.tilde     // ~a
 210        case increment:      return ShortcutOp.increment // ++a, a++
 211        case decrement:      return ShortcutOp.decrement // --a, a--
 212        case eq:             return ShortcutOp.eq        // a == b
 213        case notEq:          return ShortcutOp.eq        // a != b
 214        case cmp:            return ShortcutOp.cmp       // a <=> b
 215        case gt:             return ShortcutOp.cmp       // a > b
 216        case gtEq:           return ShortcutOp.cmp       // a >= b
 217        case lt:             return ShortcutOp.cmp       // a < b
 218        case ltEq:           return ShortcutOp.cmp       // a <= b
 219        case assignPlus:     return ShortcutOp.plus      // a += b
 220        case assignMinus:    return ShortcutOp.minus     // a -= b
 221        case assignStar:     return ShortcutOp.star      // a *= b
 222        case assignSlash:    return ShortcutOp.slash     // a /= b
 223        case assignPercent:  return ShortcutOp.percent   // a %= b
 224        case assignAmp:      return ShortcutOp.amp       // a &= b
 225        case assignPipe:     return ShortcutOp.pipe      // a |= b
 226        case assignCaret:    return ShortcutOp.caret     // a ^= b
 227        case assignLshift:   return ShortcutOp.lshift    // a <<= b
 228        case assignRshift:   return ShortcutOp.rshift    // a >>= b
 229        default: throw Err.make(toStr)
 230      }
 231    }
 232  
 233  //////////////////////////////////////////////////////////////////////////
 234  // Keyword Lookup
 235  //////////////////////////////////////////////////////////////////////////
 236  
 237    **
 238    ** Get a map of the keywords
 239    **
 240    const static Str:Token keywords
 241    static
 242    {
 243      map := Str:Token[:]
 244      values.each |Token t|
 245      {
 246        if (t.keyword) map[t.symbol] = t
 247      }
 248      keywords = map.toImmutable
 249    }
 250  
 251  //////////////////////////////////////////////////////////////////////////
 252  // Test
 253  //////////////////////////////////////////////////////////////////////////
 254  
 255    static Void main()
 256    {
 257      values.each |Token t|
 258      {
 259        echo(t.name + "  '" + t.symbol + "'")
 260      }
 261  
 262      echo(keywords)
 263    }
 264  
 265  //////////////////////////////////////////////////////////////////////////
 266  // Fields
 267  //////////////////////////////////////////////////////////////////////////
 268  
 269    ** Get string used to display token to user in error messages
 270    const Str symbol
 271  
 272    ** Is this a keyword token such as "null"
 273    const Bool keyword
 274  
 275    ** Is this an assignment token such as "=", etc "+=", etc
 276    const Bool isAssign
 277  
 278  }