diff --git a/main.go b/main.go index 8b17c4e..65d99cf 100644 --- a/main.go +++ b/main.go @@ -19,14 +19,35 @@ type Preprocessor struct { // Evaluate the expression and return the value // it would print. -func (pp *Preprocessor) Eval(data string) (string, error) { +func (pp *Preprocessor) Eval(codes []string) ([]string, error) { const retHead = ` + __ret_one__ := "" printf := func(format, ...vals) { - __ret__ += __Sprintf(format, vals...) + __ret_one__ += sprintf(format, vals...) + } + + print := func(...vals) { + __ret_one__ += sprint(vals...) + } + + println := func(...vals) { + __ret_one__ += sprintln(vals...) } ` - script := tengo.NewScript([]byte(retHead + pp.head + "\n" + data)) - err := script.Add("__Sprintf", &tengo.UserFunction{ + + const retSeparator = ` + __Separate(__ret_one__) + __ret_one__ = "" + ` + rets := []string{} + + fullCode := retHead + "\n" + pp.head + for _, code := range codes { + fullCode += "\n" + code + retSeparator + "\n" + } + script := tengo.NewScript([]byte(fullCode)) + script.SetImports(pp.modules) + err := script.Add("sprintf", &tengo.UserFunction{ Value: func(args ...tengo.Object) (tengo.Object, error){ if len(args) < 1 { return nil, tengo.ErrWrongNumArguments @@ -48,28 +69,71 @@ func (pp *Preprocessor) Eval(data string) (string, error) { }, ) if err != nil { - return "", err + return nil, err } - err = script.Add("__ret__", "") - if err != nil{ - return "", err - } - compiled, err := script.RunContext(context.Background()) + err = script.Add("sprint", &tengo.UserFunction{ + Value: func(args ...tengo.Object) (tengo.Object, error){ + gargs := make([]any, len(args)) + for i := range gargs { + gargs[i] = tengo.ToInterface(args[i]) + } + str := fmt.Sprint(gargs...) + return tengo.FromInterface(str) + }, + }, + ) if err != nil { - return "", err + return nil, err + } + err = script.Add("sprintln", &tengo.UserFunction{ + Value: func(args ...tengo.Object) (tengo.Object, error){ + gargs := make([]any, len(args)) + for i := range gargs { + gargs[i] = tengo.ToInterface(args[i]) + } + str := fmt.Sprintln(gargs...) + return tengo.FromInterface(str) + }, + }, + ) + if err != nil { + return nil, err + } + err = script.Add("__Separate", &tengo.UserFunction{ + Value: func(args ...tengo.Object) (tengo.Object, error){ + if len(args) < 1 { + return nil, tengo.ErrWrongNumArguments + } + str, ok := tengo.ToString(args[0]) + if !ok { + return nil, tengo.ErrInvalidArgumentType{ + } + } + rets = append(rets, str) + return nil, nil + }, + }, + ) + if err != nil { + return nil, err } - return compiled.Get("__ret__").String(), nil + _, err = script.RunContext(context.Background()) + if err != nil { + return nil, err + } + + return rets, nil } // Get the new preprocessor with default options. func NewPp() *Preprocessor { pp := &Preprocessor{ tags: [2]string{ - "", }, - modules: stdlib.GetModuleMap(stdlib.AllModuleNames()...) + modules: stdlib.GetModuleMap(stdlib.AllModuleNames()...), } return pp } @@ -77,6 +141,8 @@ func NewPp() *Preprocessor { func (pp *Preprocessor) Process(data string) (string, error) { var b strings.Builder last := 0 + texts := []string{} + codes := []string{} for { idxStart := strings.Index(data[last:], pp.tags[0]) idxEnd := strings.Index(data[last:], pp.tags[1]) @@ -87,22 +153,34 @@ func (pp *Preprocessor) Process(data string) (string, error) { What: "end tag", } } - fmt.Fprint(&b, data[last:]) + texts = append(texts, data[last:]) break } else if idxEnd < 0 { return "", UnexpectedError{ What: "start tag", } } - fmt.Fprint(&b, data[last:idxStart]) + text := data[last:idxStart] + texts = append(texts, text) + code := data[idxStart+len(pp.tags[0]):idxEnd] - str, err := pp.Eval(code) - if err != nil { - return "", err - } - fmt.Fprint(&b, str) - data = data[idxEnd + len(pp.tags[1])+1:] + codes = append(codes, code) + + data = data[idxEnd + len(pp.tags[1]):] + /*if len(data) > 0 && data[0] == '\n' { + data = data[1:] + }*/ } + codeRets, err := pp.Eval(codes) + if err != nil { + return "", err + } + + for i, codeRet := range codeRets { + fmt.Fprint(&b, texts[i]) + fmt.Fprintf(&b, codeRet) + } + fmt.Fprint(&b, texts[len(codeRets)]) return b.String(), nil } diff --git a/tests/index.md.pp b/tests/index.md.pp index 8126fd1..c1694a2 100644 --- a/tests/index.md.pp +++ b/tests/index.md.pp @@ -1,11 +1,9 @@ -# The index testing - 1 + 1 = +# The index testing + 1 + 1 = + cock + ## The shit after -checking - +checking