1
0
mirror of https://github.com/danog/liquid.git synced 2025-01-23 08:01:15 +01:00

If tag parses during parse stage

This commit is contained in:
Oliver Steele 2017-06-28 22:22:07 -04:00
parent 5dddabeb78
commit 621992c6af

View File

@ -44,17 +44,17 @@ func caseTagParser(node chunks.ASTControlTag) (func(io.Writer, chunks.Context) e
if err != nil { if err != nil {
return nil, err return nil, err
} }
type branchRec struct { type caseRec struct {
fn func(chunks.Context) (interface{}, error) fn func(chunks.Context) (interface{}, error)
node *chunks.ASTControlTag node *chunks.ASTControlTag
} }
cases := []branchRec{} cases := []caseRec{}
for _, branch := range node.Branches { for _, branch := range node.Branches {
bfn, err := chunks.MakeExpressionValueFn(branch.Args) bfn, err := chunks.MakeExpressionValueFn(branch.Args)
if err != nil { if err != nil {
return nil, err return nil, err
} }
cases = append(cases, branchRec{bfn, branch}) cases = append(cases, caseRec{bfn, branch})
} }
return func(w io.Writer, ctx chunks.Context) error { return func(w io.Writer, ctx chunks.Context) error {
value, err := expr(ctx) value, err := expr(ctx)
@ -74,39 +74,57 @@ func caseTagParser(node chunks.ASTControlTag) (func(io.Writer, chunks.Context) e
}, nil }, nil
} }
func constTrueExpr(_ chunks.Context) (interface{}, error) { return true, nil }
func negateExpr(f func(chunks.Context) (interface{}, error)) func(chunks.Context) (interface{}, error) {
return func(ctx chunks.Context) (interface{}, error) {
value, err := f(ctx)
if err != nil {
return nil, err
}
return value == nil || value == false, nil
}
}
func ifTagParser(polarity bool) func(chunks.ASTControlTag) (func(io.Writer, chunks.Context) error, error) { func ifTagParser(polarity bool) func(chunks.ASTControlTag) (func(io.Writer, chunks.Context) error, error) {
// TODO parse error if the order of branches is other than ifelse*else?
// TODO parse the tests into a table evaluator -> []AST
return func(node chunks.ASTControlTag) (func(io.Writer, chunks.Context) error, error) { return func(node chunks.ASTControlTag) (func(io.Writer, chunks.Context) error, error) {
type branchRec struct {
test func(chunks.Context) (interface{}, error)
body []chunks.ASTNode
}
expr, err := chunks.MakeExpressionValueFn(node.Args) expr, err := chunks.MakeExpressionValueFn(node.Args)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return func(w io.Writer, ctx chunks.Context) error {
val, err := expr(ctx)
if err != nil {
return err
}
if !polarity { if !polarity {
val = (val == nil || val == false) expr = negateExpr(expr)
}
branches := []branchRec{
{expr, node.Body},
} }
switch val {
default:
return ctx.RenderASTSequence(w, node.Body)
case nil, false:
for _, c := range node.Branches { for _, c := range node.Branches {
test := constTrueExpr
switch c.Tag { switch c.Tag {
case "else": case "else":
val = true // TODO parse error if this isn't the last branch
case "elsif": case "elsif":
val, err = ctx.EvaluateExpr(c.Args) t, err := chunks.MakeExpressionValueFn(c.Args)
if err != nil {
return nil, err
}
test = t
default:
}
branches = append(branches, branchRec{test, c.Body})
}
return func(w io.Writer, ctx chunks.Context) error {
for _, b := range branches {
value, err := b.test(ctx)
if err != nil { if err != nil {
return err return err
} }
} if value != nil && value != false {
if val != nil && val != false { return ctx.RenderASTSequence(w, b.body)
return ctx.RenderASTSequence(w, c.Body)
}
} }
} }
return nil return nil