aboutsummaryrefslogtreecommitdiff
path: root/pkg/lang/vm/value
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/lang/vm/value')
-rw-r--r--pkg/lang/vm/value/data.go55
-rw-r--r--pkg/lang/vm/value/value.go46
2 files changed, 73 insertions, 28 deletions
diff --git a/pkg/lang/vm/value/data.go b/pkg/lang/vm/value/data.go
index 5d1398d..fecf8cf 100644
--- a/pkg/lang/vm/value/data.go
+++ b/pkg/lang/vm/value/data.go
@@ -2,11 +2,14 @@ package value
import (
"fmt"
+ "jinx/pkg/lang/vm/mem"
"strconv"
"strings"
)
-type Data fmt.Stringer
+type Data interface {
+ String(*mem.Mem) string
+}
type IntData int64
@@ -14,7 +17,7 @@ func (i IntData) Get() int64 {
return int64(i)
}
-func (i IntData) String() string {
+func (i IntData) String(_ *mem.Mem) string {
return strconv.FormatInt(int64(i), 10)
}
@@ -24,18 +27,17 @@ func (f FloatData) Get() float64 {
return float64(f)
}
-func (f FloatData) String() string {
+func (f FloatData) String(_ *mem.Mem) string {
return strconv.FormatFloat(float64(f), 'f', -1, 64)
}
-type StringData string
-
-func (s StringData) Get() string {
- return string(s)
+type StringData struct {
+ data mem.Ptr
}
-func (s StringData) String() string {
- return "\"" + string(s) + "\""
+func (s StringData) String(m *mem.Mem) string {
+ data := m.Get(s.data)
+ return "\"" + data.(string) + "\""
}
type BoolData bool
@@ -44,41 +46,46 @@ func (b BoolData) Get() bool {
return bool(b)
}
-func (b BoolData) String() string {
+func (b BoolData) String(_ *mem.Mem) string {
return strconv.FormatBool(bool(b))
}
type ArrayData struct {
- arr *[]Value
+ data mem.Ptr
}
-func (a ArrayData) Get() *[]Value {
- return a.arr
-}
+func (a ArrayData) String(m *mem.Mem) string {
+ arr := m.Get(a.data).([]Value)
-func (a ArrayData) String() string {
builder := strings.Builder{}
builder.WriteString("[")
- for i, v := range *a.arr {
+ for i, v := range arr {
if i > 0 {
builder.WriteString(", ")
}
- builder.WriteString(v.Data().String())
+ builder.WriteString(v.Data().String(m))
}
builder.WriteString("]")
return builder.String()
}
-func (a ArrayData) Len() int {
- return len(*a.arr)
+func (a ArrayData) Len(m *mem.Mem) int {
+ data := m.Get(a.data)
+ arr := data.([]Value)
+ return len(arr)
}
-func (a ArrayData) At(i int) Value {
- return (*a.arr)[i]
+func (a ArrayData) At(m *mem.Mem, i int) Value {
+ data := m.Get(a.data)
+ arr := data.([]Value)
+ return arr[i]
}
-func (a ArrayData) Push(v Value) {
- *a.arr = append(*a.arr, v)
+func (a ArrayData) Push(m *mem.Mem, v Value) {
+ data := m.Get(a.data)
+ arr := data.([]Value)
+ arr = append(arr, v)
+ m.Set(a.data, arr)
}
type NullData struct{}
@@ -91,7 +98,7 @@ func (f FunctionData) Pc() int {
return f.pc
}
-func (f FunctionData) String() string {
+func (f FunctionData) String(_ *mem.Mem) string {
return fmt.Sprintf("<fn %d>", f.pc)
}
diff --git a/pkg/lang/vm/value/value.go b/pkg/lang/vm/value/value.go
index 93989cf..06306df 100644
--- a/pkg/lang/vm/value/value.go
+++ b/pkg/lang/vm/value/value.go
@@ -1,5 +1,9 @@
package value
+import (
+ "jinx/pkg/lang/vm/mem"
+)
+
type Value struct {
t Type
d Data
@@ -15,9 +19,13 @@ func NewFloat(x float64) Value {
return Value{t: t, d: FloatData(x)}
}
-func NewString(str string) Value {
+func NewString(m *mem.Mem, str string) Value {
t := Type{Kind: StringType}
- return Value{t: t, d: StringData(str)}
+
+ ptr := m.Allocate(mem.CellKindString)
+ m.Set(ptr, str)
+
+ return Value{t: t, d: StringData{data: ptr}}
}
func NewBool(b bool) Value {
@@ -25,9 +33,13 @@ func NewBool(b bool) Value {
return Value{t: t, d: BoolData(b)}
}
-func NewArray(arr []Value) Value {
+func NewArray(m *mem.Mem, arr []Value) Value {
t := Type{Kind: ArrayType}
- return Value{t: t, d: ArrayData{arr: &arr}}
+
+ ptr := m.Allocate(mem.CellKindArray)
+ m.Set(ptr, arr)
+
+ return Value{t: t, d: ArrayData{data: ptr}}
}
func NewNull() Value {
@@ -51,3 +63,29 @@ func (v Value) Type() Type {
func (v Value) Data() Data {
return v.d
}
+
+func (v Value) Clone(m *mem.Mem) Value {
+ if v.t.Kind == StringType {
+ str := v.d.(StringData)
+ m.Retain(str.data)
+ }
+
+ if v.t.Kind == ArrayType {
+ arr := v.d.(ArrayData)
+ m.Retain(arr.data)
+ }
+
+ return v
+}
+
+func (v Value) Drop(m *mem.Mem) {
+ if v.t.Kind == StringType {
+ str := v.d.(StringData)
+ m.Release(str.data)
+ }
+
+ if v.t.Kind == ArrayType {
+ arr := v.d.(ArrayData)
+ m.Release(arr.data)
+ }
+}