1 // Copyright 2015 The Go 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 asm implements the parser and instruction generator for the assembler. 6 // TODO: Split apart? 7 package asm 8 9 import ( 10 "fmt" 11 "log" 12 "os" 13 "strconv" 14 "text/scanner" 15 "unicode/utf8" 16 17 "cmd/asm/internal/arch" 18 "cmd/asm/internal/lex" 19 "cmd/internal/obj" 20 ) 21 22 type Parser struct { 23 lex lex.TokenReader 24 lineNum int // Line number in source file. 25 histLineNum int32 // Cumulative line number across source files. 26 errorLine int32 // (Cumulative) line number of last error. 27 errorCount int // Number of errors. 28 pc int64 // virtual PC; count of Progs; doesn't advance for GLOBL or DATA. 29 input []lex.Token 30 inputPos int 31 pendingLabels []string // Labels to attach to next instruction. 32 labels map[string]*obj.Prog 33 toPatch []Patch 34 addr []obj.Addr 35 arch *arch.Arch 36 ctxt *obj.Link 37 firstProg *obj.Prog 38 lastProg *obj.Prog 39 dataAddr map[string]int64 // Most recent address for DATA for this symbol. 40 } 41 42 type Patch struct { 43 prog *obj.Prog 44 label string 45 } 46 47 func NewParser(ctxt *obj.Link, ar *arch.Arch, lexer lex.TokenReader) *Parser { 48 return &Parser{ 49 ctxt: ctxt, 50 arch: ar, 51 lex: lexer, 52 labels: make(map[string]*obj.Prog), 53 dataAddr: make(map[string]int64), 54 } 55 } 56 57 // panicOnError is enable when testing to abort execution on the first error 58 // and turn it into a recoverable panic. 59 var panicOnError bool 60 61 func (p *Parser) errorf(format string, args ...interface{}) { 62 if panicOnError { 63 panic(fmt.Errorf(format, args...)) 64 } 65 if p.histLineNum == p.errorLine { 66 // Only one error per line. 67 return 68 } 69 p.errorLine = p.histLineNum 70 // Put file and line information on head of message. 71 format = "%s:%d: " + format + "\n" 72 args = append([]interface{}{p.lex.File(), p.lineNum}, args...) 73 fmt.Fprintf(os.Stderr, format, args...) 74 p.errorCount++ 75 if p.errorCount > 10 { 76 log.Fatal("too many errors") 77 } 78 } 79 80 func (p *Parser) Parse() (*obj.Prog, bool) { 81 for p.line() { 82 } 83 if p.errorCount > 0 { 84 return nil, false 85 } 86 p.patch() 87 return p.firstProg, true 88 } 89 90 // WORD [ arg {, arg} ] (';' | '\n') 91 func (p *Parser) line() bool { 92 // Skip newlines. 93 var tok lex.ScanToken 94 for { 95 tok = p.lex.Next() 96 // We save the line number here so error messages from this instruction 97 // are labeled with this line. Otherwise we complain after we've absorbed 98 // the terminating newline and the line numbers are off by one in errors. 99 p.lineNum = p.lex.Line() 100 p.histLineNum = lex.HistLine() 101 switch tok { 102 case '\n', ';': 103 continue 104 case scanner.EOF: 105 return false 106 } 107 break 108 } 109 // First item must be an identifier. 110 if tok != scanner.Ident { 111 p.errorf("expected identifier, found %q", p.lex.Text()) 112 return false // Might as well stop now. 113 } 114 word := p.lex.Text() 115 var cond string 116 operands := make([][]lex.Token, 0, 3) 117 // Zero or more comma-separated operands, one per loop. 118 nesting := 0 119 colon := -1 120 for tok != '\n' && tok != ';' { 121 // Process one operand. 122 items := make([]lex.Token, 0, 3) 123 for { 124 tok = p.lex.Next() 125 if len(operands) == 0 && len(items) == 0 { 126 if (p.arch.Thechar == '5' || p.arch.Thechar == '7') && tok == '.' { 127 // ARM conditionals. 128 tok = p.lex.Next() 129 str := p.lex.Text() 130 if tok != scanner.Ident { 131 p.errorf("ARM condition expected identifier, found %s", str) 132 } 133 cond = cond + "." + str 134 continue 135 } 136 if tok == ':' { 137 // Labels. 138 p.pendingLabels = append(p.pendingLabels, word) 139 return true 140 } 141 } 142 if tok == scanner.EOF { 143 p.errorf("unexpected EOF") 144 return false 145 } 146 // Split operands on comma. Also, the old syntax on x86 for a "register pair" 147 // was AX:DX, for which the new syntax is DX, AX. Note the reordering. 148 if tok == '\n' || tok == ';' || (nesting == 0 && (tok == ',' || tok == ':')) { 149 if tok == ':' { 150 // Remember this location so we can swap the operands below. 151 if colon >= 0 { 152 p.errorf("invalid ':' in operand") 153 } 154 colon = len(operands) 155 } 156 break 157 } 158 if tok == '(' || tok == '[' { 159 nesting++ 160 } 161 if tok == ')' || tok == ']' { 162 nesting-- 163 } 164 items = append(items, lex.Make(tok, p.lex.Text())) 165 } 166 if len(items) > 0 { 167 operands = append(operands, items) 168 if colon >= 0 && len(operands) == colon+2 { 169 // AX:DX becomes DX, AX. 170 operands[colon], operands[colon+1] = operands[colon+1], operands[colon] 171 colon = -1 172 } 173 } else if len(operands) > 0 || tok == ',' || colon >= 0 { 174 // Had a separator with nothing after. 175 p.errorf("missing operand") 176 } 177 } 178 i, present := arch.Pseudos[word] 179 if present { 180 p.pseudo(i, word, operands) 181 return true 182 } 183 i, present = p.arch.Instructions[word] 184 if present { 185 p.instruction(i, word, cond, operands) 186 return true 187 } 188 p.errorf("unrecognized instruction %q", word) 189 return true 190 } 191 192 func (p *Parser) instruction(op int, word, cond string, operands [][]lex.Token) { 193 p.addr = p.addr[0:0] 194 isJump := p.arch.IsJump(word) 195 for _, op := range operands { 196 addr := p.address(op) 197 if !isJump && addr.Reg < 0 { // Jumps refer to PC, a pseudo. 198 p.errorf("illegal use of pseudo-register in %s", word) 199 } 200 p.addr = append(p.addr, addr) 201 } 202 if isJump { 203 p.asmJump(op, cond, p.addr) 204 return 205 } 206 p.asmInstruction(op, cond, p.addr) 207 } 208 209 func (p *Parser) pseudo(op int, word string, operands [][]lex.Token) { 210 switch op { 211 case obj.ATEXT: 212 p.asmText(word, operands) 213 case obj.ADATA: 214 p.asmData(word, operands) 215 case obj.AGLOBL: 216 p.asmGlobl(word, operands) 217 case obj.APCDATA: 218 p.asmPCData(word, operands) 219 case obj.AFUNCDATA: 220 p.asmFuncData(word, operands) 221 default: 222 p.errorf("unimplemented: %s", word) 223 } 224 } 225 226 func (p *Parser) start(operand []lex.Token) { 227 p.input = operand 228 p.inputPos = 0 229 } 230 231 // address parses the operand into a link address structure. 232 func (p *Parser) address(operand []lex.Token) obj.Addr { 233 p.start(operand) 234 addr := obj.Addr{} 235 p.operand(&addr) 236 return addr 237 } 238 239 // parseScale converts a decimal string into a valid scale factor. 240 func (p *Parser) parseScale(s string) int8 { 241 switch s { 242 case "1", "2", "4", "8": 243 return int8(s[0] - '0') 244 } 245 p.errorf("bad scale: %s", s) 246 return 0 247 } 248 249 // operand parses a general operand and stores the result in *a. 250 func (p *Parser) operand(a *obj.Addr) bool { 251 //fmt.Printf("Operand: %v\n", p.input) 252 if len(p.input) == 0 { 253 p.errorf("empty operand: cannot happen") 254 return false 255 } 256 // General address (with a few exceptions) looks like 257 // $symoffset(SB)(reg)(index*scale) 258 // Exceptions are: 259 // 260 // R1 261 // offset 262 // $offset 263 // Every piece is optional, so we scan left to right and what 264 // we discover tells us where we are. 265 266 // Prefix: $. 267 var prefix rune 268 switch tok := p.peek(); tok { 269 case '$', '*': 270 prefix = rune(tok) 271 p.next() 272 } 273 274 // Symbol: symoffset(SB) 275 tok := p.next() 276 name := tok.String() 277 if tok.ScanToken == scanner.Ident && !p.atStartOfRegister(name) { 278 // We have a symbol. Parse $symoffset(symkind) 279 p.symbolReference(a, name, prefix) 280 // fmt.Printf("SYM %s\n", obj.Dconv(&emptyProg, 0, a)) 281 if p.peek() == scanner.EOF { 282 return true 283 } 284 } 285 286 // Special register list syntax for arm: [R1,R3-R7] 287 if tok.ScanToken == '[' { 288 if prefix != 0 { 289 p.errorf("illegal use of register list") 290 } 291 p.registerList(a) 292 p.expect(scanner.EOF) 293 return true 294 } 295 296 // Register: R1 297 if tok.ScanToken == scanner.Ident && p.atStartOfRegister(name) { 298 if p.atRegisterShift() { 299 // ARM shifted register such as R1<<R2 or R1>>2. 300 a.Type = obj.TYPE_SHIFT 301 a.Offset = p.registerShift(tok.String(), prefix) 302 if p.peek() == '(' { 303 // Can only be a literal register here. 304 p.next() 305 tok := p.next() 306 name := tok.String() 307 if !p.atStartOfRegister(name) { 308 p.errorf("expected register; found %s", name) 309 } 310 a.Reg, _ = p.registerReference(name) 311 p.get(')') 312 } 313 } else if r1, r2, scale, ok := p.register(tok.String(), prefix); ok { 314 if scale != 0 { 315 p.errorf("expected simple register reference") 316 } 317 a.Type = obj.TYPE_REG 318 a.Reg = r1 319 if r2 != 0 { 320 // Form is R1:R2. It is on RHS and the second register 321 // needs to go into the LHS. 322 panic("cannot happen (Addr.Reg2)") 323 } 324 } 325 // fmt.Printf("REG %s\n", obj.Dconv(&emptyProg, 0, a)) 326 p.expect(scanner.EOF) 327 return true 328 } 329 330 // Constant. 331 haveConstant := false 332 switch tok.ScanToken { 333 case scanner.Int, scanner.Float, scanner.String, scanner.Char, '+', '-', '~': 334 haveConstant = true 335 case '(': 336 // Could be parenthesized expression or (R). 337 rname := p.next().String() 338 p.back() 339 haveConstant = !p.atStartOfRegister(rname) 340 if !haveConstant { 341 p.back() // Put back the '('. 342 } 343 } 344 if haveConstant { 345 p.back() 346 if p.have(scanner.Float) { 347 if prefix != '$' { 348 p.errorf("floating-point constant must be an immediate") 349 } 350 a.Type = obj.TYPE_FCONST 351 a.Val = p.floatExpr() 352 // fmt.Printf("FCONST %s\n", obj.Dconv(&emptyProg, 0, a)) 353 p.expect(scanner.EOF) 354 return true 355 } 356 if p.have(scanner.String) { 357 if prefix != '$' { 358 p.errorf("string constant must be an immediate") 359 } 360 str, err := strconv.Unquote(p.get(scanner.String).String()) 361 if err != nil { 362 p.errorf("string parse error: %s", err) 363 } 364 a.Type = obj.TYPE_SCONST 365 a.Val = str 366 // fmt.Printf("SCONST %s\n", obj.Dconv(&emptyProg, 0, a)) 367 p.expect(scanner.EOF) 368 return true 369 } 370 a.Offset = int64(p.expr()) 371 if p.peek() != '(' { 372 switch prefix { 373 case '$': 374 a.Type = obj.TYPE_CONST 375 case '*': 376 a.Type = obj.TYPE_INDIR // Can appear but is illegal, will be rejected by the linker. 377 default: 378 a.Type = obj.TYPE_MEM 379 } 380 // fmt.Printf("CONST %d %s\n", a.Offset, obj.Dconv(&emptyProg, 0, a)) 381 p.expect(scanner.EOF) 382 return true 383 } 384 // fmt.Printf("offset %d \n", a.Offset) 385 } 386 387 // Register indirection: (reg) or (index*scale). We are on the opening paren. 388 p.registerIndirect(a, prefix) 389 // fmt.Printf("DONE %s\n", p.arch.Dconv(&emptyProg, 0, a)) 390 391 p.expect(scanner.EOF) 392 return true 393 } 394 395 // atStartOfRegister reports whether the parser is at the start of a register definition. 396 func (p *Parser) atStartOfRegister(name string) bool { 397 // Simple register: R10. 398 _, present := p.arch.Register[name] 399 if present { 400 return true 401 } 402 // Parenthesized register: R(10). 403 return p.arch.RegisterPrefix[name] && p.peek() == '(' 404 } 405 406 // atRegisterShift reports whether we are at the start of an ARM shifted register. 407 // We have consumed the register or R prefix. 408 func (p *Parser) atRegisterShift() bool { 409 // ARM only. 410 if p.arch.Thechar != '5' { 411 return false 412 } 413 // R1<<... 414 if lex.IsRegisterShift(p.peek()) { 415 return true 416 } 417 // R(1)<<... Ugly check. TODO: Rethink how we handle ARM register shifts to be 418 // less special. 419 if p.peek() != '(' || len(p.input)-p.inputPos < 4 { 420 return false 421 } 422 return p.at('(', scanner.Int, ')') && lex.IsRegisterShift(p.input[p.inputPos+3].ScanToken) 423 } 424 425 // registerReference parses a register given either the name, R10, or a parenthesized form, SPR(10). 426 func (p *Parser) registerReference(name string) (int16, bool) { 427 r, present := p.arch.Register[name] 428 if present { 429 return r, true 430 } 431 if !p.arch.RegisterPrefix[name] { 432 p.errorf("expected register; found %s", name) 433 return 0, false 434 } 435 p.get('(') 436 tok := p.get(scanner.Int) 437 num, err := strconv.ParseInt(tok.String(), 10, 16) 438 p.get(')') 439 if err != nil { 440 p.errorf("parsing register list: %s", err) 441 return 0, false 442 } 443 r, ok := p.arch.RegisterNumber(name, int16(num)) 444 if !ok { 445 p.errorf("illegal register %s(%d)", name, r) 446 return 0, false 447 } 448 return r, true 449 } 450 451 // register parses a full register reference where there is no symbol present (as in 4(R0) or R(10) but not sym(SB)) 452 // including forms involving multiple registers such as R1:R2. 453 func (p *Parser) register(name string, prefix rune) (r1, r2 int16, scale int8, ok bool) { 454 // R1 or R(1) R1:R2 R1,R2 R1+R2, or R1*scale. 455 r1, ok = p.registerReference(name) 456 if !ok { 457 return 458 } 459 if prefix != 0 && prefix != '*' { // *AX is OK. 460 p.errorf("prefix %c not allowed for register: %c%s", prefix, prefix, name) 461 } 462 c := p.peek() 463 if c == ':' || c == ',' || c == '+' { 464 // 2nd register; syntax (R1+R2) etc. No two architectures agree. 465 // Check the architectures match the syntax. 466 char := p.arch.Thechar 467 switch p.next().ScanToken { 468 case ',': 469 if char != '5' && char != '7' { 470 p.errorf("(register,register) not supported on this architecture") 471 return 472 } 473 case '+': 474 if char != '9' { 475 p.errorf("(register+register) not supported on this architecture") 476 return 477 } 478 } 479 name := p.next().String() 480 r2, ok = p.registerReference(name) 481 if !ok { 482 return 483 } 484 } 485 if p.peek() == '*' { 486 // Scale 487 p.next() 488 scale = p.parseScale(p.next().String()) 489 } 490 return r1, r2, scale, true 491 } 492 493 // registerShift parses an ARM shifted register reference and returns the encoded representation. 494 // There is known to be a register (current token) and a shift operator (peeked token). 495 func (p *Parser) registerShift(name string, prefix rune) int64 { 496 if prefix != 0 { 497 p.errorf("prefix %c not allowed for shifted register: $%s", prefix, name) 498 } 499 // R1 op R2 or r1 op constant. 500 // op is: 501 // "<<" == 0 502 // ">>" == 1 503 // "->" == 2 504 // "@>" == 3 505 r1, ok := p.registerReference(name) 506 if !ok { 507 return 0 508 } 509 var op int16 510 switch p.next().ScanToken { 511 case lex.LSH: 512 op = 0 513 case lex.RSH: 514 op = 1 515 case lex.ARR: 516 op = 2 517 case lex.ROT: 518 op = 3 519 } 520 tok := p.next() 521 str := tok.String() 522 var count int16 523 switch tok.ScanToken { 524 case scanner.Ident: 525 r2, ok := p.registerReference(str) 526 if !ok { 527 p.errorf("rhs of shift must be register or integer: %s", str) 528 } 529 count = (r2&15)<<8 | 1<<4 530 case scanner.Int, '(': 531 p.back() 532 x := int64(p.expr()) 533 if x >= 32 { 534 p.errorf("register shift count too large: %s", str) 535 } 536 count = int16((x & 31) << 7) 537 default: 538 p.errorf("unexpected %s in register shift", tok.String()) 539 } 540 return int64((r1 & 15) | op<<5 | count) 541 } 542 543 // symbolReference parses a symbol that is known not to be a register. 544 func (p *Parser) symbolReference(a *obj.Addr, name string, prefix rune) { 545 // Identifier is a name. 546 switch prefix { 547 case 0: 548 a.Type = obj.TYPE_MEM 549 case '$': 550 a.Type = obj.TYPE_ADDR 551 case '*': 552 a.Type = obj.TYPE_INDIR 553 } 554 // Weirdness with statics: Might now have "<>". 555 isStatic := 0 // TODO: Really a boolean, but Linklookup wants a "version" integer. 556 if p.peek() == '<' { 557 isStatic = 1 558 p.next() 559 p.get('>') 560 } 561 if p.peek() == '+' || p.peek() == '-' { 562 a.Offset = int64(p.expr()) 563 } 564 a.Sym = obj.Linklookup(p.ctxt, name, isStatic) 565 if p.peek() == scanner.EOF { 566 if prefix != 0 { 567 p.errorf("illegal addressing mode for symbol %s", name) 568 } 569 return 570 } 571 // Expect (SB) or (FP), (PC), (SB), or (SP) 572 p.get('(') 573 reg := p.get(scanner.Ident).String() 574 p.get(')') 575 p.setPseudoRegister(a, reg, isStatic != 0, prefix) 576 } 577 578 // setPseudoRegister sets the NAME field of addr for a pseudo-register reference such as (SB). 579 func (p *Parser) setPseudoRegister(addr *obj.Addr, reg string, isStatic bool, prefix rune) { 580 if addr.Reg != 0 { 581 p.errorf("internal error: reg %s already set in pseudo", reg) 582 } 583 switch reg { 584 case "FP": 585 addr.Name = obj.NAME_PARAM 586 case "PC": 587 if prefix != 0 { 588 p.errorf("illegal addressing mode for PC") 589 } 590 addr.Type = obj.TYPE_BRANCH // We set the type and leave NAME untouched. See asmJump. 591 case "SB": 592 addr.Name = obj.NAME_EXTERN 593 if isStatic { 594 addr.Name = obj.NAME_STATIC 595 } 596 case "SP": 597 addr.Name = obj.NAME_AUTO // The pseudo-stack. 598 default: 599 p.errorf("expected pseudo-register; found %s", reg) 600 } 601 if prefix == '$' { 602 addr.Type = obj.TYPE_ADDR 603 } 604 } 605 606 // registerIndirect parses the general form of a register indirection. 607 // It is can be (R1), (R2*scale), or (R1)(R2*scale) where R1 may be a simple 608 // register or register pair R:R or (R, R) or (R+R). 609 // Or it might be a pseudo-indirection like (FP). 610 // We are sitting on the opening parenthesis. 611 func (p *Parser) registerIndirect(a *obj.Addr, prefix rune) { 612 p.get('(') 613 tok := p.next() 614 name := tok.String() 615 r1, r2, scale, ok := p.register(name, 0) 616 if !ok { 617 p.errorf("indirect through non-register %s", tok) 618 } 619 p.get(')') 620 a.Type = obj.TYPE_MEM 621 if r1 < 0 { 622 // Pseudo-register reference. 623 if r2 != 0 { 624 p.errorf("cannot use pseudo-register in pair") 625 return 626 } 627 // For SB, SP, and FP, there must be a name here. 0(FP) is not legal. 628 if name != "PC" && a.Name == obj.NAME_NONE { 629 p.errorf("cannot reference %s without a symbol", name) 630 } 631 p.setPseudoRegister(a, name, false, prefix) 632 return 633 } 634 a.Reg = r1 635 if r2 != 0 { 636 // TODO: Consistency in the encoding would be nice here. 637 if p.arch.Thechar == '5' || p.arch.Thechar == '7' { 638 // Special form 639 // ARM: destination register pair (R1, R2). 640 // ARM64: register pair (R1, R2) for LDP/STP. 641 if prefix != 0 || scale != 0 { 642 p.errorf("illegal address mode for register pair") 643 return 644 } 645 a.Type = obj.TYPE_REGREG 646 a.Offset = int64(r2) 647 // Nothing may follow 648 return 649 } 650 if p.arch.Thechar == '9' { 651 // Special form for PPC64: (R1+R2); alias for (R1)(R2*1). 652 if prefix != 0 || scale != 0 { 653 p.errorf("illegal address mode for register+register") 654 return 655 } 656 a.Type = obj.TYPE_MEM 657 a.Scale = 1 658 a.Index = r2 659 // Nothing may follow. 660 return 661 } 662 } 663 if r2 != 0 { 664 p.errorf("indirect through register pair") 665 } 666 if prefix == '$' { 667 a.Type = obj.TYPE_ADDR 668 } 669 if r1 == arch.RPC && prefix != 0 { 670 p.errorf("illegal addressing mode for PC") 671 } 672 if scale == 0 && p.peek() == '(' { 673 // General form (R)(R*scale). 674 p.next() 675 tok := p.next() 676 r1, r2, scale, ok = p.register(tok.String(), 0) 677 if !ok { 678 p.errorf("indirect through non-register %s", tok) 679 } 680 if r2 != 0 { 681 p.errorf("unimplemented two-register form") 682 } 683 a.Index = r1 684 a.Scale = int16(scale) 685 p.get(')') 686 } else if scale != 0 { 687 // First (R) was missing, all we have is (R*scale). 688 a.Reg = 0 689 a.Index = r1 690 a.Scale = int16(scale) 691 } 692 } 693 694 // registerList parses an ARM register list expression, a list of registers in []. 695 // There may be comma-separated ranges or individual registers, as in 696 // [R1,R3-R5]. Only R0 through R15 may appear. 697 // The opening bracket has been consumed. 698 func (p *Parser) registerList(a *obj.Addr) { 699 // One range per loop. 700 var bits uint16 701 ListLoop: 702 for { 703 tok := p.next() 704 switch tok.ScanToken { 705 case ']': 706 break ListLoop 707 case scanner.EOF: 708 p.errorf("missing ']' in register list") 709 return 710 } 711 lo := p.registerNumber(tok.String()) 712 hi := lo 713 if p.peek() == '-' { 714 p.next() 715 hi = p.registerNumber(p.next().String()) 716 } 717 if hi < lo { 718 lo, hi = hi, lo 719 } 720 for lo <= hi { 721 if bits&(1<<lo) != 0 { 722 p.errorf("register R%d already in list", lo) 723 } 724 bits |= 1 << lo 725 lo++ 726 } 727 if p.peek() != ']' { 728 p.get(',') 729 } 730 } 731 a.Type = obj.TYPE_REGLIST 732 a.Offset = int64(bits) 733 } 734 735 // register number is ARM-specific. It returns the number of the specified register. 736 func (p *Parser) registerNumber(name string) uint16 { 737 if p.arch.Thechar == '5' && name == "g" { 738 return 10 739 } 740 if name[0] != 'R' { 741 p.errorf("expected g or R0 through R15; found %s", name) 742 } 743 r, ok := p.registerReference(name) 744 if !ok { 745 return 0 746 } 747 return uint16(r - p.arch.Register["R0"]) 748 } 749 750 // Note: There are two changes in the expression handling here 751 // compared to the old yacc/C implementations. Neither has 752 // much practical consequence because the expressions we 753 // see in assembly code are simple, but for the record: 754 // 755 // 1) Evaluation uses uint64; the old one used int64. 756 // 2) Precedence uses Go rules not C rules. 757 758 // expr = term | term ('+' | '-' | '|' | '^') term. 759 func (p *Parser) expr() uint64 { 760 value := p.term() 761 for { 762 switch p.peek() { 763 case '+': 764 p.next() 765 value += p.term() 766 case '-': 767 p.next() 768 value -= p.term() 769 case '|': 770 p.next() 771 value |= p.term() 772 case '^': 773 p.next() 774 value ^= p.term() 775 default: 776 return value 777 } 778 } 779 } 780 781 // floatExpr = fconst | '-' floatExpr | '+' floatExpr | '(' floatExpr ')' 782 func (p *Parser) floatExpr() float64 { 783 tok := p.next() 784 switch tok.ScanToken { 785 case '(': 786 v := p.floatExpr() 787 if p.next().ScanToken != ')' { 788 p.errorf("missing closing paren") 789 } 790 return v 791 case '+': 792 return +p.floatExpr() 793 case '-': 794 return -p.floatExpr() 795 case scanner.Float: 796 return p.atof(tok.String()) 797 } 798 p.errorf("unexpected %s evaluating float expression", tok) 799 return 0 800 } 801 802 // term = factor | factor ('*' | '/' | '%' | '>>' | '<<' | '&') factor 803 func (p *Parser) term() uint64 { 804 value := p.factor() 805 for { 806 switch p.peek() { 807 case '*': 808 p.next() 809 value *= p.factor() 810 case '/': 811 p.next() 812 if int64(value) < 0 { 813 p.errorf("divide of value with high bit set") 814 } 815 divisor := p.factor() 816 if divisor == 0 { 817 p.errorf("division by zero") 818 } else { 819 value /= divisor 820 } 821 case '%': 822 p.next() 823 divisor := p.factor() 824 if int64(value) < 0 { 825 p.errorf("modulo of value with high bit set") 826 } 827 if divisor == 0 { 828 p.errorf("modulo by zero") 829 } else { 830 value %= divisor 831 } 832 case lex.LSH: 833 p.next() 834 shift := p.factor() 835 if int64(shift) < 0 { 836 p.errorf("negative left shift count") 837 } 838 return value << shift 839 case lex.RSH: 840 p.next() 841 shift := p.term() 842 if int64(shift) < 0 { 843 p.errorf("negative right shift count") 844 } 845 if int64(value) < 0 { 846 p.errorf("right shift of value with high bit set") 847 } 848 value >>= shift 849 case '&': 850 p.next() 851 value &= p.factor() 852 default: 853 return value 854 } 855 } 856 } 857 858 // factor = const | '+' factor | '-' factor | '~' factor | '(' expr ')' 859 func (p *Parser) factor() uint64 { 860 tok := p.next() 861 switch tok.ScanToken { 862 case scanner.Int: 863 return p.atoi(tok.String()) 864 case scanner.Char: 865 str, err := strconv.Unquote(tok.String()) 866 if err != nil { 867 p.errorf("%s", err) 868 } 869 r, w := utf8.DecodeRuneInString(str) 870 if w == 1 && r == utf8.RuneError { 871 p.errorf("illegal UTF-8 encoding for character constant") 872 } 873 return uint64(r) 874 case '+': 875 return +p.factor() 876 case '-': 877 return -p.factor() 878 case '~': 879 return ^p.factor() 880 case '(': 881 v := p.expr() 882 if p.next().ScanToken != ')' { 883 p.errorf("missing closing paren") 884 } 885 return v 886 } 887 p.errorf("unexpected %s evaluating expression", tok) 888 return 0 889 } 890 891 // positiveAtoi returns an int64 that must be >= 0. 892 func (p *Parser) positiveAtoi(str string) int64 { 893 value, err := strconv.ParseInt(str, 0, 64) 894 if err != nil { 895 p.errorf("%s", err) 896 } 897 if value < 0 { 898 p.errorf("%s overflows int64", str) 899 } 900 return value 901 } 902 903 func (p *Parser) atoi(str string) uint64 { 904 value, err := strconv.ParseUint(str, 0, 64) 905 if err != nil { 906 p.errorf("%s", err) 907 } 908 return value 909 } 910 911 func (p *Parser) atof(str string) float64 { 912 value, err := strconv.ParseFloat(str, 64) 913 if err != nil { 914 p.errorf("%s", err) 915 } 916 return value 917 } 918 919 func (p *Parser) atos(str string) string { 920 value, err := strconv.Unquote(str) 921 if err != nil { 922 p.errorf("%s", err) 923 } 924 return value 925 } 926 927 // EOF represents the end of input. 928 var EOF = lex.Make(scanner.EOF, "EOF") 929 930 func (p *Parser) next() lex.Token { 931 if !p.more() { 932 return EOF 933 } 934 tok := p.input[p.inputPos] 935 p.inputPos++ 936 return tok 937 } 938 939 func (p *Parser) back() { 940 p.inputPos-- 941 } 942 943 func (p *Parser) peek() lex.ScanToken { 944 if p.more() { 945 return p.input[p.inputPos].ScanToken 946 } 947 return scanner.EOF 948 } 949 950 func (p *Parser) more() bool { 951 return p.inputPos < len(p.input) 952 } 953 954 // get verifies that the next item has the expected type and returns it. 955 func (p *Parser) get(expected lex.ScanToken) lex.Token { 956 p.expect(expected) 957 return p.next() 958 } 959 960 // expect verifies that the next item has the expected type. It does not consume it. 961 func (p *Parser) expect(expected lex.ScanToken) { 962 if p.peek() != expected { 963 p.errorf("expected %s, found %s", expected, p.next()) 964 } 965 } 966 967 // have reports whether the remaining tokens (including the current one) contain the specified token. 968 func (p *Parser) have(token lex.ScanToken) bool { 969 for i := p.inputPos; i < len(p.input); i++ { 970 if p.input[i].ScanToken == token { 971 return true 972 } 973 } 974 return false 975 } 976 977 // at reports whether the next tokens are as requested. 978 func (p *Parser) at(next ...lex.ScanToken) bool { 979 if len(p.input)-p.inputPos < len(next) { 980 return false 981 } 982 for i, r := range next { 983 if p.input[p.inputPos+i].ScanToken != r { 984 return false 985 } 986 } 987 return true 988 } 989