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 { type Router struct {
selectors []string selectors []string
symbols map[string]string symbols map[string]string
navigable bool
} }
func NewRouter() Router { func NewRouter() Router {
return Router{ return Router{
symbols: make(map[string]string), 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 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 { func(r *Router) Next() []byte {
if len(r.selectors) == 0 { if len(r.selectors) == 0 {
return []byte{} return []byte{}
@ -67,14 +84,23 @@ func(r *Router) ToBytes() []byte {
func FromBytes(b []byte) Router { func FromBytes(b []byte) Router {
rb := NewRouter() rb := NewRouter()
navigable := true
for len(b) > 0 { for len(b) > 0 {
var k string
l := b[0] l := b[0]
k := b[1:1+l] if l == 0 {
navigable = false
} else {
k = string(b[1:1+l])
b = b[1+l:] b = b[1+l:]
}
l = b[0] l = b[0]
v := b[1:1+l] v := string(b[1:1+l])
if !navigable {
return NewStaticRouter(v)
}
b = b[1+l:] b = b[1+l:]
rb.Add(string(k), string(v)) rb.Add(k, v)
} }
return rb return rb
} }

View File

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

View File

@ -2,22 +2,30 @@ package vm
import ( import (
"encoding/binary" "encoding/binary"
"fmt"
"context" "context"
"fmt"
"log" "log"
"git.defalsify.org/festive/state"
"git.defalsify.org/festive/resource" "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) 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 var err error
st, instruction, err = Run(instruction, st, rs, ctx) st, instruction, err = Run(instruction, st, rs, ctx)
if err != nil { if err != nil {
return st, instruction, err 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 return st, instruction, nil
} }