github.com/cloudwego/iasm@v0.2.0/repl/scanner.go (about) 1 // 2 // Copyright 2024 CloudWeGo Authors 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 package repl 18 19 import ( 20 `go/scanner` 21 `go/token` 22 `strconv` 23 ) 24 25 type _SyntaxError string 26 27 func (self _SyntaxError) Error() string { 28 return string(self) 29 } 30 31 type _Scanner struct { 32 val string 33 tok token.Token 34 lex scanner.Scanner 35 } 36 37 const ( 38 dontInsertSemis scanner.Mode = 2 39 ) 40 41 func scan(cmd string) (p *_Scanner) { 42 p = new(_Scanner) 43 p.lex.Init(token.NewFileSet().AddFile("(REPL)", 1, len(cmd)), []byte(cmd), nil, dontInsertSemis) 44 p.next() 45 return 46 } 47 48 func (self *_Scanner) next() { 49 _, self.tok, self.val = self.lex.Scan() 50 } 51 52 func (self *_Scanner) must(tok token.Token) { 53 if self.tok == token.EOF { 54 panic(_SyntaxError("unexpected EOF")) 55 } else if self.tok != tok { 56 panic(_SyntaxError(tok.String() + " required")) 57 } 58 } 59 60 func (self *_Scanner) close() { 61 if self.tok != token.EOF { 62 panic(_SyntaxError("excess parameters")) 63 } 64 } 65 66 func (self *_Scanner) str(v *string) *_Scanner { 67 self.must(token.STRING) 68 *v, _ = strconv.Unquote(self.val) 69 self.next() 70 return self 71 } 72 73 func (self *_Scanner) uint(v *uint64) *_Scanner { 74 self.must(token.INT) 75 *v, _ = strconv.ParseUint(self.val, 0, 64) 76 self.next() 77 return self 78 } 79 80 func (self *_Scanner) idoff(id *uint64, offs *uint64) *_Scanner { 81 self.must(token.INT) 82 *id, _ = strconv.ParseUint(self.val, 0, 64) 83 self.next() 84 85 /* check for the optional offset */ 86 if self.tok != token.ADD { 87 return self 88 } 89 90 /* parse the offset */ 91 self.next() 92 self.must(token.INT) 93 *offs, _ = strconv.ParseUint(self.val, 0, 64) 94 self.next() 95 return self 96 } 97 98 func (self *_Scanner) uintopt(v *uint64) *_Scanner { 99 if self.tok != token.INT { 100 return self 101 } else { 102 *v, _ = strconv.ParseUint(self.val, 0, 64) 103 self.next() 104 return self 105 } 106 }