1
0
mirror of https://github.com/danog/liquid.git synced 2024-11-27 09:24:38 +01:00
liquid/evaluator.go

89 lines
1.6 KiB
Go
Raw Normal View History

package main
2017-06-26 15:06:55 +02:00
import (
"fmt"
"reflect"
)
type Expression struct {
value func(Context) (interface{}, error)
}
func EvaluateExpr(expr string, ctx Context) (interface{}, error) {
lexer := newLexer([]byte(expr + ";"))
n := yyParse(lexer)
if n != 0 {
return nil, fmt.Errorf("parse error in %s", expr)
}
return lexer.val(ctx), nil
}
2017-06-26 15:06:55 +02:00
func GenericCompare(a, b reflect.Value) int {
if a.Interface() == b.Interface() {
return 0
}
ak, bk := a.Kind(), b.Kind()
// _ = ak.Convert
switch a.Kind() {
case reflect.Bool:
if b.Kind() == reflect.Bool {
switch {
case a.Bool() && b.Bool():
return 0
case a.Bool():
return 1
case b.Bool():
return -1
default:
return 0
}
}
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
if hasIntKind(b) {
if a.Int() < b.Int() {
return -1
}
if a.Int() > b.Int() {
return 1
}
return 0
}
if hasFloatKind(b) {
return GenericCompare(reflect.ValueOf(float64(a.Int())), b)
}
case reflect.Float32, reflect.Float64:
if hasIntKind(b) {
b = reflect.ValueOf(float64(b.Int()))
}
if hasFloatKind(b) {
if a.Float() < b.Float() {
return -1
}
if a.Float() > b.Float() {
return 1
}
return 0
}
}
panic(fmt.Errorf("unimplemented: comparison of %v<%s> with %v<%s>", a, ak, b, bk))
return 0
}
func hasIntKind(n reflect.Value) bool {
switch n.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return true
default:
return false
}
}
func hasFloatKind(n reflect.Value) bool {
switch n.Kind() {
case reflect.Float32, reflect.Float64:
return true
default:
return false
}
}