summaryrefslogtreecommitdiff
path: root/vm
diff options
context:
space:
mode:
Diffstat (limited to 'vm')
-rw-r--r--vm/type.go18
-rw-r--r--vm/vm.go11
2 files changed, 27 insertions, 2 deletions
diff --git a/vm/type.go b/vm/type.go
index 16e3733..49215db 100644
--- a/vm/type.go
+++ b/vm/type.go
@@ -10,10 +10,19 @@ type Type struct {
Rtype reflect.Type
}
+func (t *Type) String() string {
+ if t.Name != "" {
+ return t.Name
+ }
+ return t.Rtype.String()
+}
+
+// Elem returns a type's element type.
func (t *Type) Elem() *Type {
return &Type{Rtype: t.Rtype.Elem()}
}
+// Out returns the type's i'th output parameter.
func (t *Type) Out(i int) *Type {
return &Type{Rtype: t.Rtype.Out(i)}
}
@@ -43,18 +52,22 @@ func ValueOf(v any) Value {
return Value{Data: reflect.ValueOf(v)}
}
+// PointerTo returns the pointer type with element t.
func PointerTo(t *Type) *Type {
return &Type{Rtype: reflect.PointerTo(t.Rtype)}
}
-func ArrayOf(size int, t *Type) *Type {
- return &Type{Rtype: reflect.ArrayOf(size, t.Rtype)}
+// ArrayOf returns the array type with the given length and element type.
+func ArrayOf(length int, t *Type) *Type {
+ return &Type{Rtype: reflect.ArrayOf(length, t.Rtype)}
}
+// SliceOf returns the slice type with the given element type.
func SliceOf(t *Type) *Type {
return &Type{Rtype: reflect.SliceOf(t.Rtype)}
}
+// FuncOf returns the function type with the given argument and result types.
func FuncOf(arg, ret []*Type, variadic bool) *Type {
a := make([]reflect.Type, len(arg))
for i, e := range arg {
@@ -67,6 +80,7 @@ func FuncOf(arg, ret []*Type, variadic bool) *Type {
return &Type{Rtype: reflect.FuncOf(a, r, variadic)}
}
+// StructOf returns the struct type with the given field types.
func StructOf(fields []*Type) *Type {
rf := make([]reflect.StructField, len(fields))
for i, f := range fields {
diff --git a/vm/vm.go b/vm/vm.go
index 0b2a1ad..408be6e 100644
--- a/vm/vm.go
+++ b/vm/vm.go
@@ -1,3 +1,4 @@
+// Package vm implement a stack based virtual machine.
package vm
import (
@@ -85,6 +86,7 @@ var strop = [...]string{ // for VM tracing.
Vassign: "Vassign",
}
+// Code represents the virtual machine byte code.
type Code [][]int64
// Machine represents a virtual machine.
@@ -256,19 +258,24 @@ func (m *Machine) Run() (err error) {
}
}
+// PushCode adds instructions to the machine code.
func (m *Machine) PushCode(code ...[]int64) (p int) {
p = len(m.code)
m.code = append(m.code, code...)
return p
}
+// SetIP sets the value of machine instruction pointer to given index.
func (m *Machine) SetIP(ip int) { m.ip = ip }
+
+// Push pushes data values on top of machine memory stack.
func (m *Machine) Push(v ...Value) (l int) {
l = len(m.mem)
m.mem = append(m.mem, v...)
return l
}
+// Pop removes and returns the value on the top of machine stack.
func (m *Machine) Pop() (v Value) {
l := len(m.mem) - 1
v = m.mem[l]
@@ -276,6 +283,7 @@ func (m *Machine) Pop() (v Value) {
return v
}
+// Top returns (but not remove) the value on the top of machine stack.
func (m *Machine) Top() (v Value) {
if l := len(m.mem); l > 0 {
v = m.mem[l-1]
@@ -283,12 +291,14 @@ func (m *Machine) Top() (v Value) {
return v
}
+// PopExit removes the last machine code instruction if is Exit.
func (m *Machine) PopExit() {
if l := len(m.code); l > 0 && m.code[l-1][1] == Exit {
m.code = m.code[:l-1]
}
}
+// CodeString returns the string representation of a machine code instruction.
func CodeString(op []int64) string {
switch len(op) {
case 2:
@@ -317,6 +327,7 @@ func slint(a []int64) []int {
return r
}
+// Vstring returns the string repreentation of a list of values.
func Vstring(lv []Value) string {
s := "["
for _, v := range lv {