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
|
module git.defalsify.org/festive
|
||||||
|
|
||||||
go 1.20
|
go 1.20
|
||||||
|
|
||||||
|
require github.com/peteole/testdata-loader v0.3.0
|
||||||
|
@ -2,6 +2,10 @@ package resource
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"path"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FsResource struct {
|
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
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func(fs *FsResource) Render(sym string, values []string) (string, error) {
|
func(fs FsResource) GetCode(sym string) ([]byte, error) {
|
||||||
return "", nil
|
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.
|
// Resource implementation are responsible for retrieving values and templates for symbols, and can render templates from value dictionaries.
|
||||||
type Resource interface {
|
type Resource interface {
|
||||||
Get(sym string) (string, error)
|
GetTemplate(sym string) (string, error) // Get the template for a given symbol.
|
||||||
Render(sym string, values map[string]string) (string, error)
|
GetCode(sym string) ([]byte, error) // Get the bytecode for the given symbol.
|
||||||
FuncFor(sym string) (EntryFunc, error)
|
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
|
CacheUseSize uint32 // Currently used bytes by all values in cache
|
||||||
Cache []map[string]string // All loaded cache items
|
Cache []map[string]string // All loaded cache items
|
||||||
CacheMap map[string]string // Mapped
|
CacheMap map[string]string // Mapped
|
||||||
|
Code []byte // Pending bytecode to execute
|
||||||
execPath []string // Command symbols stack
|
execPath []string // Command symbols stack
|
||||||
arg *string // Optional argument. Nil if not set.
|
arg *string // Optional argument. Nil if not set.
|
||||||
sizes map[string]uint16 // Size limits for all loaded symbols.
|
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 {
|
if err != nil {
|
||||||
return st, instruction, err
|
return st, instruction, err
|
||||||
}
|
}
|
||||||
// TODO: perhaps check against the registered byte size
|
|
||||||
//l := st.FlagByteSize()
|
|
||||||
bitFieldSize := tail[0]
|
bitFieldSize := tail[0]
|
||||||
bitField := tail[1:1+bitFieldSize]
|
bitField := tail[1:1+bitFieldSize]
|
||||||
tail = tail[1+bitFieldSize:]
|
tail = tail[1+bitFieldSize:]
|
||||||
if st.GetIndex(bitField) {
|
if st.GetIndex(bitField) {
|
||||||
log.Printf("catch at flag %v, moving to %v", bitField, head)
|
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)
|
st.Down(head)
|
||||||
tail = []byte{}
|
tail = []byte{}
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ func (r *TestResource) getEachArg(ctx context.Context) (string, error) {
|
|||||||
return r.state.PopArg()
|
return r.state.PopArg()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *TestResource) Get(sym string) (string, error) {
|
func (r *TestResource) GetTemplate(sym string) (string, error) {
|
||||||
switch sym {
|
switch sym {
|
||||||
case "foo":
|
case "foo":
|
||||||
return "inky pinky blinky clyde", nil
|
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)
|
return "", fmt.Errorf("unknown symbol %s", sym)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *TestResource) Render(sym string, values map[string]string) (string, error) {
|
func (r *TestResource) RenderTemplate(sym string, values map[string]string) (string, error) {
|
||||||
v, err := r.Get(sym)
|
v, err := r.GetTemplate(sym)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -87,6 +87,10 @@ func (r *TestResource) FuncFor(sym string) (resource.EntryFunc, error) {
|
|||||||
return nil, fmt.Errorf("invalid function: '%s'", sym)
|
return nil, fmt.Errorf("invalid function: '%s'", sym)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *TestResource) GetCode(sym string) ([]byte, error) {
|
||||||
|
return []byte{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func TestRun(t *testing.T) {
|
func TestRun(t *testing.T) {
|
||||||
st := state.NewState(5)
|
st := state.NewState(5)
|
||||||
rs := TestResource{}
|
rs := TestResource{}
|
||||||
@ -121,7 +125,7 @@ func TestRunLoadRender(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
r, err := rs.Render("foo", m)
|
r, err := rs.RenderTemplate("foo", m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
@ -130,7 +134,7 @@ func TestRunLoadRender(t *testing.T) {
|
|||||||
t.Errorf("Expected %v, got %v", []byte(expect), []byte(r))
|
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 {
|
if err == nil {
|
||||||
t.Errorf("expected error for render of bar: %v" ,err)
|
t.Errorf("expected error for render of bar: %v" ,err)
|
||||||
}
|
}
|
||||||
@ -146,7 +150,7 @@ func TestRunLoadRender(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
r, err = rs.Render("bar", m)
|
r, err = rs.RenderTemplate("bar", m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
@ -280,7 +284,7 @@ func TestRunArgInstructions(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
r, err := rs.Render(loc, m)
|
r, err := rs.RenderTemplate(loc, m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user