1
0
mirror of https://github.com/MontFerret/ferret.git synced 2024-12-16 11:37:36 +02:00
ferret/pkg/compiler/compiler.go

81 lines
1.4 KiB
Go
Raw Normal View History

2018-09-18 22:42:38 +02:00
package compiler
import (
"github.com/MontFerret/ferret/pkg/parser"
"github.com/MontFerret/ferret/pkg/runtime"
"github.com/MontFerret/ferret/pkg/runtime/core"
"github.com/MontFerret/ferret/pkg/stdlib"
"github.com/pkg/errors"
)
type FqlCompiler struct {
*NamespaceContainer
2018-09-18 22:42:38 +02:00
}
2018-09-19 03:41:16 +02:00
func New(setters ...Option) *FqlCompiler {
c := &FqlCompiler{}
c.NamespaceContainer = newRootNamespace()
c.funcs = make(map[string]core.Function)
2018-09-19 03:41:16 +02:00
opts := &Options{}
for _, setter := range setters {
setter(opts)
}
if !opts.noStdlib {
if err := stdlib.RegisterLib(c.NamespaceContainer); err != nil {
panic(err)
2018-09-19 03:41:16 +02:00
}
}
2018-09-18 22:42:38 +02:00
return c
}
2018-09-18 22:42:38 +02:00
func (c *FqlCompiler) Compile(query string) (program *runtime.Program, err error) {
if query == "" {
return nil, ErrEmptyQuery
}
defer func() {
if r := recover(); r != nil {
// find out exactly what the error was and set err
switch x := r.(type) {
case string:
err = errors.New(x)
case error:
err = x
default:
err = errors.New("unknown panic")
}
program = nil
}
}()
2018-11-05 18:45:33 +02:00
p := parser.New(query)
p.AddErrorListener(&errorListener{})
2018-09-28 06:28:33 +02:00
l := newVisitor(query, c.funcs)
2018-09-18 22:42:38 +02:00
res := p.Visit(l).(*result)
if res.Ok() {
program = res.Data().(*runtime.Program)
} else {
err = res.Error()
}
return program, err
}
2018-09-28 04:10:17 +02:00
func (c *FqlCompiler) MustCompile(query string) *runtime.Program {
program, err := c.Compile(query)
if err != nil {
panic(err)
}
return program
}