about summary refs log tree commit diff
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/core_ptrs.go98
-rw-r--r--pkg/lang/vm/value/data.go22
-rw-r--r--pkg/lang/vm/value/value.go18
3 files changed, 117 insertions, 21 deletions
diff --git a/pkg/lang/vm/value/core_ptrs.go b/pkg/lang/vm/value/core_ptrs.go
index a1f0365..adb9a6b 100644
--- a/pkg/lang/vm/value/core_ptrs.go
+++ b/pkg/lang/vm/value/core_ptrs.go
@@ -4,14 +4,90 @@ import (
 	"jinx/pkg/lang/vm/mem"
 )
 
-const (
-	CORE_TYPE_NULL = mem.Ptr(iota + 1)
-	CORE_TYPE_INT
-	CORE_TYPE_FLOAT
-	CORE_TYPE_STRING
-	CORE_TYPE_BOOL
-	CORE_TYPE_ARRAY
-	CORE_TYPE_FUNCTION
-
-	CORE_TYPE_TYPE_REF
-)
+// All CorePtrs are unitialized until the core module is loaded.
+type CorePtrs struct {
+	CoreTypeNull     mem.Ptr
+	CoreTypeInt      mem.Ptr
+	CoreTypeFloat    mem.Ptr
+	CoreTypeString   mem.Ptr
+	CoreTypeBool     mem.Ptr
+	CoreTypeArray    mem.Ptr
+	CoreTypeFunction mem.Ptr
+
+	CoreTypeTypeRef mem.Ptr
+}
+
+func (c *CorePtrs) SetNull(p mem.Ptr) {
+	if c.CoreTypeNull != mem.NullPtr {
+		panic("core ptr null already set")
+	}
+
+	c.CoreTypeNull = p
+}
+
+func (c *CorePtrs) SetInt(p mem.Ptr) {
+	if c.CoreTypeInt != mem.NullPtr {
+		panic("core ptr int already set")
+	}
+
+	c.CoreTypeInt = p
+}
+
+func (c *CorePtrs) SetFloat(p mem.Ptr) {
+	if c.CoreTypeFloat != mem.NullPtr {
+		panic("core ptr float already set")
+	}
+
+	c.CoreTypeFloat = p
+}
+
+func (c *CorePtrs) SetString(p mem.Ptr) {
+	if c.CoreTypeString != mem.NullPtr {
+		panic("core ptr string already set")
+	}
+
+	c.CoreTypeString = p
+}
+
+func (c *CorePtrs) SetBool(p mem.Ptr) {
+	if c.CoreTypeBool != mem.NullPtr {
+		panic("core ptr bool already set")
+	}
+
+	c.CoreTypeBool = p
+}
+
+func (c *CorePtrs) SetArray(p mem.Ptr) {
+	if c.CoreTypeArray != mem.NullPtr {
+		panic("core ptr array already set")
+	}
+
+	c.CoreTypeArray = p
+}
+
+func (c *CorePtrs) SetFunction(p mem.Ptr) {
+	if c.CoreTypeFunction != mem.NullPtr {
+		panic("core ptr function already set")
+	}
+
+	c.CoreTypeFunction = p
+}
+
+func (c *CorePtrs) SetTypeRef(p mem.Ptr) {
+	if c.CoreTypeTypeRef != mem.NullPtr {
+		panic("core ptr type ref already set")
+	}
+
+	c.CoreTypeTypeRef = p
+}
+
+func (c *CorePtrs) Complete() bool {
+	return c.CoreTypeNull != mem.NullPtr &&
+		c.CoreTypeInt != mem.NullPtr &&
+		c.CoreTypeFloat != mem.NullPtr &&
+		c.CoreTypeString != mem.NullPtr &&
+		c.CoreTypeBool != mem.NullPtr &&
+		c.CoreTypeArray != mem.NullPtr &&
+		c.CoreTypeFunction != mem.NullPtr &&
+		c.CoreTypeTypeRef != mem.NullPtr
+}
diff --git a/pkg/lang/vm/value/data.go b/pkg/lang/vm/value/data.go
index 39193d5..1cd258b 100644
--- a/pkg/lang/vm/value/data.go
+++ b/pkg/lang/vm/value/data.go
@@ -116,11 +116,31 @@ func (a ArrayData) Push(m mem.Mem, v Value) error {
 
 	arr := data.(ArrayCell).Get()
 	arr = append(arr, v)
-	m.Set(a.data, ArrayCell(arr))
 
+	if err := m.Set(a.data, ArrayCell(arr)); err != nil {
+		return err
+	}
 	return nil
 }
 
+func (a ArrayData) Pop(m mem.Mem) (Value, error) {
+	data, err := m.Get(a.data)
+	if err != nil {
+		return Value{}, err
+	}
+
+	arr := data.(ArrayCell).Get()
+
+	popped := arr[len(arr)-1]
+	arr = arr[:len(arr)-1]
+
+	if err := m.Set(a.data, ArrayCell(arr)); err != nil {
+		return Value{}, err
+	}
+
+	return popped, nil
+}
+
 type NullData struct{}
 
 func (n NullData) String(_ mem.Mem) (string, error) {
diff --git a/pkg/lang/vm/value/value.go b/pkg/lang/vm/value/value.go
index 5ef3f07..cce2f5e 100644
--- a/pkg/lang/vm/value/value.go
+++ b/pkg/lang/vm/value/value.go
@@ -93,24 +93,24 @@ func (v Value) Type() TypeKind {
 	return v.t
 }
 
-func (v Value) TypePtr() mem.Ptr {
+func (v Value) TypePtr(corePtrs *CorePtrs) mem.Ptr {
 	switch v.t {
 	case IntType:
-		return CORE_TYPE_INT
+		return corePtrs.CoreTypeInt
 	case FloatType:
-		return CORE_TYPE_FLOAT
+		return corePtrs.CoreTypeFloat
 	case StringType:
-		return CORE_TYPE_STRING
+		return corePtrs.CoreTypeFloat
 	case BoolType:
-		return CORE_TYPE_BOOL
+		return corePtrs.CoreTypeBool
 	case ArrayType:
-		return CORE_TYPE_ARRAY
+		return corePtrs.CoreTypeArray
 	case NullType:
-		return CORE_TYPE_NULL
+		return corePtrs.CoreTypeNull
 	case FunctionType:
-		return CORE_TYPE_FUNCTION
+		return corePtrs.CoreTypeFunction
 	case TypeRefType:
-		return CORE_TYPE_TYPE_REF
+		return corePtrs.CoreTypeTypeRef
 	case ObjectType:
 		return v.d.(ObjectData).t
 	default: