github.com/lmittmann/w3@v0.20.0/internal/abi/lexer.go (about)

     1  package abi
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  	"strings"
     7  	"unicode/utf8"
     8  
     9  	"github.com/ethereum/go-ethereum/accounts/abi"
    10  )
    11  
    12  type item struct {
    13  	Typ itemType
    14  	Val string
    15  }
    16  
    17  type itemType int
    18  
    19  func (i item) String() string {
    20  	if i.Typ == itemTypeEOF {
    21  		return "EOF"
    22  	}
    23  	return strconv.Quote(i.Val)
    24  }
    25  
    26  // IsType returns whether the item is a type or not.
    27  func (i *item) IsType() (*abi.Type, bool) {
    28  	if i.Typ != itemTypeID {
    29  		return nil, false
    30  	}
    31  	typ, ok := types[i.Val]
    32  	return &typ, ok
    33  }
    34  
    35  const (
    36  	// lexer item types
    37  	itemTypeID    itemType = iota // identifier: [a-zA-Z_][0-9a-zA-Z_]*
    38  	itemTypePunct                 // punctuation: [\(\)\[\],]
    39  	itemTypeNum                   // number: [1-9][0-9]*
    40  	itemTypeEOF                   // end of file
    41  
    42  	eof rune = -1
    43  
    44  	num0  = "123456789"
    45  	num   = "0" + num0
    46  	id0   = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_"
    47  	id    = id0 + num
    48  	space = " \t\r\n"
    49  )
    50  
    51  // lexer holds the state of the scanner.
    52  type lexer struct {
    53  	input string // the string being scanned
    54  	start int    // start position of this item
    55  	pos   int    // current position in the input
    56  	width int    // width of last rune read from input
    57  }
    58  
    59  func newLexer(input string) *lexer {
    60  	return &lexer{input: input}
    61  }
    62  
    63  func (l *lexer) nextItem() (*item, error) {
    64  Start:
    65  	switch l.peek() {
    66  	case ' ', '\t', '\r', '\n':
    67  		l.acceptRun(space)
    68  		l.ignore()
    69  		goto Start
    70  	case '(', ')', '[', ']', ',':
    71  		l.next()
    72  		return &item{itemTypePunct, l.token()}, nil
    73  	case '1', '2', '3', '4', '5', '6', '7', '8', '9':
    74  		l.accept(num0)
    75  		l.acceptRun(num)
    76  		return &item{itemTypeNum, l.token()}, nil
    77  	case 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '_':
    78  		l.accept(id0)
    79  		l.acceptRun(id)
    80  		return &item{itemTypeID, l.token()}, nil
    81  	case eof:
    82  		return &item{itemTypeEOF, ""}, nil
    83  	default:
    84  		return nil, fmt.Errorf("unexpected character: %c", l.next())
    85  	}
    86  }
    87  
    88  func (l *lexer) next() (next rune) {
    89  	if l.pos >= len(l.input) {
    90  		l.width = 0
    91  		return eof
    92  	}
    93  	next, l.width = utf8.DecodeRuneInString(l.input[l.pos:])
    94  	l.pos += l.width
    95  	return
    96  }
    97  
    98  func (l *lexer) backup() {
    99  	l.pos -= l.width
   100  }
   101  
   102  func (l *lexer) ignore() {
   103  	l.start = l.pos
   104  }
   105  
   106  func (l *lexer) peek() (next rune) {
   107  	next = l.next()
   108  	l.backup()
   109  	return
   110  }
   111  
   112  func (l *lexer) accept(valid string) bool {
   113  	if strings.ContainsRune(valid, l.next()) {
   114  		return true
   115  	}
   116  	l.backup()
   117  	return false
   118  }
   119  
   120  // acceptRun consumes a run of runes from the valid set.
   121  func (l *lexer) acceptRun(valid string) {
   122  	for strings.ContainsRune(valid, l.next()) {
   123  	}
   124  	l.backup()
   125  }
   126  
   127  func (l *lexer) token() string {
   128  	token := l.input[l.start:l.pos]
   129  	l.ignore()
   130  	return token
   131  }
   132  
   133  var types = map[string]abi.Type{
   134  	"address": {T: abi.AddressTy, Size: 20},
   135  	"hash":    {T: abi.HashTy, Size: 32},
   136  	"bool":    {T: abi.BoolTy},
   137  	"bytes":   {T: abi.BytesTy},
   138  	"string":  {T: abi.StringTy},
   139  	"bytes1":  {T: abi.FixedBytesTy, Size: 1},
   140  	"bytes2":  {T: abi.FixedBytesTy, Size: 2},
   141  	"bytes3":  {T: abi.FixedBytesTy, Size: 3},
   142  	"bytes4":  {T: abi.FixedBytesTy, Size: 4},
   143  	"bytes5":  {T: abi.FixedBytesTy, Size: 5},
   144  	"bytes6":  {T: abi.FixedBytesTy, Size: 6},
   145  	"bytes7":  {T: abi.FixedBytesTy, Size: 7},
   146  	"bytes8":  {T: abi.FixedBytesTy, Size: 8},
   147  	"bytes9":  {T: abi.FixedBytesTy, Size: 9},
   148  	"bytes10": {T: abi.FixedBytesTy, Size: 10},
   149  	"bytes11": {T: abi.FixedBytesTy, Size: 11},
   150  	"bytes12": {T: abi.FixedBytesTy, Size: 12},
   151  	"bytes13": {T: abi.FixedBytesTy, Size: 13},
   152  	"bytes14": {T: abi.FixedBytesTy, Size: 14},
   153  	"bytes15": {T: abi.FixedBytesTy, Size: 15},
   154  	"bytes16": {T: abi.FixedBytesTy, Size: 16},
   155  	"bytes17": {T: abi.FixedBytesTy, Size: 17},
   156  	"bytes18": {T: abi.FixedBytesTy, Size: 18},
   157  	"bytes19": {T: abi.FixedBytesTy, Size: 19},
   158  	"bytes20": {T: abi.FixedBytesTy, Size: 20},
   159  	"bytes21": {T: abi.FixedBytesTy, Size: 21},
   160  	"bytes22": {T: abi.FixedBytesTy, Size: 22},
   161  	"bytes23": {T: abi.FixedBytesTy, Size: 23},
   162  	"bytes24": {T: abi.FixedBytesTy, Size: 24},
   163  	"bytes25": {T: abi.FixedBytesTy, Size: 25},
   164  	"bytes26": {T: abi.FixedBytesTy, Size: 26},
   165  	"bytes27": {T: abi.FixedBytesTy, Size: 27},
   166  	"bytes28": {T: abi.FixedBytesTy, Size: 28},
   167  	"bytes29": {T: abi.FixedBytesTy, Size: 29},
   168  	"bytes30": {T: abi.FixedBytesTy, Size: 30},
   169  	"bytes31": {T: abi.FixedBytesTy, Size: 31},
   170  	"bytes32": {T: abi.FixedBytesTy, Size: 32},
   171  	"uint8":   {T: abi.UintTy, Size: 8},
   172  	"uint16":  {T: abi.UintTy, Size: 16},
   173  	"uint24":  {T: abi.UintTy, Size: 24},
   174  	"uint32":  {T: abi.UintTy, Size: 32},
   175  	"uint40":  {T: abi.UintTy, Size: 40},
   176  	"uint48":  {T: abi.UintTy, Size: 48},
   177  	"uint56":  {T: abi.UintTy, Size: 56},
   178  	"uint64":  {T: abi.UintTy, Size: 64},
   179  	"uint72":  {T: abi.UintTy, Size: 72},
   180  	"uint80":  {T: abi.UintTy, Size: 80},
   181  	"uint88":  {T: abi.UintTy, Size: 88},
   182  	"uint96":  {T: abi.UintTy, Size: 96},
   183  	"uint104": {T: abi.UintTy, Size: 104},
   184  	"uint112": {T: abi.UintTy, Size: 112},
   185  	"uint120": {T: abi.UintTy, Size: 120},
   186  	"uint128": {T: abi.UintTy, Size: 128},
   187  	"uint136": {T: abi.UintTy, Size: 136},
   188  	"uint144": {T: abi.UintTy, Size: 144},
   189  	"uint152": {T: abi.UintTy, Size: 152},
   190  	"uint160": {T: abi.UintTy, Size: 160},
   191  	"uint168": {T: abi.UintTy, Size: 168},
   192  	"uint176": {T: abi.UintTy, Size: 176},
   193  	"uint184": {T: abi.UintTy, Size: 184},
   194  	"uint192": {T: abi.UintTy, Size: 192},
   195  	"uint200": {T: abi.UintTy, Size: 200},
   196  	"uint208": {T: abi.UintTy, Size: 208},
   197  	"uint216": {T: abi.UintTy, Size: 216},
   198  	"uint224": {T: abi.UintTy, Size: 224},
   199  	"uint232": {T: abi.UintTy, Size: 232},
   200  	"uint240": {T: abi.UintTy, Size: 240},
   201  	"uint248": {T: abi.UintTy, Size: 248},
   202  	"uint256": {T: abi.UintTy, Size: 256},
   203  	"uint":    {T: abi.UintTy, Size: 256},
   204  	"int8":    {T: abi.IntTy, Size: 8},
   205  	"int16":   {T: abi.IntTy, Size: 16},
   206  	"int24":   {T: abi.IntTy, Size: 24},
   207  	"int32":   {T: abi.IntTy, Size: 32},
   208  	"int40":   {T: abi.IntTy, Size: 40},
   209  	"int48":   {T: abi.IntTy, Size: 48},
   210  	"int56":   {T: abi.IntTy, Size: 56},
   211  	"int64":   {T: abi.IntTy, Size: 64},
   212  	"int72":   {T: abi.IntTy, Size: 72},
   213  	"int80":   {T: abi.IntTy, Size: 80},
   214  	"int88":   {T: abi.IntTy, Size: 88},
   215  	"int96":   {T: abi.IntTy, Size: 96},
   216  	"int104":  {T: abi.IntTy, Size: 104},
   217  	"int112":  {T: abi.IntTy, Size: 112},
   218  	"int120":  {T: abi.IntTy, Size: 120},
   219  	"int128":  {T: abi.IntTy, Size: 128},
   220  	"int136":  {T: abi.IntTy, Size: 136},
   221  	"int144":  {T: abi.IntTy, Size: 144},
   222  	"int152":  {T: abi.IntTy, Size: 152},
   223  	"int160":  {T: abi.IntTy, Size: 160},
   224  	"int168":  {T: abi.IntTy, Size: 168},
   225  	"int176":  {T: abi.IntTy, Size: 176},
   226  	"int184":  {T: abi.IntTy, Size: 184},
   227  	"int192":  {T: abi.IntTy, Size: 192},
   228  	"int200":  {T: abi.IntTy, Size: 200},
   229  	"int208":  {T: abi.IntTy, Size: 208},
   230  	"int216":  {T: abi.IntTy, Size: 216},
   231  	"int224":  {T: abi.IntTy, Size: 224},
   232  	"int232":  {T: abi.IntTy, Size: 232},
   233  	"int240":  {T: abi.IntTy, Size: 240},
   234  	"int248":  {T: abi.IntTy, Size: 248},
   235  	"int256":  {T: abi.IntTy, Size: 256},
   236  	"int":     {T: abi.IntTy, Size: 256},
   237  }