File: gen_builtin.go

package info (click to toggle)
golang-github-wader-gojq 0.0~git20231105.2b6d9e2-1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 960 kB
  • sloc: yacc: 642; makefile: 84
file content (100 lines) | stat: -rw-r--r-- 2,201 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package main

import (
	"flag"
	"fmt"
	"go/ast"
	"go/printer"
	"go/token"
	"os"
	"regexp"
	"strings"

	"github.com/itchyny/astgen-go"
	"github.com/wader/gojq"
)

const fileFormat = `// Code generated by _tools/gen_builtin.go; DO NOT EDIT.

package gojq

func init() {%s}
`

func main() {
	var input, output string
	flag.StringVar(&input, "i", "", "input file")
	flag.StringVar(&output, "o", "", "output file")
	flag.Parse()
	if err := run(input, output); err != nil {
		fmt.Fprint(os.Stderr, err)
		os.Exit(1)
	}
}

func run(input, output string) error {
	cnt, err := os.ReadFile(input)
	if err != nil {
		return err
	}
	q, err := gojq.Parse(string(cnt))
	if err != nil {
		return err
	}
	fds := make(map[string][]*gojq.FuncDef)
	for _, fd := range q.FuncDefs {
		fd.Minify()
		fds[fd.Name] = append(fds[fd.Name], fd)
	}
	fds["_assign"] = nil
	fds["_modify"] = nil
	t, err := astgen.Build(fds)
	if err != nil {
		return err
	}
	var sb strings.Builder
	sb.WriteString("\n\tbuiltinFuncDefs = ")
	if err := printCompositeLit(&sb, t.(*ast.CompositeLit)); err != nil {
		return err
	}
	out := os.Stdout
	if output != "" {
		f, err := os.Create(output)
		if err != nil {
			return err
		}
		defer f.Close()
		out = f
	}
	_, err = fmt.Fprintf(out, fileFormat, sb.String())
	return err
}

func printCompositeLit(out *strings.Builder, t *ast.CompositeLit) error {
	err := printer.Fprint(out, token.NewFileSet(), t.Type)
	if err != nil {
		return err
	}
	out.WriteString("{")
	for _, kv := range t.Elts {
		out.WriteString("\n\t\t")
		var sb strings.Builder
		err = printer.Fprint(&sb, token.NewFileSet(), kv)
		if err != nil {
			return err
		}
		str := sb.String()
		for op := gojq.OpPipe; op <= gojq.OpUpdateAlt; op++ {
			r := regexp.MustCompile(fmt.Sprintf(`\b((?:Update)?Op): %d\b`, op))
			str = r.ReplaceAllString(str, fmt.Sprintf("$1: %#v", op))
		}
		for termType := gojq.TermTypeIdentity; termType <= gojq.TermTypeQuery; termType++ {
			r := regexp.MustCompile(fmt.Sprintf(`(Term{Type): %d\b`, termType))
			str = r.ReplaceAllString(str, fmt.Sprintf("$1: %#v", termType))
		}
		out.WriteString(strings.ReplaceAll(str, "gojq.", ""))
		out.WriteString(",")
	}
	out.WriteString("\n\t}\n")
	return nil
}