about summary refs log tree commit diff
path: root/pkg/lang/vm/code/builder.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/lang/vm/code/builder.go')
-rw-r--r--pkg/lang/vm/code/builder.go60
1 files changed, 60 insertions, 0 deletions
diff --git a/pkg/lang/vm/code/builder.go b/pkg/lang/vm/code/builder.go
new file mode 100644
index 0000000..3aa6b6b
--- /dev/null
+++ b/pkg/lang/vm/code/builder.go
@@ -0,0 +1,60 @@
+package code
+
+import (
+	"encoding/binary"
+	"math"
+)
+
+type Builder struct {
+	code      []byte
+	debugInfo DebugInfo
+}
+
+func NewBuilder() Builder {
+	return Builder{
+		code:      make([]byte, 0, 64),
+		debugInfo: NewDebugInfo("unknown file"),
+	}
+}
+
+func (b *Builder) AppendOp(op Op) {
+	b.code = append(b.code, byte(op))
+}
+
+func (b *Builder) AppendInt(x int64) {
+	b.code = append(b.code, make([]byte, 8)...)
+	binary.LittleEndian.PutUint64(b.code[len(b.code)-8:], uint64(x))
+}
+
+func (b *Builder) AppendFloat(x float64) {
+	b.AppendInt(int64(math.Float64bits(x)))
+}
+
+func (b *Builder) AppendString(s string) {
+	b.code = append(b.code, []byte(s)...)
+	b.code = append(b.code, 0)
+}
+
+func (b *Builder) AppendRaw(raw Raw) {
+	b.code = append(b.code, raw...)
+}
+
+func (b *Builder) AppendLine(line int) {
+	b.debugInfo.AppendLine(len(b.code)-1, line)
+}
+
+func (b *Builder) SetInt(at int, x int64) {
+	binary.LittleEndian.PutUint64(b.code[at:], uint64(x))
+}
+
+func (b *Builder) Code() Raw {
+	return Raw(b.code)
+}
+
+func (b *Builder) Len() int {
+	return len(b.code)
+}
+
+func (b *Builder) Build() Code {
+	return New(b.code, b.debugInfo)
+}