Add engine object
This commit is contained in:
parent
832228ba11
commit
39eafc8ff2
48
go/engine/engine.go
Normal file
48
go/engine/engine.go
Normal file
@ -0,0 +1,48 @@
|
||||
package engine
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"log"
|
||||
|
||||
"git.defalsify.org/festive/resource"
|
||||
"git.defalsify.org/festive/state"
|
||||
"git.defalsify.org/festive/vm"
|
||||
)
|
||||
//
|
||||
//type Config struct {
|
||||
// FlagCount uint32
|
||||
// CacheSize uint32
|
||||
//}
|
||||
|
||||
type Engine struct {
|
||||
st state.State
|
||||
rs resource.Resource
|
||||
}
|
||||
|
||||
func NewEngine(st state.State, rs resource.Resource) Engine {
|
||||
engine := Engine{st, rs}
|
||||
return engine
|
||||
}
|
||||
|
||||
func(en *Engine) Init(ctx context.Context) error {
|
||||
b := vm.NewLine([]byte{}, vm.MOVE, []string{"root"}, nil, nil)
|
||||
var err error
|
||||
en.st, _, err = vm.Run(b, en.st, en.rs, ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
func(en *Engine) WriteResult(w io.Writer) error {
|
||||
location := en.st.Where()
|
||||
v, err := en.st.Get()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r, err := en.rs.RenderTemplate(location, v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c, err := io.WriteString(w, r)
|
||||
log.Printf("%v bytes written as result for %v", c, location)
|
||||
return err
|
||||
}
|
81
go/engine/engine_test.go
Normal file
81
go/engine/engine_test.go
Normal file
@ -0,0 +1,81 @@
|
||||
package engine
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"log"
|
||||
"path"
|
||||
"text/template"
|
||||
"testing"
|
||||
|
||||
testdataloader "github.com/peteole/testdata-loader"
|
||||
|
||||
"git.defalsify.org/festive/state"
|
||||
"git.defalsify.org/festive/resource"
|
||||
)
|
||||
|
||||
type FsWrapper struct {
|
||||
*resource.FsResource
|
||||
st state.State
|
||||
}
|
||||
|
||||
func NewFsWrapper(path string, st state.State, ctx context.Context) FsWrapper {
|
||||
rs := resource.NewFsResource(path, ctx)
|
||||
return FsWrapper {
|
||||
&rs,
|
||||
st,
|
||||
}
|
||||
}
|
||||
|
||||
func (r FsWrapper) RenderTemplate(sym string, values map[string]string) (string, error) {
|
||||
v, err := r.GetTemplate(sym)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
tp, err := template.New("tester").Option("missingkey=error").Parse(v)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
b := bytes.NewBuffer([]byte{})
|
||||
err = tp.Execute(b, values)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
log.Printf("template is %v render is %v", v, b)
|
||||
return b.String(), err
|
||||
}
|
||||
|
||||
func(fs FsWrapper) FuncFor(sym string) (resource.EntryFunc, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func TestEngineInit(t *testing.T) {
|
||||
// cfg := Config{
|
||||
// FlagCount: 12,
|
||||
// CacheSize: 1024,
|
||||
// }
|
||||
st := state.NewState(17).WithCacheSize(1024)
|
||||
// dir, err := ioutil.TempDir("", "festive_test_")
|
||||
// if err != nil {
|
||||
// t.Fatal(err)
|
||||
// }
|
||||
dir := path.Join(testdataloader.GetBasePath(), "testdata")
|
||||
ctx := context.TODO()
|
||||
rs := NewFsWrapper(dir, st, ctx)
|
||||
en := NewEngine(st, rs)
|
||||
err := en.Init(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
w := bytes.NewBuffer(nil)
|
||||
err = en.WriteResult(w)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
b := w.Bytes()
|
||||
if !bytes.Equal(b, []byte("hello world")) {
|
||||
t.Fatalf("expected result 'hello world', got %v", b)
|
||||
}
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
module git.defalsify.org/festive
|
||||
|
||||
go 1.20
|
||||
|
||||
require github.com/peteole/testdata-loader v0.3.0
|
||||
|
@ -2,6 +2,10 @@ package resource
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type FsResource struct {
|
||||
@ -16,10 +20,21 @@ func NewFsResource(path string, ctx context.Context) (FsResource) {
|
||||
}
|
||||
}
|
||||
|
||||
func(fs *FsResource) Get(sym string) (string, error) {
|
||||
func(fs FsResource) GetTemplate(sym string) (string, error) {
|
||||
fp := path.Join(fs.path, sym)
|
||||
r, err := ioutil.ReadFile(fp)
|
||||
s := string(r)
|
||||
return strings.TrimSpace(s), err
|
||||
}
|
||||
|
||||
func(fs FsResource) RenderTemplate(sym string, values map[string]string) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func(fs *FsResource) Render(sym string, values []string) (string, error) {
|
||||
return "", nil
|
||||
func(fs FsResource) GetCode(sym string) ([]byte, error) {
|
||||
return []byte{}, nil
|
||||
}
|
||||
|
||||
func(fs FsResource) FuncFor(sym string) (EntryFunc, error) {
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
|
@ -9,7 +9,8 @@ type EntryFunc func(ctx context.Context) (string, error)
|
||||
|
||||
// Resource implementation are responsible for retrieving values and templates for symbols, and can render templates from value dictionaries.
|
||||
type Resource interface {
|
||||
Get(sym string) (string, error)
|
||||
Render(sym string, values map[string]string) (string, error)
|
||||
FuncFor(sym string) (EntryFunc, error)
|
||||
GetTemplate(sym string) (string, error) // Get the template for a given symbol.
|
||||
GetCode(sym string) ([]byte, error) // Get the bytecode for the given symbol.
|
||||
RenderTemplate(sym string, values map[string]string) (string, error) // Render the given data map using the template of the symbol.
|
||||
FuncFor(sym string) (EntryFunc, error) // Resolve symbol code point for.
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ type State struct {
|
||||
CacheUseSize uint32 // Currently used bytes by all values in cache
|
||||
Cache []map[string]string // All loaded cache items
|
||||
CacheMap map[string]string // Mapped
|
||||
Code []byte // Pending bytecode to execute
|
||||
execPath []string // Command symbols stack
|
||||
arg *string // Optional argument. Nil if not set.
|
||||
sizes map[string]uint16 // Size limits for all loaded symbols.
|
||||
|
1
go/testdata/root
vendored
Normal file
1
go/testdata/root
vendored
Normal file
@ -0,0 +1 @@
|
||||
hello world
|
@ -120,18 +120,11 @@ func RunCatch(instruction []byte, st state.State, rs resource.Resource, ctx cont
|
||||
if err != nil {
|
||||
return st, instruction, err
|
||||
}
|
||||
// TODO: perhaps check against the registered byte size
|
||||
//l := st.FlagByteSize()
|
||||
bitFieldSize := tail[0]
|
||||
bitField := tail[1:1+bitFieldSize]
|
||||
tail = tail[1+bitFieldSize:]
|
||||
if st.GetIndex(bitField) {
|
||||
log.Printf("catch at flag %v, moving to %v", bitField, head)
|
||||
// r, err := rs.Get(head)
|
||||
// if err != nil {
|
||||
// return st, instruction, err
|
||||
// }
|
||||
//st.Add(head, r, 0)
|
||||
st.Down(head)
|
||||
tail = []byte{}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ func (r *TestResource) getEachArg(ctx context.Context) (string, error) {
|
||||
return r.state.PopArg()
|
||||
}
|
||||
|
||||
func (r *TestResource) Get(sym string) (string, error) {
|
||||
func (r *TestResource) GetTemplate(sym string) (string, error) {
|
||||
switch sym {
|
||||
case "foo":
|
||||
return "inky pinky blinky clyde", nil
|
||||
@ -55,8 +55,8 @@ func (r *TestResource) Get(sym string) (string, error) {
|
||||
return "", fmt.Errorf("unknown symbol %s", sym)
|
||||
}
|
||||
|
||||
func (r *TestResource) Render(sym string, values map[string]string) (string, error) {
|
||||
v, err := r.Get(sym)
|
||||
func (r *TestResource) RenderTemplate(sym string, values map[string]string) (string, error) {
|
||||
v, err := r.GetTemplate(sym)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@ -87,6 +87,10 @@ func (r *TestResource) FuncFor(sym string) (resource.EntryFunc, error) {
|
||||
return nil, fmt.Errorf("invalid function: '%s'", sym)
|
||||
}
|
||||
|
||||
func (r *TestResource) GetCode(sym string) ([]byte, error) {
|
||||
return []byte{}, nil
|
||||
}
|
||||
|
||||
func TestRun(t *testing.T) {
|
||||
st := state.NewState(5)
|
||||
rs := TestResource{}
|
||||
@ -121,7 +125,7 @@ func TestRunLoadRender(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
r, err := rs.Render("foo", m)
|
||||
r, err := rs.RenderTemplate("foo", m)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@ -130,7 +134,7 @@ func TestRunLoadRender(t *testing.T) {
|
||||
t.Errorf("Expected %v, got %v", []byte(expect), []byte(r))
|
||||
}
|
||||
|
||||
r, err = rs.Render("bar", m)
|
||||
r, err = rs.RenderTemplate("bar", m)
|
||||
if err == nil {
|
||||
t.Errorf("expected error for render of bar: %v" ,err)
|
||||
}
|
||||
@ -146,7 +150,7 @@ func TestRunLoadRender(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
r, err = rs.Render("bar", m)
|
||||
r, err = rs.RenderTemplate("bar", m)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@ -280,7 +284,7 @@ func TestRunArgInstructions(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
r, err := rs.Render(loc, m)
|
||||
r, err := rs.RenderTemplate(loc, m)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user