package code import ( "encoding/binary" "math" ) type Builder struct { code []byte debugInfo DebugInfo currentLine int lineStart int } func NewBuilder() Builder { return Builder{ code: make([]byte, 0, 64), debugInfo: NewDebugInfo("unknown file"), lineStart: -1, currentLine: -1, } } 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) StartLine(line int) { if b.lineStart != -1 { panic("line already started") } b.currentLine = line b.lineStart = len(b.code) } func (b *Builder) EndLine() { defer func() { b.currentLine = -1 b.lineStart = -1 }() if b.lineStart == -1 { panic("line not started") } if b.lineStart == len(b.code) { return } b.debugInfo.AppendLine(len(b.code)-1, b.currentLine) } 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) }