Initial commit
This commit is contained in:
25
go/resource/fs.go
Normal file
25
go/resource/fs.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package resource
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
type FsResource struct {
|
||||
path string
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
func NewFsResource(path string, ctx context.Context) (FsResource) {
|
||||
return FsResource{
|
||||
path: path,
|
||||
ctx: ctx,
|
||||
}
|
||||
}
|
||||
|
||||
func(fs *FsResource) Get(sym string) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func(fs *FsResource) Render(sym string, values []string) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
11
go/resource/fs_test.go
Normal file
11
go/resource/fs_test.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package resource
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNewFs(t *testing.T) {
|
||||
n := NewFsResource("./testdata", context.TODO())
|
||||
_ = n
|
||||
}
|
||||
7
go/resource/resource.go
Normal file
7
go/resource/resource.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package resource
|
||||
|
||||
|
||||
type Fetcher interface {
|
||||
Get(symbol string) (string, error)
|
||||
Render(symbol string, values map[string]string) (string, error)
|
||||
}
|
||||
36
go/state/state.go
Normal file
36
go/state/state.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package state
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
type State struct {
|
||||
Flags []byte
|
||||
OutputSize uint16
|
||||
CacheSize uint32
|
||||
CacheUseSize uint32
|
||||
Cache io.ReadWriteSeeker
|
||||
}
|
||||
|
||||
func NewState(bitSize uint64, outputSize uint16) State {
|
||||
if bitSize == 0 {
|
||||
panic("bitsize cannot be 0")
|
||||
}
|
||||
n := bitSize % 8
|
||||
if n > 0 {
|
||||
bitSize += (8 - n)
|
||||
}
|
||||
|
||||
return State{
|
||||
Flags: make([]byte, bitSize / 8),
|
||||
OutputSize: outputSize,
|
||||
CacheSize: 0,
|
||||
CacheUseSize: 0,
|
||||
Cache: nil,
|
||||
}
|
||||
}
|
||||
|
||||
func(st State) WithCacheSize(cacheSize uint32) State {
|
||||
st.CacheSize = cacheSize
|
||||
return st
|
||||
}
|
||||
33
go/state/state_test.go
Normal file
33
go/state/state_test.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package state
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNewStateFlags(t *testing.T) {
|
||||
st := NewState(5, 0)
|
||||
if len(st.Flags) != 1 {
|
||||
t.Errorf("invalid state flag length: %v", len(st.Flags))
|
||||
}
|
||||
st = NewState(8, 0)
|
||||
if len(st.Flags) != 1 {
|
||||
t.Errorf("invalid state flag length: %v", len(st.Flags))
|
||||
}
|
||||
st = NewState(17, 0)
|
||||
if len(st.Flags) != 3 {
|
||||
t.Errorf("invalid state flag length: %v", len(st.Flags))
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewStateCache(t *testing.T) {
|
||||
st := NewState(17, 0)
|
||||
if st.CacheSize != 0 {
|
||||
t.Errorf("cache size not 0")
|
||||
}
|
||||
st = st.WithCacheSize(102525)
|
||||
if st.CacheSize != 102525 {
|
||||
t.Errorf("cache size not 102525")
|
||||
}
|
||||
|
||||
}
|
||||
11
go/vm/opcodes.go
Normal file
11
go/vm/opcodes.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package vm
|
||||
|
||||
const VERSION = 0
|
||||
|
||||
const (
|
||||
CATCH = iota
|
||||
CROAK
|
||||
LOAD
|
||||
RELOAD
|
||||
_MAX
|
||||
)
|
||||
50
go/vm/vm.go
Normal file
50
go/vm/vm.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package vm
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"context"
|
||||
|
||||
"git.defalsify.org/festive/state"
|
||||
"git.defalsify.org/festive/resource"
|
||||
)
|
||||
|
||||
type Runner func(instruction []byte, st state.State, rs resource.Fetcher, ctx context.Context) (state.State, error)
|
||||
|
||||
func Run(instruction []byte, st state.State, rs resource.Fetcher, ctx context.Context) (state.State, error) {
|
||||
op := binary.BigEndian.Uint16(instruction[:2])
|
||||
if op > _MAX {
|
||||
return st, fmt.Errorf("opcode value %v out of range (%v)", op, _MAX)
|
||||
}
|
||||
switch op {
|
||||
case CATCH:
|
||||
RunCatch(instruction[2:], st, rs, ctx)
|
||||
case CROAK:
|
||||
RunCroak(instruction[2:], st, rs, ctx)
|
||||
case LOAD:
|
||||
RunLoad(instruction[2:], st, rs, ctx)
|
||||
case RELOAD:
|
||||
RunReload(instruction[2:], st, rs, ctx)
|
||||
default:
|
||||
err := fmt.Errorf("Unhandled state: %v", op)
|
||||
return st, err
|
||||
}
|
||||
return st, nil
|
||||
}
|
||||
|
||||
func RunCatch(instruction []byte, st state.State, rs resource.Fetcher, ctx context.Context) (state.State, error) {
|
||||
return st, nil
|
||||
}
|
||||
|
||||
|
||||
func RunCroak(instruction []byte, st state.State, rs resource.Fetcher, ctx context.Context) (state.State, error) {
|
||||
return st, nil
|
||||
}
|
||||
|
||||
func RunLoad(instruction []byte, st state.State, rs resource.Fetcher, ctx context.Context) (state.State, error) {
|
||||
return st, nil
|
||||
}
|
||||
|
||||
func RunReload(instruction []byte, st state.State, rs resource.Fetcher, ctx context.Context) (state.State, error) {
|
||||
return st, nil
|
||||
}
|
||||
44
go/vm/vm_test.go
Normal file
44
go/vm/vm_test.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package vm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"git.defalsify.org/festive/state"
|
||||
)
|
||||
|
||||
type TestResource struct {
|
||||
}
|
||||
|
||||
func (r *TestResource) Get(sym string) (string, error) {
|
||||
switch sym {
|
||||
case "foo":
|
||||
return "inky pinky blinky clyde", nil
|
||||
case "bar":
|
||||
return "inky pinky {.one} blinky {.two} clyde", nil
|
||||
}
|
||||
return "", fmt.Errorf("unknown symbol %s", sym)
|
||||
}
|
||||
|
||||
func (r *TestResource) Render(sym string, values map[string]string) (string, error) {
|
||||
v, err := r.Get(sym)
|
||||
return v, err
|
||||
}
|
||||
|
||||
func TestRun(t *testing.T) {
|
||||
st := state.NewState(5, 255)
|
||||
rs := TestResource{}
|
||||
b := []byte{0x00, 0x02}
|
||||
r, err := Run(b, st, &rs, context.TODO())
|
||||
if err != nil {
|
||||
t.Errorf("error on valid opcode: %v", err)
|
||||
}
|
||||
|
||||
b = []byte{0x01, 0x02}
|
||||
r, err = Run(b, st, &rs, context.TODO())
|
||||
if err == nil {
|
||||
t.Errorf("no error on invalid opcode")
|
||||
}
|
||||
_ = r
|
||||
}
|
||||
Reference in New Issue
Block a user