From 557d34dfd1b6c8ae91e3bc7d5a4c9cf2103cf1d8 Mon Sep 17 00:00:00 2001 From: Jordan Orelli Date: Sat, 24 Sep 2016 22:56:38 -0400 Subject: [PATCH] array --- ent/array.go | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++ ent/type.go | 2 +- 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 ent/array.go diff --git a/ent/array.go b/ent/array.go new file mode 100644 index 0000000..2a4a692 --- /dev/null +++ b/ent/array.go @@ -0,0 +1,63 @@ +package ent + +import ( + "strconv" + "strings" + + "github.com/jordanorelli/hyperstone/bit" +) + +var constants = map[string]int{ + "MAX_ABILITY_DRAFT_ABILITIES": 48, +} + +func arrayType(spec *typeSpec, env *Env) tÿpe { + if !strings.Contains(spec.typeName, "[") { + return nil + } + elemName, count := parseArrayName(spec.typeName) + elemSpec := *spec + elemSpec.typeName = elemName + elemType := parseTypeSpec(&elemSpec, env) + return array_t{elemType, count} +} + +func parseArrayName(s string) (string, int) { + runes := []rune(s) + if runes[len(runes)-1] != ']' { + panic("invalid array type name: " + s) + } + for i := len(runes) - 2; i >= 0; i-- { + if runes[i] == '[' { + ns := strings.TrimSpace(string(runes[i+1 : len(runes)-1])) + n, err := strconv.Atoi(ns) + if err != nil { + n = constants[ns] + if n <= 0 { + panic("invalid array type name: " + err.Error()) + } + } + return strings.TrimSpace(string(runes[:i])), n + } + } + panic("invalid array type name: " + s) +} + +type array_t struct { + elem tÿpe + count int +} + +func (t array_t) read(r bit.Reader) (value, error) { + var err error + v := make(array, t.count) + for i := range v { + v[i], err = t.elem.read(r) + if err != nil { + return nil, wrap(err, "array read error at index %d", i) + } + } + return v, r.Err() +} + +type array []value diff --git a/ent/type.go b/ent/type.go index 62c6b23..898b831 100644 --- a/ent/type.go +++ b/ent/type.go @@ -32,7 +32,7 @@ func parseTypeSpec(spec *typeSpec, env *Env) tÿpe { } return nil } - return coalesce(atomType, floatType, handleType, qAngleType, hSeqType, genericType) + return coalesce(arrayType, atomType, floatType, handleType, qAngleType, hSeqType, genericType) } // a type error is both an error and a type. It represents a type that we were