update + repl fixed + bugfixes
This commit is contained in:
parent
d315a53fbd
commit
828ebb23c0
10 changed files with 138 additions and 124 deletions
|
|
@ -2,4 +2,4 @@ module neemek.com/anglais/cli
|
|||
|
||||
go 1.25
|
||||
|
||||
require github.com/alecthomas/kong v1.12.1
|
||||
require github.com/alecthomas/kong v1.15.0
|
||||
|
|
|
|||
|
|
@ -4,7 +4,10 @@ github.com/alecthomas/kong v1.5.1 h1:9quB93P2aNGXf5C1kWNei85vjBgITNJQA4dSwJQGCOY
|
|||
github.com/alecthomas/kong v1.5.1/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU=
|
||||
github.com/alecthomas/kong v1.12.1 h1:iq6aMJDcFYP9uFrLdsiZQ2ZMmcshduyGv4Pek0MQPW0=
|
||||
github.com/alecthomas/kong v1.12.1/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU=
|
||||
github.com/alecthomas/kong v1.15.0 h1:BVJstKbpO73zKpmIu+m/aLRrNmWwxXPIGTNin9VmLVI=
|
||||
github.com/alecthomas/kong v1.15.0/go.mod h1:wrlbXem1CWqUV5Vbmss5ISYhsVPkBb1Yo7YKJghju2I=
|
||||
github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
|
||||
github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
|
||||
github.com/alecthomas/repr v0.5.2 h1:SU73FTI9D1P5UNtvseffFSGmdNci/O6RsqzeXJtP0Qs=
|
||||
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
|
||||
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
|
||||
|
|
|
|||
|
|
@ -3,13 +3,14 @@ package main
|
|||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"github.com/alecthomas/kong"
|
||||
"log"
|
||||
"neemek.com/anglais/core"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/kong"
|
||||
"neemek.com/anglais/core"
|
||||
)
|
||||
|
||||
type Context struct {
|
||||
|
|
@ -306,6 +307,8 @@ func (cmd *ReplCmd) Run(ctx *Context) error {
|
|||
vm.SetChunk(c.Chunk)
|
||||
for vm.Next() {
|
||||
}
|
||||
|
||||
println(vm.Stack.Pop().DebugString())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ func TestAll(t *testing.T) {
|
|||
|
||||
t.Log("Comparing stacks")
|
||||
|
||||
CompareStacks(t, tc.expectedStack, vm.stack)
|
||||
CompareStacks(t, tc.expectedStack, vm.Stack)
|
||||
|
||||
// expected scope == nil => we don't care
|
||||
if tc.expectedScope != nil {
|
||||
|
|
|
|||
|
|
@ -966,6 +966,8 @@ func (c *Compiler) deduceSignature(tree Node) (TypeSignature, error) {
|
|||
}
|
||||
|
||||
return c.deduceSignature(n.statements[len(n.statements)-1])
|
||||
case AssignNodeType:
|
||||
return c.deduceSignature(tree.(*AssignNode).value)
|
||||
default:
|
||||
return nil, c.error(fmt.Sprintf("impossible to deduce signature of %s", tree.Type()), tree)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -642,7 +642,7 @@ func TestCompile(t *testing.T) {
|
|||
}
|
||||
t.Log("Executed bytecode")
|
||||
|
||||
CompareStacks(t, testCase.expectedStack, vm.stack)
|
||||
CompareStacks(t, testCase.expectedStack, vm.Stack)
|
||||
CompareScope(t, testCase.expectedScope, vm.scope)
|
||||
})
|
||||
}
|
||||
|
|
@ -693,8 +693,8 @@ func TestCompiler_CleanStack(t *testing.T) {
|
|||
}
|
||||
|
||||
// make sure stack has only assigned values
|
||||
for i := 1; i < int(vm.stack.Current); i++ {
|
||||
v := vm.stack.items[i]
|
||||
for i := 1; i < int(vm.Stack.Current); i++ {
|
||||
v := vm.Stack.items[i]
|
||||
|
||||
if v == nil || v.Type() != VariableValueType {
|
||||
t.Errorf("Unclean stack! value %v at %d on the stack is intermediary", v.String(), i)
|
||||
|
|
|
|||
|
|
@ -343,7 +343,7 @@ func (p *Parser) expression(mustBeBlock bool) (Node, error) {
|
|||
yield,
|
||||
logic,
|
||||
start,
|
||||
start + p.prev.End,
|
||||
p.prev.End,
|
||||
}
|
||||
|
||||
if name != nil {
|
||||
|
|
@ -352,7 +352,7 @@ func (p *Parser) expression(mustBeBlock bool) (Node, error) {
|
|||
fn,
|
||||
true,
|
||||
start,
|
||||
start + p.prev.End,
|
||||
p.prev.End,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
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++
|
||||
|
||||
|
|
|
|||
|
|
@ -76,8 +76,8 @@ func TestNewVM(t *testing.T) {
|
|||
}
|
||||
|
||||
// should have given stack size
|
||||
if vm.stack.Capacity != stackSize {
|
||||
t.Errorf("vm.stack.Capacity = %d, want %d", vm.stack.Capacity, stackSize)
|
||||
if vm.Stack.Capacity != stackSize {
|
||||
t.Errorf("vm.stack.Capacity = %d, want %d", vm.Stack.Capacity, stackSize)
|
||||
}
|
||||
|
||||
// should have given call stack size
|
||||
|
|
@ -628,7 +628,7 @@ func TestVM_Execution(t *testing.T) {
|
|||
for vm.Next() {
|
||||
}
|
||||
|
||||
CompareStacks(t, test.resultingStack, vm.stack)
|
||||
CompareStacks(t, test.resultingStack, vm.Stack)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
7
era3.ang
7
era3.ang
|
|
@ -1,16 +1,11 @@
|
|||
fn counter() -> (fn() -> int) {
|
||||
i := 0
|
||||
|
||||
fn() -> int {
|
||||
i = i + 1
|
||||
}
|
||||
fn() -> int { i = i + 1 }
|
||||
}
|
||||
|
||||
next := counter()
|
||||
other := counter()
|
||||
|
||||
println(next())
|
||||
println(next())
|
||||
println(other())
|
||||
println(other())
|
||||
println(next())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue