github.com/neilgarb/delve@v1.9.2-nobreaks/_scripts/gen-opcodes.go (about)

     1  // This script generates pkg/dwarf/op/opcodes.go from pkg/dwarf/op/opcodes.txt
     2  
     3  package main
     4  
     5  import (
     6  	"bufio"
     7  	"bytes"
     8  	"fmt"
     9  	"go/format"
    10  	"log"
    11  	"os"
    12  	"strings"
    13  )
    14  
    15  type Opcode struct {
    16  	Name string
    17  	Code string
    18  	Args string
    19  	Func string
    20  }
    21  
    22  func main() {
    23  	fh, err := os.Open(os.Args[1])
    24  	if err != nil {
    25  		log.Fatal(err)
    26  	}
    27  	defer fh.Close()
    28  
    29  	outfh := os.Stdout
    30  	if os.Args[2] != "-" {
    31  		outfh, err = os.Create(os.Args[2])
    32  		if err != nil {
    33  			log.Fatal(err)
    34  		}
    35  		defer outfh.Close()
    36  	}
    37  
    38  	opcodes := []Opcode{}
    39  	s := bufio.NewScanner(fh)
    40  	for s.Scan() {
    41  		line := strings.TrimSpace(s.Text())
    42  		if line == "" || strings.HasPrefix(line, "//") {
    43  			continue
    44  		}
    45  		fields := strings.Split(line, "\t")
    46  		opcode := Opcode{Name: fields[0], Code: fields[1], Args: fields[2]}
    47  		if len(fields) > 3 {
    48  			opcode.Func = fields[3]
    49  		}
    50  		opcodes = append(opcodes, opcode)
    51  	}
    52  
    53  	var buf bytes.Buffer
    54  
    55  	fmt.Fprintf(&buf, `// THIS FILE IS AUTOGENERATED, EDIT opcodes.table INSTEAD
    56  	
    57  package op
    58  `)
    59  
    60  	// constants
    61  	fmt.Fprintf(&buf, "const (\n")
    62  	for _, opcode := range opcodes {
    63  		fmt.Fprintf(&buf, "%s Opcode = %s\n", opcode.Name, opcode.Code)
    64  	}
    65  	fmt.Fprintf(&buf, ")\n\n")
    66  
    67  	// name map
    68  	fmt.Fprintf(&buf, "var opcodeName = map[Opcode]string{\n")
    69  	for _, opcode := range opcodes {
    70  		fmt.Fprintf(&buf, "%s: %q,\n", opcode.Name, opcode.Name)
    71  	}
    72  	fmt.Fprintf(&buf, "}\n")
    73  
    74  	// arguments map
    75  	fmt.Fprintf(&buf, "var opcodeArgs = map[Opcode]string{\n")
    76  	for _, opcode := range opcodes {
    77  		fmt.Fprintf(&buf, "%s: %s,\n", opcode.Name, opcode.Args)
    78  	}
    79  	fmt.Fprintf(&buf, "}\n")
    80  
    81  	// function map
    82  	fmt.Fprintf(&buf, "var oplut = map[Opcode]stackfn{\n")
    83  	for _, opcode := range opcodes {
    84  		if opcode.Func != "" {
    85  			fmt.Fprintf(&buf, "%s: %s,\n", opcode.Name, opcode.Func)
    86  		}
    87  	}
    88  	fmt.Fprintf(&buf, "}\n")
    89  
    90  	src, err := format.Source(buf.Bytes())
    91  	if err != nil {
    92  		log.Fatal(err)
    93  	}
    94  	outfh.Write(src)
    95  }