1package gojq
2
3import (
4	"context"
5	"encoding/json"
6	"errors"
7	"fmt"
8	"sort"
9	"strconv"
10	"strings"
11)
12
13type compiler struct {
14	moduleLoader  ModuleLoader
15	environLoader func() []string
16	variables     []string
17	customFuncs   map[string]function
18	inputIter     Iter
19	codes         []*code
20	codeinfos     []codeinfo
21	scopes        []*scopeinfo
22	scopecnt      int
23}
24
25// Code is a compiled jq query.
26type Code struct {
27	variables []string
28	codes     []*code
29	codeinfos []codeinfo
30}
31
32// Run runs the code with the variable values (which should be in the
33// same order as the given variables using WithVariables) and returns
34// a result iterator.
35//
36// It is safe to call this method of a *Code in multiple goroutines.
37func (c *Code) Run(v interface{}, values ...interface{}) Iter {
38	return c.RunWithContext(context.Background(), v, values...)
39}
40
41// RunWithContext runs the code with context.
42func (c *Code) RunWithContext(ctx context.Context, v interface{}, values ...interface{}) Iter {
43	if len(values) > len(c.variables) {
44		return NewIter(&tooManyVariableValuesError{})
45	} else if len(values) < len(c.variables) {
46		return NewIter(&expectedVariableError{c.variables[len(values)]})
47	}
48	for i, v := range values {
49		values[i] = normalizeNumbers(v)
50	}
51	return newEnv(ctx).execute(c, normalizeNumbers(v), values...)
52}
53
54// ModuleLoader is an interface for loading modules.
55//
56// Implement following optional methods. Use NewModuleLoader to load local modules.
57//  LoadModule(string) (*Query, error)
58//  LoadModuleWithMeta(string, map[string]interface{}) (*Query, error)
59//  LoadInitModules() ([]*Query, error)
60//  LoadJSON(string) (interface{}, error)
61//  LoadJSONWithMeta(string, map[string]interface{}) (interface{}, error)
62type ModuleLoader interface{}
63
64type scopeinfo struct {
65	variables   []*varinfo
66	funcs       []*funcinfo
67	id          int
68	depth       int
69	variablecnt int
70}
71
72type varinfo struct {
73	name  string
74	index [2]int
75	depth int
76}
77
78type funcinfo struct {
79	name   string
80	pc     int
81	argcnt int
82}
83
84// Compile compiles a query.
85func Compile(q *Query, options ...CompilerOption) (*Code, error) {
86	c := &compiler{}
87	for _, opt := range options {
88		opt(c)
89	}
90	scope := c.newScope()
91	c.scopes = []*scopeinfo{scope}
92	setscope := c.lazy(func() *code {
93		return &code{op: opscope, v: [3]int{scope.id, scope.variablecnt, 0}}
94	})
95	if c.moduleLoader != nil {
96		if moduleLoader, ok := c.moduleLoader.(interface {
97			LoadInitModules() ([]*Query, error)
98		}); ok {
99			qs, err := moduleLoader.LoadInitModules()
100			if err != nil {
101				return nil, err
102			}
103			for _, q := range qs {
104				if err := c.compileModule(q, ""); err != nil {
105					return nil, err
106				}
107			}
108		}
109	}
110	if err := c.compile(q); err != nil {
111		return nil, err
112	}
113	setscope()
114	c.optimizeTailRec()
115	c.optimizeCodeOps()
116	return &Code{
117		variables: c.variables,
118		codes:     c.codes,
119		codeinfos: c.codeinfos,
120	}, nil
121}
122
123func (c *compiler) compile(q *Query) error {
124	for _, name := range c.variables {
125		if !newLexer(name).validVarName() {
126			return &variableNameError{name}
127		}
128		c.appendCodeInfo(name)
129		c.append(&code{op: opstore, v: c.pushVariable(name)})
130	}
131	for _, i := range q.Imports {
132		if err := c.compileImport(i); err != nil {
133			return err
134		}
135	}
136	if err := c.compileQuery(q); err != nil {
137		return err
138	}
139	c.append(&code{op: opret})
140	return nil
141}
142
143func (c *compiler) compileImport(i *Import) error {
144	var path, alias string
145	var err error
146	if i.ImportPath != "" {
147		path, alias = i.ImportPath, i.ImportAlias
148	} else {
149		path = i.IncludePath
150	}
151	if c.moduleLoader == nil {
152		return fmt.Errorf("cannot load module: %q", path)
153	}
154	if strings.HasPrefix(alias, "$") {
155		var vals interface{}
156		if moduleLoader, ok := c.moduleLoader.(interface {
157			LoadJSONWithMeta(string, map[string]interface{}) (interface{}, error)
158		}); ok {
159			if vals, err = moduleLoader.LoadJSONWithMeta(path, i.Meta.ToValue()); err != nil {
160				return err
161			}
162		} else if moduleLoader, ok := c.moduleLoader.(interface {
163			LoadJSON(string) (interface{}, error)
164		}); ok {
165			if vals, err = moduleLoader.LoadJSON(path); err != nil {
166				return err
167			}
168		} else {
169			return fmt.Errorf("module not found: %q", path)
170		}
171		vals = normalizeNumbers(vals)
172		c.append(&code{op: oppush, v: vals})
173		c.append(&code{op: opstore, v: c.pushVariable(alias)})
174		c.append(&code{op: oppush, v: vals})
175		c.append(&code{op: opstore, v: c.pushVariable(alias + "::" + alias[1:])})
176		return nil
177	}
178	var q *Query
179	if moduleLoader, ok := c.moduleLoader.(interface {
180		LoadModuleWithMeta(string, map[string]interface{}) (*Query, error)
181	}); ok {
182		if q, err = moduleLoader.LoadModuleWithMeta(path, i.Meta.ToValue()); err != nil {
183			return err
184		}
185	} else if moduleLoader, ok := c.moduleLoader.(interface {
186		LoadModule(string) (*Query, error)
187	}); ok {
188		if q, err = moduleLoader.LoadModule(path); err != nil {
189			return err
190		}
191	}
192	c.appendCodeInfo("module " + path)
193	defer c.appendCodeInfo("end of module " + path)
194	return c.compileModule(q, alias)
195}
196
197func (c *compiler) compileModule(q *Query, alias string) error {
198	scope := c.scopes[len(c.scopes)-1]
199	scope.depth++
200	defer func(l int) {
201		scope.depth--
202		scope.variables = scope.variables[:l]
203	}(len(scope.variables))
204	if alias != "" {
205		defer func(l int) {
206			for _, f := range scope.funcs[l:] {
207				f.name = alias + "::" + f.name
208			}
209		}(len(scope.funcs))
210	}
211	for _, i := range q.Imports {
212		if err := c.compileImport(i); err != nil {
213			return err
214		}
215	}
216	for _, fd := range q.FuncDefs {
217		if err := c.compileFuncDef(fd, false); err != nil {
218			return err
219		}
220	}
221	return nil
222}
223
224func (c *compiler) newVariable() [2]int {
225	return c.createVariable("")
226}
227
228func (c *compiler) pushVariable(name string) [2]int {
229	s := c.scopes[len(c.scopes)-1]
230	for _, v := range s.variables {
231		if v.name == name && v.depth == s.depth {
232			return v.index
233		}
234	}
235	return c.createVariable(name)
236}
237
238func (c *compiler) createVariable(name string) [2]int {
239	s := c.scopes[len(c.scopes)-1]
240	v := [2]int{s.id, s.variablecnt}
241	s.variablecnt++
242	s.variables = append(s.variables, &varinfo{name, v, s.depth})
243	return v
244}
245
246func (c *compiler) lookupVariable(name string) ([2]int, error) {
247	for i := len(c.scopes) - 1; i >= 0; i-- {
248		s := c.scopes[i]
249		for j := len(s.variables) - 1; j >= 0; j-- {
250			if w := s.variables[j]; w.name == name {
251				return w.index, nil
252			}
253		}
254	}
255	return [2]int{}, &variableNotFoundError{name}
256}
257
258func (c *compiler) lookupFuncOrVariable(name string) (*funcinfo, *varinfo) {
259	for i, isFunc := len(c.scopes)-1, name[0] != '$'; i >= 0; i-- {
260		s := c.scopes[i]
261		if isFunc {
262			for j := len(s.funcs) - 1; j >= 0; j-- {
263				if f := s.funcs[j]; f.name == name && f.argcnt == 0 {
264					return f, nil
265				}
266			}
267		}
268		for j := len(s.variables) - 1; j >= 0; j-- {
269			if v := s.variables[j]; v.name == name {
270				return nil, v
271			}
272		}
273	}
274	return nil, nil
275}
276
277func (c *compiler) newScope() *scopeinfo {
278	i := c.scopecnt // do not use len(c.scopes) because it pops
279	c.scopecnt++
280	return &scopeinfo{id: i}
281}
282
283func (c *compiler) newScopeDepth() func() {
284	scope := c.scopes[len(c.scopes)-1]
285	l, m := len(scope.variables), len(scope.funcs)
286	scope.depth++
287	return func() {
288		scope.depth--
289		scope.variables = scope.variables[:l]
290		scope.funcs = scope.funcs[:m]
291	}
292}
293
294func (c *compiler) compileFuncDef(e *FuncDef, builtin bool) error {
295	var scope *scopeinfo
296	if builtin {
297		scope = c.scopes[0]
298		for i := len(scope.funcs) - 1; i >= 0; i-- {
299			if f := scope.funcs[i]; f.name == e.Name && f.argcnt == len(e.Args) {
300				return nil
301			}
302		}
303	} else {
304		scope = c.scopes[len(c.scopes)-1]
305	}
306	defer c.lazy(func() *code {
307		return &code{op: opjump, v: c.pc()}
308	})()
309	c.appendCodeInfo(e.Name)
310	defer c.appendCodeInfo("end of " + e.Name)
311	pc := c.pc()
312	scope.funcs = append(scope.funcs, &funcinfo{e.Name, pc, len(e.Args)})
313	defer func(scopes []*scopeinfo, variables []string) {
314		c.scopes, c.variables = scopes, variables
315	}(c.scopes, c.variables)
316	c.variables = c.variables[len(c.variables):]
317	scope = c.newScope()
318	if builtin {
319		c.scopes = []*scopeinfo{c.scopes[0], scope}
320	} else {
321		c.scopes = append(c.scopes, scope)
322	}
323	defer c.lazy(func() *code {
324		return &code{op: opscope, v: [3]int{scope.id, scope.variablecnt, len(e.Args)}}
325	})()
326	if len(e.Args) > 0 {
327		type varIndex struct {
328			name  string
329			index [2]int
330		}
331		vis := make([]varIndex, 0, len(e.Args))
332		v := c.newVariable()
333		c.append(&code{op: opstore, v: v})
334		for _, arg := range e.Args {
335			if arg[0] == '$' {
336				c.appendCodeInfo(arg[1:])
337				w := c.createVariable(arg[1:])
338				c.append(&code{op: opstore, v: w})
339				vis = append(vis, varIndex{arg, w})
340			} else {
341				c.appendCodeInfo(arg)
342				c.append(&code{op: opstore, v: c.createVariable(arg)})
343			}
344		}
345		for _, w := range vis {
346			c.append(&code{op: opload, v: v})
347			c.append(&code{op: opload, v: w.index})
348			c.append(&code{op: opcallpc})
349			c.appendCodeInfo(w.name)
350			c.append(&code{op: opstore, v: c.pushVariable(w.name)})
351		}
352		c.append(&code{op: opload, v: v})
353	}
354	return c.compile(e.Body)
355}
356
357func (c *compiler) compileQuery(e *Query) error {
358	for _, fd := range e.FuncDefs {
359		if err := c.compileFuncDef(fd, false); err != nil {
360			return err
361		}
362	}
363	if e.Func != "" {
364		switch e.Func {
365		case ".":
366			return c.compileTerm(&Term{Type: TermTypeIdentity})
367		case "..":
368			return c.compileTerm(&Term{Type: TermTypeRecurse})
369		case "null":
370			return c.compileTerm(&Term{Type: TermTypeNull})
371		case "true":
372			return c.compileTerm(&Term{Type: TermTypeTrue})
373		case "false":
374			return c.compileTerm(&Term{Type: TermTypeFalse})
375		default:
376			return c.compileFunc(&Func{Name: e.Func})
377		}
378	} else if e.Term != nil {
379		return c.compileTerm(e.Term)
380	}
381	switch e.Op {
382	case OpPipe:
383		if err := c.compileQuery(e.Left); err != nil {
384			return err
385		}
386		return c.compileQuery(e.Right)
387	case OpComma:
388		return c.compileComma(e.Left, e.Right)
389	case OpAlt:
390		return c.compileAlt(e.Left, e.Right)
391	case OpAssign, OpModify, OpUpdateAdd, OpUpdateSub,
392		OpUpdateMul, OpUpdateDiv, OpUpdateMod, OpUpdateAlt:
393		return c.compileQueryUpdate(e.Left, e.Right, e.Op)
394	case OpOr:
395		return c.compileIf(
396			&If{
397				Cond: e.Left,
398				Then: &Query{Term: &Term{Type: TermTypeTrue}},
399				Else: &Query{Term: &Term{Type: TermTypeIf, If: &If{
400					Cond: e.Right,
401					Then: &Query{Term: &Term{Type: TermTypeTrue}},
402					Else: &Query{Term: &Term{Type: TermTypeFalse}},
403				}}},
404			},
405		)
406	case OpAnd:
407		return c.compileIf(
408			&If{
409				Cond: e.Left,
410				Then: &Query{Term: &Term{Type: TermTypeIf, If: &If{
411					Cond: e.Right,
412					Then: &Query{Term: &Term{Type: TermTypeTrue}},
413					Else: &Query{Term: &Term{Type: TermTypeFalse}},
414				}}},
415				Else: &Query{Term: &Term{Type: TermTypeFalse}},
416			},
417		)
418	default:
419		return c.compileCall(
420			e.Op.getFunc(),
421			[]*Query{e.Left, e.Right},
422		)
423	}
424}
425
426func (c *compiler) compileComma(l, r *Query) error {
427	setfork := c.lazy(func() *code {
428		return &code{op: opfork, v: c.pc() + 1}
429	})
430	if err := c.compileQuery(l); err != nil {
431		return err
432	}
433	setfork()
434	defer c.lazy(func() *code {
435		return &code{op: opjump, v: c.pc()}
436	})()
437	return c.compileQuery(r)
438}
439
440func (c *compiler) compileAlt(l, r *Query) error {
441	c.append(&code{op: oppush, v: false})
442	found := c.newVariable()
443	c.append(&code{op: opstore, v: found})
444	setfork := c.lazy(func() *code {
445		return &code{op: opfork, v: c.pc()} // opload found
446	})
447	if err := c.compileQuery(l); err != nil {
448		return err
449	}
450	c.append(&code{op: opdup})
451	c.append(&code{op: opjumpifnot, v: c.pc() + 4}) // oppop
452	c.append(&code{op: oppush, v: true})            // found some value
453	c.append(&code{op: opstore, v: found})
454	defer c.lazy(func() *code {
455		return &code{op: opjump, v: c.pc()} // ret
456	})()
457	c.append(&code{op: oppop})
458	c.append(&code{op: opbacktrack})
459	setfork()
460	c.append(&code{op: opload, v: found})
461	c.append(&code{op: opjumpifnot, v: c.pc() + 3})
462	c.append(&code{op: opbacktrack}) // if found, backtrack
463	c.append(&code{op: oppop})
464	return c.compileQuery(r)
465}
466
467func (c *compiler) compileQueryUpdate(l, r *Query, op Operator) error {
468	switch op {
469	case OpAssign:
470		// .foo.bar = f => setpath(["foo", "bar"]; f)
471		if xs := l.toIndices(); xs != nil {
472			// ref: compileCall
473			v := c.newVariable()
474			c.append(&code{op: opstore, v: v})
475			c.append(&code{op: opload, v: v})
476			if err := c.compileQuery(r); err != nil {
477				return err
478			}
479			c.append(&code{op: oppush, v: xs})
480			c.append(&code{op: opload, v: v})
481			c.append(&code{op: opcall, v: [3]interface{}{internalFuncs["setpath"].callback, 2, "setpath"}})
482			return nil
483		}
484		fallthrough
485	case OpModify:
486		return c.compileFunc(
487			&Func{
488				Name: op.getFunc(),
489				Args: []*Query{l, r},
490			},
491		)
492	default:
493		name := "$%0"
494		c.append(&code{op: opdup})
495		if err := c.compileQuery(r); err != nil {
496			return err
497		}
498		c.append(&code{op: opstore, v: c.pushVariable(name)})
499		return c.compileFunc(
500			&Func{
501				Name: "_modify",
502				Args: []*Query{
503					l,
504					{Term: &Term{
505						Type: TermTypeFunc,
506						Func: &Func{
507							Name: op.getFunc(),
508							Args: []*Query{
509								{Term: &Term{Type: TermTypeIdentity}},
510								{Func: name},
511							},
512						},
513					}},
514				},
515			},
516		)
517	}
518}
519
520func (c *compiler) compileBind(b *Bind) error {
521	var pc int
522	var vs [][2]int
523	for i, p := range b.Patterns {
524		var pcc int
525		var err error
526		if i < len(b.Patterns)-1 {
527			defer c.lazy(func() *code {
528				return &code{op: opforkalt, v: pcc}
529			})()
530		}
531		if 0 < i {
532			for _, v := range vs {
533				c.append(&code{op: oppush, v: nil})
534				c.append(&code{op: opstore, v: v})
535			}
536		}
537		vs, err = c.compilePattern(p)
538		if err != nil {
539			return err
540		}
541		if i < len(b.Patterns)-1 {
542			defer c.lazy(func() *code {
543				return &code{op: opjump, v: pc}
544			})()
545			pcc = c.pc()
546		}
547	}
548	if len(b.Patterns) > 1 {
549		pc = c.pc()
550	}
551	if len(b.Patterns) == 1 && c.codes[len(c.codes)-2].op == opexpbegin {
552		c.codes[len(c.codes)-2].op = opnop
553	} else {
554		c.append(&code{op: opexpend}) // ref: compileTermSuffix
555	}
556	return c.compileQuery(b.Body)
557}
558
559func (c *compiler) compilePattern(p *Pattern) ([][2]int, error) {
560	c.appendCodeInfo(p)
561	if p.Name != "" {
562		v := c.pushVariable(p.Name)
563		c.append(&code{op: opstore, v: v})
564		return [][2]int{v}, nil
565	} else if len(p.Array) > 0 {
566		var vs [][2]int
567		v := c.newVariable()
568		c.append(&code{op: opstore, v: v})
569		for i, p := range p.Array {
570			c.append(&code{op: oppush, v: i})
571			c.append(&code{op: opload, v: v})
572			c.append(&code{op: opload, v: v})
573			// ref: compileCall
574			c.append(&code{op: opcall, v: [3]interface{}{internalFuncs["_index"].callback, 2, "_index"}})
575			ns, err := c.compilePattern(p)
576			if err != nil {
577				return nil, err
578			}
579			vs = append(vs, ns...)
580		}
581		return vs, nil
582	} else if len(p.Object) > 0 {
583		var vs [][2]int
584		v := c.newVariable()
585		c.append(&code{op: opstore, v: v})
586		for _, kv := range p.Object {
587			var key, name string
588			if kv.KeyOnly != "" {
589				key, name = kv.KeyOnly[1:], kv.KeyOnly
590				c.append(&code{op: oppush, v: key})
591			} else if kv.Key != "" {
592				key = kv.Key
593				if key != "" && key[0] == '$' {
594					key, name = key[1:], key
595				}
596				c.append(&code{op: oppush, v: key})
597			} else if kv.KeyString != nil {
598				c.append(&code{op: opload, v: v})
599				if err := c.compileString(kv.KeyString, nil); err != nil {
600					return nil, err
601				}
602			} else if kv.KeyQuery != nil {
603				c.append(&code{op: opload, v: v})
604				if err := c.compileQuery(kv.KeyQuery); err != nil {
605					return nil, err
606				}
607			}
608			c.append(&code{op: opload, v: v})
609			c.append(&code{op: opload, v: v})
610			// ref: compileCall
611			c.append(&code{op: opcall, v: [3]interface{}{internalFuncs["_index"].callback, 2, "_index"}})
612			if name != "" {
613				if kv.Val != nil {
614					c.append(&code{op: opdup})
615				}
616				ns, err := c.compilePattern(&Pattern{Name: name})
617				if err != nil {
618					return nil, err
619				}
620				vs = append(vs, ns...)
621			}
622			if kv.Val != nil {
623				ns, err := c.compilePattern(kv.Val)
624				if err != nil {
625					return nil, err
626				}
627				vs = append(vs, ns...)
628			}
629		}
630		return vs, nil
631	} else {
632		return nil, fmt.Errorf("invalid pattern: %s", p)
633	}
634}
635
636func (c *compiler) compileIf(e *If) error {
637	c.appendCodeInfo(e)
638	c.append(&code{op: opdup}) // duplicate the value for then or else clause
639	c.append(&code{op: opexpbegin})
640	pc := len(c.codes)
641	f := c.newScopeDepth()
642	if err := c.compileQuery(e.Cond); err != nil {
643		return err
644	}
645	f()
646	if pc == len(c.codes) {
647		c.codes = c.codes[:pc-1]
648	} else {
649		c.append(&code{op: opexpend})
650	}
651	pcc := len(c.codes)
652	setjumpifnot := c.lazy(func() *code {
653		return &code{op: opjumpifnot, v: c.pc() + 1} // if falsy, skip then clause
654	})
655	f = c.newScopeDepth()
656	if err := c.compileQuery(e.Then); err != nil {
657		return err
658	}
659	f()
660	setjumpifnot()
661	defer c.lazy(func() *code {
662		return &code{op: opjump, v: c.pc()} // jump to ret after else clause
663	})()
664	if len(e.Elif) > 0 {
665		return c.compileIf(&If{e.Elif[0].Cond, e.Elif[0].Then, e.Elif[1:], e.Else})
666	}
667	if e.Else != nil {
668		defer c.newScopeDepth()()
669		defer func() {
670			// optimize constant results
671			//    opdup, ..., opjumpifnot, opconst, opjump, opconst
672			// => opnop, ..., opjumpifnot, oppush,  opjump, oppush
673			if pcc+4 == len(c.codes) &&
674				c.codes[pcc+1] != nil && c.codes[pcc+1].op == opconst &&
675				c.codes[pcc+3] != nil && c.codes[pcc+3].op == opconst {
676				c.codes[pc-2].op = opnop
677				c.codes[pcc+1].op = oppush
678				c.codes[pcc+3].op = oppush
679			}
680		}()
681		return c.compileQuery(e.Else)
682	}
683	return nil
684}
685
686func (c *compiler) compileTry(e *Try) error {
687	c.appendCodeInfo(e)
688	setforktrybegin := c.lazy(func() *code {
689		return &code{op: opforktrybegin, v: c.pc()}
690	})
691	f := c.newScopeDepth()
692	if err := c.compileQuery(e.Body); err != nil {
693		return err
694	}
695	f()
696	c.append(&code{op: opforktryend})
697	defer c.lazy(func() *code {
698		return &code{op: opjump, v: c.pc()}
699	})()
700	setforktrybegin()
701	if e.Catch != nil {
702		defer c.newScopeDepth()()
703		return c.compileQuery(e.Catch)
704	}
705	c.append(&code{op: opbacktrack})
706	return nil
707}
708
709func (c *compiler) compileReduce(e *Reduce) error {
710	c.appendCodeInfo(e)
711	defer c.newScopeDepth()()
712	defer c.lazy(func() *code {
713		return &code{op: opfork, v: c.pc() - 2}
714	})()
715	c.append(&code{op: opdup})
716	v := c.newVariable()
717	f := c.newScopeDepth()
718	if err := c.compileQuery(e.Start); err != nil {
719		return err
720	}
721	f()
722	c.append(&code{op: opstore, v: v})
723	if err := c.compileTerm(e.Term); err != nil {
724		return err
725	}
726	if _, err := c.compilePattern(e.Pattern); err != nil {
727		return err
728	}
729	c.append(&code{op: opload, v: v})
730	f = c.newScopeDepth()
731	if err := c.compileQuery(e.Update); err != nil {
732		return err
733	}
734	f()
735	c.append(&code{op: opstore, v: v})
736	c.append(&code{op: opbacktrack})
737	c.append(&code{op: oppop})
738	c.append(&code{op: opload, v: v})
739	return nil
740}
741
742func (c *compiler) compileForeach(e *Foreach) error {
743	c.appendCodeInfo(e)
744	defer c.newScopeDepth()()
745	c.append(&code{op: opdup})
746	v := c.newVariable()
747	f := c.newScopeDepth()
748	if err := c.compileQuery(e.Start); err != nil {
749		return err
750	}
751	f()
752	c.append(&code{op: opstore, v: v})
753	if err := c.compileTerm(e.Term); err != nil {
754		return err
755	}
756	if _, err := c.compilePattern(e.Pattern); err != nil {
757		return err
758	}
759	c.append(&code{op: opload, v: v})
760	f = c.newScopeDepth()
761	if err := c.compileQuery(e.Update); err != nil {
762		return err
763	}
764	f()
765	c.append(&code{op: opdup})
766	c.append(&code{op: opstore, v: v})
767	if e.Extract != nil {
768		defer c.newScopeDepth()()
769		return c.compileQuery(e.Extract)
770	}
771	return nil
772}
773
774func (c *compiler) compileLabel(e *Label) error {
775	c.appendCodeInfo(e)
776	v := c.pushVariable("$%" + e.Ident[1:])
777	defer c.lazy(func() *code {
778		return &code{op: opforklabel, v: v}
779	})()
780	return c.compileQuery(e.Body)
781}
782
783func (c *compiler) compileBreak(label string) error {
784	v, err := c.lookupVariable("$%" + label[1:])
785	if err != nil {
786		return &breakError{label, nil}
787	}
788	c.append(&code{op: oppop})
789	c.append(&code{op: opload, v: v})
790	c.append(&code{op: opcall, v: [3]interface{}{
791		func(v interface{}, _ []interface{}) interface{} {
792			return &breakError{label, v}
793		},
794		0,
795		"_break",
796	}})
797	return nil
798}
799
800func (c *compiler) compileTerm(e *Term) error {
801	if len(e.SuffixList) > 0 {
802		s := e.SuffixList[len(e.SuffixList)-1]
803		t := *e // clone without changing e
804		(&t).SuffixList = t.SuffixList[:len(e.SuffixList)-1]
805		return c.compileTermSuffix(&t, s)
806	}
807	switch e.Type {
808	case TermTypeIdentity:
809		return nil
810	case TermTypeRecurse:
811		return c.compileFunc(&Func{Name: "recurse"})
812	case TermTypeNull:
813		c.append(&code{op: opconst, v: nil})
814		return nil
815	case TermTypeTrue:
816		c.append(&code{op: opconst, v: true})
817		return nil
818	case TermTypeFalse:
819		c.append(&code{op: opconst, v: false})
820		return nil
821	case TermTypeIndex:
822		return c.compileIndex(&Term{Type: TermTypeIdentity}, e.Index)
823	case TermTypeFunc:
824		return c.compileFunc(e.Func)
825	case TermTypeObject:
826		return c.compileObject(e.Object)
827	case TermTypeArray:
828		return c.compileArray(e.Array)
829	case TermTypeNumber:
830		v := normalizeNumbers(json.Number(e.Number))
831		if err, ok := v.(error); ok {
832			return err
833		}
834		c.append(&code{op: opconst, v: v})
835		return nil
836	case TermTypeUnary:
837		return c.compileUnary(e.Unary)
838	case TermTypeFormat:
839		return c.compileFormat(e.Format, e.Str)
840	case TermTypeString:
841		return c.compileString(e.Str, nil)
842	case TermTypeIf:
843		return c.compileIf(e.If)
844	case TermTypeTry:
845		return c.compileTry(e.Try)
846	case TermTypeReduce:
847		return c.compileReduce(e.Reduce)
848	case TermTypeForeach:
849		return c.compileForeach(e.Foreach)
850	case TermTypeLabel:
851		return c.compileLabel(e.Label)
852	case TermTypeBreak:
853		return c.compileBreak(e.Break)
854	case TermTypeQuery:
855		defer c.newScopeDepth()()
856		return c.compileQuery(e.Query)
857	default:
858		panic("invalid term: " + e.String())
859	}
860}
861
862func (c *compiler) compileIndex(e *Term, x *Index) error {
863	c.appendCodeInfo(x)
864	if x.Name != "" {
865		return c.compileCall("_index", []*Query{{Term: e}, {Term: &Term{Type: TermTypeString, Str: &String{Str: x.Name}}}})
866	}
867	if x.Str != nil {
868		return c.compileCall("_index", []*Query{{Term: e}, {Term: &Term{Type: TermTypeString, Str: x.Str}}})
869	}
870	if !x.IsSlice {
871		return c.compileCall("_index", []*Query{{Term: e}, x.Start})
872	}
873	if x.Start == nil {
874		return c.compileCall("_slice", []*Query{{Term: e}, x.End, {Term: &Term{Type: TermTypeNull}}})
875	}
876	if x.End == nil {
877		return c.compileCall("_slice", []*Query{{Term: e}, {Term: &Term{Type: TermTypeNull}}, x.Start})
878	}
879	return c.compileCall("_slice", []*Query{{Term: e}, x.End, x.Start})
880}
881
882func (c *compiler) compileFunc(e *Func) error {
883	name := e.Name
884	if len(e.Args) == 0 {
885		if f, v := c.lookupFuncOrVariable(name); f != nil {
886			return c.compileCallPc(f, e.Args)
887		} else if v != nil {
888			if name[0] == '$' {
889				c.append(&code{op: oppop})
890				c.append(&code{op: opload, v: v.index})
891			} else {
892				c.append(&code{op: opload, v: v.index})
893				c.append(&code{op: opcallpc})
894			}
895			return nil
896		} else if name == "$ENV" || name == "env" {
897			env := make(map[string]interface{})
898			if c.environLoader != nil {
899				for _, kv := range c.environLoader() {
900					if i := strings.IndexByte(kv, '='); i > 0 {
901						env[kv[:i]] = kv[i+1:]
902					}
903				}
904			}
905			c.append(&code{op: opconst, v: env})
906			return nil
907		} else if name[0] == '$' {
908			return &variableNotFoundError{name}
909		}
910	} else {
911		for i := len(c.scopes) - 1; i >= 0; i-- {
912			s := c.scopes[i]
913			for j := len(s.funcs) - 1; j >= 0; j-- {
914				if f := s.funcs[j]; f.name == name && f.argcnt == len(e.Args) {
915					return c.compileCallPc(f, e.Args)
916				}
917			}
918		}
919	}
920	if name[0] == '_' {
921		name = name[1:]
922	}
923	if fds, ok := builtinFuncDefs[name]; ok {
924		for _, fd := range fds {
925			if len(fd.Args) == len(e.Args) {
926				if err := c.compileFuncDef(fd, true); err != nil {
927					return err
928				}
929			}
930		}
931		s := c.scopes[0]
932		for i := len(s.funcs) - 1; i >= 0; i-- {
933			if f := s.funcs[i]; f.name == e.Name && f.argcnt == len(e.Args) {
934				return c.compileCallPc(f, e.Args)
935			}
936		}
937	}
938	if fn, ok := internalFuncs[e.Name]; ok && fn.accept(len(e.Args)) {
939		switch e.Name {
940		case "empty":
941			c.append(&code{op: opbacktrack})
942			return nil
943		case "path":
944			c.append(&code{op: oppathbegin})
945			if err := c.compileCall(e.Name, e.Args); err != nil {
946				return err
947			}
948			c.codes[len(c.codes)-1] = &code{op: oppathend}
949			return nil
950		case "builtins":
951			return c.compileCallInternal(
952				[3]interface{}{c.funcBuiltins, 0, e.Name},
953				e.Args,
954				true,
955				false,
956			)
957		case "scope":
958			return c.compileCallInternal(
959				[3]interface{}{c.funcScope, 0, e.Name},
960				e.Args,
961				true,
962				false,
963			)
964		case "input":
965			if c.inputIter == nil {
966				return &inputNotAllowedError{}
967			}
968			return c.compileCallInternal(
969				[3]interface{}{c.funcInput, 0, e.Name},
970				e.Args,
971				true,
972				false,
973			)
974		case "modulemeta":
975			return c.compileCallInternal(
976				[3]interface{}{c.funcModulemeta, 0, e.Name},
977				e.Args,
978				true,
979				false,
980			)
981		case "scopedump":
982			c.append(&code{op: oppop})
983			n := 0
984			for i := len(c.scopes) - 1; i >= 0; i-- {
985				s := c.scopes[i]
986				for j := len(s.variables) - 1; j >= 0; j-- {
987					v := s.variables[j]
988					c.append(&code{op: oppush, v: v.name})
989					c.append(&code{op: opload, v: v.index})
990					n++
991				}
992			}
993			c.append(&code{op: opobject, v: n})
994			return nil
995		default:
996			return c.compileCall(e.Name, e.Args)
997		}
998	}
999	if fn, ok := c.customFuncs[e.Name]; ok && fn.accept(len(e.Args)) {
1000		if err := c.compileCallInternal(
1001			[3]interface{}{fn.callback, len(e.Args), e.Name},
1002			e.Args,
1003			true,
1004			false,
1005		); err != nil {
1006			return err
1007		}
1008		if fn.iter {
1009			c.append(&code{op: opeach})
1010		}
1011		return nil
1012	}
1013	return &funcNotFoundError{e}
1014}
1015
1016func (c *compiler) funcBuiltins(interface{}, []interface{}) interface{} {
1017	type funcNameArity struct {
1018		name  string
1019		arity int
1020	}
1021	var xs []*funcNameArity
1022	for _, fds := range builtinFuncDefs {
1023		for _, fd := range fds {
1024			if fd.Name[0] != '_' {
1025				xs = append(xs, &funcNameArity{fd.Name, len(fd.Args)})
1026			}
1027		}
1028	}
1029	for name, fn := range internalFuncs {
1030		if name[0] != '_' {
1031			for i, cnt := 0, fn.argcount; cnt > 0; i, cnt = i+1, cnt>>1 {
1032				if cnt&1 > 0 {
1033					xs = append(xs, &funcNameArity{name, i})
1034				}
1035			}
1036		}
1037	}
1038	for name, fn := range c.customFuncs {
1039		if name[0] != '_' {
1040			for i, cnt := 0, fn.argcount; cnt > 0; i, cnt = i+1, cnt>>1 {
1041				if cnt&1 > 0 {
1042					xs = append(xs, &funcNameArity{name, i})
1043				}
1044			}
1045		}
1046	}
1047	sort.Slice(xs, func(i, j int) bool {
1048		return xs[i].name < xs[j].name ||
1049			xs[i].name == xs[j].name && xs[i].arity < xs[j].arity
1050	})
1051	ys := make([]interface{}, len(xs))
1052	for i, x := range xs {
1053		ys[i] = x.name + "/" + strconv.Itoa(x.arity)
1054	}
1055	return ys
1056}
1057
1058func (c *compiler) funcScope(interface{}, []interface{}) interface{} {
1059	var xs []interface{}
1060	for _, fds := range builtinFuncDefs {
1061		xs = append(xs, fds[0].Name)
1062	}
1063	for name := range internalFuncs {
1064		xs = append(xs, name)
1065	}
1066	for name := range c.customFuncs {
1067		xs = append(xs, name)
1068	}
1069	if c.environLoader != nil {
1070		xs = append(xs, "$ENV")
1071	}
1072	for i := len(c.scopes) - 1; i >= 0; i-- {
1073		s := c.scopes[i]
1074		for j := len(s.variables) - 1; j >= 0; j-- {
1075			v := s.variables[j]
1076			xs = append(xs, v.name)
1077		}
1078		for j := len(s.funcs) - 1; j >= 0; j-- {
1079			f := s.funcs[j]
1080			xs = append(xs, f.name)
1081		}
1082	}
1083	sort.Slice(xs, func(i, j int) bool {
1084		return xs[i].(string) < xs[j].(string)
1085	})
1086	return xs
1087}
1088
1089func (c *compiler) funcInput(interface{}, []interface{}) interface{} {
1090	v, ok := c.inputIter.Next()
1091	if !ok {
1092		return errors.New("break")
1093	}
1094	return normalizeNumbers(v)
1095}
1096
1097func (c *compiler) funcModulemeta(v interface{}, _ []interface{}) interface{} {
1098	s, ok := v.(string)
1099	if !ok {
1100		return &funcTypeError{"modulemeta", v}
1101	}
1102	if c.moduleLoader == nil {
1103		return fmt.Errorf("cannot load module: %q", s)
1104	}
1105	var q *Query
1106	var err error
1107	if moduleLoader, ok := c.moduleLoader.(interface {
1108		LoadModuleWithMeta(string, map[string]interface{}) (*Query, error)
1109	}); ok {
1110		if q, err = moduleLoader.LoadModuleWithMeta(s, nil); err != nil {
1111			return err
1112		}
1113	} else if moduleLoader, ok := c.moduleLoader.(interface {
1114		LoadModule(string) (*Query, error)
1115	}); ok {
1116		if q, err = moduleLoader.LoadModule(s); err != nil {
1117			return err
1118		}
1119	}
1120	meta := q.Meta.ToValue()
1121	if meta == nil {
1122		meta = make(map[string]interface{})
1123	}
1124	var deps []interface{}
1125	for _, i := range q.Imports {
1126		v := i.Meta.ToValue()
1127		if v == nil {
1128			v = make(map[string]interface{})
1129		} else {
1130			for k := range v {
1131				// dirty hack to remove the internal fields
1132				if strings.HasPrefix(k, "$$") {
1133					delete(v, k)
1134				}
1135			}
1136		}
1137		if i.ImportPath == "" {
1138			v["relpath"] = i.IncludePath
1139		} else {
1140			v["relpath"] = i.ImportPath
1141		}
1142		if err != nil {
1143			return err
1144		}
1145		if i.ImportAlias != "" {
1146			v["as"] = strings.TrimPrefix(i.ImportAlias, "$")
1147		}
1148		v["is_data"] = strings.HasPrefix(i.ImportAlias, "$")
1149		deps = append(deps, v)
1150	}
1151	meta["deps"] = deps
1152	return meta
1153}
1154
1155func (c *compiler) compileObject(e *Object) error {
1156	c.appendCodeInfo(e)
1157	if len(e.KeyVals) == 0 {
1158		c.append(&code{op: opconst, v: map[string]interface{}{}})
1159		return nil
1160	}
1161	defer c.newScopeDepth()()
1162	v := c.newVariable()
1163	c.append(&code{op: opstore, v: v})
1164	pc := len(c.codes)
1165	for _, kv := range e.KeyVals {
1166		if err := c.compileObjectKeyVal(v, kv); err != nil {
1167			return err
1168		}
1169	}
1170	c.append(&code{op: opobject, v: len(e.KeyVals)})
1171	// optimize constant objects
1172	l := len(e.KeyVals)
1173	if pc+l*3+1 != len(c.codes) {
1174		return nil
1175	}
1176	for i := 0; i < l; i++ {
1177		if c.codes[pc+i*3].op != oppush ||
1178			c.codes[pc+i*3+1].op != opload ||
1179			c.codes[pc+i*3+2].op != opconst {
1180			return nil
1181		}
1182	}
1183	w := make(map[string]interface{}, l)
1184	for i := 0; i < l; i++ {
1185		w[c.codes[pc+i*3].v.(string)] = c.codes[pc+i*3+2].v
1186	}
1187	c.codes[pc-1] = &code{op: opconst, v: w}
1188	c.codes = c.codes[:pc]
1189	return nil
1190}
1191
1192func (c *compiler) compileObjectKeyVal(v [2]int, kv *ObjectKeyVal) error {
1193	if kv.KeyOnly != "" {
1194		if kv.KeyOnly[0] == '$' {
1195			c.append(&code{op: oppush, v: kv.KeyOnly[1:]})
1196			c.append(&code{op: opload, v: v})
1197			return c.compileFunc(&Func{Name: kv.KeyOnly})
1198		}
1199		c.append(&code{op: oppush, v: kv.KeyOnly})
1200		c.append(&code{op: opload, v: v})
1201		return c.compileIndex(&Term{Type: TermTypeIdentity}, &Index{Name: kv.KeyOnly})
1202	} else if kv.KeyOnlyString != nil {
1203		c.append(&code{op: opload, v: v})
1204		if err := c.compileString(kv.KeyOnlyString, nil); err != nil {
1205			return err
1206		}
1207		c.append(&code{op: opdup})
1208		c.append(&code{op: opload, v: v})
1209		c.append(&code{op: opload, v: v})
1210		// ref: compileCall
1211		c.append(&code{op: opcall, v: [3]interface{}{internalFuncs["_index"].callback, 2, "_index"}})
1212		return nil
1213	} else {
1214		if kv.KeyQuery != nil {
1215			c.append(&code{op: opload, v: v})
1216			f := c.newScopeDepth()
1217			if err := c.compileQuery(kv.KeyQuery); err != nil {
1218				return err
1219			}
1220			f()
1221		} else if kv.KeyString != nil {
1222			c.append(&code{op: opload, v: v})
1223			if err := c.compileString(kv.KeyString, nil); err != nil {
1224				return err
1225			}
1226			if d := c.codes[len(c.codes)-1]; d.op == opconst {
1227				c.codes[len(c.codes)-2] = &code{op: oppush, v: d.v}
1228				c.codes = c.codes[:len(c.codes)-1]
1229			}
1230		} else if kv.Key[0] == '$' {
1231			c.append(&code{op: opload, v: v})
1232			if err := c.compileFunc(&Func{Name: kv.Key}); err != nil {
1233				return err
1234			}
1235		} else {
1236			c.append(&code{op: oppush, v: kv.Key})
1237		}
1238		c.append(&code{op: opload, v: v})
1239		return c.compileObjectVal(kv.Val)
1240	}
1241}
1242
1243func (c *compiler) compileObjectVal(e *ObjectVal) error {
1244	for _, e := range e.Queries {
1245		if err := c.compileQuery(e); err != nil {
1246			return err
1247		}
1248	}
1249	return nil
1250}
1251
1252func (c *compiler) compileArray(e *Array) error {
1253	c.appendCodeInfo(e)
1254	if e.Query == nil {
1255		c.append(&code{op: opconst, v: []interface{}{}})
1256		return nil
1257	}
1258	c.append(&code{op: oppush, v: []interface{}{}})
1259	arr := c.newVariable()
1260	c.append(&code{op: opstore, v: arr})
1261	pc := len(c.codes)
1262	c.append(&code{op: opfork})
1263	defer func() {
1264		if pc < len(c.codes) {
1265			c.codes[pc].v = c.pc() - 2
1266		}
1267	}()
1268	defer c.newScopeDepth()()
1269	if err := c.compileQuery(e.Query); err != nil {
1270		return err
1271	}
1272	c.append(&code{op: opappend, v: arr})
1273	c.append(&code{op: opbacktrack})
1274	c.append(&code{op: oppop})
1275	c.append(&code{op: opload, v: arr})
1276	if e.Query.Op == OpPipe {
1277		return nil
1278	}
1279	// optimize constant arrays
1280	if (len(c.codes)-pc)%3 != 0 {
1281		return nil
1282	}
1283	l := (len(c.codes) - pc - 3) / 3
1284	for i := 0; i < l; i++ {
1285		if c.codes[pc+i].op != opfork ||
1286			c.codes[pc+i*2+l].op != opconst ||
1287			(i < l-1 && c.codes[pc+i*2+l+1].op != opjump) {
1288			return nil
1289		}
1290	}
1291	v := make([]interface{}, l)
1292	for i := 0; i < l; i++ {
1293		v[i] = c.codes[pc+i*2+l].v
1294	}
1295	c.codes[pc-2] = &code{op: opconst, v: v}
1296	c.codes = c.codes[:pc-1]
1297	return nil
1298}
1299
1300func (c *compiler) compileUnary(e *Unary) error {
1301	c.appendCodeInfo(e)
1302	if err := c.compileTerm(e.Term); err != nil {
1303		return err
1304	}
1305	switch e.Op {
1306	case OpAdd:
1307		return c.compileCall("_plus", nil)
1308	case OpSub:
1309		return c.compileCall("_negate", nil)
1310	case OpBnot:
1311		return c.compileCall("_bnot", nil)
1312	default:
1313		return fmt.Errorf("unexpected operator in Unary: %s", e.Op)
1314	}
1315}
1316
1317func (c *compiler) compileFormat(fmt string, str *String) error {
1318	f := formatToFunc(fmt)
1319	if f == nil {
1320		f = &Func{
1321			Name: "format",
1322			Args: []*Query{{Term: &Term{Type: TermTypeString, Str: &String{Str: fmt[1:]}}}},
1323		}
1324	}
1325	if str == nil {
1326		return c.compileFunc(f)
1327	}
1328	return c.compileString(str, f)
1329}
1330
1331func formatToFunc(fmt string) *Func {
1332	switch fmt {
1333	case "@text":
1334		return &Func{Name: "tostring"}
1335	case "@json":
1336		return &Func{Name: "tojson"}
1337	case "@html":
1338		return &Func{Name: "_tohtml"}
1339	case "@uri":
1340		return &Func{Name: "_touri"}
1341	case "@csv":
1342		return &Func{Name: "_tocsv"}
1343	case "@tsv":
1344		return &Func{Name: "_totsv"}
1345	case "@sh":
1346		return &Func{Name: "_tosh"}
1347	case "@base64":
1348		return &Func{Name: "_tobase64"}
1349	case "@base64d":
1350		return &Func{Name: "_tobase64d"}
1351	default:
1352		return nil
1353	}
1354}
1355
1356func (c *compiler) compileString(s *String, f *Func) error {
1357	if s.Queries == nil {
1358		c.append(&code{op: opconst, v: s.Str})
1359		return nil
1360	}
1361	if f == nil {
1362		f = &Func{Name: "tostring"}
1363	}
1364	var q *Query
1365	for _, e := range s.Queries {
1366		if e.Term.Str == nil {
1367			e = &Query{Left: e, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: f}}}
1368		}
1369		if q == nil {
1370			q = e
1371		} else {
1372			q = &Query{Left: q, Op: OpAdd, Right: e}
1373		}
1374	}
1375	return c.compileQuery(q)
1376}
1377
1378func (c *compiler) compileTermSuffix(e *Term, s *Suffix) error {
1379	if s.Index != nil {
1380		return c.compileIndex(e, s.Index)
1381	} else if s.Iter {
1382		if err := c.compileTerm(e); err != nil {
1383			return err
1384		}
1385		c.append(&code{op: opeach})
1386		return nil
1387	} else if s.Optional {
1388		if len(e.SuffixList) > 1 || len(e.SuffixList) == 1 && !e.SuffixList[0].Iter {
1389			if u, ok := e.SuffixList[len(e.SuffixList)-1].toTerm(); ok {
1390				t := *e // clone without changing e
1391				(&t).SuffixList = t.SuffixList[:len(e.SuffixList)-1]
1392				if err := c.compileTerm(&t); err != nil {
1393					return err
1394				}
1395				return c.compileTermSuffix(u, s)
1396			}
1397		}
1398		return c.compileTry(&Try{Body: &Query{Term: e}})
1399	} else if s.Bind != nil {
1400		c.append(&code{op: opdup})
1401		c.append(&code{op: opexpbegin})
1402		if err := c.compileTerm(e); err != nil {
1403			return err
1404		}
1405		return c.compileBind(s.Bind)
1406	} else {
1407		return fmt.Errorf("invalid suffix: %s", s)
1408	}
1409}
1410
1411func (c *compiler) compileCall(name string, args []*Query) error {
1412	fn := internalFuncs[name]
1413	if err := c.compileCallInternal(
1414		[3]interface{}{fn.callback, len(args), name},
1415		args,
1416		true,
1417		name == "_index" || name == "_slice",
1418	); err != nil {
1419		return err
1420	}
1421	if fn.iter {
1422		c.append(&code{op: opeach})
1423	}
1424	return nil
1425}
1426
1427func (c *compiler) compileCallPc(fn *funcinfo, args []*Query) error {
1428	return c.compileCallInternal(fn.pc, args, false, false)
1429}
1430
1431func (c *compiler) compileCallInternal(
1432	fn interface{}, args []*Query, internal, indexing bool) error {
1433	if len(args) == 0 {
1434		c.append(&code{op: opcall, v: fn})
1435		return nil
1436	}
1437	idx := c.newVariable()
1438	c.append(&code{op: opstore, v: idx})
1439	if indexing && len(args) > 1 {
1440		c.append(&code{op: opexpbegin})
1441	}
1442	for i := len(args) - 1; i >= 0; i-- {
1443		pc := c.pc() + 1 // skip opjump (ref: compileFuncDef)
1444		name := "lambda:" + strconv.Itoa(pc)
1445		if err := c.compileFuncDef(&FuncDef{Name: name, Body: args[i]}, false); err != nil {
1446			return err
1447		}
1448		if internal {
1449			switch c.pc() - pc {
1450			case 2: // optimize identity argument (opscope, opret)
1451				j := len(c.codes) - 3
1452				c.codes[j] = &code{op: opload, v: idx}
1453				c.codes = c.codes[:j+1]
1454				s := c.scopes[len(c.scopes)-1]
1455				s.funcs = s.funcs[:len(s.funcs)-1]
1456				c.deleteCodeInfo(name)
1457			case 3: // optimize one instruction argument (opscope, opX, opret)
1458				j := len(c.codes) - 4
1459				if c.codes[j+2].op == opconst {
1460					c.codes[j] = &code{op: oppush, v: c.codes[j+2].v}
1461					c.codes = c.codes[:j+1]
1462				} else {
1463					c.codes[j] = &code{op: opload, v: idx}
1464					c.codes[j+1] = c.codes[j+2]
1465					c.codes = c.codes[:j+2]
1466				}
1467				s := c.scopes[len(c.scopes)-1]
1468				s.funcs = s.funcs[:len(s.funcs)-1]
1469				c.deleteCodeInfo(name)
1470			default:
1471				c.append(&code{op: opload, v: idx})
1472				c.append(&code{op: oppushpc, v: pc})
1473				c.append(&code{op: opcallpc})
1474			}
1475		} else {
1476			c.append(&code{op: oppushpc, v: pc})
1477		}
1478		if indexing && i == 1 {
1479			if c.codes[len(c.codes)-2].op == opexpbegin {
1480				c.codes[len(c.codes)-2] = c.codes[len(c.codes)-1]
1481				c.codes = c.codes[:len(c.codes)-1]
1482			} else {
1483				c.append(&code{op: opexpend})
1484			}
1485		}
1486	}
1487	c.append(&code{op: opload, v: idx})
1488	c.append(&code{op: opcall, v: fn})
1489	return nil
1490}
1491
1492func (c *compiler) append(code *code) {
1493	c.codes = append(c.codes, code)
1494}
1495
1496func (c *compiler) pc() int {
1497	return len(c.codes)
1498}
1499
1500func (c *compiler) lazy(f func() *code) func() {
1501	i := len(c.codes)
1502	c.codes = append(c.codes, nil)
1503	return func() { c.codes[i] = f() }
1504}
1505
1506func (c *compiler) optimizeTailRec() {
1507	var pcs []int
1508	scopes := map[int]bool{}
1509L:
1510	for i, l := 0, len(c.codes); i < l; i++ {
1511		switch c.codes[i].op {
1512		case opscope:
1513			pcs = append(pcs, i)
1514			if v := c.codes[i].v.([3]int); v[2] == 0 {
1515				scopes[i] = v[1] == 0
1516			}
1517		case opcall:
1518			var canjump bool
1519			if j, ok := c.codes[i].v.(int); !ok ||
1520				len(pcs) == 0 || pcs[len(pcs)-1] != j {
1521				break
1522			} else if canjump, ok = scopes[j]; !ok {
1523				break
1524			}
1525			for j := i + 1; j < l; {
1526				switch c.codes[j].op {
1527				case opjump:
1528					j = c.codes[j].v.(int)
1529				case opret:
1530					if canjump {
1531						c.codes[i].op = opjump
1532						c.codes[i].v = pcs[len(pcs)-1] + 1
1533					} else {
1534						c.codes[i].op = opcallrec
1535					}
1536					continue L
1537				default:
1538					continue L
1539				}
1540			}
1541		case opret:
1542			if len(pcs) == 0 {
1543				break L
1544			}
1545			pcs = pcs[:len(pcs)-1]
1546		}
1547	}
1548}
1549
1550func (c *compiler) optimizeCodeOps() {
1551	for i, next := len(c.codes)-1, (*code)(nil); i >= 0; i-- {
1552		code := c.codes[i]
1553		switch code.op {
1554		case oppush, opdup, opload:
1555			switch next.op {
1556			case oppop:
1557				code.op = opnop
1558				next.op = opnop
1559			case opconst:
1560				code.op = opnop
1561				next.op = oppush
1562			}
1563		case opjump, opjumpifnot:
1564			if j := code.v.(int); j-1 == i {
1565				code.op = opnop
1566			} else if next = c.codes[j]; next.op == opjump {
1567				code.v = next.v
1568			}
1569		}
1570		next = code
1571	}
1572}
1573