Add default router for non-selector inputs

This commit is contained in:
lash 2023-03-31 18:04:11 +01:00
parent f6e1d2bacc
commit 5a300944c8
Signed by untrusted user who does not match committer: lash
GPG Key ID: 21D2E7BB88C2A746
3 changed files with 50 additions and 7 deletions

View File

@ -7,11 +7,20 @@ import (
type Router struct {
selectors []string
symbols map[string]string
navigable bool
}
func NewRouter() Router {
return Router{
symbols: make(map[string]string),
navigable: true,
}
}
func NewStaticRouter(symbol string) Router {
return Router{
symbols: map[string]string{"_": symbol},
navigable: false,
}
}
@ -32,6 +41,14 @@ func(r *Router) Add(selector string, symbol string) error {
return nil
}
func(r *Router) Get(selector string) string {
return r.symbols[selector]
}
func(r *Router) Default() string {
return r.symbols["_"]
}
func(r *Router) Next() []byte {
if len(r.selectors) == 0 {
return []byte{}
@ -67,14 +84,23 @@ func(r *Router) ToBytes() []byte {
func FromBytes(b []byte) Router {
rb := NewRouter()
navigable := true
for len(b) > 0 {
var k string
l := b[0]
k := b[1:1+l]
if l == 0 {
navigable = false
} else {
k = string(b[1:1+l])
b = b[1+l:]
}
l = b[0]
v := b[1:1+l]
v := string(b[1:1+l])
if !navigable {
return NewStaticRouter(v)
}
b = b[1+l:]
rb.Add(string(k), string(v))
rb.Add(k, v)
}
return rb
}

View File

@ -12,6 +12,7 @@ type State struct {
Cache []map[string]string
CacheMap map[string]string
ExecPath []string
Arg *string
Idx uint16
}
@ -38,6 +39,14 @@ func(st State) WithCacheSize(cacheSize uint32) State {
return st
}
func(st *State) PutArg(input string) {
st.Arg = &input
}
func(st *State) PopArg() string {
return *st.Arg
}
func(st *State) Down(input string) {
m := make(map[string]string)
st.Cache = append(st.Cache, m)

View File

@ -2,22 +2,30 @@ package vm
import (
"encoding/binary"
"fmt"
"context"
"fmt"
"log"
"git.defalsify.org/festive/state"
"git.defalsify.org/festive/resource"
"git.defalsify.org/festive/router"
"git.defalsify.org/festive/state"
)
type Runner func(instruction []byte, st state.State, rs resource.Fetcher, ctx context.Context) (state.State, []byte, error)
func Apply(instruction []byte, st state.State, rs resource.Fetcher, ctx context.Context) (state.State, []byte, error) {
func Apply(input []byte, instruction []byte, st state.State, rs resource.Fetcher, ctx context.Context) (state.State, []byte, error) {
var err error
st, instruction, err = Run(instruction, st, rs, ctx)
if err != nil {
return st, instruction, err
}
rt := router.FromBytes(instruction)
sym := rt.Get(string(input))
if sym == "" {
sym = rt.Default()
st.PutArg(string(input))
}
return st, instruction, nil
}