github.com/chenzhuoyu/iasm@v0.9.1/repl/scanner.go (about) 1 package repl 2 3 import ( 4 `go/scanner` 5 `go/token` 6 `strconv` 7 ) 8 9 type _SyntaxError string 10 11 func (self _SyntaxError) Error() string { 12 return string(self) 13 } 14 15 type _Scanner struct { 16 val string 17 tok token.Token 18 lex scanner.Scanner 19 } 20 21 const ( 22 dontInsertSemis scanner.Mode = 2 23 ) 24 25 func scan(cmd string) (p *_Scanner) { 26 p = new(_Scanner) 27 p.lex.Init(token.NewFileSet().AddFile("(REPL)", 1, len(cmd)), []byte(cmd), nil, dontInsertSemis) 28 p.next() 29 return 30 } 31 32 func (self *_Scanner) next() { 33 _, self.tok, self.val = self.lex.Scan() 34 } 35 36 func (self *_Scanner) must(tok token.Token) { 37 if self.tok == token.EOF { 38 panic(_SyntaxError("unexpected EOF")) 39 } else if self.tok != tok { 40 panic(_SyntaxError(tok.String() + " required")) 41 } 42 } 43 44 func (self *_Scanner) close() { 45 if self.tok != token.EOF { 46 panic(_SyntaxError("excess parameters")) 47 } 48 } 49 50 func (self *_Scanner) str(v *string) *_Scanner { 51 self.must(token.STRING) 52 *v, _ = strconv.Unquote(self.val) 53 self.next() 54 return self 55 } 56 57 func (self *_Scanner) uint(v *uint64) *_Scanner { 58 self.must(token.INT) 59 *v, _ = strconv.ParseUint(self.val, 0, 64) 60 self.next() 61 return self 62 } 63 64 func (self *_Scanner) idoff(id *uint64, offs *uint64) *_Scanner { 65 self.must(token.INT) 66 *id, _ = strconv.ParseUint(self.val, 0, 64) 67 self.next() 68 69 /* check for the optional offset */ 70 if self.tok != token.ADD { 71 return self 72 } 73 74 /* parse the offset */ 75 self.next() 76 self.must(token.INT) 77 *offs, _ = strconv.ParseUint(self.val, 0, 64) 78 self.next() 79 return self 80 } 81 82 func (self *_Scanner) uintopt(v *uint64) *_Scanner { 83 if self.tok != token.INT { 84 return self 85 } else { 86 *v, _ = strconv.ParseUint(self.val, 0, 64) 87 self.next() 88 return self 89 } 90 }