lots o fixes
This commit is contained in:
@@ -5,23 +5,22 @@ import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"monkey/internal/code"
|
||||
"monkey/internal/object"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func Indent(text, ident string) string {
|
||||
func indent(text, indent string) string {
|
||||
if text[len(text)-1:] == "\n" {
|
||||
result := ""
|
||||
for _, j := range strings.Split(text[:len(text)-1], "\n") {
|
||||
result += ident + j + "\n"
|
||||
result += indent + j + "\n"
|
||||
}
|
||||
return result
|
||||
}
|
||||
result := ""
|
||||
for _, j := range strings.Split(strings.TrimRight(text, "\n"), "\n") {
|
||||
result += ident + j + "\n"
|
||||
result += indent + j + "\n"
|
||||
}
|
||||
return result[:len(result)-1]
|
||||
}
|
||||
@@ -38,7 +37,7 @@ func (b *Bytecode) String() string {
|
||||
for i, c := range b.Constants {
|
||||
s.WriteString(fmt.Sprintf("%02d %s\n", i, c))
|
||||
if cf, ok := c.(*object.CompiledFunction); ok {
|
||||
s.WriteString(fmt.Sprintf(" Instructions:\n%s\n", Indent(cf.Instructions.String(), " ")))
|
||||
s.WriteString(fmt.Sprintf(" Instructions:\n%s\n", indent(cf.Instructions.String(), " ")))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,22 +50,40 @@ type encoder struct {
|
||||
bytes.Buffer
|
||||
}
|
||||
|
||||
func (e *encoder) Write(b []byte) (err error) {
|
||||
_, err = e.Buffer.Write(b)
|
||||
return
|
||||
func (e *encoder) WriteBytes(b []byte) error {
|
||||
if err := e.WriteValue(len(b)); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := e.Buffer.Write(b); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *encoder) WriteString(s string) (err error) {
|
||||
_, err = e.Buffer.WriteString(s)
|
||||
return
|
||||
func (e *encoder) WriteString(s string) error {
|
||||
if err := e.WriteValue(len(s)); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := e.Buffer.WriteString(s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *encoder) WriteValue(data any) error {
|
||||
return binary.Write(&e.Buffer, binary.BigEndian, data)
|
||||
switch val := data.(type) {
|
||||
case int:
|
||||
return binary.Write(&e.Buffer, binary.BigEndian, int64(val))
|
||||
case object.Type:
|
||||
return e.WriteValue(int(val))
|
||||
default:
|
||||
return binary.Write(&e.Buffer, binary.BigEndian, data)
|
||||
}
|
||||
}
|
||||
|
||||
func (e *encoder) WriteObjects(objs ...object.Object) (err error) {
|
||||
for _, obj := range objs {
|
||||
func (e *encoder) WriteObjects(objects ...object.Object) (err error) {
|
||||
err = errors.Join(err, e.WriteValue(len(objects)))
|
||||
for _, obj := range objects {
|
||||
err = errors.Join(err, e.WriteValue(obj.Type()))
|
||||
|
||||
switch o := obj.(type) {
|
||||
@@ -77,13 +94,11 @@ func (e *encoder) WriteObjects(objs ...object.Object) (err error) {
|
||||
case object.Integer:
|
||||
err = errors.Join(err, e.WriteValue(o.Value))
|
||||
case object.String:
|
||||
err = errors.Join(err, e.WriteValue(len(o.Value)))
|
||||
err = errors.Join(err, e.WriteValue(o.Value))
|
||||
err = errors.Join(err, e.WriteString(o.Value))
|
||||
case *object.CompiledFunction:
|
||||
err = errors.Join(err, e.WriteValue(o.NumParameters))
|
||||
err = errors.Join(err, e.WriteValue(o.NumLocals))
|
||||
err = errors.Join(err, e.WriteValue(len(o.Instructions)))
|
||||
err = errors.Join(err, e.Write(o.Instructions))
|
||||
err = errors.Join(err, e.WriteBytes(o.Instructions))
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -92,9 +107,7 @@ func (e *encoder) WriteObjects(objs ...object.Object) (err error) {
|
||||
func (b Bytecode) Encode() (data []byte, err error) {
|
||||
var e encoder
|
||||
|
||||
err = errors.Join(err, e.WriteValue(len(b.Instructions)))
|
||||
err = errors.Join(err, e.Write(b.Instructions))
|
||||
err = errors.Join(err, e.WriteValue(len(b.Constants)))
|
||||
err = errors.Join(err, e.WriteBytes(b.Instructions))
|
||||
err = errors.Join(err, e.WriteObjects(b.Constants...))
|
||||
return e.Bytes(), err
|
||||
}
|
||||
@@ -110,10 +123,8 @@ func (d *decoder) Byte() (b byte) {
|
||||
return
|
||||
}
|
||||
|
||||
func (d *decoder) Int() (i int) {
|
||||
i = int(binary.BigEndian.Uint32(d.b[d.pos:]))
|
||||
d.pos += 4
|
||||
return
|
||||
func (d *decoder) Int() int {
|
||||
return int(d.Int64())
|
||||
}
|
||||
|
||||
func (d *decoder) Uint64() (i uint64) {
|
||||
@@ -122,14 +133,10 @@ func (d *decoder) Uint64() (i uint64) {
|
||||
return
|
||||
}
|
||||
|
||||
func (d *decoder) Int64() (i int64) {
|
||||
func (d *decoder) Int64() int64 {
|
||||
return int64(d.Uint64())
|
||||
}
|
||||
|
||||
func (d *decoder) Float64() (f float64) {
|
||||
return math.Float64frombits(d.Uint64())
|
||||
}
|
||||
|
||||
func (d *decoder) Bytes(len int) (b []byte) {
|
||||
b = d.b[d.pos : d.pos+len]
|
||||
d.pos += len
|
||||
@@ -161,7 +168,7 @@ func (d *decoder) Objects(len int) (o []object.Object) {
|
||||
Instructions: d.Bytes(d.Int()),
|
||||
})
|
||||
default:
|
||||
panic(fmt.Sprintf("decoder: unsupported decoding for type %d", t))
|
||||
panic(fmt.Sprintf("decoder: unsupported decoding for type %d (%s)", t, t))
|
||||
}
|
||||
}
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user