update + repl fixed + bugfixes
This commit is contained in:
parent
d315a53fbd
commit
828ebb23c0
10 changed files with 138 additions and 124 deletions
223
core/vm.go
223
core/vm.go
|
|
@ -362,7 +362,7 @@ type VM struct {
|
|||
// local variable storage
|
||||
scope *Scope
|
||||
|
||||
stack *Stack[Value]
|
||||
Stack *Stack[Value]
|
||||
call *Stack[Call]
|
||||
}
|
||||
|
||||
|
|
@ -657,7 +657,7 @@ var DefaultGlobals = map[string]Value{
|
|||
func NewVM(chunk *Chunk, stackSize Pos, callstackSize Pos) *VM {
|
||||
vm := &VM{
|
||||
chunk: chunk,
|
||||
stack: NewStack[Value](stackSize),
|
||||
Stack: NewStack[Value](stackSize),
|
||||
call: NewStack[Call](callstackSize),
|
||||
|
||||
globals: DefaultGlobals,
|
||||
|
|
@ -682,7 +682,7 @@ func (vm *VM) Next() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
v := vm.stack.Pop()
|
||||
v := vm.Stack.Pop()
|
||||
c := vm.call.Pop()
|
||||
|
||||
// reset stack current and variable end and scope
|
||||
|
|
@ -692,10 +692,10 @@ func (vm *VM) Next() bool {
|
|||
vm.ip = c.ip
|
||||
vm.chunk = c.chunk
|
||||
|
||||
vm.stack.Push(v)
|
||||
vm.Stack.Push(v)
|
||||
|
||||
case InstructionPop:
|
||||
vm.stack.Pop()
|
||||
vm.Stack.Pop()
|
||||
|
||||
case InstructionConstant:
|
||||
c := vm.ReadConstant()
|
||||
|
|
@ -704,140 +704,140 @@ func (vm *VM) Next() bool {
|
|||
c.Scope = vm.scope
|
||||
}
|
||||
|
||||
vm.stack.Push(c)
|
||||
vm.Stack.Push(c)
|
||||
|
||||
case InstructionAddFloat:
|
||||
r := vm.stack.Pop().(*FloatValue).Number
|
||||
l := vm.stack.Pop().(*FloatValue).Number
|
||||
r := vm.Stack.Pop().(*FloatValue).Number
|
||||
l := vm.Stack.Pop().(*FloatValue).Number
|
||||
|
||||
vm.stack.Push(&FloatValue{l + r})
|
||||
vm.Stack.Push(&FloatValue{l + r})
|
||||
|
||||
case InstructionSubFloat:
|
||||
r := vm.stack.Pop().(*FloatValue).Number
|
||||
l := vm.stack.Pop().(*FloatValue).Number
|
||||
r := vm.Stack.Pop().(*FloatValue).Number
|
||||
l := vm.Stack.Pop().(*FloatValue).Number
|
||||
|
||||
vm.stack.Push(&FloatValue{l - r})
|
||||
vm.Stack.Push(&FloatValue{l - r})
|
||||
|
||||
case InstructionMulFloat:
|
||||
r := vm.stack.Pop().(*FloatValue).Number
|
||||
l := vm.stack.Pop().(*FloatValue).Number
|
||||
r := vm.Stack.Pop().(*FloatValue).Number
|
||||
l := vm.Stack.Pop().(*FloatValue).Number
|
||||
|
||||
vm.stack.Push(&FloatValue{l * r})
|
||||
vm.Stack.Push(&FloatValue{l * r})
|
||||
|
||||
case InstructionDivFloat:
|
||||
r := vm.stack.Pop().(*FloatValue).Number
|
||||
l := vm.stack.Pop().(*FloatValue).Number
|
||||
r := vm.Stack.Pop().(*FloatValue).Number
|
||||
l := vm.Stack.Pop().(*FloatValue).Number
|
||||
|
||||
vm.stack.Push(&FloatValue{l / r})
|
||||
vm.Stack.Push(&FloatValue{l / r})
|
||||
|
||||
case InstructionNegateFloat:
|
||||
v := vm.stack.Pop().(*FloatValue).Number
|
||||
v := vm.Stack.Pop().(*FloatValue).Number
|
||||
|
||||
vm.stack.Push(&FloatValue{-v})
|
||||
vm.Stack.Push(&FloatValue{-v})
|
||||
|
||||
case InstructionAddInt:
|
||||
r := vm.stack.Pop().(*IntegerValue).Number
|
||||
l := vm.stack.Pop().(*IntegerValue).Number
|
||||
r := vm.Stack.Pop().(*IntegerValue).Number
|
||||
l := vm.Stack.Pop().(*IntegerValue).Number
|
||||
|
||||
vm.stack.Push(&IntegerValue{new(big.Int).Add(l, r)})
|
||||
vm.Stack.Push(&IntegerValue{new(big.Int).Add(l, r)})
|
||||
|
||||
case InstructionSubInt:
|
||||
r := vm.stack.Pop().(*IntegerValue).Number
|
||||
l := vm.stack.Pop().(*IntegerValue).Number
|
||||
r := vm.Stack.Pop().(*IntegerValue).Number
|
||||
l := vm.Stack.Pop().(*IntegerValue).Number
|
||||
|
||||
vm.stack.Push(&IntegerValue{new(big.Int).Sub(l, r)})
|
||||
vm.Stack.Push(&IntegerValue{new(big.Int).Sub(l, r)})
|
||||
|
||||
case InstructionMulInt:
|
||||
r := vm.stack.Pop().(*IntegerValue).Number
|
||||
l := vm.stack.Pop().(*IntegerValue).Number
|
||||
r := vm.Stack.Pop().(*IntegerValue).Number
|
||||
l := vm.Stack.Pop().(*IntegerValue).Number
|
||||
|
||||
vm.stack.Push(&IntegerValue{new(big.Int).Mul(l, r)})
|
||||
vm.Stack.Push(&IntegerValue{new(big.Int).Mul(l, r)})
|
||||
|
||||
case InstructionDivInt:
|
||||
r := vm.stack.Pop().(*IntegerValue).Number
|
||||
l := vm.stack.Pop().(*IntegerValue).Number
|
||||
r := vm.Stack.Pop().(*IntegerValue).Number
|
||||
l := vm.Stack.Pop().(*IntegerValue).Number
|
||||
|
||||
vm.stack.Push(&IntegerValue{new(big.Int).Div(l, r)})
|
||||
vm.Stack.Push(&IntegerValue{new(big.Int).Div(l, r)})
|
||||
|
||||
case InstructionNegateInt:
|
||||
v := vm.stack.Pop().(*IntegerValue).Number
|
||||
v := vm.Stack.Pop().(*IntegerValue).Number
|
||||
|
||||
vm.stack.Push(&IntegerValue{new(big.Int).Neg(v)})
|
||||
vm.Stack.Push(&IntegerValue{new(big.Int).Neg(v)})
|
||||
|
||||
case InstructionEquals:
|
||||
vm.stack.Push(
|
||||
&BoolValue{vm.stack.Pop().Equals(vm.stack.Pop())},
|
||||
vm.Stack.Push(
|
||||
&BoolValue{vm.Stack.Pop().Equals(vm.Stack.Pop())},
|
||||
)
|
||||
|
||||
case InstructionNotEqual:
|
||||
vm.stack.Push(
|
||||
&BoolValue{!vm.stack.Pop().Equals(vm.stack.Pop())},
|
||||
vm.Stack.Push(
|
||||
&BoolValue{!vm.Stack.Pop().Equals(vm.Stack.Pop())},
|
||||
)
|
||||
|
||||
case InstructionNot:
|
||||
b := vm.stack.Pop().(*BoolValue).Boolean
|
||||
vm.stack.Push(&BoolValue{!b})
|
||||
b := vm.Stack.Pop().(*BoolValue).Boolean
|
||||
vm.Stack.Push(&BoolValue{!b})
|
||||
|
||||
case InstructionAnd:
|
||||
r := vm.stack.Pop().(*BoolValue).Boolean
|
||||
l := vm.stack.Pop().(*BoolValue).Boolean
|
||||
vm.stack.Push(&BoolValue{l && r})
|
||||
r := vm.Stack.Pop().(*BoolValue).Boolean
|
||||
l := vm.Stack.Pop().(*BoolValue).Boolean
|
||||
vm.Stack.Push(&BoolValue{l && r})
|
||||
|
||||
case InstructionOr:
|
||||
r := vm.stack.Pop().(*BoolValue).Boolean
|
||||
l := vm.stack.Pop().(*BoolValue).Boolean
|
||||
vm.stack.Push(&BoolValue{l || r})
|
||||
r := vm.Stack.Pop().(*BoolValue).Boolean
|
||||
l := vm.Stack.Pop().(*BoolValue).Boolean
|
||||
vm.Stack.Push(&BoolValue{l || r})
|
||||
|
||||
case InstructionLessFloat:
|
||||
r := vm.stack.Pop().(*FloatValue).Number
|
||||
l := vm.stack.Pop().(*FloatValue).Number
|
||||
r := vm.Stack.Pop().(*FloatValue).Number
|
||||
l := vm.Stack.Pop().(*FloatValue).Number
|
||||
|
||||
vm.stack.Push(&BoolValue{l < r})
|
||||
vm.Stack.Push(&BoolValue{l < r})
|
||||
|
||||
case InstructionLessOrEqualFloat:
|
||||
r := vm.stack.Pop().(*FloatValue).Number
|
||||
l := vm.stack.Pop().(*FloatValue).Number
|
||||
r := vm.Stack.Pop().(*FloatValue).Number
|
||||
l := vm.Stack.Pop().(*FloatValue).Number
|
||||
|
||||
vm.stack.Push(&BoolValue{l <= r})
|
||||
vm.Stack.Push(&BoolValue{l <= r})
|
||||
|
||||
case InstructionGreaterFloat:
|
||||
r := vm.stack.Pop().(*FloatValue).Number
|
||||
l := vm.stack.Pop().(*FloatValue).Number
|
||||
r := vm.Stack.Pop().(*FloatValue).Number
|
||||
l := vm.Stack.Pop().(*FloatValue).Number
|
||||
|
||||
vm.stack.Push(&BoolValue{l > r})
|
||||
vm.Stack.Push(&BoolValue{l > r})
|
||||
|
||||
case InstructionGreaterOrEqualFloat:
|
||||
r := vm.stack.Pop().(*FloatValue).Number
|
||||
l := vm.stack.Pop().(*FloatValue).Number
|
||||
r := vm.Stack.Pop().(*FloatValue).Number
|
||||
l := vm.Stack.Pop().(*FloatValue).Number
|
||||
|
||||
vm.stack.Push(&BoolValue{l >= r})
|
||||
vm.Stack.Push(&BoolValue{l >= r})
|
||||
|
||||
case InstructionLessInt:
|
||||
r := vm.stack.Pop().(*IntegerValue).Number
|
||||
l := vm.stack.Pop().(*IntegerValue).Number
|
||||
r := vm.Stack.Pop().(*IntegerValue).Number
|
||||
l := vm.Stack.Pop().(*IntegerValue).Number
|
||||
|
||||
vm.stack.Push(&BoolValue{l.Cmp(r) == -1})
|
||||
vm.Stack.Push(&BoolValue{l.Cmp(r) == -1})
|
||||
|
||||
case InstructionLessOrEqualInt:
|
||||
r := vm.stack.Pop().(*IntegerValue).Number
|
||||
l := vm.stack.Pop().(*IntegerValue).Number
|
||||
r := vm.Stack.Pop().(*IntegerValue).Number
|
||||
l := vm.Stack.Pop().(*IntegerValue).Number
|
||||
|
||||
vm.stack.Push(&BoolValue{l.Cmp(r) != 1})
|
||||
vm.Stack.Push(&BoolValue{l.Cmp(r) != 1})
|
||||
|
||||
case InstructionGreaterInt:
|
||||
r := vm.stack.Pop().(*IntegerValue).Number
|
||||
l := vm.stack.Pop().(*IntegerValue).Number
|
||||
r := vm.Stack.Pop().(*IntegerValue).Number
|
||||
l := vm.Stack.Pop().(*IntegerValue).Number
|
||||
|
||||
vm.stack.Push(&BoolValue{l.Cmp(r) == 1})
|
||||
vm.Stack.Push(&BoolValue{l.Cmp(r) == 1})
|
||||
|
||||
case InstructionGreaterOrEqualInt:
|
||||
r := vm.stack.Pop().(*IntegerValue).Number
|
||||
l := vm.stack.Pop().(*IntegerValue).Number
|
||||
r := vm.Stack.Pop().(*IntegerValue).Number
|
||||
l := vm.Stack.Pop().(*IntegerValue).Number
|
||||
|
||||
vm.stack.Push(&BoolValue{l.Cmp(r) != -1})
|
||||
vm.Stack.Push(&BoolValue{l.Cmp(r) != -1})
|
||||
|
||||
case InstructionCall:
|
||||
v := vm.stack.Pop()
|
||||
v := vm.Stack.Pop()
|
||||
switch f := v.(type) {
|
||||
case *FunctionValue:
|
||||
vm.call.Push(Call{
|
||||
|
|
@ -850,7 +850,7 @@ func (vm *VM) Next() bool {
|
|||
vm.descend()
|
||||
|
||||
for i := len(f.Params) - 1; i >= 0; i-- {
|
||||
vm.addVar(f.Params[i].Name, vm.stack.Pop())
|
||||
vm.addVar(f.Params[i].Name, vm.Stack.Pop())
|
||||
}
|
||||
|
||||
if f.Parent != nil {
|
||||
|
|
@ -863,7 +863,7 @@ func (vm *VM) Next() bool {
|
|||
args := make([]Value, len(f.Signature.In))
|
||||
|
||||
for i := len(f.Signature.In) - 1; i >= 0; i-- {
|
||||
args[i] = vm.stack.Pop()
|
||||
args[i] = vm.Stack.Pop()
|
||||
}
|
||||
|
||||
v, err := f.F(vm, f.Parent, args)
|
||||
|
|
@ -871,9 +871,13 @@ func (vm *VM) Next() bool {
|
|||
vm.error(err.Error())
|
||||
}
|
||||
|
||||
vm.stack.Push(v)
|
||||
if v == nil {
|
||||
v = &NilValue{}
|
||||
}
|
||||
|
||||
vm.Stack.Push(v)
|
||||
default:
|
||||
vm.error(fmt.Sprintf("value called is not a function (%s, type %T)", v.DebugString(), v))
|
||||
vm.error(fmt.Sprintf("%s (%s) is not callable ", v.DebugString(), v.Type()))
|
||||
return false
|
||||
}
|
||||
|
||||
|
|
@ -885,7 +889,7 @@ func (vm *VM) Next() bool {
|
|||
|
||||
case InstructionJumpFalse:
|
||||
n := vm.NextU16()
|
||||
if !vm.stack.Pop().(*BoolValue).Boolean {
|
||||
if !vm.Stack.Pop().(*BoolValue).Boolean {
|
||||
vm.ip += Pos(n)
|
||||
}
|
||||
|
||||
|
|
@ -898,10 +902,10 @@ func (vm *VM) Next() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
vm.stack.Push(v)
|
||||
vm.Stack.Push(v)
|
||||
|
||||
case InstructionSetLocal:
|
||||
value := vm.stack.Peek().Clone()
|
||||
value := vm.Stack.Peek().Clone()
|
||||
name := vm.GetConstant(vm.NextByte()).(*StringValue).Text
|
||||
|
||||
vm.setVar(name, value)
|
||||
|
|
@ -909,50 +913,50 @@ func (vm *VM) Next() bool {
|
|||
case InstructionDeclareLocal:
|
||||
vm.addVar(
|
||||
vm.GetConstant(vm.NextByte()).(*StringValue).Text,
|
||||
vm.stack.Peek().Clone(),
|
||||
vm.Stack.Peek().Clone(),
|
||||
)
|
||||
|
||||
case InstructionGetGlobal:
|
||||
vm.stack.Push(vm.globals[vm.GetConstant(vm.NextByte()).(*StringValue).Text])
|
||||
vm.Stack.Push(vm.globals[vm.GetConstant(vm.NextByte()).(*StringValue).Text])
|
||||
|
||||
case InstructionSetGlobal:
|
||||
vm.globals[vm.GetConstant(vm.NextByte()).(*StringValue).Text] = vm.stack.Pop()
|
||||
vm.globals[vm.GetConstant(vm.NextByte()).(*StringValue).Text] = vm.Stack.Pop()
|
||||
|
||||
case InstructionTrue:
|
||||
vm.stack.Push(&BoolValue{true})
|
||||
vm.Stack.Push(&BoolValue{true})
|
||||
|
||||
case InstructionFalse:
|
||||
vm.stack.Push(&BoolValue{false})
|
||||
vm.Stack.Push(&BoolValue{false})
|
||||
|
||||
case InstructionNil:
|
||||
vm.stack.Push(&NilValue{})
|
||||
vm.Stack.Push(&NilValue{})
|
||||
|
||||
case InstructionFormList:
|
||||
n := int(vm.NextU16())
|
||||
|
||||
items := make([]Value, n)
|
||||
for i := n - 1; i >= 0; i-- {
|
||||
items[i] = vm.stack.Pop()
|
||||
items[i] = vm.Stack.Pop()
|
||||
}
|
||||
|
||||
vm.stack.Push(&ListValue{
|
||||
vm.Stack.Push(&ListValue{
|
||||
items,
|
||||
})
|
||||
|
||||
case InstructionNewList:
|
||||
vm.stack.Push(&ListValue{[]Value{}})
|
||||
vm.Stack.Push(&ListValue{[]Value{}})
|
||||
|
||||
case InstructionAppend:
|
||||
value := vm.stack.Pop()
|
||||
list := vm.stack.Pop().(*ListValue)
|
||||
value := vm.Stack.Pop()
|
||||
list := vm.Stack.Pop().(*ListValue)
|
||||
list.Items = append(list.Items, value)
|
||||
vm.stack.Push(list)
|
||||
vm.Stack.Push(list)
|
||||
|
||||
case InstructionConcatLists:
|
||||
r := vm.stack.Pop().(*ListValue)
|
||||
l := vm.stack.Pop().(*ListValue)
|
||||
r := vm.Stack.Pop().(*ListValue)
|
||||
l := vm.Stack.Pop().(*ListValue)
|
||||
|
||||
vm.stack.Push(&ListValue{
|
||||
vm.Stack.Push(&ListValue{
|
||||
append(l.Items, r.Items...),
|
||||
})
|
||||
|
||||
|
|
@ -963,26 +967,26 @@ func (vm *VM) Next() bool {
|
|||
vm.ascend()
|
||||
|
||||
case InstructionStringConversion:
|
||||
v := vm.stack.Pop()
|
||||
vm.stack.Push(&StringValue{v.String()})
|
||||
v := vm.Stack.Pop()
|
||||
vm.Stack.Push(&StringValue{v.String()})
|
||||
|
||||
case InstructionStringConcatenation:
|
||||
r := vm.stack.Pop().(*StringValue).Text
|
||||
l := vm.stack.Pop().(*StringValue).Text
|
||||
r := vm.Stack.Pop().(*StringValue).Text
|
||||
l := vm.Stack.Pop().(*StringValue).Text
|
||||
|
||||
vm.stack.Push(&StringValue{l + r})
|
||||
vm.Stack.Push(&StringValue{l + r})
|
||||
|
||||
case InstructionSwap:
|
||||
r := vm.stack.Pop()
|
||||
l := vm.stack.Pop()
|
||||
r := vm.Stack.Pop()
|
||||
l := vm.Stack.Pop()
|
||||
|
||||
vm.stack.Push(r, l)
|
||||
vm.Stack.Push(r, l)
|
||||
|
||||
case InstructionDuplicate:
|
||||
vm.stack.Push(vm.stack.Peek().Clone())
|
||||
vm.Stack.Push(vm.Stack.Peek().Clone())
|
||||
|
||||
case InstructionAccessProperty:
|
||||
source := vm.stack.Pop()
|
||||
source := vm.Stack.Pop()
|
||||
property := vm.ReadConstant()
|
||||
|
||||
member, err := source.Get(property.(*StringValue).String())
|
||||
|
|
@ -997,7 +1001,7 @@ func (vm *VM) Next() bool {
|
|||
member.(*BuiltinFunctionValue).Parent = source
|
||||
}
|
||||
|
||||
vm.stack.Push(member)
|
||||
vm.Stack.Push(member)
|
||||
|
||||
case InstructionBreakpoint:
|
||||
/*
|
||||
|
|
@ -1009,7 +1013,7 @@ func (vm *VM) Next() bool {
|
|||
s = s.parent
|
||||
}
|
||||
*/
|
||||
vm.stack.Push(&NilValue{})
|
||||
vm.Stack.Push(&NilValue{})
|
||||
|
||||
default:
|
||||
panic("invalid byte code")
|
||||
|
|
@ -1027,6 +1031,9 @@ func (vm *VM) Call(v Value, args []Value) (Value, error) {
|
|||
scope: vm.scope,
|
||||
})
|
||||
|
||||
vm.scope = f.Scope
|
||||
vm.descend()
|
||||
|
||||
for i := 0; i < len(f.Params); i++ {
|
||||
vm.addVar(f.Params[i].Name, args[i])
|
||||
}
|
||||
|
|
@ -1043,7 +1050,7 @@ func (vm *VM) Call(v Value, args []Value) (Value, error) {
|
|||
|
||||
vm.Next()
|
||||
|
||||
return vm.stack.Pop(), nil
|
||||
return vm.Stack.Pop(), nil
|
||||
|
||||
case *BuiltinFunctionValue:
|
||||
return f.F(vm, f.Parent, args)
|
||||
|
|
@ -1069,6 +1076,10 @@ func (vm *VM) TryNextByte() (Bytecode, error) {
|
|||
vm.scope = c.scope
|
||||
}
|
||||
|
||||
if int(vm.ip) >= len(vm.chunk.Bytecode) {
|
||||
return 0, errors.New("there are no more instructions")
|
||||
}
|
||||
|
||||
v := vm.chunk.Bytecode[vm.ip]
|
||||
vm.ip++
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue