diff options
Diffstat (limited to 'pkg/lang/vm/value/data.go')
| -rw-r--r-- | pkg/lang/vm/value/data.go | 80 |
1 files changed, 52 insertions, 28 deletions
diff --git a/pkg/lang/vm/value/data.go b/pkg/lang/vm/value/data.go index a49753e..2e3b3e6 100644 --- a/pkg/lang/vm/value/data.go +++ b/pkg/lang/vm/value/data.go @@ -8,7 +8,7 @@ import ( ) type Data interface { - String(*mem.Mem) string + String(*mem.Mem) (string, error) } type IntData int64 @@ -17,8 +17,8 @@ func (i IntData) Get() int64 { return int64(i) } -func (i IntData) String(_ *mem.Mem) string { - return strconv.FormatInt(int64(i), 10) +func (i IntData) String(_ *mem.Mem) (string, error) { + return strconv.FormatInt(int64(i), 10), nil } type FloatData float64 @@ -27,17 +27,20 @@ func (f FloatData) Get() float64 { return float64(f) } -func (f FloatData) String(_ *mem.Mem) string { - return strconv.FormatFloat(float64(f), 'f', -1, 64) +func (f FloatData) String(_ *mem.Mem) (string, error) { + return strconv.FormatFloat(float64(f), 'f', -1, 64), nil } type StringData struct { data mem.Ptr } -func (s StringData) String(m *mem.Mem) string { - data := m.Get(s.data) - return "\"" + data.(string) + "\"" +func (s StringData) String(m *mem.Mem) (string, error) { + if data, err := m.Get(s.data); err == nil { + return "\"" + data.(StringCell).Get() + "\"", nil + } else { + return "", err + } } type BoolData bool @@ -46,16 +49,21 @@ func (b BoolData) Get() bool { return bool(b) } -func (b BoolData) String(_ *mem.Mem) string { - return strconv.FormatBool(bool(b)) +func (b BoolData) String(_ *mem.Mem) (string, error) { + return strconv.FormatBool(bool(b)), nil } type ArrayData struct { data mem.Ptr } -func (a ArrayData) String(m *mem.Mem) string { - arr := m.Get(a.data).([]Value) +func (a ArrayData) String(m *mem.Mem) (string, error) { + val, err := m.Get(a.data) + if err != nil { + return "", err + } + + arr := val.(ArrayCell).Get() builder := strings.Builder{} builder.WriteString("[") @@ -63,29 +71,45 @@ func (a ArrayData) String(m *mem.Mem) string { if i > 0 { builder.WriteString(", ") } - builder.WriteString(v.Data().String(m)) + if s, err := v.Data().String(m); err == nil { + builder.WriteString(s) + } else { + return "", err + } } builder.WriteString("]") - return builder.String() + return builder.String(), nil } -func (a ArrayData) Len(m *mem.Mem) int { - data := m.Get(a.data) - arr := data.([]Value) - return len(arr) +func (a ArrayData) Len(m *mem.Mem) (int, error) { + data, err := m.Get(a.data) + if err != nil { + return 0, err + } + arr := data.(ArrayCell).Get() + return len(arr), nil } -func (a ArrayData) At(m *mem.Mem, i int) Value { - data := m.Get(a.data) - arr := data.([]Value) - return arr[i] +func (a ArrayData) At(m *mem.Mem, i int) (Value, error) { + data, err := m.Get(a.data) + if err != nil { + return Value{}, err + } + arr := data.(ArrayCell).Get() + return arr[i], nil } -func (a ArrayData) Push(m *mem.Mem, v Value) { - data := m.Get(a.data) - arr := data.([]Value) +func (a ArrayData) Push(m *mem.Mem, v Value) error { + data, err := m.Get(a.data) + if err != nil { + return err + } + + arr := data.(ArrayCell).Get() arr = append(arr, v) - m.Set(a.data, arr) + m.Set(a.data, ArrayCell(arr)) + + return nil } type NullData struct{} @@ -107,8 +131,8 @@ func (f FunctionData) WithEnv(env mem.Ptr) FunctionData { return FunctionData{pc: f.pc, env: env} } -func (f FunctionData) String(_ *mem.Mem) string { - return fmt.Sprintf("<fn %d>", f.pc) +func (f FunctionData) String(_ *mem.Mem) (string, error) { + return fmt.Sprintf("<fn %d>", f.pc), nil } type ObjectData struct{} // TODO |
