Have a buffer for the fragments too, so we can add an optimisation pass.

This commit is contained in:
Azareal 2018-11-18 17:14:18 +10:00
parent 21b2c54166
commit 5a459ba780
1 changed files with 61 additions and 17 deletions

View File

@ -2,6 +2,7 @@ package tmpl
import ( import (
"bytes" "bytes"
"errors"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log" "log"
@ -43,6 +44,57 @@ type CTemplateConfig struct {
type OutBufferFrame struct { type OutBufferFrame struct {
Body string Body string
Type string Type string
TemplateName string
}
type CContext struct {
VarHolder string
HoldReflect reflect.Value
TemplateName string
OutBuf *[]OutBufferFrame
}
func (con *CContext) Push(nType string, body string) {
*con.OutBuf = append(*con.OutBuf, OutBufferFrame{body, nType, con.TemplateName})
}
func (con *CContext) GetLastType() string {
outBuf := *con.OutBuf
if len(outBuf) == 0 {
return ""
}
return outBuf[len(outBuf)-1].Type
}
func (con *CContext) GetLastBody() string {
outBuf := *con.OutBuf
if len(outBuf) == 0 {
return ""
}
return outBuf[len(outBuf)-1].Body
}
func (con *CContext) SetLastBody(newBody string) error {
outBuf := *con.OutBuf
if len(outBuf) == 0 {
return errors.New("outbuf is empty")
}
outBuf[len(outBuf)-1].Body = newBody
return nil
}
func (con *CContext) GetLastTemplate() string {
outBuf := *con.OutBuf
if len(outBuf) == 0 {
return ""
}
return outBuf[len(outBuf)-1].TemplateName
}
type Fragment struct {
Body string
TemplateName string
Index int
} }
// nolint // nolint
@ -55,6 +107,7 @@ type CTemplateSet struct {
Fragments map[string]int Fragments map[string]int
fragmentCursor map[string]int fragmentCursor map[string]int
FragOut string FragOut string
fragBuf []Fragment
varList map[string]VarItem varList map[string]VarItem
localVars map[string]map[string]VarItemReflect localVars map[string]map[string]VarItemReflect
hasDispInt bool hasDispInt bool
@ -244,9 +297,11 @@ func (c *CTemplateSet) Compile(name string, fileDir string, expects string, expe
fout = strings.Replace(fout, `)) fout = strings.Replace(fout, `))
w.Write([]byte(`, " + ", -1) w.Write([]byte(`, " + ", -1)
fout = strings.Replace(fout, "` + `", "", -1) fout = strings.Replace(fout, "` + `", "", -1)
//spstr := "`([:space:]*)`"
//whitespaceWrites := regexp.MustCompile(`(?s)w.Write\(\[\]byte\(`+spstr+`\)\)`) for _, frag := range c.fragBuf {
//fout = whitespaceWrites.ReplaceAllString(fout,"") fragmentPrefix := frag.TemplateName + "_frags[" + strconv.Itoa(frag.Index) + "]"
c.FragOut += fragmentPrefix + " = []byte(`" + frag.Body + "`)\n"
}
if c.config.Debug { if c.config.Debug {
for index, count := range c.stats { for index, count := range c.stats {
@ -259,17 +314,6 @@ w.Write([]byte(`, " + ", -1)
return fout, nil return fout, nil
} }
type CContext struct {
VarHolder string
HoldReflect reflect.Value
TemplateName string
OutBuf *[]OutBufferFrame
}
func (con *CContext) Push(nType string, body string) {
*con.OutBuf = append(*con.OutBuf, OutBufferFrame{body, nType})
}
func (c *CTemplateSet) rootIterate(tree *parse.Tree, con CContext) { func (c *CTemplateSet) rootIterate(tree *parse.Tree, con CContext) {
c.detail(tree.Root) c.detail(tree.Root)
treeLength := len(tree.Root.Nodes) treeLength := len(tree.Root.Nodes)
@ -345,7 +389,7 @@ func (c *CTemplateSet) compileSwitch(con CContext, node parse.Node) {
_, ok := c.Fragments[fragmentName] _, ok := c.Fragments[fragmentName]
if !ok { if !ok {
c.Fragments[fragmentName] = len(node.Text) c.Fragments[fragmentName] = len(node.Text)
c.FragOut += fragmentPrefix + " = []byte(`" + string(node.Text) + "`)\n" c.fragBuf = append(c.fragBuf, Fragment{string(node.Text), con.TemplateName, c.fragmentCursor[con.TemplateName]})
} }
c.fragmentCursor[con.TemplateName] = c.fragmentCursor[con.TemplateName] + 1 c.fragmentCursor[con.TemplateName] = c.fragmentCursor[con.TemplateName] + 1
con.Push("text", "w.Write("+fragmentPrefix+")\n") con.Push("text", "w.Write("+fragmentPrefix+")\n")