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  }