forked from quasilyte/gogrep
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcompile_import.go
57 lines (53 loc) · 1.22 KB
/
compile_import.go
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
package gogrep
import (
"errors"
"fmt"
"strings"
"unicode"
"unicode/utf8"
)
func compileImportPattern(config CompileConfig) (*Pattern, PatternInfo, error) {
// TODO: figure out how to compile it as a part of a normal pattern compilation?
// This is an adhoc solution to a problem.
readIdent := func(s string) (varname, rest string) {
first := true
var offset int
for _, ch := range s {
ok := unicode.IsLetter(ch) ||
ch == '_' ||
(!first && unicode.IsDigit(ch))
if !ok {
break
}
offset += utf8.RuneLen(ch)
first = false
}
return s[:offset], s[offset:]
}
info := newPatternInfo()
src := config.Src
src = src[len("import $"):]
if src == "" {
return nil, info, errors.New("expected ident after $, found EOF")
}
varname, rest := readIdent(src)
if strings.TrimSpace(rest) != "" {
return nil, info, fmt.Errorf("unexpected %s", rest)
}
var p program
if varname != "_" {
info.Vars[src] = struct{}{}
p.strings = []string{varname}
p.insts = []instruction{
{op: opImportDecl},
{op: opNamedNodeSeq, valueIndex: 0},
{op: opEnd},
}
} else {
p.insts = []instruction{
{op: opAnyImportDecl},
}
}
m := matcher{prog: &p, insts: p.insts}
return &Pattern{m: &m}, info, nil
}