package value import ( "fmt" "jinx/pkg/lang/vm/mem" "strconv" "strings" ) type Data interface { String(*mem.Mem) (string, error) } type IntData int64 func (i IntData) Get() int64 { return int64(i) } func (i IntData) String(_ *mem.Mem) (string, error) { return strconv.FormatInt(int64(i), 10), nil } type FloatData float64 func (f FloatData) Get() float64 { return float64(f) } 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, error) { if data, err := m.Get(s.data); err == nil { return "\"" + data.(StringCell).Get() + "\"", nil } else { return "", err } } type BoolData bool func (b BoolData) Get() bool { return 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, error) { val, err := m.Get(a.data) if err != nil { return "", err } arr := val.(ArrayCell).Get() builder := strings.Builder{} builder.WriteString("[") for i, v := range arr { if i > 0 { builder.WriteString(", ") } if s, err := v.Data().String(m); err == nil { builder.WriteString(s) } else { return "", err } } builder.WriteString("]") return builder.String(), nil } 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, 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) error { data, err := m.Get(a.data) if err != nil { return err } arr := data.(ArrayCell).Get() arr = append(arr, v) m.Set(a.data, ArrayCell(arr)) return nil } type NullData struct{} type FunctionData struct { pc int env mem.Ptr } func (f FunctionData) Pc() int { return f.pc } func (f FunctionData) Env() mem.Ptr { return f.env } func (f FunctionData) WithEnv(env mem.Ptr) FunctionData { return FunctionData{pc: f.pc, env: env} } func (f FunctionData) String(_ *mem.Mem) (string, error) { return fmt.Sprintf("", f.pc), nil } type ObjectData struct{} // TODO