feat: added way to print binary values.

This commit is contained in:
Andrey Parhomenko 2024-04-26 01:27:45 +05:00
parent 34b6f06901
commit 898c27134e
5 changed files with 39 additions and 32 deletions

BIN
cat.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

View file

@ -43,13 +43,6 @@ func (tengo *Tengo) SetPreCompile(fn func(*Script)) *Tengo {
return tengo return tengo
} }
func (pp *Tengo) Tags() [2]string {
return [2]string{
"{{",
"}}",
}
}
// Simple Evaler implementation for the Tengo language // Simple Evaler implementation for the Tengo language
func (pp *Tengo) Eval( func (pp *Tengo) Eval(
ctx context.Context, ctx context.Context,
@ -59,22 +52,27 @@ func (pp *Tengo) Eval(
) ([][]byte, error) { ) ([][]byte, error) {
var fullCodeBuf bytes.Buffer var fullCodeBuf bytes.Buffer
const retHead = ` const retHead = `
__ret_one__ := "" __ret_one__ := bytes("")
printf := func(format, ...vals) { pp := {
__ret_one__ += sprintf(format, vals...) printf : func(format, ...vals) {
__ret_one__ += __sprintf__(format, vals...)
},
print : func(...vals) {
__ret_one__ += __sprint__(vals...)
},
println : func(...vals) {
__ret_one__ += __sprintln__(vals...)
},
write_raw : func(bts) {
__ret_one__ += bytes(bts)
}
} }
print := func(...vals) {
__ret_one__ += sprint(vals...)
}
println := func(...vals) {
__ret_one__ += sprintln(vals...)
}
` `
const retSeparator = ` const retSeparator = `
__separate(__ret_one__) __separate__(__ret_one__)
__ret_one__ = "" __ret_one__ = ""
` `
rets := [][]byte{} rets := [][]byte{}
@ -96,7 +94,7 @@ func (pp *Tengo) Eval(
pp.preCompile(script) pp.preCompile(script)
} }
err := script.Add("sprintf", &tengo.UserFunction{ err := script.Add("__sprintf__", &tengo.UserFunction{
Value: func(args ...tengo.Object) (tengo.Object, error){ Value: func(args ...tengo.Object) (tengo.Object, error){
if len(args) < 1 { if len(args) < 1 {
return nil, tengo.ErrWrongNumArguments return nil, tengo.ErrWrongNumArguments
@ -113,52 +111,52 @@ func (pp *Tengo) Eval(
//fmt.Printf("shit: %q\n", gargs[i]) //fmt.Printf("shit: %q\n", gargs[i])
} }
str := fmt.Sprintf(format, gargs...) str := fmt.Sprintf(format, gargs...)
return tengo.FromInterface(str) return tengo.FromInterface([]byte(str))
}, },
}, },
) )
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = script.Add("sprint", &tengo.UserFunction{ err = script.Add("__sprint__", &tengo.UserFunction{
Value: func(args ...tengo.Object) (tengo.Object, error){ Value: func(args ...tengo.Object) (tengo.Object, error){
gargs := make([]any, len(args)) gargs := make([]any, len(args))
for i := range gargs { for i := range gargs {
gargs[i] = tengo.ToInterface(args[i]) gargs[i] = tengo.ToInterface(args[i])
} }
str := fmt.Sprint(gargs...) str := fmt.Sprint(gargs...)
return tengo.FromInterface(str) return tengo.FromInterface([]byte(str))
}, },
}, },
) )
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = script.Add("sprintln", &tengo.UserFunction{ err = script.Add("__sprintln__", &tengo.UserFunction{
Value: func(args ...tengo.Object) (tengo.Object, error){ Value: func(args ...tengo.Object) (tengo.Object, error){
gargs := make([]any, len(args)) gargs := make([]any, len(args))
for i := range gargs { for i := range gargs {
gargs[i] = tengo.ToInterface(args[i]) gargs[i] = tengo.ToInterface(args[i])
} }
str := fmt.Sprintln(gargs...) str := fmt.Sprintln(gargs...)
return tengo.FromInterface(str) return tengo.FromInterface([]byte(str))
}, },
}, },
) )
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = script.Add("__separate", &tengo.UserFunction{ err = script.Add("__separate__", &tengo.UserFunction{
Value: func(args ...tengo.Object) (tengo.Object, error){ Value: func(args ...tengo.Object) (tengo.Object, error){
if len(args) < 1 { if len(args) < 1 {
return nil, tengo.ErrWrongNumArguments return nil, tengo.ErrWrongNumArguments
} }
str, ok := tengo.ToByteSlice(args[0]) bts, ok := tengo.ToByteSlice(args[0])
if !ok { if !ok {
return nil, tengo.ErrInvalidArgumentType{ return nil, tengo.ErrInvalidArgumentType{
} }
} }
rets = append(rets, str) rets = append(rets, bts)
return nil, nil return nil, nil
}, },
}, },

9
tests/cat.jpg.tpp Normal file
View file

@ -0,0 +1,9 @@
{{
// The example shows the way to write
// binary files
// so it makes possible to make templates
// for them or for dynamic content.
os := import("os")
bts := os.read_file("tests/cat.webp")
pp.write_raw(bts)
}}

BIN
tests/cat.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

View file

@ -2,19 +2,19 @@
os := import("os") os := import("os")
shit := import("./tests/shit.tengo") shit := import("./tests/shit.tengo")
newVar := "'this is gen shita'" newVar := "'this is gen shita'"
println(shit.some_func()) pp.println(shit.some_func())
}}# The index testing }}# The index testing
1 + 1 = {{ print(1+1) }} 1 + 1 = {{ pp.print(1+1) }}
cock {{ print(newVar, "and cock") }} cock {{ pp.print(newVar, "and cock") }}
## The shit after ## The shit after
checking {{ printf(newVar) }} checking {{ pp.printf(newVar) }}
## File contents ## File contents
{{ {{
bts := os.read_file("tests/somefile") bts := os.read_file("tests/somefile")
printf("%v\n%s", bts, bts) pp.printf("%v\n%s", bts, bts)
}} }}