values read themselves

types
Jordan Orelli 8 years ago
parent 4a0872f3ff
commit b5e5280913

@ -20,7 +20,7 @@ func arrayType(spec *typeSpec, env *Env) tÿpe {
elemSpec := *spec elemSpec := *spec
elemSpec.typeName = elemName elemSpec.typeName = elemName
elemType := parseTypeSpec(&elemSpec, env) elemType := parseTypeSpec(&elemSpec, env)
return array_t{elemType, count} return &array_t{elemType, count}
} }
func parseArrayName(s string) (string, int) { func parseArrayName(s string) (string, int) {
@ -49,18 +49,28 @@ type array_t struct {
count int count int
} }
func (t *array_t) nü() value { return array{t: t, slots: make([]value, t.count)} }
func (t array_t) typeName() string { return fmt.Sprintf("array:%s", t.elem.typeName()) } func (t array_t) typeName() string { return fmt.Sprintf("array:%s", t.elem.typeName()) }
func (t array_t) read(r bit.Reader) (value, error) { type array struct {
var err error t *array_t
v := make(array, t.count) slots []value
for i := range v { }
v[i], err = t.elem.read(r)
if err != nil { func (a array) tÿpe() tÿpe { return a.t }
return nil, wrap(err, "array read error at index %d", i)
func (a array) read(r bit.Reader) error {
for i := range a.slots {
if a.slots[i] == nil {
a.slots[i] = a.t.elem.nü()
}
if err := a.slots[i].read(r); err != nil {
return wrap(err, "array read error at index %d", i)
} }
} }
return v, r.Err() return r.Err()
} }
type array []value func (a array) String() string {
return fmt.Sprintf("%s%v", a.t.typeName(), a.slots)
}

@ -1,73 +1,252 @@
package ent package ent
import ( import (
"fmt"
"github.com/jordanorelli/hyperstone/bit" "github.com/jordanorelli/hyperstone/bit"
"strconv"
) )
var atom_types = []typeLiteral{ // ------------------------------------------------------------------------------
{ // bool
"bool", // ------------------------------------------------------------------------------
func(r bit.Reader) (value, error) {
return bit.ReadBool(r), r.Err() var bool_t = &typeLiteral{
}, name: "bool",
}, newFn: func() value {
{ return new(bool_v)
"uint8",
func(r bit.Reader) (value, error) {
// TODO: bounds check here
return uint8(bit.ReadVarInt(r)), r.Err()
},
},
{
"uint16",
func(r bit.Reader) (value, error) {
// TODO: bounds check here
return uint16(bit.ReadVarInt(r)), r.Err()
},
},
{
"uint32",
func(r bit.Reader) (value, error) {
return bit.ReadVarInt32(r), r.Err()
},
}, },
{ }
"uint64",
func(r bit.Reader) (value, error) { type bool_v bool
return bit.ReadVarInt(r), r.Err()
func (v bool_v) tÿpe() tÿpe { return bool_t }
func (v *bool_v) read(r bit.Reader) error {
*v = bool_v(bit.ReadBool(r))
return r.Err()
}
func (v bool_v) String() string {
if v {
return "true"
}
return "false"
}
// ------------------------------------------------------------------------------
// uint8
// ------------------------------------------------------------------------------
var uint8_t = &typeLiteral{
name: "uint8",
newFn: func() value {
return new(uint8_v)
}, },
}
type uint8_v uint8
func (v uint8_v) tÿpe() tÿpe { return uint8_t }
func (v *uint8_v) read(r bit.Reader) error {
u := bit.ReadVarInt(r)
if u > 1<<8-1 {
return fmt.Errorf("uint8 overflow: %d", u)
}
*v = uint8_v(u)
return r.Err()
}
func (v uint8_v) String() string {
return strconv.FormatUint(uint64(v), 10)
}
// ------------------------------------------------------------------------------
// uint16
// ------------------------------------------------------------------------------
var uint16_t = &typeLiteral{
name: "uint16",
newFn: func() value {
return new(uint16_v)
}, },
{ }
"int8",
func(r bit.Reader) (value, error) { type uint16_v uint16
// TODO: bounds check here
return int8(bit.ReadZigZag32(r)), r.Err() func (v uint16_v) tÿpe() tÿpe { return uint16_t }
func (v *uint16_v) read(r bit.Reader) error {
u := bit.ReadVarInt(r)
if u > 1<<16-1 {
return fmt.Errorf("uint16 overflow: %d", u)
}
*v = uint16_v(u)
return r.Err()
}
func (v uint16_v) String() string {
return strconv.FormatUint(uint64(v), 10)
}
// ------------------------------------------------------------------------------
// uint32
// ------------------------------------------------------------------------------
var uint32_t = &typeLiteral{
name: "uint32",
newFn: func() value {
return new(uint32_v)
}, },
}
type uint32_v uint32
func (v uint32_v) tÿpe() tÿpe { return uint32_t }
func (v *uint32_v) read(r bit.Reader) error {
u := bit.ReadVarInt(r)
if u > 1<<32-1 {
return fmt.Errorf("uint32 overflow: %d", u)
}
*v = uint32_v(u)
return r.Err()
}
func (v uint32_v) String() string {
return strconv.FormatUint(uint64(v), 0)
}
// ------------------------------------------------------------------------------
// uint64
// ------------------------------------------------------------------------------
var uint64_t = &typeLiteral{
name: "uint64",
newFn: func() value {
return new(uint64_v)
}, },
{ }
"int32",
func(r bit.Reader) (value, error) { type uint64_v uint64
return bit.ReadZigZag32(r), r.Err()
func (v uint64_v) tÿpe() tÿpe { return uint64_t }
func (v *uint64_v) read(r bit.Reader) error {
*v = uint64_v(bit.ReadVarInt(r))
return r.Err()
}
func (v uint64_v) String() string {
return strconv.FormatUint(uint64(v), 10)
}
// ------------------------------------------------------------------------------
// int8
// ------------------------------------------------------------------------------
var int8_t = &typeLiteral{
name: "int8",
newFn: func() value {
return new(int8_v)
}, },
}
type int8_v int8
func (v int8_v) tÿpe() tÿpe { return int8_t }
func (v *int8_v) read(r bit.Reader) error {
// TODO: bounds check here?
*v = int8_v(bit.ReadZigZag32(r))
return r.Err()
}
func (v int8_v) String() string {
return strconv.FormatInt(int64(v), 10)
}
// ------------------------------------------------------------------------------
// int32
// ------------------------------------------------------------------------------
var int32_t = &typeLiteral{
name: "int32",
newFn: func() value {
return new(int32_v)
}, },
{ }
"CUtlStringToken",
func(r bit.Reader) (value, error) { type int32_v int32
return bit.ReadVarInt(r), r.Err()
func (v int32_v) tÿpe() tÿpe { return int32_t }
func (v *int32_v) read(r bit.Reader) error {
*v = int32_v(bit.ReadZigZag32(r))
return r.Err()
}
func (v int32_v) String() string {
return strconv.FormatInt(int64(v), 10)
}
// ------------------------------------------------------------------------------
// CUtlStringToken
//
// weirdly, this type isn't a string; it's actually a number. The number
// presumably indicates some value on a symbol table.
// ------------------------------------------------------------------------------
var stringToken_t = &typeLiteral{
name: "CUtlStringToken",
newFn: func() value {
return new(stringToken_v)
}, },
}
type stringToken_v uint64
func (v stringToken_v) tÿpe() tÿpe { return stringToken_t }
func (v *stringToken_v) read(r bit.Reader) error {
*v = stringToken_v(bit.ReadVarInt(r))
return r.Err()
}
func (v stringToken_v) String() string {
return fmt.Sprintf("token:%d", v)
}
// ------------------------------------------------------------------------------
// Color
// ------------------------------------------------------------------------------
var color_t = &typeLiteral{
name: "Color",
newFn: func() value {
return new(color)
}, },
{ }
"Color",
func(r bit.Reader) (value, error) { type color struct{ r, g, b, a uint8 }
func (c color) tÿpe() tÿpe { return color_t }
func (c *color) read(r bit.Reader) error {
u := bit.ReadVarInt(r) u := bit.ReadVarInt(r)
return color{ c.r = uint8(u >> 6 & 0xff)
r: uint8(u >> 6 & 0xff), c.g = uint8(u >> 4 & 0xff)
g: uint8(u >> 4 & 0xff), c.b = uint8(u >> 2 & 0xff)
b: uint8(u >> 2 & 0xff), c.a = uint8(u >> 0 & 0xff)
a: uint8(u >> 0 & 0xff), return r.Err()
}, r.Err() }
},
}, func (c color) String() string {
return fmt.Sprintf("#%x%x%x%x", c.r, c.g, c.b, c.a)
}
var atom_types = []tÿpe{
bool_t,
uint8_t,
uint16_t,
uint32_t,
uint64_t,
int8_t,
int32_t,
stringToken_t,
color_t,
} }
func atomType(spec *typeSpec, env *Env) tÿpe { func atomType(spec *typeSpec, env *Env) tÿpe {
@ -79,5 +258,3 @@ func atomType(spec *typeSpec, env *Env) tÿpe {
} }
return nil return nil
} }
type color struct{ r, g, b, a uint8 }

@ -24,8 +24,8 @@ func (c *class) read(r bit.Reader) (value, error) {
return c.nü(), nil return c.nü(), nil
} }
func (c *class) nü() entity { func (c *class) nü() value {
return entity{class: c, slots: make([]value, len(c.fields))} return &entity{class: c, slots: make([]value, len(c.fields))}
} }
type classHistory struct { type classHistory struct {

@ -1,6 +1,7 @@
package ent package ent
import ( import (
"fmt"
"github.com/jordanorelli/hyperstone/bit" "github.com/jordanorelli/hyperstone/bit"
) )
@ -31,6 +32,12 @@ func (e *entity) className() string {
return "<None>" return "<None>"
} }
func (e *entity) String() string {
return fmt.Sprintf("%s{%v}", e.class.typeName(), e.slots)
}
func (e *entity) tÿpe() tÿpe { return e.class }
func (e *entity) slotType(i int) tÿpe { return e.class.fields[i].tÿpe } func (e *entity) slotType(i int) tÿpe { return e.class.fields[i].tÿpe }
func (e *entity) slotName(i int) string { return e.class.fields[i].name }
func (e *entity) setSlotValue(i int, v value) { e.slots[i] = v } func (e *entity) setSlotValue(i int, v value) { e.slots[i] = v }
func (e *entity) getSlotValue(i int) value { return e.slots[i] } func (e *entity) getSlotValue(i int) value { return e.slots[i] }

@ -2,6 +2,7 @@ package ent
import ( import (
"math" "math"
"strconv"
"github.com/jordanorelli/hyperstone/bit" "github.com/jordanorelli/hyperstone/bit"
) )
@ -23,12 +24,7 @@ func floatType(spec *typeSpec, env *Env) tÿpe {
} }
if spec.encoder == "coord" { if spec.encoder == "coord" {
Debug.Printf(" coord float type") Debug.Printf(" coord float type")
return typeLiteral{ return coord_t
"float:coord",
func(r bit.Reader) (value, error) {
return bit.ReadCoord(r), r.Err()
},
}
} }
if spec.serializer == "simulationtime" { if spec.serializer == "simulationtime" {
return nil return nil
@ -36,18 +32,50 @@ func floatType(spec *typeSpec, env *Env) tÿpe {
switch spec.bits { switch spec.bits {
case 0, 32: case 0, 32:
Debug.Printf(" std float type") Debug.Printf(" std float type")
return typeLiteral{ return float_t
"float:std",
func(r bit.Reader) (value, error) {
// TODO: check uint32 overflow here?
return math.Float32frombits(uint32(r.ReadBits(32))), r.Err()
},
}
default: default:
return qFloatType(spec, env) return qFloatType(spec, env)
} }
} }
var coord_t = &typeLiteral{
name: "coord",
newFn: func() value {
return new(coord_v)
},
}
type coord_v float32
func (v coord_v) tÿpe() tÿpe { return coord_t }
func (v *coord_v) read(r bit.Reader) error {
*v = coord_v(bit.ReadCoord(r))
return r.Err()
}
func (v coord_v) String() string {
return strconv.FormatFloat(float64(v), 'f', 3, 32)
}
var float_t = &typeLiteral{
name: "float",
newFn: func() value {
return new(float_v)
},
}
type float_v float32
func (v float_v) tÿpe() tÿpe { return float_t }
func (v *float_v) read(r bit.Reader) error {
*v = float_v(math.Float32frombits(uint32(r.ReadBits(32))))
return r.Err()
}
func (v float_v) String() string {
return strconv.FormatFloat(float64(v), 'f', 3, 32)
}
func qFloatType(spec *typeSpec, env *Env) tÿpe { func qFloatType(spec *typeSpec, env *Env) tÿpe {
if spec.bits < 0 { if spec.bits < 0 {
return typeError("quantized float has invalid negative bit count specifier") return typeError("quantized float has invalid negative bit count specifier")
@ -56,7 +84,7 @@ func qFloatType(spec *typeSpec, env *Env) tÿpe {
return typeError("quantized float has invalid negative range") return typeError("quantized float has invalid negative range")
} }
t := qfloat_t{typeSpec: *spec} t := &qfloat_t{typeSpec: *spec}
t.span = t.high - t.low t.span = t.high - t.low
t.intervals = uint(1<<t.bits - 1) t.intervals = uint(1<<t.bits - 1)
t.interval = t.span / float32(t.intervals) t.interval = t.span / float32(t.intervals)
@ -87,11 +115,24 @@ type qfloat_t struct {
special *float32 special *float32
} }
func (t *qfloat_t) nü() value { return &qfloat_v{t: t} }
func (t qfloat_t) typeName() string { return "qfloat" } func (t qfloat_t) typeName() string { return "qfloat" }
func (t qfloat_t) read(r bit.Reader) (value, error) { type qfloat_v struct {
if t.special != nil && bit.ReadBool(r) { t *qfloat_t
return *t.special, nil v float32
}
func (v qfloat_v) tÿpe() tÿpe { return v.t }
func (v *qfloat_v) read(r bit.Reader) error {
if v.t.special != nil && bit.ReadBool(r) {
v.v = *v.t.special
} else {
v.v = v.t.low + float32(r.ReadBits(v.t.bits))*v.t.interval
} }
return t.low + float32(r.ReadBits(t.bits))*t.interval, r.Err() return r.Err()
}
func (v qfloat_v) String() string {
return strconv.FormatFloat(float64(v.v), 'f', 3, 32)
} }

@ -24,14 +24,10 @@ func genericType(spec *typeSpec, env *Env) tÿpe {
switch genericName { switch genericName {
case "CHandle", "CStrongHandle": case "CHandle", "CStrongHandle":
return typeLiteral{ t := handle_t(spec.typeName)
fmt.Sprintf("handle:%s", genericName), return &t
func(r bit.Reader) (value, error) {
return handle(bit.ReadVarInt(r)), r.Err()
},
}
case "CUtlVector": case "CUtlVector":
return cutl_vector_t{elem} return &cutl_vector_t{elem}
default: default:
return typeError("unknown generic name: %v", parts[0]) return typeError("unknown generic name: %v", parts[0])
} }
@ -75,11 +71,27 @@ type cutl_vector_t struct {
elem tÿpe elem tÿpe
} }
func (t *cutl_vector_t) nü() value {
return &cutl_vector{t: t}
}
func (t cutl_vector_t) typeName() string { func (t cutl_vector_t) typeName() string {
return fmt.Sprintf("vector:%s", t.elem.typeName()) return fmt.Sprintf("vector:%s", t.elem.typeName())
} }
func (t cutl_vector_t) read(r bit.Reader) (value, error) { type cutl_vector struct {
t tÿpe
slots []value
}
func (v *cutl_vector) tÿpe() tÿpe { return v.t }
func (v *cutl_vector) read(r bit.Reader) error {
count := bit.ReadVarInt32(r) count := bit.ReadVarInt32(r)
return make(array, count), r.Err() v.slots = make([]value, count)
return r.Err()
}
func (v cutl_vector) String() string {
return fmt.Sprintf("%s<%v>", v.t.typeName(), v.slots)
} }

@ -1,12 +1,32 @@
package ent package ent
import ( import (
"fmt"
"github.com/jordanorelli/hyperstone/bit" "github.com/jordanorelli/hyperstone/bit"
) )
type handle_t string
func (t handle_t) typeName() string { return string(t) }
func (t *handle_t) nü() value { return &handle{t: t} }
// a handle represents a soft pointer to an entity. handles are represented by // a handle represents a soft pointer to an entity. handles are represented by
// IDs and can cross the client-server divide. // IDs and can cross the client-server divide.
type handle int type handle struct {
t tÿpe
id uint64
}
func (h handle) tÿpe() tÿpe { return h.t }
func (h *handle) read(r bit.Reader) error {
h.id = bit.ReadVarInt(r)
return r.Err()
}
func (h handle) String() string {
return fmt.Sprintf("handle<%s>: %d", h.t.typeName(), h.id)
}
func handleType(spec *typeSpec, env *Env) tÿpe { func handleType(spec *typeSpec, env *Env) tÿpe {
if spec.typeName != "CGameSceneNodeHandle" { if spec.typeName != "CGameSceneNodeHandle" {
@ -14,10 +34,6 @@ func handleType(spec *typeSpec, env *Env) tÿpe {
} }
Debug.Printf(" handle type") Debug.Printf(" handle type")
return typeLiteral{ t := handle_t(spec.typeName)
"handle:CGameSceneNodeHandle", return &t
func(r bit.Reader) (value, error) {
return handle(bit.ReadVarInt(r)), r.Err()
},
}
} }

@ -1,19 +1,34 @@
package ent package ent
import ( import (
"fmt"
"github.com/jordanorelli/hyperstone/bit" "github.com/jordanorelli/hyperstone/bit"
) )
var hseq_t = &typeLiteral{
name: "HSequence",
newFn: func() value {
return new(hseq_v)
},
}
type hseq_v uint64
func (v hseq_v) tÿpe() tÿpe { return hseq_t }
func (v *hseq_v) read(r bit.Reader) error {
*v = hseq_v(bit.ReadVarInt(r) - 1)
return r.Err()
}
func (v hseq_v) String() string {
return fmt.Sprintf("hseq:%d", uint64(v))
}
func hSeqType(spec *typeSpec, env *Env) tÿpe { func hSeqType(spec *typeSpec, env *Env) tÿpe {
if spec.typeName != "HSequence" { if spec.typeName != "HSequence" {
return nil return nil
} }
Debug.Printf(" hsequence type") Debug.Printf(" hsequence type")
return typeLiteral{ return hseq_t
"HSequence",
func(r bit.Reader) (value, error) {
return bit.ReadVarInt(r) - 1, r.Err()
},
}
} }

@ -1,12 +1,40 @@
package ent package ent
import ( import (
"github.com/jordanorelli/hyperstone/bit" "fmt"
"math" "math"
"github.com/jordanorelli/hyperstone/bit"
) )
var qangle_t = &typeLiteral{
name: "qangle",
newFn: func() value {
return new(qangle)
},
}
type qangle struct{ pitch, yaw, roll float32 } type qangle struct{ pitch, yaw, roll float32 }
func (q qangle) tÿpe() tÿpe { return qangle_t }
func (q *qangle) read(r bit.Reader) error {
pitch, yaw, roll := bit.ReadBool(r), bit.ReadBool(r), bit.ReadBool(r)
if pitch {
q.pitch = bit.ReadCoord(r)
}
if yaw {
q.yaw = bit.ReadCoord(r)
}
if roll {
q.roll = bit.ReadCoord(r)
}
return r.Err()
}
func (q qangle) String() string {
return fmt.Sprintf("qangle{%f %f %f}", q.pitch, q.yaw, q.roll)
}
func qAngleType(spec *typeSpec, env *Env) tÿpe { func qAngleType(spec *typeSpec, env *Env) tÿpe {
if spec.typeName != "QAngle" { if spec.typeName != "QAngle" {
return nil return nil
@ -16,31 +44,16 @@ func qAngleType(spec *typeSpec, env *Env) tÿpe {
case spec.bits <= 0 || spec.bits > 32: case spec.bits <= 0 || spec.bits > 32:
return typeError("qangle pitch_yaw has invalid bit size: %d", spec.bits) return typeError("qangle pitch_yaw has invalid bit size: %d", spec.bits)
case spec.bits == 32: case spec.bits == 32:
return typeLiteral{"qangle:pitchYaw", pitchYaw_t} return pitchYaw_t
default: default:
return pitchYawAngles_t(spec.bits) t := pitchYawAngles_t(spec.bits)
return &t
} }
} }
switch spec.bits { switch spec.bits {
case 0: case 0:
Debug.Printf(" qangle type") Debug.Printf(" qangle type")
return typeLiteral{ return qangle_t
"qangle",
func(r bit.Reader) (value, error) {
var q qangle
pitch, yaw, roll := bit.ReadBool(r), bit.ReadBool(r), bit.ReadBool(r)
if pitch {
q.pitch = bit.ReadCoord(r)
}
if yaw {
q.yaw = bit.ReadCoord(r)
}
if roll {
q.roll = bit.ReadCoord(r)
}
return q, nil
},
}
case 32: case 32:
return nil return nil
default: default:
@ -48,20 +61,45 @@ func qAngleType(spec *typeSpec, env *Env) tÿpe {
} }
} }
func pitchYaw_t(r bit.Reader) (value, error) { var pitchYaw_t = &typeLiteral{
var q qangle name: "qangle:pitchYaw",
q.pitch = math.Float32frombits(uint32(r.ReadBits(32))) newFn: func() value {
q.yaw = math.Float32frombits(uint32(r.ReadBits(32))) return new(pitchYaw_v)
return q, r.Err() },
}
type pitchYaw_v qangle
func (v pitchYaw_v) tÿpe() tÿpe { return pitchYaw_t }
func (v *pitchYaw_v) read(r bit.Reader) error {
v.pitch = math.Float32frombits(uint32(r.ReadBits(32)))
v.yaw = math.Float32frombits(uint32(r.ReadBits(32)))
return r.Err()
}
func (v pitchYaw_v) String() string {
return fmt.Sprintf("qangle:pitchYaw{%f %f}", v.pitch, v.yaw)
} }
type pitchYawAngles_t uint type pitchYawAngles_t uint
func (t pitchYawAngles_t) typeName() string { return "qangle:pitchYawAngles" } func (t pitchYawAngles_t) typeName() string { return "qangle:pitchYawAngles" }
func (t *pitchYawAngles_t) nü() value {
return &pitchYawAngles_v{t: t}
}
type pitchYawAngles_v struct {
t *pitchYawAngles_t
qangle
}
func (v pitchYawAngles_v) tÿpe() tÿpe { return v.t }
func (v *pitchYawAngles_v) read(r bit.Reader) error {
v.pitch = bit.ReadAngle(r, uint(*v.t))
v.yaw = bit.ReadAngle(r, uint(*v.t))
return r.Err()
}
func (t pitchYawAngles_t) read(r bit.Reader) (value, error) { func (v pitchYawAngles_v) String() string {
var q qangle return fmt.Sprintf("qangle:pitchYawAngles{%f %f}", v.pitch, v.yaw)
q.pitch = bit.ReadAngle(r, uint(t))
q.yaw = bit.ReadAngle(r, uint(t))
return q, r.Err()
} }

@ -20,31 +20,35 @@ func (s selection) String() string { return fmt.Sprint(s.path()) }
func (s selection) path() []int { return s.vals[:s.count] } func (s selection) path() []int { return s.vals[:s.count] }
func (s selection) fillSlots(v slotted, r bit.Reader) error { func (s selection) fillSlots(v slotted, r bit.Reader) error {
Debug.Printf("%v fill slots into %v", s, v) return s.fillSlotsIter(0, v, v.tÿpe().typeName(), r)
return s.fillSlotsIter(0, v, r)
} }
func (s selection) fillSlotsIter(offset int, dest slotted, r bit.Reader) error { func (s selection) fillSlotsIter(offset int, dest slotted, path string, r bit.Reader) error {
slot := s.vals[offset] slot := s.vals[offset]
if s.count-offset <= 0 { if s.count-offset <= 0 {
return fmt.Errorf("unable to fill selection %v having count %d at offset %d", s, s.count, offset) return fmt.Errorf("unable to fill selection %v having count %d at offset %d", s, s.count, offset)
} }
switch s.count - offset { switch s.count - offset {
case 1: case 1:
t := dest.slotType(slot) v := dest.slotType(slot).nü()
v, err := t.read(r) if err := v.read(r); err != nil {
if err != nil {
return fmt.Errorf("unable to fill selection: %v", err) return fmt.Errorf("unable to fill selection: %v", err)
} }
old := dest.getSlotValue(slot)
dest.setSlotValue(slot, v) dest.setSlotValue(slot, v)
Debug.Printf("%v %s.%s (%s) %v -> %v", s, path, dest.slotName(slot), dest.slotType(slot).typeName(), old, v)
return nil return nil
default: default:
v := dest.getSlotValue(slot) v := dest.getSlotValue(slot)
if v == nil {
v = dest.slotType(slot).nü()
dest.setSlotValue(slot, v)
}
vs, ok := v.(slotted) vs, ok := v.(slotted)
if !ok { if !ok {
return fmt.Errorf("destination is not slotted") return fmt.Errorf("dest isn't slotted")
} }
return s.fillSlotsIter(offset+1, vs, r) return s.fillSlotsIter(offset+1, vs, fmt.Sprintf("%s.%s", path, dest.slotName(slot)), r)
} }
} }

@ -1,7 +1,9 @@
package ent package ent
type slotted interface { type slotted interface {
value
slotType(int) tÿpe slotType(int) tÿpe
slotName(int) string
setSlotValue(int, value) setSlotValue(int, value)
getSlotValue(int) value getSlotValue(int) value
} }

@ -8,17 +8,17 @@ import (
) )
type tÿpe interface { type tÿpe interface {
read(bit.Reader) (value, error) nü() value
typeName() string typeName() string
} }
type typeLiteral struct { type typeLiteral struct {
name string name string
readFn func(r bit.Reader) (value, error) newFn func() value
} }
func (t typeLiteral) nü() value { return t.newFn() }
func (t typeLiteral) typeName() string { return t.name } func (t typeLiteral) typeName() string { return t.name }
func (t typeLiteral) read(r bit.Reader) (value, error) { return t.readFn(r) }
type typeParseFn func(*typeSpec, *Env) tÿpe type typeParseFn func(*typeSpec, *Env) tÿpe
@ -42,14 +42,32 @@ func parseTypeSpec(spec *typeSpec, env *Env) tÿpe {
hSeqType, genericType, vectorType, classType, unknownType) hSeqType, genericType, vectorType, classType, unknownType)
} }
type unknown_t string
func (t unknown_t) typeName() string { return string(t) }
func (t *unknown_t) nü() value {
return &unknown_v{t: t}
}
type unknown_v struct {
t tÿpe
v uint64
}
func (v unknown_v) tÿpe() tÿpe { return v.t }
func (v *unknown_v) read(r bit.Reader) error {
v.v = bit.ReadVarInt(r)
return r.Err()
}
func (v unknown_v) String() string {
return fmt.Sprintf("%s(unknown):%d", v.t.typeName(), v.v)
}
func unknownType(spec *typeSpec, env *Env) tÿpe { func unknownType(spec *typeSpec, env *Env) tÿpe {
Debug.Printf("Unknown Type: %v", spec) Debug.Printf("Unknown Type: %v", spec)
return typeLiteral{ t := unknown_t(spec.typeName)
name: fmt.Sprintf("unknown:%s", spec.typeName), return &t
readFn: func(r bit.Reader) (value, error) {
return bit.ReadVarInt(r), r.Err()
},
}
} }
// a type error is both an error and a type. It represents a type that we were // a type error is both an error and a type. It represents a type that we were
@ -62,11 +80,9 @@ func typeError(t string, args ...interface{}) tÿpe {
type error_t string type error_t string
func (e error_t) nü() value { panic("can't create an error val like that") }
func (e error_t) typeName() string { return "error" } func (e error_t) typeName() string { return "error" }
func (e error_t) Error() string { return string(e) } func (e error_t) Error() string { return string(e) }
func (e error_t) read(r bit.Reader) (value, error) {
return nil, fmt.Errorf("type error: %s", string(e))
}
type typeSpec struct { type typeSpec struct {
name string name string

@ -1,3 +1,11 @@
package ent package ent
type value interface{} import (
"github.com/jordanorelli/hyperstone/bit"
)
type value interface {
String() string
tÿpe() tÿpe
read(bit.Reader) error
}

@ -5,8 +5,6 @@ import (
"github.com/jordanorelli/hyperstone/bit" "github.com/jordanorelli/hyperstone/bit"
) )
type vector struct{ x, y, z float32 }
func vectorType(spec *typeSpec, env *Env) tÿpe { func vectorType(spec *typeSpec, env *Env) tÿpe {
if spec.encoder != "" { if spec.encoder != "" {
return nil return nil
@ -18,7 +16,7 @@ func vectorType(spec *typeSpec, env *Env) tÿpe {
if t == nil { if t == nil {
return nil return nil
} }
return vector_t{elem: t} return &vector_t{elem: t}
} }
type vector_t struct { type vector_t struct {
@ -29,19 +27,41 @@ func (t vector_t) typeName() string {
return fmt.Sprintf("vector:%s", t.elem.typeName()) return fmt.Sprintf("vector:%s", t.elem.typeName())
} }
func (t vector_t) read(r bit.Reader) (value, error) { func (t *vector_t) nü() value {
var err error return &vector{t: t}
var v interface{} }
read := func(f *float32) {
if err != nil { type vector struct {
return t tÿpe
} x, y, z value
v, err = t.elem.read(r) }
*f = v.(float32)
} func (v vector) tÿpe() tÿpe { return v.t }
var out vector
read(&out.x) func (v *vector) read(r bit.Reader) error {
read(&out.y) if v.x == nil {
read(&out.z) v.x = v.t.nü()
return out, err }
if v.y == nil {
v.y = v.t.nü()
}
if v.z == nil {
v.z = v.t.nü()
}
type fn func(bit.Reader) error
coalesce := func(fns ...fn) error {
for _, f := range fns {
if err := f(r); err != nil {
return err
}
}
return nil
}
return coalesce(v.x.read, v.y.read, v.z.read)
}
func (v vector) String() string {
return fmt.Sprintf("vector<%s>{%s %s %s}", v.t.typeName, v.x, v.y, v.z)
} }

Loading…
Cancel
Save