misc fixes
Some checks failed
Build / build (push) Successful in 10m45s
Publish Image / publish (push) Failing after 42s
Test / build (push) Successful in 11m9s

This commit is contained in:
2024-04-01 17:44:15 -04:00
parent 99f7553d67
commit fe33fda0ab
8 changed files with 91 additions and 10 deletions

View File

@@ -18,3 +18,17 @@ func (e BinaryOpError) Error() string {
func NewBinaryOpError(left, right Object, op string) BinaryOpError {
return BinaryOpError{left, right, op}
}
// DivisionByZeroError is an error returned when dividing by zero
type DivisionByZeroError struct {
left Object
}
func (e DivisionByZeroError) Error() string {
return fmt.Sprintf("cannot divide %s by zero", e.left)
}
// NewDivisionByZeroError returns a new DivisionByZeroError
func NewDivisionByZeroError(left Object) DivisionByZeroError {
return DivisionByZeroError{left}
}

View File

@@ -65,6 +65,9 @@ func (i Integer) Mul(other Object) (Object, error) {
func (i Integer) Div(other Object) (Object, error) {
switch obj := other.(type) {
case Integer:
if obj.Value == 0 {
return nil, NewDivisionByZeroError(i)
}
return Integer{i.Value / obj.Value}, nil
default:
return nil, NewBinaryOpError(i, other, "/")

View File

@@ -130,11 +130,19 @@ func (vm *VM) currentFrame() *Frame {
}
func (vm *VM) pushFrame(f Frame) {
if vm.fp >= MaxFrames {
panic("frame overflow")
}
vm.frames[vm.fp] = f
vm.fp++
}
func (vm *VM) popFrame() Frame {
if vm.fp == 0 {
panic("fame underflow")
}
vm.fp--
return vm.frames[vm.fp]
}
@@ -201,6 +209,10 @@ func (vm *VM) push(o object.Object) error {
}
func (vm *VM) pop() object.Object {
if vm.sp == 0 {
panic("stack underflow")
}
o := vm.stack[vm.sp-1]
vm.sp--
return o
@@ -768,20 +780,22 @@ func (vm *VM) Run() (err error) {
if vm.Debug {
start := time.Now()
defer func() {
end := time.Now().Sub(start)
total := 0
opcodes := make([]code.Opcode, 0, len(opcodeFreqs))
for opcode := range opcodeFreqs {
for opcode, count := range opcodeFreqs {
opcodes = append(opcodes, opcode)
total += count
}
sort.SliceStable(opcodes, func(i, j int) bool {
return opcodeFreqs[opcodes[i]] > opcodeFreqs[opcodes[j]]
})
log.Printf("%d instructions executed in %s", total, time.Now().Sub(start))
log.Print("Top 10 instructions:")
for _, opcode := range opcodes[:10] {
log.Printf("%d instructions executed in %s %d/µs", total, end, total/int(end.Microseconds()))
log.Print("Top Instructions:")
for _, opcode := range opcodes[:min(len(opcodes), 10)] {
log.Printf("%10d %s", opcodeFreqs[opcode], opcode)
}
}()