package compiler import ( "encoding/gob" "fmt" "io" "reflect" "github.com/d5/tengo/compiler/source" "github.com/d5/tengo/objects" ) // Bytecode is a compiled instructions and constants. type Bytecode struct { FileSet *source.FileSet MainFunction *objects.CompiledFunction Constants []objects.Object } // Encode writes Bytecode data to the writer. func (b *Bytecode) Encode(w io.Writer) error { enc := gob.NewEncoder(w) if err := enc.Encode(b.FileSet); err != nil { return err } if err := enc.Encode(b.MainFunction); err != nil { return err } // constants return enc.Encode(b.Constants) } // CountObjects returns the number of objects found in Constants. func (b *Bytecode) CountObjects() int { n := 0 for _, c := range b.Constants { n += objects.CountObjects(c) } return n } // FormatInstructions returns human readable string representations of // compiled instructions. func (b *Bytecode) FormatInstructions() []string { return FormatInstructions(b.MainFunction.Instructions, 0) } // FormatConstants returns human readable string representations of // compiled constants. func (b *Bytecode) FormatConstants() (output []string) { for cidx, cn := range b.Constants { switch cn := cn.(type) { case *objects.CompiledFunction: output = append(output, fmt.Sprintf("[% 3d] (Compiled Function|%p)", cidx, &cn)) for _, l := range FormatInstructions(cn.Instructions, 0) { output = append(output, fmt.Sprintf(" %s", l)) } default: output = append(output, fmt.Sprintf("[% 3d] %s (%s|%p)", cidx, cn, reflect.TypeOf(cn).Elem().Name(), &cn)) } } return } func init() { gob.Register(&source.FileSet{}) gob.Register(&source.File{}) gob.Register(&objects.Array{}) gob.Register(&objects.Bool{}) gob.Register(&objects.Bytes{}) gob.Register(&objects.Char{}) gob.Register(&objects.Closure{}) gob.Register(&objects.CompiledFunction{}) gob.Register(&objects.Error{}) gob.Register(&objects.Float{}) gob.Register(&objects.ImmutableArray{}) gob.Register(&objects.ImmutableMap{}) gob.Register(&objects.Int{}) gob.Register(&objects.Map{}) gob.Register(&objects.String{}) gob.Register(&objects.Time{}) gob.Register(&objects.Undefined{}) gob.Register(&objects.UserFunction{}) }