modernc.org/cc@v1.0.1/encoding.go (about) 1 // Copyright 2016 The CC Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package cc // import "modernc.org/cc" 6 7 import ( 8 "encoding/binary" 9 "go/token" 10 "sort" 11 "strings" 12 "time" 13 14 "modernc.org/golex/lex" 15 "modernc.org/mathutil" 16 "modernc.org/xc" 17 ) 18 19 const ( 20 intBits = mathutil.IntBits 21 bitShift = intBits>>6 + 5 22 bitMask = intBits - 1 23 24 scINITIAL = 0 // Start condition (shared value). 25 ) 26 27 const ( 28 // Character class is an 8 bit encoding of an Unicode rune for the 29 // golex generated FSM. 30 // 31 // Every ASCII rune is its own class. DO NOT change any of the 32 // existing values. Adding new classes is OK. 33 ccEOF = iota + 0x80 34 _ // ccError 35 ccOther // Any other rune. 36 ccUCNDigit // [0], Annex D, Universal character names for identifiers - digits. 37 ccUCNNonDigit // [0], Annex D, Universal character names for identifiers - non digits. 38 ) 39 40 const ( 41 tsVoid = iota // 0: "void" 42 tsChar // 1: "char" 43 tsShort // 2: "short" 44 tsInt // 3: "int" 45 tsLong // 4: "long" 46 tsFloat // 5: "float" 47 tsDouble // 6: "double" 48 tsSigned // 7: "signed" 49 tsUnsigned // 8: "unsigned" 50 tsBool // 9: "_Bool" 51 tsComplex // 10: "_Complex" 52 tsStructSpecifier // 11: StructOrUnionSpecifier: struct 53 tsUnionSpecifier // 12: StructOrUnionSpecifier: union 54 tsEnumSpecifier // 13: EnumSpecifier 55 tsTypedefName // 14: TYPEDEFNAME 56 tsTypeof // 15: "typeof" 57 tsUintptr // 16: Pseudo type 58 ) 59 60 const ( 61 tsBits = 5 // Values [0, 16] 62 tsMask = 1<<tsBits - 1 63 ) 64 65 // specifier attributes. 66 const ( 67 saInline = 1 << iota 68 saTypedef 69 saExtern 70 saStatic 71 saAuto 72 saRegister 73 saConst 74 saRestrict 75 saVolatile 76 saNoreturn 77 ) 78 79 func attrString(attr int) string { 80 if attr == 0 { 81 return "" 82 } 83 84 a := []string{} 85 if attr&saAuto != 0 { 86 a = append(a, "auto") 87 } 88 if attr&saConst != 0 { 89 a = append(a, "const") 90 } 91 if attr&saExtern != 0 { 92 a = append(a, "extern") 93 } 94 if attr&saInline != 0 { 95 a = append(a, "inline") 96 } 97 if attr&saRegister != 0 { 98 a = append(a, "register") 99 } 100 if attr&saRestrict != 0 { 101 a = append(a, "restrict") 102 } 103 if attr&saStatic != 0 { 104 a = append(a, "static") 105 } 106 if attr&saTypedef != 0 { 107 a = append(a, "typedef") 108 } 109 if attr&saVolatile != 0 { 110 a = append(a, "volatile") 111 } 112 if attr&saNoreturn != 0 { 113 a = append(a, "_Noreturn") 114 } 115 return strings.Join(a, " ") 116 } 117 118 // PPTokenList represents a sequence of tokens. 119 type PPTokenList int 120 121 func (p PPTokenList) Pos() token.Pos { 122 if p == 0 { 123 return 0 124 } 125 126 return decodeTokens(p, nil, false)[0].Pos() 127 } 128 129 // Linkage is a C linkage kind ([0], 6.2.2, p. 30) 130 type Linkage int 131 132 // Values of type Linkage. 133 const ( 134 None Linkage = iota 135 Internal 136 External 137 ) 138 139 // Values from GCC's typeclass.h 140 const ( 141 noTypeClass = iota - 1 142 voidTypeClass 143 integerTypeClass 144 charTypeClass 145 enumeralTypeClass 146 booleanTypeClass 147 pointerTypeClass 148 referenceTypeClass 149 offsetTypeClass 150 realTypeClass 151 complexTypeClass 152 functionTypeClass 153 methodTypeClass 154 recordTypeClass 155 unionTypeClass 156 arrayTypeClass 157 stringTypeClass 158 langTypeClass 159 ) 160 161 var classifyType = map[Kind]int{ 162 Undefined: noTypeClass, 163 Void: voidTypeClass, 164 Ptr: pointerTypeClass, 165 UintPtr: noTypeClass, 166 Char: charTypeClass, 167 SChar: charTypeClass, 168 UChar: charTypeClass, 169 Short: integerTypeClass, 170 UShort: integerTypeClass, 171 Int: integerTypeClass, 172 UInt: integerTypeClass, 173 Long: integerTypeClass, 174 ULong: integerTypeClass, 175 LongLong: integerTypeClass, 176 ULongLong: integerTypeClass, 177 Float: realTypeClass, 178 Double: realTypeClass, 179 LongDouble: realTypeClass, 180 Bool: booleanTypeClass, 181 FloatComplex: complexTypeClass, 182 DoubleComplex: complexTypeClass, 183 LongDoubleComplex: complexTypeClass, 184 Struct: recordTypeClass, 185 Union: unionTypeClass, 186 Enum: enumeralTypeClass, 187 TypedefName: noTypeClass, 188 Function: functionTypeClass, 189 Array: arrayTypeClass, 190 typeof: noTypeClass, 191 } 192 193 // Kind is a type category. Kind formally implements Type the only method 194 // returning a non nil value is Kind. 195 type Kind int 196 197 // Values of type Kind. 198 const ( 199 Undefined Kind = iota 200 Void 201 Ptr 202 UintPtr // Type used for pointer arithmetic. 203 Char 204 SChar 205 UChar 206 Short 207 UShort 208 Int 209 UInt 210 Long 211 ULong 212 LongLong 213 ULongLong 214 Float 215 Double 216 LongDouble 217 Bool 218 FloatComplex 219 DoubleComplex 220 LongDoubleComplex 221 Struct 222 Union 223 Enum 224 TypedefName 225 Function 226 Array 227 typeof 228 229 kindMax 230 ) 231 232 func (k Kind) CString() string { 233 switch k { 234 case Undefined: 235 return "undefined" 236 case Void: 237 return "void" 238 case Ptr: 239 return "pointer" 240 case Char: 241 return "char" 242 case SChar: 243 return "signed char" 244 case UChar: 245 return "unsigned char" 246 case Short: 247 return "short" 248 case UShort: 249 return "unsigned short" 250 case Int: 251 return "int" 252 case UInt: 253 return "unsigned" 254 case Long: 255 return "long" 256 case ULong: 257 return "unsigned long" 258 case LongLong: 259 return "long long" 260 case ULongLong: 261 return "unsigned long long" 262 case Float: 263 return "float" 264 case Double: 265 return "double" 266 case LongDouble: 267 return "long double" 268 case Bool: 269 return "bool" 270 case FloatComplex: 271 return "float complex" 272 case DoubleComplex: 273 return "double complex" 274 case LongDoubleComplex: 275 return "long double complex" 276 case Struct: 277 return "struct" 278 case Union: 279 return "union" 280 case Enum: 281 return "enum" 282 case TypedefName: 283 return "typedefname" 284 case Function: 285 return "function" 286 case Array: 287 return "array" 288 case UintPtr: 289 return "uintptr" 290 default: 291 panic("internal error") 292 } 293 } 294 295 // Scope is a bindings category. 296 type Scope int 297 298 // Values of type Scope 299 const ( 300 ScopeFile Scope = iota 301 ScopeBlock 302 ScopeMembers 303 ScopeParams 304 ) 305 306 // Namespace is a binding category. 307 type Namespace int 308 309 // Values of type Namespace. 310 const ( 311 NSIdentifiers Namespace = iota 312 NSTags 313 ) 314 315 var ( 316 cwords = map[int]rune{ 317 dict.SID("auto"): AUTO, 318 dict.SID("_Bool"): BOOL, 319 dict.SID("break"): BREAK, 320 dict.SID("case"): CASE, 321 dict.SID("char"): CHAR, 322 dict.SID("_Complex"): COMPLEX, 323 dict.SID("const"): CONST, 324 dict.SID("continue"): CONTINUE, 325 dict.SID("default"): DEFAULT, 326 dict.SID("do"): DO, 327 dict.SID("double"): DOUBLE, 328 dict.SID("else"): ELSE, 329 dict.SID("enum"): ENUM, 330 dict.SID("extern"): EXTERN, 331 dict.SID("float"): FLOAT, 332 dict.SID("for"): FOR, 333 dict.SID("goto"): GOTO, 334 dict.SID("if"): IF, 335 dict.SID("inline"): INLINE, 336 dict.SID("int"): INT, 337 dict.SID("long"): LONG, 338 dict.SID("register"): REGISTER, 339 dict.SID("restrict"): RESTRICT, 340 dict.SID("return"): RETURN, 341 dict.SID("short"): SHORT, 342 dict.SID("signed"): SIGNED, 343 dict.SID("sizeof"): SIZEOF, 344 dict.SID("static"): STATIC, 345 dict.SID("struct"): STRUCT, 346 dict.SID("switch"): SWITCH, 347 dict.SID("typedef"): TYPEDEF, 348 dict.SID("union"): UNION, 349 dict.SID("unsigned"): UNSIGNED, 350 dict.SID("void"): VOID, 351 dict.SID("volatile"): VOLATILE, 352 dict.SID("while"): WHILE, 353 } 354 355 tokConstVals = map[rune]int{ 356 ADDASSIGN: dict.SID("+="), 357 ALIGNOF: dict.SID("_Alignof"), 358 ANDAND: dict.SID("&&"), 359 ANDASSIGN: dict.SID("&="), 360 ARROW: dict.SID("->"), 361 ASM: dict.SID("asm"), 362 AUTO: dict.SID("auto"), 363 BOOL: dict.SID("_Bool"), 364 BREAK: dict.SID("break"), 365 CASE: dict.SID("case"), 366 CHAR: dict.SID("char"), 367 COMPLEX: dict.SID("_Complex"), 368 CONST: dict.SID("const"), 369 CONTINUE: dict.SID("continue"), 370 DDD: dict.SID("..."), 371 DEC: dict.SID("--"), 372 DEFAULT: dict.SID("default"), 373 DIVASSIGN: dict.SID("/="), 374 DO: dict.SID("do"), 375 DOUBLE: dict.SID("double"), 376 ELSE: dict.SID("else"), 377 ENUM: dict.SID("enum"), 378 EQ: dict.SID("=="), 379 EXTERN: dict.SID("extern"), 380 FLOAT: dict.SID("float"), 381 FOR: dict.SID("for"), 382 GEQ: dict.SID(">="), 383 GOTO: dict.SID("goto"), 384 IF: dict.SID("if"), 385 INC: dict.SID("++"), 386 INLINE: dict.SID("inline"), 387 INT: dict.SID("int"), 388 LEQ: dict.SID("<="), 389 LONG: dict.SID("long"), 390 LSH: dict.SID("<<"), 391 LSHASSIGN: dict.SID("<<="), 392 MODASSIGN: dict.SID("%="), 393 MULASSIGN: dict.SID("*="), 394 NEQ: dict.SID("!="), 395 ORASSIGN: dict.SID("|="), 396 OROR: dict.SID("||"), 397 PPPASTE: dict.SID("##"), 398 REGISTER: dict.SID("register"), 399 RESTRICT: dict.SID("restrict"), 400 RETURN: dict.SID("return"), 401 RSH: dict.SID(">>"), 402 RSHASSIGN: dict.SID(">>="), 403 SHORT: dict.SID("short"), 404 SIGNED: dict.SID("signed"), 405 SIZEOF: dict.SID("sizeof"), 406 STATIC: dict.SID("static"), 407 STATIC_ASSERT: dict.SID("_Static_assert"), 408 STRUCT: dict.SID("struct"), 409 SUBASSIGN: dict.SID("-="), 410 SWITCH: dict.SID("switch"), 411 TYPEDEF: dict.SID("typedef"), 412 TYPEOF: dict.SID("typeof"), 413 UNION: dict.SID("union"), 414 UNSIGNED: dict.SID("unsigned"), 415 VOID: dict.SID("void"), 416 VOLATILE: dict.SID("volatile"), 417 WHILE: dict.SID("while"), 418 XORASSIGN: dict.SID("^="), 419 } 420 421 id0 = dict.SID("0") 422 id1 = dict.SID("1") 423 idAlignof = dict.SID("_Alignof") 424 idAlignofAlt = dict.SID("__alignof__") 425 idAsm = dict.SID("asm") 426 idAsmAlt = dict.SID("__asm__") 427 idBuiltinClasifyType = dict.SID("__builtin_classify_type") 428 idBuiltinConstantP = dict.SID("__builtin_constant_p") 429 idBuiltinTypesCompatible = dict.SID("__builtin_types_compatible__") // Implements __builtin_types_compatible_p 430 idChar = dict.SID("char") 431 idConst = dict.SID("const") 432 idDate = dict.SID("__DATE__") 433 idDefined = dict.SID("defined") 434 idEmptyString = dict.SID(`""`) 435 idFile = dict.SID("__FILE__") 436 idID = dict.SID("ID") 437 idInlineAlt = dict.SID("__inline__") 438 idL = dict.SID("L") 439 idLine = dict.SID("__LINE__") 440 idMagicFunc = dict.SID("__func__") 441 idNoreturn = dict.SID("_Noreturn") 442 idPopMacro = dict.SID("pop_macro") 443 idPragma = dict.SID("_Pragma") 444 idPushMacro = dict.SID("push_macro") 445 idRestrictAlt = dict.SID("__restrict__") 446 idSTDC = dict.SID("__STDC__") 447 idSTDCHosted = dict.SID("__STDC_HOSTED__") 448 idSTDCMBMightNeqWc = dict.SID("__STDC_MB_MIGHT_NEQ_WC__") 449 idSTDCVersion = dict.SID("__STDC_VERSION__") 450 idSignedAlt = dict.SID("__signed__") 451 idSpace = dict.SID(" ") 452 idStatic = dict.SID("static") 453 idStaticAssert = dict.SID("_Static_assert") 454 idTDate = dict.SID(tuTime.Format("Jan _2 2006")) // The date of translation of the preprocessing translation unit. 455 idTTime = dict.SID(tuTime.Format("15:04:05")) // The time of translation of the preprocessing translation unit. 456 idTime = dict.SID("__TIME__") 457 idTypeof = dict.SID("typeof") 458 idTypeofAlt = dict.SID("__typeof__") 459 idVAARGS = dict.SID("__VA_ARGS__") 460 idVolatileAlt = dict.SID("__volatile__") 461 tuTime = time.Now() 462 463 tokHasVal = map[rune]bool{ 464 CHARCONST: true, 465 FLOATCONST: true, 466 IDENTIFIER: true, 467 IDENTIFIER_LPAREN: true, 468 INTCONST: true, 469 LONGCHARCONST: true, 470 LONGSTRINGLITERAL: true, 471 PPHEADER_NAME: true, 472 PPNUMBER: true, 473 PPOTHER: true, 474 STRINGLITERAL: true, 475 TYPEDEFNAME: true, 476 } 477 478 // Valid combinations of TypeSpecifier.Case ([0], 6.7.2, 2) 479 tsValid = map[int]Kind{ 480 tsEncode(tsBool): Bool, // _Bool 481 tsEncode(tsChar): Char, // char 482 tsEncode(tsComplex): DoubleComplex, // _Complex 483 tsEncode(tsDouble): Double, // double 484 tsEncode(tsDouble, tsComplex): DoubleComplex, // double _Complex 485 tsEncode(tsEnumSpecifier): Enum, // enum specifier 486 tsEncode(tsFloat): Float, // float 487 tsEncode(tsFloat, tsComplex): FloatComplex, // float _Complex 488 tsEncode(tsInt): Int, // int 489 tsEncode(tsLong): Long, // long 490 tsEncode(tsLong, tsDouble): LongDouble, // long double 491 tsEncode(tsLong, tsDouble, tsComplex): LongDoubleComplex, // long double _Complex 492 tsEncode(tsLong, tsInt): Long, // long int 493 tsEncode(tsLong, tsLong): LongLong, // long long 494 tsEncode(tsLong, tsLong, tsInt): LongLong, // long long int 495 tsEncode(tsShort): Short, // short 496 tsEncode(tsShort, tsInt): Short, // short int 497 tsEncode(tsSigned): Int, // signed 498 tsEncode(tsSigned, tsChar): SChar, // signed char 499 tsEncode(tsSigned, tsInt): Int, // signed int 500 tsEncode(tsSigned, tsLong): Long, // signed long 501 tsEncode(tsSigned, tsLong, tsInt): Long, // signed long int 502 tsEncode(tsSigned, tsLong, tsLong): LongLong, // signed long long 503 tsEncode(tsSigned, tsLong, tsLong, tsInt): LongLong, // signed long long int 504 tsEncode(tsSigned, tsShort): Short, // signed short 505 tsEncode(tsSigned, tsShort, tsInt): Short, // signed short int 506 tsEncode(tsStructSpecifier): Struct, // struct 507 tsEncode(tsTypedefName): TypedefName, // typedef name 508 tsEncode(tsTypeof): typeof, // typeof name 509 tsEncode(tsUintptr): UintPtr, // Pseudo type. 510 tsEncode(tsUnionSpecifier): Union, // union 511 tsEncode(tsUnsigned): UInt, // unsigned 512 tsEncode(tsUnsigned, tsChar): UChar, // unsigned char 513 tsEncode(tsUnsigned, tsInt): UInt, // unsigned int 514 tsEncode(tsUnsigned, tsLong): ULong, // unsigned long 515 tsEncode(tsUnsigned, tsLong, tsInt): ULong, // unsigned long int 516 tsEncode(tsUnsigned, tsLong, tsLong): ULongLong, // unsigned long long 517 tsEncode(tsUnsigned, tsLong, tsLong, tsInt): ULongLong, // unsigned long long int 518 tsEncode(tsUnsigned, tsShort): UShort, // unsigned short 519 tsEncode(tsUnsigned, tsShort, tsInt): UShort, // unsigned short int 520 tsEncode(tsVoid): Void, // void 521 } 522 ) 523 524 func isUCNDigit(r rune) bool { 525 return int(r) < len(ucnDigits)<<bitShift && ucnDigits[uint(r)>>bitShift]&(1<<uint(r&bitMask)) != 0 526 } 527 528 func isUCNNonDigit(r rune) bool { 529 return int(r) < len(ucnNonDigits)<<bitShift && ucnNonDigits[uint(r)>>bitShift]&(1<<uint(r&bitMask)) != 0 530 } 531 532 func rune2class(r rune) (c int) { 533 switch { 534 case r == lex.RuneEOF: 535 return ccEOF 536 case r < 128: 537 return int(r) 538 case isUCNDigit(r): 539 return ccUCNDigit 540 case isUCNNonDigit(r): 541 return ccUCNNonDigit 542 default: 543 return ccOther 544 } 545 } 546 547 func toC(t xc.Token, tw *tweaks) xc.Token { 548 if t.Rune != IDENTIFIER { 549 return t 550 } 551 552 if x, ok := cwords[t.Val]; ok { 553 t.Rune = x 554 } 555 556 if tw.enableStaticAssert && t.Val == idStaticAssert { 557 t.Rune = STATIC_ASSERT 558 return t 559 } 560 561 if tw.enableAlignof && (t.Val == idAlignof || t.Val == idAlignofAlt) { 562 t.Rune = ALIGNOF 563 return t 564 } 565 566 if tw.enableNoreturn { 567 if t.Val == idNoreturn { 568 t.Rune = NORETURN 569 return t 570 } 571 572 } 573 574 if tw.enableTypeof && (t.Val == idTypeof || t.Val == idTypeofAlt) { 575 t.Rune = TYPEOF 576 return t 577 } 578 579 if tw.enableAsm { 580 if t.Val == idAsm { 581 t.Rune = ASM 582 return t 583 } 584 585 if tw.enableAlternateKeywords && t.Val == idAsmAlt { 586 t.Rune = ASM 587 return t 588 } 589 } 590 591 if tw.enableAlternateKeywords { 592 if t.Val == idInlineAlt { 593 t.Rune = INLINE 594 return t 595 } 596 597 if t.Val == idVolatileAlt { 598 t.Rune = VOLATILE 599 return t 600 } 601 602 if t.Val == idSignedAlt { 603 t.Rune = SIGNED 604 return t 605 } 606 607 if t.Val == idRestrictAlt { 608 t.Rune = RESTRICT 609 return t 610 } 611 } 612 613 return t 614 } 615 616 func tsEncode(a ...int) (r int) { 617 sort.Ints(a) 618 for _, v := range a { 619 r = r<<tsBits | v 620 } 621 return r<<1 | 1 // Bit 0 set: value is valid. 622 } 623 624 func tsDecode(n int) (r []int) { 625 if n == 0 { 626 return nil 627 } 628 629 n >>= 1 // Remove value is valid bit. 630 for n != 0 { 631 r = append(r, n&tsMask) 632 n >>= tsBits 633 } 634 return r 635 } 636 637 func (l *lexer) encodeToken(tok xc.Token) { 638 n := binary.PutUvarint(l.encBuf1[:], uint64(tok.Rune)) 639 pos := tok.Pos() 640 n += binary.PutUvarint(l.encBuf1[n:], uint64(pos-l.encPos)) 641 l.encPos = pos 642 if tokHasVal[tok.Rune] { 643 n += binary.PutUvarint(l.encBuf1[n:], uint64(tok.Val)) 644 } 645 l.encBuf = append(l.encBuf, l.encBuf1[:n]...) 646 } 647 648 func decodeToken(p *[]byte, pos *token.Pos) xc.Token { 649 b := *p 650 r, n := binary.Uvarint(b) 651 b = b[n:] 652 d, n := binary.Uvarint(b) 653 b = b[n:] 654 np := *pos + token.Pos(d) 655 *pos = np 656 c := lex.NewChar(np, rune(r)) 657 var v uint64 658 if tokHasVal[c.Rune] { 659 v, n = binary.Uvarint(b) 660 b = b[n:] 661 } 662 *p = b 663 return xc.Token{Char: c, Val: int(v)} 664 } 665 666 func decodeTokens(id PPTokenList, r []xc.Token, withSpaces bool) []xc.Token { 667 b := dict.S(int(id)) 668 var pos token.Pos 669 r = r[:0] 670 for len(b) != 0 { 671 tok := decodeToken(&b, &pos) 672 if tok.Rune == ' ' && !withSpaces { 673 continue 674 } 675 676 r = append(r, tok) 677 } 678 return r 679 } 680 681 func tokVal(t xc.Token) int { 682 r := t.Rune 683 if r == 0 { 684 return 0 685 } 686 687 if v := t.Val; v != 0 { 688 return v 689 } 690 691 if r != 0 && r < 0x80 { 692 return int(r) + 1 693 } 694 695 if i, ok := tokConstVals[r]; ok { 696 return i 697 } 698 699 panic("internal error") 700 } 701 702 // TokSrc returns t in its source form. 703 func TokSrc(t xc.Token) string { 704 if x, ok := tokConstVals[t.Rune]; ok { 705 return string(dict.S(x)) 706 } 707 708 if tokHasVal[t.Rune] { 709 return string(t.S()) 710 } 711 712 return string(t.Rune) 713 } 714 715 // universal-character-name \\u{hex-quad}|\\U{hex-quad}{hex-quad} 716 func decodeUCN(runes []rune) (rune, int) { 717 if runes[0] != '\\' { 718 panic("internal error") 719 } 720 721 runes = runes[1:] 722 switch runes[0] { 723 case 'u': 724 return rune(decodeHexQuad(runes[1:])), 6 725 case 'U': 726 return rune(decodeHexQuad(runes[1:])<<16 | decodeHexQuad(runes[5:])), 10 727 default: 728 panic("internal error") 729 } 730 } 731 732 // hex-quad {hexadecimal-digit}{hexadecimal-digit}{hexadecimal-digit}{hexadecimal-digit} 733 func decodeHexQuad(runes []rune) int { 734 n := 0 735 for _, r := range runes[:4] { 736 n = n<<4 | decodeHex(r) 737 } 738 return n 739 } 740 741 func decodeHex(r rune) int { 742 switch { 743 case r >= '0' && r <= '9': 744 return int(r) - '0' 745 default: 746 x := int(r) &^ 0x20 747 return x - 'A' + 10 748 } 749 } 750 751 // escape-sequence {simple-sequence}|{octal-escape-sequence}|{hexadecimal-escape-sequence}|{universal-character-name} 752 // simple-sequence \\['\x22?\\abfnrtv] 753 // octal-escape-sequence \\{octal-digit}{octal-digit}?{octal-digit}? 754 // hexadecimal-escape-sequence \\x{hexadecimal-digit}+ 755 func decodeEscapeSequence(runes []rune) (rune, int) { 756 if runes[0] != '\\' { 757 panic("internal error") 758 } 759 760 r := runes[1] 761 switch r { 762 case '\'', '"', '?', '\\': 763 return r, 2 764 case 'a': 765 return 7, 2 766 case 'b': 767 return 8, 2 768 case 'f': 769 return 12, 2 770 case 'n': 771 return 10, 2 772 case 'r': 773 return 13, 2 774 case 't': 775 return 9, 2 776 case 'v': 777 return 11, 2 778 case 'x': 779 v, n := 0, 2 780 loop2: 781 for _, r := range runes[2:] { 782 switch { 783 case r >= '0' && r <= '9', r >= 'a' && r <= 'f', r >= 'A' && r <= 'F': 784 v = v<<4 | decodeHex(r) 785 n++ 786 default: 787 break loop2 788 } 789 } 790 return -rune(v & 0xff), n 791 case 'u', 'U': 792 return decodeUCN(runes) 793 } 794 795 if r < '0' || r > '7' { 796 panic("internal error") 797 } 798 799 v, n := 0, 1 800 loop: 801 for _, r := range runes[1:] { 802 switch { 803 case r >= '0' && r <= '7': 804 v = v<<3 | (int(r) - '0') 805 n++ 806 default: 807 break loop 808 } 809 } 810 return -rune(v), n 811 }