about summary refs log tree commit diff
path: root/pkg/lang/vm/code/code.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/lang/vm/code/code.go')
-rw-r--r--pkg/lang/vm/code/code.go59
1 files changed, 59 insertions, 0 deletions
diff --git a/pkg/lang/vm/code/code.go b/pkg/lang/vm/code/code.go
new file mode 100644
index 0000000..ab06d27
--- /dev/null
+++ b/pkg/lang/vm/code/code.go
@@ -0,0 +1,59 @@
+package code
+
+import (
+	"bytes"
+	"encoding/binary"
+	"math"
+	"strings"
+)
+
+type Code struct {
+	code []byte
+}
+
+func (c *Code) Len() int {
+	return len(c.code)
+}
+
+func (c *Code) GetOp(at int) (Op, int) {
+	return Op(c.code[at]), 1
+}
+
+func (c *Code) GetUint(at int) (uint64, int) {
+	advance := 8
+	x := binary.LittleEndian.Uint64(c.code[at : at+advance])
+	return x, advance
+}
+
+func (c *Code) GetInt(at int) (int64, int) {
+	x, advance := c.GetUint(at)
+	return int64(x), advance
+}
+
+func (c *Code) GetFloat(at int) (float64, int) {
+	x, advance := c.GetUint(at)
+	return math.Float64frombits(x), advance
+}
+
+func (c *Code) GetString(at int) (string, int) {
+	advance := 0
+	reader := bytes.NewReader(c.code[at:])
+	builder := strings.Builder{}
+
+	for {
+		r, size, err := reader.ReadRune()
+		advance += size
+
+		if err != nil {
+			break
+		}
+
+		if r == 0 {
+			break
+		}
+
+		builder.WriteRune(r)
+	}
+
+	return builder.String(), advance
+}