1// Copyright 2017 The Wuffs Authors. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// https://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package token 16 17// MaxIntBits is the largest size (in bits) of the i8, u8, i16, u16, etc. 18// integer types. 19const MaxIntBits = 64 20 21// ID is a token type. Every identifier (in the programming language sense), 22// keyword, operator and literal has its own ID. 23// 24// Some IDs are built-in: the "func" keyword always has the same numerical ID 25// value. Others are mapped at runtime. For example, the ID value for the 26// "foobar" identifier (e.g. a variable name) is looked up in a Map. 27type ID uint32 28 29// Str returns a string form of x. 30func (x ID) Str(m *Map) string { return m.ByID(x) } 31 32func (x ID) AmbiguousForm() ID { 33 if x >= ID(len(ambiguousForms)) { 34 return 0 35 } 36 return ambiguousForms[x] 37} 38 39func (x ID) UnaryForm() ID { 40 if x >= ID(len(unaryForms)) { 41 return 0 42 } 43 return unaryForms[x] 44} 45 46func (x ID) BinaryForm() ID { 47 if x >= ID(len(binaryForms)) { 48 return 0 49 } 50 return binaryForms[x] 51} 52 53func (x ID) AssociativeForm() ID { 54 if x >= ID(len(associativeForms)) { 55 return 0 56 } 57 return associativeForms[x] 58} 59 60func (x ID) IsBuiltIn() bool { return x < nBuiltInIDs } 61 62func (x ID) IsUnaryOp() bool { return minOp <= x && x <= maxOp && unaryForms[x] != 0 } 63func (x ID) IsBinaryOp() bool { return minOp <= x && x <= maxOp && binaryForms[x] != 0 } 64func (x ID) IsAssociativeOp() bool { return minOp <= x && x <= maxOp && associativeForms[x] != 0 } 65 66func (x ID) IsLiteral(m *Map) bool { 67 if x < nBuiltInIDs { 68 return minBuiltInLiteral <= x && x <= maxBuiltInLiteral 69 } else if s := m.ByID(x); s != "" { 70 return !alpha(s[0]) 71 } 72 return false 73} 74 75func (x ID) IsNumLiteral(m *Map) bool { 76 if x < nBuiltInIDs { 77 return minBuiltInNumLiteral <= x && x <= maxBuiltInNumLiteral 78 } else if s := m.ByID(x); s != "" { 79 return numeric(s[0]) 80 } 81 return false 82} 83 84func (x ID) IsStrLiteral(m *Map) bool { 85 if x < nBuiltInIDs { 86 return false 87 } else if s := m.ByID(x); s != "" { 88 return s[0] == '"' 89 } 90 return false 91} 92 93func (x ID) IsIdent(m *Map) bool { 94 if x < nBuiltInIDs { 95 return minBuiltInIdent <= x && x <= maxBuiltInIdent 96 } else if s := m.ByID(x); s != "" { 97 return alpha(s[0]) 98 } 99 return false 100} 101 102func (x ID) IsTightLeft() bool { return x < ID(len(isTightLeft)) && isTightLeft[x] } 103func (x ID) IsTightRight() bool { return x < ID(len(isTightRight)) && isTightRight[x] } 104 105func (x ID) IsAssign() bool { return minAssign <= x && x <= maxAssign } 106func (x ID) IsCannotAssignTo() bool { return minCannotAssignTo <= x && x <= maxCannotAssignTo } 107func (x ID) IsClose() bool { return minClose <= x && x <= maxClose } 108func (x ID) IsKeyword() bool { return minKeyword <= x && x <= maxKeyword } 109func (x ID) IsNumType() bool { return minNumType <= x && x <= maxNumType } 110func (x ID) IsNumTypeOrIdeal() bool { return minNumTypeOrIdeal <= x && x <= maxNumTypeOrIdeal } 111func (x ID) IsOpen() bool { return minOpen <= x && x <= maxOpen } 112 113func (x ID) IsImplicitSemicolon(m *Map) bool { 114 return x.IsClose() || x.IsKeyword() || x.IsIdent(m) || x.IsLiteral(m) 115} 116 117func (x ID) IsXOp() bool { return minXOp <= x && x <= maxXOp } 118func (x ID) IsXUnaryOp() bool { return minXOp <= x && x <= maxXOp && unaryForms[x] != 0 } 119func (x ID) IsXBinaryOp() bool { return minXOp <= x && x <= maxXOp && binaryForms[x] != 0 } 120func (x ID) IsXAssociativeOp() bool { return minXOp <= x && x <= maxXOp && associativeForms[x] != 0 } 121 122func (x ID) SmallPowerOf2Value() int { 123 switch x { 124 case ID1: 125 return 1 126 case ID2: 127 return 2 128 case ID4: 129 return 4 130 case ID8: 131 return 8 132 case ID16: 133 return 16 134 case ID32: 135 return 32 136 case ID64: 137 return 64 138 case ID128: 139 return 128 140 case ID256: 141 return 256 142 } 143 return 0 144} 145 146// QID is a qualified ID, such as "foo.bar". QID[0] is "foo"'s ID and QID[1] is 147// "bar"'s. QID[0] may be 0 for a plain "bar". 148type QID [2]ID 149 150func (x QID) IsZero() bool { return x == QID{} } 151 152// Str returns a string form of x. 153func (x QID) Str(m *Map) string { 154 if x[0] != 0 { 155 return m.ByID(x[0]) + "." + m.ByID(x[1]) 156 } 157 return m.ByID(x[1]) 158} 159 160// QQID is a double-qualified ID, such as "receiverPkg.receiverName.funcName". 161type QQID [3]ID 162 163func (x QQID) IsZero() bool { return x == QQID{} } 164 165// Str returns a string form of x. 166func (x QQID) Str(m *Map) string { 167 if x[0] != 0 { 168 return m.ByID(x[0]) + "." + m.ByID(x[1]) + "." + m.ByID(x[2]) 169 } 170 if x[1] != 0 { 171 return m.ByID(x[1]) + "." + m.ByID(x[2]) 172 } 173 return m.ByID(x[2]) 174} 175 176// Token combines an ID and the line number it was seen. 177type Token struct { 178 ID ID 179 Line uint32 180} 181 182// nBuiltInIDs is the number of built-in IDs. The packing is: 183// - Zero is invalid. 184// - [ 0x01, 0x0F] are squiggly punctuation, such as "(", ")" and ";". 185// - [ 0x10, 0x2F] are squiggly assignments, such as "=" and "+=". 186// - [ 0x30, 0x4F] are operators, such as "+", "==" and "not". 187// - [ 0x50, 0x7F] are x-ops (disambiguation forms): unary vs binary "+". 188// - [ 0x80, 0x9F] are keywords, such as "if" and "return". 189// - [ 0xA0, 0xAF] are type modifiers, such as "ptr" and "slice". 190// - [ 0xB0, 0xBF] are literals, such as "false" and "true". 191// - [ 0xC0, 0xFF] are reserved. 192// - [0x100, 0x3FF] are identifiers, such as "bool", "u32" and "read_u8". 193// 194// "Squiggly" means a sequence of non-alpha-numeric characters, such as "+" and 195// "&=". Roughly speaking, their IDs range in [0x01, 0x4F], or disambiguation 196// forms range in [0x50, 0x7F], but vice versa does not necessarily hold. For 197// example, the "and" operator is not "squiggly" but it is within [0x01, 0x4F]. 198const ( 199 nBuiltInSymbolicIDs = ID(0x80) // 128 200 nBuiltInIDs = ID(0x400) // 1024 201) 202 203const ( 204 IDInvalid = ID(0) 205 IDSemicolon = ID(0x01) 206 207 minOpen = 0x02 208 maxOpen = 0x04 209 210 IDOpenParen = ID(0x02) 211 IDOpenBracket = ID(0x03) 212 IDOpenCurly = ID(0x04) 213 214 minClose = 0x05 215 maxClose = 0x07 216 217 IDCloseParen = ID(0x05) 218 IDCloseBracket = ID(0x06) 219 IDCloseCurly = ID(0x07) 220 221 IDDot = ID(0x08) 222 IDDotDot = ID(0x09) 223 IDDotDotEq = ID(0x0A) 224 IDComma = ID(0x0B) 225 IDExclam = ID(0x0C) 226 IDQuestion = ID(0x0D) 227 IDColon = ID(0x0E) 228) 229 230const ( 231 minAssign = 0x10 232 maxAssign = 0x2F 233 234 IDPlusEq = ID(0x10) 235 IDMinusEq = ID(0x11) 236 IDStarEq = ID(0x12) 237 IDSlashEq = ID(0x13) 238 IDShiftLEq = ID(0x14) 239 IDShiftREq = ID(0x15) 240 IDAmpEq = ID(0x16) 241 IDPipeEq = ID(0x17) 242 IDHatEq = ID(0x18) 243 IDPercentEq = ID(0x19) 244 IDTildeModShiftLEq = ID(0x1A) 245 IDTildeModPlusEq = ID(0x1B) 246 IDTildeModMinusEq = ID(0x1C) 247 IDTildeSatPlusEq = ID(0x1D) 248 IDTildeSatMinusEq = ID(0x1E) 249 250 IDEq = ID(0x20) 251 IDEqQuestion = ID(0x21) 252) 253 254const ( 255 minOp = 0x30 256 minAmbiguousOp = 0x30 257 maxAmbiguousOp = 0x4F 258 minXOp = 0x50 259 maxXOp = 0x7F 260 maxOp = 0x7F 261 262 IDPlus = ID(0x30) 263 IDMinus = ID(0x31) 264 IDStar = ID(0x32) 265 IDSlash = ID(0x33) 266 IDShiftL = ID(0x34) 267 IDShiftR = ID(0x35) 268 IDAmp = ID(0x36) 269 IDPipe = ID(0x37) 270 IDHat = ID(0x38) 271 IDPercent = ID(0x39) 272 IDTildeModShiftL = ID(0x3A) 273 IDTildeModPlus = ID(0x3B) 274 IDTildeModMinus = ID(0x3C) 275 IDTildeSatPlus = ID(0x3D) 276 IDTildeSatMinus = ID(0x3E) 277 278 IDNotEq = ID(0x40) 279 IDLessThan = ID(0x41) 280 IDLessEq = ID(0x42) 281 IDEqEq = ID(0x43) 282 IDGreaterEq = ID(0x44) 283 IDGreaterThan = ID(0x45) 284 285 IDAnd = ID(0x48) 286 IDOr = ID(0x49) 287 IDNot = ID(0x4A) 288 IDAs = ID(0x4B) 289 290 // The IDXFoo IDs are not returned by the tokenizer. They are used by the 291 // ast.Node ID-typed fields to disambiguate e.g. unary vs binary plus. 292 293 IDXUnaryPlus = ID(0x50) 294 IDXUnaryMinus = ID(0x51) 295 IDXUnaryNot = ID(0x52) 296 297 IDXBinaryPlus = ID(0x58) 298 IDXBinaryMinus = ID(0x59) 299 IDXBinaryStar = ID(0x5A) 300 IDXBinarySlash = ID(0x5B) 301 IDXBinaryShiftL = ID(0x5C) 302 IDXBinaryShiftR = ID(0x5D) 303 IDXBinaryAmp = ID(0x5E) 304 IDXBinaryPipe = ID(0x5F) 305 IDXBinaryHat = ID(0x60) 306 IDXBinaryPercent = ID(0x61) 307 IDXBinaryTildeModShiftL = ID(0x62) 308 IDXBinaryTildeModPlus = ID(0x63) 309 IDXBinaryTildeModMinus = ID(0x64) 310 IDXBinaryTildeSatPlus = ID(0x65) 311 IDXBinaryTildeSatMinus = ID(0x66) 312 IDXBinaryNotEq = ID(0x67) 313 IDXBinaryLessThan = ID(0x68) 314 IDXBinaryLessEq = ID(0x69) 315 IDXBinaryEqEq = ID(0x6A) 316 IDXBinaryGreaterEq = ID(0x6B) 317 IDXBinaryGreaterThan = ID(0x6C) 318 IDXBinaryAnd = ID(0x6D) 319 IDXBinaryOr = ID(0x6E) 320 IDXBinaryAs = ID(0x6F) 321 322 IDXAssociativePlus = ID(0x70) 323 IDXAssociativeStar = ID(0x71) 324 IDXAssociativeAmp = ID(0x72) 325 IDXAssociativePipe = ID(0x73) 326 IDXAssociativeHat = ID(0x74) 327 IDXAssociativeAnd = ID(0x75) 328 IDXAssociativeOr = ID(0x76) 329) 330 331const ( 332 minKeyword = 0x80 333 maxKeyword = 0x9F 334 335 // TODO: sort these by name, when the list has stabilized. 336 IDFunc = ID(0x80) 337 IDAssert = ID(0x81) 338 IDWhile = ID(0x82) 339 IDIf = ID(0x83) 340 IDElse = ID(0x84) 341 IDReturn = ID(0x85) 342 IDBreak = ID(0x86) 343 IDContinue = ID(0x87) 344 IDStruct = ID(0x88) 345 IDUse = ID(0x89) 346 IDVar = ID(0x8A) 347 IDPre = ID(0x8B) 348 IDInv = ID(0x8C) 349 IDPost = ID(0x8D) 350 IDVia = ID(0x8E) 351 IDPub = ID(0x8F) 352 IDPri = ID(0x90) 353 IDConst = ID(0x91) 354 IDIterate = ID(0x92) 355 IDYield = ID(0x93) 356 IDIOBind = ID(0x94) 357 IDIOLimit = ID(0x95) 358) 359 360const ( 361 minTypeModifier = 0xA0 362 maxTypeModifier = 0xAF 363 364 IDArray = ID(0xA0) 365 IDNptr = ID(0xA1) 366 IDPtr = ID(0xA2) 367 IDSlice = ID(0xA3) 368 IDTable = ID(0xA4) 369) 370 371const ( 372 minBuiltInLiteral = 0xB0 373 minBuiltInNumLiteral = 0xC0 374 maxBuiltInNumLiteral = 0xCF 375 maxBuiltInLiteral = 0xCF 376 377 IDFalse = ID(0xB0) 378 IDTrue = ID(0xB1) 379 IDNothing = ID(0xB2) 380 IDNullptr = ID(0xB3) 381 IDOk = ID(0xB4) 382 383 ID0 = ID(0xC0) 384 ID1 = ID(0xC1) 385 ID2 = ID(0xC2) 386 ID4 = ID(0xC3) 387 ID8 = ID(0xC4) 388 ID16 = ID(0xC5) 389 ID32 = ID(0xC6) 390 ID64 = ID(0xC7) 391 ID128 = ID(0xC8) 392 ID256 = ID(0xC9) 393) 394 395const ( 396 minBuiltInIdent = 0x100 397 minCannotAssignTo = 0x100 398 maxCannotAssignTo = 0x102 399 minNumTypeOrIdeal = 0x10F 400 minNumType = 0x110 401 maxNumType = 0x117 402 maxNumTypeOrIdeal = 0x117 403 maxBuiltInIdent = 0x3FF 404 405 // -------- 0x100 block. 406 407 IDArgs = ID(0x100) 408 IDCoroutineResumed = ID(0x101) 409 IDThis = ID(0x102) 410 411 IDT1 = ID(0x108) 412 IDT2 = ID(0x109) 413 IDDagger1 = ID(0x10A) 414 IDDagger2 = ID(0x10B) 415 416 IDQNullptr = ID(0x10C) 417 IDQPlaceholder = ID(0x10D) 418 IDQTypeExpr = ID(0x10E) 419 420 // It is important that IDQIdeal is right next to the IDI8..IDU64 block. 421 // See the ID.IsNumTypeOrIdeal method. 422 IDQIdeal = ID(0x10F) 423 424 IDI8 = ID(0x110) 425 IDI16 = ID(0x111) 426 IDI32 = ID(0x112) 427 IDI64 = ID(0x113) 428 IDU8 = ID(0x114) 429 IDU16 = ID(0x115) 430 IDU32 = ID(0x116) 431 IDU64 = ID(0x117) 432 433 IDBase = ID(0x120) 434 IDBool = ID(0x121) 435 IDEmptyIOReader = ID(0x122) 436 IDEmptyIOWriter = ID(0x123) 437 IDEmptyStruct = ID(0x124) 438 IDIOReader = ID(0x125) 439 IDIOWriter = ID(0x126) 440 IDStatus = ID(0x127) 441 IDUtility = ID(0x128) 442 443 IDRangeIEU32 = ID(0x130) 444 IDRangeIIU32 = ID(0x131) 445 IDRangeIEU64 = ID(0x132) 446 IDRangeIIU64 = ID(0x133) 447 IDRectIEU32 = ID(0x134) 448 IDRectIIU32 = ID(0x135) 449 450 IDFrameConfig = ID(0x150) 451 IDImageConfig = ID(0x151) 452 IDPixelBuffer = ID(0x152) 453 IDPixelConfig = ID(0x153) 454 IDPixelSwizzler = ID(0x154) 455 456 IDDecodeFrameOptions = ID(0x158) 457 458 IDCanUndoByte = ID(0x160) 459 IDCountSince = ID(0x161) 460 IDHistoryAvailable = ID(0x162) 461 IDMark = ID(0x163) 462 IDPosition = ID(0x164) 463 IDSince = ID(0x165) 464 IDSkip = ID(0x166) 465 IDSkipFast = ID(0x167) 466 IDTake = ID(0x168) 467 468 IDCopyFromSlice = ID(0x170) 469 IDCopyNFromHistory = ID(0x171) 470 IDCopyNFromHistoryFast = ID(0x172) 471 IDCopyNFromReader = ID(0x173) 472 IDCopyNFromSlice = ID(0x174) 473 474 // -------- 0x180 block. 475 476 IDUndoByte = ID(0x180) 477 IDReadU8 = ID(0x181) 478 479 IDReadU16BE = ID(0x182) 480 IDReadU16LE = ID(0x183) 481 482 IDReadU8AsU32 = ID(0x189) 483 IDReadU16BEAsU32 = ID(0x18A) 484 IDReadU16LEAsU32 = ID(0x18B) 485 IDReadU24BEAsU32 = ID(0x18C) 486 IDReadU24LEAsU32 = ID(0x18D) 487 IDReadU32BE = ID(0x18E) 488 IDReadU32LE = ID(0x18F) 489 490 IDReadU8AsU64 = ID(0x191) 491 IDReadU16BEAsU64 = ID(0x192) 492 IDReadU16LEAsU64 = ID(0x193) 493 IDReadU24BEAsU64 = ID(0x194) 494 IDReadU24LEAsU64 = ID(0x195) 495 IDReadU32BEAsU64 = ID(0x196) 496 IDReadU32LEAsU64 = ID(0x197) 497 IDReadU40BEAsU64 = ID(0x198) 498 IDReadU40LEAsU64 = ID(0x199) 499 IDReadU48BEAsU64 = ID(0x19A) 500 IDReadU48LEAsU64 = ID(0x19B) 501 IDReadU56BEAsU64 = ID(0x19C) 502 IDReadU56LEAsU64 = ID(0x19D) 503 IDReadU64BE = ID(0x19E) 504 IDReadU64LE = ID(0x19F) 505 506 // -------- 507 508 IDPeekU8 = ID(0x1A1) 509 510 IDPeekU16BE = ID(0x1A2) 511 IDPeekU16LE = ID(0x1A3) 512 513 IDPeekU8AsU32 = ID(0x1A9) 514 IDPeekU16BEAsU32 = ID(0x1AA) 515 IDPeekU16LEAsU32 = ID(0x1AB) 516 IDPeekU24BEAsU32 = ID(0x1AC) 517 IDPeekU24LEAsU32 = ID(0x1AD) 518 IDPeekU32BE = ID(0x1AE) 519 IDPeekU32LE = ID(0x1AF) 520 521 IDPeekU8AsU64 = ID(0x1B1) 522 IDPeekU16BEAsU64 = ID(0x1B2) 523 IDPeekU16LEAsU64 = ID(0x1B3) 524 IDPeekU24BEAsU64 = ID(0x1B4) 525 IDPeekU24LEAsU64 = ID(0x1B5) 526 IDPeekU32BEAsU64 = ID(0x1B6) 527 IDPeekU32LEAsU64 = ID(0x1B7) 528 IDPeekU40BEAsU64 = ID(0x1B8) 529 IDPeekU40LEAsU64 = ID(0x1B9) 530 IDPeekU48BEAsU64 = ID(0x1BA) 531 IDPeekU48LEAsU64 = ID(0x1BB) 532 IDPeekU56BEAsU64 = ID(0x1BC) 533 IDPeekU56LEAsU64 = ID(0x1BD) 534 IDPeekU64BE = ID(0x1BE) 535 IDPeekU64LE = ID(0x1BF) 536 537 // -------- 538 539 // TODO: IDUnwriteU8? 540 541 IDWriteU8 = ID(0x1C1) 542 IDWriteU16BE = ID(0x1C2) 543 IDWriteU16LE = ID(0x1C3) 544 IDWriteU24BE = ID(0x1C4) 545 IDWriteU24LE = ID(0x1C5) 546 IDWriteU32BE = ID(0x1C6) 547 IDWriteU32LE = ID(0x1C7) 548 IDWriteU40BE = ID(0x1C8) 549 IDWriteU40LE = ID(0x1C9) 550 IDWriteU48BE = ID(0x1CA) 551 IDWriteU48LE = ID(0x1CB) 552 IDWriteU56BE = ID(0x1CC) 553 IDWriteU56LE = ID(0x1CD) 554 IDWriteU64BE = ID(0x1CE) 555 IDWriteU64LE = ID(0x1CF) 556 557 // -------- 558 559 IDWriteFastU8 = ID(0x1E1) 560 IDWriteFastU16BE = ID(0x1E2) 561 IDWriteFastU16LE = ID(0x1E3) 562 IDWriteFastU24BE = ID(0x1E4) 563 IDWriteFastU24LE = ID(0x1E5) 564 IDWriteFastU32BE = ID(0x1E6) 565 IDWriteFastU32LE = ID(0x1E7) 566 IDWriteFastU40BE = ID(0x1E8) 567 IDWriteFastU40LE = ID(0x1E9) 568 IDWriteFastU48BE = ID(0x1EA) 569 IDWriteFastU48LE = ID(0x1EB) 570 IDWriteFastU56BE = ID(0x1EC) 571 IDWriteFastU56LE = ID(0x1ED) 572 IDWriteFastU64BE = ID(0x1EE) 573 IDWriteFastU64LE = ID(0x1EF) 574 575 // -------- 0x200 block. 576 577 IDInitialize = ID(0x200) 578 IDReset = ID(0x201) 579 IDSet = ID(0x202) 580 IDUnroll = ID(0x203) 581 IDUpdate = ID(0x204) 582 583 // TODO: range/rect methods like intersection and contains? 584 585 IDHighBits = ID(0x220) 586 IDLowBits = ID(0x221) 587 IDMax = ID(0x222) 588 IDMin = ID(0x223) 589 590 IDIsError = ID(0x230) 591 IDIsOK = ID(0x231) 592 IDIsSuspension = ID(0x232) 593 594 IDAvailable = ID(0x240) 595 IDHeight = ID(0x241) 596 IDLength = ID(0x242) 597 IDPrefix = ID(0x243) 598 IDRow = ID(0x244) 599 IDStride = ID(0x245) 600 IDSuffix = ID(0x246) 601 IDWidth = ID(0x247) 602 IDIO = ID(0x248) 603 IDLimit = ID(0x249) 604 IDData = ID(0x24A) 605) 606 607var builtInsByID = [nBuiltInIDs]string{ 608 IDOpenParen: "(", 609 IDCloseParen: ")", 610 IDOpenBracket: "[", 611 IDCloseBracket: "]", 612 IDOpenCurly: "{", 613 IDCloseCurly: "}", 614 615 IDDot: ".", 616 IDDotDot: "..", 617 IDDotDotEq: "..=", 618 IDComma: ",", 619 IDExclam: "!", 620 IDQuestion: "?", 621 IDColon: ":", 622 IDSemicolon: ";", 623 624 IDPlusEq: "+=", 625 IDMinusEq: "-=", 626 IDStarEq: "*=", 627 IDSlashEq: "/=", 628 IDShiftLEq: "<<=", 629 IDShiftREq: ">>=", 630 IDAmpEq: "&=", 631 IDPipeEq: "|=", 632 IDHatEq: "^=", 633 IDPercentEq: "%=", 634 IDTildeModShiftLEq: "~mod<<=", 635 IDTildeModPlusEq: "~mod+=", 636 IDTildeModMinusEq: "~mod-=", 637 IDTildeSatPlusEq: "~sat+=", 638 IDTildeSatMinusEq: "~sat-=", 639 640 IDEq: "=", 641 IDEqQuestion: "=?", 642 643 IDPlus: "+", 644 IDMinus: "-", 645 IDStar: "*", 646 IDSlash: "/", 647 IDShiftL: "<<", 648 IDShiftR: ">>", 649 IDAmp: "&", 650 IDPipe: "|", 651 IDHat: "^", 652 IDPercent: "%", 653 IDTildeModShiftL: "~mod<<", 654 IDTildeModPlus: "~mod+", 655 IDTildeModMinus: "~mod-", 656 IDTildeSatPlus: "~sat+", 657 IDTildeSatMinus: "~sat-", 658 659 IDNotEq: "<>", 660 IDLessThan: "<", 661 IDLessEq: "<=", 662 IDEqEq: "==", 663 IDGreaterEq: ">=", 664 IDGreaterThan: ">", 665 666 IDAnd: "and", 667 IDOr: "or", 668 IDNot: "not", 669 IDAs: "as", 670 671 IDFunc: "func", 672 IDAssert: "assert", 673 IDWhile: "while", 674 IDIf: "if", 675 IDElse: "else", 676 IDReturn: "return", 677 IDBreak: "break", 678 IDContinue: "continue", 679 IDStruct: "struct", 680 IDUse: "use", 681 IDVar: "var", 682 IDPre: "pre", 683 IDInv: "inv", 684 IDPost: "post", 685 IDVia: "via", 686 IDPub: "pub", 687 IDPri: "pri", 688 IDConst: "const", 689 IDIterate: "iterate", 690 IDYield: "yield", 691 IDIOBind: "io_bind", 692 IDIOLimit: "io_limit", 693 694 IDArray: "array", 695 IDNptr: "nptr", 696 IDPtr: "ptr", 697 IDSlice: "slice", 698 IDTable: "table", 699 700 IDFalse: "false", 701 IDTrue: "true", 702 IDNothing: "nothing", 703 IDNullptr: "nullptr", 704 IDOk: "ok", 705 706 ID0: "0", 707 ID1: "1", 708 ID2: "2", 709 ID4: "4", 710 ID8: "8", 711 ID16: "16", 712 ID32: "32", 713 ID64: "64", 714 ID128: "128", 715 ID256: "256", 716 717 // -------- 0x100 block. 718 719 IDArgs: "args", 720 IDCoroutineResumed: "coroutine_resumed", 721 IDThis: "this", 722 723 // Some of the next few IDs are never returned by the tokenizer, as it 724 // rejects non-ASCII input. The string representations "¶", "ℤ" etc. are 725 // specifically non-ASCII so that no user-defined (non built-in) identifier 726 // will conflict with them. 727 728 // IDDaggerN is used by the type checker as a dummy-valued built-in ID to 729 // represent a generic type. 730 IDT1: "T1", 731 IDT2: "T2", 732 IDDagger1: "†", // U+2020 DAGGER 733 IDDagger2: "‡", // U+2021 DOUBLE DAGGER 734 735 // IDQNullptr is used by the type checker to build an artificial MType for 736 // the nullptr literal. 737 IDQNullptr: "«Nullptr»", 738 739 // IDQPlaceholder is used by the type checker to build an artificial MType 740 // for AST nodes that aren't expression nodes or type expression nodes, 741 // such as struct definition nodes and statement nodes. Its presence means 742 // that the node is type checked. 743 IDQPlaceholder: "«Placeholder»", 744 745 // IDQTypeExpr is used by the type checker to build an artificial MType for 746 // type expression AST nodes. 747 IDQTypeExpr: "«TypeExpr»", 748 749 // IDQIdeal is used by the type checker to build an artificial MType for 750 // ideal integers (in mathematical terms, the integer ring ℤ), as opposed 751 // to a realized integer type whose range is restricted. For example, the 752 // base.u16 type is restricted to [0x0000, 0xFFFF]. 753 IDQIdeal: "«Ideal»", 754 755 // Change MaxIntBits if a future update adds an i128 or u128 type. 756 IDI8: "i8", 757 IDI16: "i16", 758 IDI32: "i32", 759 IDI64: "i64", 760 IDU8: "u8", 761 IDU16: "u16", 762 IDU32: "u32", 763 IDU64: "u64", 764 765 IDBase: "base", 766 IDBool: "bool", 767 IDEmptyIOReader: "empty_io_reader", 768 IDEmptyIOWriter: "empty_io_writer", 769 IDEmptyStruct: "empty_struct", 770 IDIOReader: "io_reader", 771 IDIOWriter: "io_writer", 772 IDStatus: "status", 773 IDUtility: "utility", 774 775 IDRangeIEU32: "range_ie_u32", 776 IDRangeIIU32: "range_ii_u32", 777 IDRangeIEU64: "range_ie_u64", 778 IDRangeIIU64: "range_ii_u64", 779 IDRectIEU32: "rect_ie_u32", 780 IDRectIIU32: "rect_ii_u32", 781 782 IDFrameConfig: "frame_config", 783 IDImageConfig: "image_config", 784 IDPixelBuffer: "pixel_buffer", 785 IDPixelConfig: "pixel_config", 786 IDPixelSwizzler: "pixel_swizzler", 787 788 IDDecodeFrameOptions: "decode_frame_options", 789 790 IDCanUndoByte: "can_undo_byte", 791 IDCountSince: "count_since", 792 IDHistoryAvailable: "history_available", 793 IDMark: "mark", 794 IDPosition: "position", 795 IDSince: "since", 796 IDSkip: "skip", 797 IDSkipFast: "skip_fast", 798 IDTake: "take", 799 800 IDCopyFromSlice: "copy_from_slice", 801 IDCopyNFromHistory: "copy_n_from_history", 802 IDCopyNFromHistoryFast: "copy_n_from_history_fast", 803 IDCopyNFromReader: "copy_n_from_reader", 804 IDCopyNFromSlice: "copy_n_from_slice", 805 806 // -------- 0x180 block. 807 808 IDUndoByte: "undo_byte", 809 IDReadU8: "read_u8", 810 811 IDReadU16BE: "read_u16be", 812 IDReadU16LE: "read_u16le", 813 814 IDReadU8AsU32: "read_u8_as_u32", 815 IDReadU16BEAsU32: "read_u16be_as_u32", 816 IDReadU16LEAsU32: "read_u16le_as_u32", 817 IDReadU24BEAsU32: "read_u24be_as_u32", 818 IDReadU24LEAsU32: "read_u24le_as_u32", 819 IDReadU32BE: "read_u32be", 820 IDReadU32LE: "read_u32le", 821 822 IDReadU8AsU64: "read_u8_as_u64", 823 IDReadU16BEAsU64: "read_u16be_as_u64", 824 IDReadU16LEAsU64: "read_u16le_as_u64", 825 IDReadU24BEAsU64: "read_u24be_as_u64", 826 IDReadU24LEAsU64: "read_u24le_as_u64", 827 IDReadU32BEAsU64: "read_u32be_as_u64", 828 IDReadU32LEAsU64: "read_u32le_as_u64", 829 IDReadU40BEAsU64: "read_u40be_as_u64", 830 IDReadU40LEAsU64: "read_u40le_as_u64", 831 IDReadU48BEAsU64: "read_u48be_as_u64", 832 IDReadU48LEAsU64: "read_u48le_as_u64", 833 IDReadU56BEAsU64: "read_u56be_as_u64", 834 IDReadU56LEAsU64: "read_u56le_as_u64", 835 IDReadU64BE: "read_u64be", 836 IDReadU64LE: "read_u64le", 837 838 // -------- 839 840 IDPeekU8: "peek_u8", 841 842 IDPeekU16BE: "peek_u16be", 843 IDPeekU16LE: "peek_u16le", 844 845 IDPeekU8AsU32: "peek_u8_as_u32", 846 IDPeekU16BEAsU32: "peek_u16be_as_u32", 847 IDPeekU16LEAsU32: "peek_u16le_as_u32", 848 IDPeekU24BEAsU32: "peek_u24be_as_u32", 849 IDPeekU24LEAsU32: "peek_u24le_as_u32", 850 IDPeekU32BE: "peek_u32be", 851 IDPeekU32LE: "peek_u32le", 852 853 IDPeekU8AsU64: "peek_u8_as_u64", 854 IDPeekU16BEAsU64: "peek_u16be_as_u64", 855 IDPeekU16LEAsU64: "peek_u16le_as_u64", 856 IDPeekU24BEAsU64: "peek_u24be_as_u64", 857 IDPeekU24LEAsU64: "peek_u24le_as_u64", 858 IDPeekU32BEAsU64: "peek_u32be_as_u64", 859 IDPeekU32LEAsU64: "peek_u32le_as_u64", 860 IDPeekU40BEAsU64: "peek_u40be_as_u64", 861 IDPeekU40LEAsU64: "peek_u40le_as_u64", 862 IDPeekU48BEAsU64: "peek_u48be_as_u64", 863 IDPeekU48LEAsU64: "peek_u48le_as_u64", 864 IDPeekU56BEAsU64: "peek_u56be_as_u64", 865 IDPeekU56LEAsU64: "peek_u56le_as_u64", 866 IDPeekU64BE: "peek_u64be", 867 IDPeekU64LE: "peek_u64le", 868 869 // -------- 870 871 IDWriteU8: "write_u8", 872 IDWriteU16BE: "write_u16be", 873 IDWriteU16LE: "write_u16le", 874 IDWriteU24BE: "write_u24be", 875 IDWriteU24LE: "write_u24le", 876 IDWriteU32BE: "write_u32be", 877 IDWriteU32LE: "write_u32le", 878 IDWriteU40BE: "write_u40be", 879 IDWriteU40LE: "write_u40le", 880 IDWriteU48BE: "write_u48be", 881 IDWriteU48LE: "write_u48le", 882 IDWriteU56BE: "write_u56be", 883 IDWriteU56LE: "write_u56le", 884 IDWriteU64BE: "write_u64be", 885 IDWriteU64LE: "write_u64le", 886 887 // -------- 888 889 IDWriteFastU8: "write_fast_u8", 890 IDWriteFastU16BE: "write_fast_u16be", 891 IDWriteFastU16LE: "write_fast_u16le", 892 IDWriteFastU24BE: "write_fast_u24be", 893 IDWriteFastU24LE: "write_fast_u24le", 894 IDWriteFastU32BE: "write_fast_u32be", 895 IDWriteFastU32LE: "write_fast_u32le", 896 IDWriteFastU40BE: "write_fast_u40be", 897 IDWriteFastU40LE: "write_fast_u40le", 898 IDWriteFastU48BE: "write_fast_u48be", 899 IDWriteFastU48LE: "write_fast_u48le", 900 IDWriteFastU56BE: "write_fast_u56be", 901 IDWriteFastU56LE: "write_fast_u56le", 902 IDWriteFastU64BE: "write_fast_u64be", 903 IDWriteFastU64LE: "write_fast_u64le", 904 905 // -------- 0x200 block. 906 907 IDInitialize: "initialize", 908 IDReset: "reset", 909 IDSet: "set", 910 IDUnroll: "unroll", 911 IDUpdate: "update", 912 913 IDHighBits: "high_bits", 914 IDLowBits: "low_bits", 915 IDMax: "max", 916 IDMin: "min", 917 918 IDIsError: "is_error", 919 IDIsOK: "is_ok", 920 IDIsSuspension: "is_suspension", 921 922 IDAvailable: "available", 923 IDHeight: "height", 924 IDLength: "length", 925 IDPrefix: "prefix", 926 IDRow: "row", 927 IDStride: "stride", 928 IDSuffix: "suffix", 929 IDWidth: "width", 930 IDIO: "io", 931 IDLimit: "limit", 932 IDData: "data", 933} 934 935var builtInsByName = map[string]ID{} 936 937func init() { 938 for i, name := range builtInsByID { 939 if name != "" { 940 builtInsByName[name] = ID(i) 941 } 942 } 943} 944 945// squiggles are built-in IDs that aren't alpha-numeric. 946var squiggles = [256]ID{ 947 '(': IDOpenParen, 948 ')': IDCloseParen, 949 '[': IDOpenBracket, 950 ']': IDCloseBracket, 951 '{': IDOpenCurly, 952 '}': IDCloseCurly, 953 954 ',': IDComma, 955 '!': IDExclam, 956 '?': IDQuestion, 957 ':': IDColon, 958 ';': IDSemicolon, 959} 960 961type suffixLexer struct { 962 suffix string 963 id ID 964} 965 966// lexers lex ambiguous 1-byte squiggles. For example, "&" might be the start 967// of "&^" or "&=". 968// 969// The order of the []suffixLexer elements matters. The first match wins. Since 970// we want to lex greedily, longer suffixes should be earlier in the slice. 971var lexers = [256][]suffixLexer{ 972 '.': { 973 {".=", IDDotDotEq}, 974 {".", IDDotDot}, 975 {"", IDDot}, 976 }, 977 '&': { 978 {"=", IDAmpEq}, 979 {"", IDAmp}, 980 }, 981 '|': { 982 {"=", IDPipeEq}, 983 {"", IDPipe}, 984 }, 985 '^': { 986 {"=", IDHatEq}, 987 {"", IDHat}, 988 }, 989 '+': { 990 {"=", IDPlusEq}, 991 {"", IDPlus}, 992 }, 993 '-': { 994 {"=", IDMinusEq}, 995 {"", IDMinus}, 996 }, 997 '*': { 998 {"=", IDStarEq}, 999 {"", IDStar}, 1000 }, 1001 '/': { 1002 {"=", IDSlashEq}, 1003 {"", IDSlash}, 1004 }, 1005 '%': { 1006 {"=", IDPercentEq}, 1007 {"", IDPercent}, 1008 }, 1009 '=': { 1010 {"=", IDEqEq}, 1011 {"?", IDEqQuestion}, 1012 {"", IDEq}, 1013 }, 1014 '<': { 1015 {"<=", IDShiftLEq}, 1016 {"<", IDShiftL}, 1017 {"=", IDLessEq}, 1018 {">", IDNotEq}, 1019 {"", IDLessThan}, 1020 }, 1021 '>': { 1022 {">=", IDShiftREq}, 1023 {">", IDShiftR}, 1024 {"=", IDGreaterEq}, 1025 {"", IDGreaterThan}, 1026 }, 1027 '~': { 1028 {"mod<<=", IDTildeModShiftLEq}, 1029 {"mod<<", IDTildeModShiftL}, 1030 {"mod+=", IDTildeModPlusEq}, 1031 {"mod+", IDTildeModPlus}, 1032 {"mod-=", IDTildeModMinusEq}, 1033 {"mod-", IDTildeModMinus}, 1034 {"sat+=", IDTildeSatPlusEq}, 1035 {"sat+", IDTildeSatPlus}, 1036 {"sat-=", IDTildeSatMinusEq}, 1037 {"sat-", IDTildeSatMinus}, 1038 }, 1039} 1040 1041var ambiguousForms = [nBuiltInSymbolicIDs]ID{ 1042 IDXUnaryPlus: IDPlus, 1043 IDXUnaryMinus: IDMinus, 1044 IDXUnaryNot: IDNot, 1045 1046 IDXBinaryPlus: IDPlus, 1047 IDXBinaryMinus: IDMinus, 1048 IDXBinaryStar: IDStar, 1049 IDXBinarySlash: IDSlash, 1050 IDXBinaryShiftL: IDShiftL, 1051 IDXBinaryShiftR: IDShiftR, 1052 IDXBinaryAmp: IDAmp, 1053 IDXBinaryPipe: IDPipe, 1054 IDXBinaryHat: IDHat, 1055 IDXBinaryPercent: IDPercent, 1056 IDXBinaryTildeModShiftL: IDTildeModShiftL, 1057 IDXBinaryTildeModPlus: IDTildeModPlus, 1058 IDXBinaryTildeModMinus: IDTildeModMinus, 1059 IDXBinaryTildeSatPlus: IDTildeSatPlus, 1060 IDXBinaryTildeSatMinus: IDTildeSatMinus, 1061 IDXBinaryNotEq: IDNotEq, 1062 IDXBinaryLessThan: IDLessThan, 1063 IDXBinaryLessEq: IDLessEq, 1064 IDXBinaryEqEq: IDEqEq, 1065 IDXBinaryGreaterEq: IDGreaterEq, 1066 IDXBinaryGreaterThan: IDGreaterThan, 1067 IDXBinaryAnd: IDAnd, 1068 IDXBinaryOr: IDOr, 1069 IDXBinaryAs: IDAs, 1070 1071 IDXAssociativePlus: IDPlus, 1072 IDXAssociativeStar: IDStar, 1073 IDXAssociativeAmp: IDAmp, 1074 IDXAssociativePipe: IDPipe, 1075 IDXAssociativeHat: IDHat, 1076 IDXAssociativeAnd: IDAnd, 1077 IDXAssociativeOr: IDOr, 1078} 1079 1080func init() { 1081 addXForms(&unaryForms) 1082 addXForms(&binaryForms) 1083 addXForms(&associativeForms) 1084} 1085 1086// addXForms modifies table so that, if table[x] == y, then table[y] = y. 1087// 1088// For example, for the unaryForms table, the explicit entries are like: 1089// IDPlus: IDXUnaryPlus, 1090// and this function implicitly addes entries like: 1091// IDXUnaryPlus: IDXUnaryPlus, 1092func addXForms(table *[nBuiltInSymbolicIDs]ID) { 1093 implicitEntries := [nBuiltInSymbolicIDs]bool{} 1094 for _, y := range table { 1095 if y != 0 { 1096 implicitEntries[y] = true 1097 } 1098 } 1099 for y, implicit := range implicitEntries { 1100 if implicit { 1101 table[y] = ID(y) 1102 } 1103 } 1104} 1105 1106var unaryForms = [nBuiltInSymbolicIDs]ID{ 1107 IDPlus: IDXUnaryPlus, 1108 IDMinus: IDXUnaryMinus, 1109 IDNot: IDXUnaryNot, 1110} 1111 1112var binaryForms = [nBuiltInSymbolicIDs]ID{ 1113 IDPlusEq: IDXBinaryPlus, 1114 IDMinusEq: IDXBinaryMinus, 1115 IDStarEq: IDXBinaryStar, 1116 IDSlashEq: IDXBinarySlash, 1117 IDShiftLEq: IDXBinaryShiftL, 1118 IDShiftREq: IDXBinaryShiftR, 1119 IDAmpEq: IDXBinaryAmp, 1120 IDPipeEq: IDXBinaryPipe, 1121 IDHatEq: IDXBinaryHat, 1122 IDPercentEq: IDXBinaryPercent, 1123 IDTildeModShiftLEq: IDXBinaryTildeModShiftL, 1124 IDTildeModPlusEq: IDXBinaryTildeModPlus, 1125 IDTildeModMinusEq: IDXBinaryTildeModMinus, 1126 IDTildeSatPlusEq: IDXBinaryTildeSatPlus, 1127 IDTildeSatMinusEq: IDXBinaryTildeSatMinus, 1128 1129 IDPlus: IDXBinaryPlus, 1130 IDMinus: IDXBinaryMinus, 1131 IDStar: IDXBinaryStar, 1132 IDSlash: IDXBinarySlash, 1133 IDShiftL: IDXBinaryShiftL, 1134 IDShiftR: IDXBinaryShiftR, 1135 IDAmp: IDXBinaryAmp, 1136 IDPipe: IDXBinaryPipe, 1137 IDHat: IDXBinaryHat, 1138 IDPercent: IDXBinaryPercent, 1139 IDTildeModShiftL: IDXBinaryTildeModShiftL, 1140 IDTildeModPlus: IDXBinaryTildeModPlus, 1141 IDTildeModMinus: IDXBinaryTildeModMinus, 1142 IDTildeSatPlus: IDXBinaryTildeSatPlus, 1143 IDTildeSatMinus: IDXBinaryTildeSatMinus, 1144 1145 IDNotEq: IDXBinaryNotEq, 1146 IDLessThan: IDXBinaryLessThan, 1147 IDLessEq: IDXBinaryLessEq, 1148 IDEqEq: IDXBinaryEqEq, 1149 IDGreaterEq: IDXBinaryGreaterEq, 1150 IDGreaterThan: IDXBinaryGreaterThan, 1151 IDAnd: IDXBinaryAnd, 1152 IDOr: IDXBinaryOr, 1153 IDAs: IDXBinaryAs, 1154} 1155 1156var associativeForms = [nBuiltInSymbolicIDs]ID{ 1157 IDPlus: IDXAssociativePlus, 1158 IDStar: IDXAssociativeStar, 1159 IDAmp: IDXAssociativeAmp, 1160 IDPipe: IDXAssociativePipe, 1161 IDHat: IDXAssociativeHat, 1162 // TODO: IDTildeModPlus, IDTildeSatPlus? 1163 IDAnd: IDXAssociativeAnd, 1164 IDOr: IDXAssociativeOr, 1165} 1166 1167var isTightLeft = [...]bool{ 1168 IDSemicolon: true, 1169 1170 IDCloseParen: true, 1171 IDOpenBracket: true, 1172 IDCloseBracket: true, 1173 1174 IDDot: true, 1175 IDComma: true, 1176 IDExclam: true, 1177 IDQuestion: true, 1178 IDColon: true, 1179} 1180 1181var isTightRight = [...]bool{ 1182 IDOpenParen: true, 1183 IDOpenBracket: true, 1184 1185 IDDot: true, 1186 IDExclam: true, 1187 IDQuestion: true, 1188} 1189