|
@@ -10,9 +10,12 @@ func (handler *Handler) Call(vm *VM, arguments ...Value) []Value {
|
|
|
return (*handler)(vm, arguments...)
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-type Caller interface {
|
|
|
+
|
|
|
+type Callable interface {
|
|
|
+
|
|
|
Call(vm *VM, arguments ...Value) []Value
|
|
|
+
|
|
|
+ Position() *Position
|
|
|
}
|
|
|
|
|
|
|
|
@@ -92,10 +95,6 @@ func NewBuiltinValue(name string, handler Handler) *BuiltinValue {
|
|
|
return result
|
|
|
}
|
|
|
|
|
|
-func (builtin *BuiltinValue) Call(vm *VM, arguments ...Value) []Value {
|
|
|
- return vm.CallBuiltin(builtin.Handler, arguments...)
|
|
|
-}
|
|
|
-
|
|
|
|
|
|
type BlockValue struct {
|
|
|
CallableValue
|
|
@@ -109,9 +108,32 @@ func NewBlockValue(definition *Ast) *BlockValue {
|
|
|
return result
|
|
|
}
|
|
|
|
|
|
-func (block *BlockValue) Call(vm *VM, arguments ...Value) []Value {
|
|
|
- res := vm.CallBlock(block.Ast, arguments...)
|
|
|
- return res
|
|
|
+func (block * BlockValue) Position() *Position {
|
|
|
+ if block == nil {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
+ if block.Ast == nil {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ pos := block.Ast.Token().Position
|
|
|
+ return &pos
|
|
|
+}
|
|
|
+
|
|
|
+func (defined * DefinedValue) Position() *Position {
|
|
|
+ if defined == nil {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
+ if defined.Body == nil {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ return defined.Body.Position()
|
|
|
+}
|
|
|
+
|
|
|
+func (cv CallableValue) Position() *Position {
|
|
|
+ pos := Position{cv.Name, 1, 1}
|
|
|
+ return &pos
|
|
|
}
|
|
|
|
|
|
|
|
@@ -123,7 +145,7 @@ type Parameter struct {
|
|
|
|
|
|
|
|
|
|
|
|
-type DefinedValue struct {
|
|
|
+type DefinedValue struct {
|
|
|
CallableValue
|
|
|
Body *BlockValue
|
|
|
Parameters []*Parameter
|
|
@@ -138,10 +160,6 @@ func NewDefinedValue(name string, params []*Parameter, body *BlockValue) *Define
|
|
|
}
|
|
|
|
|
|
func (defined *DefinedValue) Call(vm *VM, arguments ...Value) []Value {
|
|
|
- defer vm.PopFrame()
|
|
|
- defer vm.PopScope()
|
|
|
- vm.PushNewFrame()
|
|
|
- vm.PushNewScope()
|
|
|
for i , arg := range arguments {
|
|
|
if i >= len(defined.Parameters) {
|
|
|
break
|
|
@@ -230,7 +248,7 @@ func (signature Signature) IsMatch(other Signature) bool {
|
|
|
|
|
|
type Overload struct {
|
|
|
Name string
|
|
|
- Caller
|
|
|
+ Callable
|
|
|
}
|
|
|
|
|
|
|
|
@@ -283,7 +301,7 @@ func (cover *CoverValue) Call(vm *VM, arguments ...Value) []Value {
|
|
|
}
|
|
|
}
|
|
|
vm.Fail()
|
|
|
- return Fail(NewErrorValuef("Could not match cover %s with arguments: %s<->%v", cover.String(), signature))
|
|
|
+ return Fail(NewErrorValuef("Could not match cover %s with arguments: %s<->%v", cover.String(), signature, arguments))
|
|
|
}
|
|
|
|
|
|
const (
|
|
@@ -319,7 +337,7 @@ func (from BlockValue) Convert(to interface{}) error {
|
|
|
}
|
|
|
|
|
|
|
|
|
-func (cv * CoverValue) AddOverload(name string, callable Caller, tv ... TypeValue) error {
|
|
|
+func (cv * CoverValue) AddOverload(name string, callable Callable, tv ... TypeValue) error {
|
|
|
|
|
|
|
|
|
signature := Signature{}
|
|
@@ -332,20 +350,20 @@ func (cv * CoverValue) AddOverload(name string, callable Caller, tv ... TypeValu
|
|
|
signature.Types[i] = tv[i]
|
|
|
}
|
|
|
|
|
|
- cv.Overloads[signature] = Overload { Name: name, Caller: callable }
|
|
|
+ cv.Overloads[signature] = Overload { Name: name, Callable: callable }
|
|
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-func (vm * VM) AddOverload(from, target string, tv... TypeValue) error {
|
|
|
+func (vm * VM) AddOverload(from, target string, level int, tv... TypeValue) error {
|
|
|
var cover *CoverValue
|
|
|
- var callable Caller
|
|
|
+ var callable Callable
|
|
|
var ok bool
|
|
|
lookup := vm.Lookup(from)
|
|
|
if lookup == nil {
|
|
|
- cover = vm.RegisterCover(from)
|
|
|
+ cover = vm.RegisterCover(from, level)
|
|
|
} else if cover, ok = lookup.(*CoverValue) ; !ok {
|
|
|
return fmt.Errorf("%s exists and is not a cover value", from)
|
|
|
}
|
|
@@ -358,7 +376,7 @@ func (vm * VM) AddOverload(from, target string, tv... TypeValue) error {
|
|
|
}
|
|
|
|
|
|
|
|
|
- if callable, ok = lookup.(Caller) ; !ok {
|
|
|
+ if callable, ok = lookup.(Callable) ; !ok {
|
|
|
return fmt.Errorf("%s is not a callable value", target)
|
|
|
}
|
|
|
res := cover.AddOverload(target, callable, tv...)
|
|
@@ -371,11 +389,12 @@ func (vm * VM) AddOverload(from, target string, tv... TypeValue) error {
|
|
|
type OverloadDescription struct {
|
|
|
Target string
|
|
|
Types []TypeValue
|
|
|
+ Level int
|
|
|
}
|
|
|
|
|
|
func (vm * VM) AddOverloads(from string, descriptions ... OverloadDescription) error {
|
|
|
for _, od := range descriptions {
|
|
|
- err := vm.AddOverload(from, od.Target, od.Types...)
|
|
|
+ err := vm.AddOverload(from, od.Target, od.Level, od.Types...)
|
|
|
if err != nil {
|
|
|
panic(fmt.Errorf("internal error: could not register overloads: %s", err))
|
|
|
}
|
|
@@ -383,8 +402,8 @@ func (vm * VM) AddOverloads(from string, descriptions ... OverloadDescription) e
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-func Over(target string, types ... TypeValue) OverloadDescription {
|
|
|
- return OverloadDescription { Target: target, Types: types}
|
|
|
+func Over(target string, level int, types ... TypeValue) OverloadDescription {
|
|
|
+ return OverloadDescription { Target: target, Level: level, Types: types}
|
|
|
}
|
|
|
|
|
|
func (vm * VM) SetHelp(target, help string) error {
|
|
@@ -412,17 +431,6 @@ func NewScope(parent *Scope) *Scope {
|
|
|
return &Scope{parent, make([]*Scope, 0), make(map[string]Value)}
|
|
|
}
|
|
|
|
|
|
-func (scope *Scope) Parent(level int) *Scope {
|
|
|
- if level < 1 {
|
|
|
- return scope
|
|
|
- }
|
|
|
- parent := scope.parent
|
|
|
- for parent != nil && level > 1 {
|
|
|
- level--
|
|
|
- parent = parent.parent
|
|
|
- }
|
|
|
- return parent
|
|
|
-}
|
|
|
|
|
|
func (scope *Scope) Lookup(name string) Value {
|
|
|
value, ok := scope.symbols[name]
|
|
@@ -491,15 +499,17 @@ func (scope* Scope) DefinedHelpers() []Helper {
|
|
|
|
|
|
|
|
|
|
|
|
-type Frame struct {
|
|
|
+type Frame struct {
|
|
|
parent *Frame
|
|
|
arguments []Value
|
|
|
results []Value
|
|
|
failed bool
|
|
|
+ returned bool
|
|
|
+ position *Position
|
|
|
}
|
|
|
|
|
|
-func NewFrame(parent *Frame) *Frame {
|
|
|
- return &Frame{parent, EmptyValueArray(), EmptyValueArray(), false}
|
|
|
+func NewFrame(parent *Frame, position *Position) *Frame {
|
|
|
+ return &Frame{parent, EmptyValueArray(), EmptyValueArray(), false, false, position}
|
|
|
}
|
|
|
|
|
|
type Tracer interface {
|
|
@@ -517,14 +527,14 @@ type VM struct {
|
|
|
}
|
|
|
|
|
|
func NewVM() *VM {
|
|
|
- vm := &VM{NewScope(nil), NewFrame(nil), nil, nil, nil, 0}
|
|
|
+ vm := &VM{NewScope(nil), NewFrame(nil, nil), nil, nil, nil, 0}
|
|
|
vm.Scope = vm.TopScope
|
|
|
vm.Frame = vm.TopFrame
|
|
|
return vm
|
|
|
}
|
|
|
|
|
|
-func (vm *VM) PushNewFrame() *Frame {
|
|
|
- frame := NewFrame(vm.Frame)
|
|
|
+func (vm *VM) PushNewFrame(position *Position) *Frame {
|
|
|
+ frame := NewFrame(vm.Frame, position)
|
|
|
vm.Frame = frame
|
|
|
return frame
|
|
|
}
|
|
@@ -535,10 +545,23 @@ func (vm *VM) PushNewScope() *Scope {
|
|
|
return scope
|
|
|
}
|
|
|
|
|
|
+func (vm *VM) Return(results ...Value) []Value {
|
|
|
+ return results
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
func (vm *VM) PopFrame() *Frame {
|
|
|
if (vm.Frame != vm.TopFrame) && (vm.Frame.parent != nil) {
|
|
|
frame := vm.Frame
|
|
|
+ if frame.returned || frame.failed {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
vm.Frame = frame.parent
|
|
|
+ vm.Frame.returned = frame.returned
|
|
|
+ vm.Frame.failed = frame.failed
|
|
|
+ vm.Frame.results = frame.results
|
|
|
return frame
|
|
|
}
|
|
|
return nil
|
|
@@ -553,6 +576,18 @@ func (vm *VM) PopScope() *Scope {
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
+func (block * BlockValue) Call(vm *VM, arguments ...Value) []Value {
|
|
|
+ ast := block.Ast
|
|
|
+ arr := vm.RunChildren(*ast, arguments...)
|
|
|
+ return arr
|
|
|
+}
|
|
|
+
|
|
|
+func (builtin * BuiltinValue) Call(vm *VM, arguments ...Value) []Value {
|
|
|
+ handler := builtin.Handler
|
|
|
+ return handler.Call(vm, arguments...)
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
func (vm *VM) CallDefined(ast *Ast, arguments ...Value) []Value {
|
|
|
arr := vm.RunChildren(*ast, arguments...)
|
|
|
return arr
|
|
@@ -570,9 +605,42 @@ func (vm *VM) CallBuiltin(handler Handler, arguments ...Value) []Value {
|
|
|
func (vm *VM) CallCover(cover * CoverValue, arguments ...Value) []Value {
|
|
|
return cover.Call(vm, arguments...)
|
|
|
}
|
|
|
+*/
|
|
|
|
|
|
|
|
|
+func (vm *VM) AddTrace(err error) error {
|
|
|
+ res := ""
|
|
|
+ for frame := vm.Frame; frame != nil; frame = frame.parent {
|
|
|
+ if frame.position == nil {
|
|
|
+ res = fmt.Sprintf("%s\nIn frame %v", res, frame)
|
|
|
+ } else {
|
|
|
+ res = fmt.Sprintf("%s\nIn %s", res, frame.position.String())
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return fmt.Errorf("%s: %s", res, err)
|
|
|
+}
|
|
|
+
|
|
|
+func (vm *VM) CallCallable(callable Callable, arguments ...Value) []Value {
|
|
|
+ defer vm.PopFrame()
|
|
|
+ defer vm.PopScope()
|
|
|
+ vm.PushNewFrame(callable.Position())
|
|
|
+ vm.PushNewScope()
|
|
|
+ return callable.Call(vm, arguments...)
|
|
|
+}
|
|
|
+
|
|
|
func (vm *VM) CallNamed(name string, arguments ...Value) []Value {
|
|
|
+ value := vm.Lookup(name)
|
|
|
+ if value == nil {
|
|
|
+ return ReturnError(vm.AddTrace(NewErrorValuef("Cannot call %s: not found.", name)))
|
|
|
+ }
|
|
|
+
|
|
|
+ if callable, ok := value.(Callable) ; ok {
|
|
|
+ return vm.CallCallable(callable, arguments...)
|
|
|
+ } else {
|
|
|
+ return ReturnError(vm.AddTrace(NewErrorValuef("Cannot call %s: %v. Not callable", name, value)))
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
value := vm.Lookup(name)
|
|
|
switch toCall := value.(type) {
|
|
|
case *BuiltinValue:
|
|
@@ -584,8 +652,9 @@ func (vm *VM) CallNamed(name string, arguments ...Value) []Value {
|
|
|
case *BlockValue:
|
|
|
return vm.CallBlock(toCall.Ast, arguments...)
|
|
|
default:
|
|
|
- return ReturnError(NewErrorValuef("Cannot call %s: %v", name, value))
|
|
|
+ return ReturnError(vm.AddTrace(NewErrorValuef("Cannot call %s: %v. Not callable", name, value)))
|
|
|
}
|
|
|
+ */
|
|
|
}
|
|
|
|
|
|
|
|
@@ -595,13 +664,34 @@ func (vm * VM) CallNamedFramed(name string, arguments ...) []Value {
|
|
|
}
|
|
|
*/
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+func (vm * VM) ScopeUp(level int) *Scope {
|
|
|
+ scope := vm.Scope
|
|
|
+ for now := 0; now < level; now++ {
|
|
|
+ if scope.parent == nil {
|
|
|
+ return scope
|
|
|
+ }
|
|
|
+ scope = scope.parent
|
|
|
+ }
|
|
|
+ return scope
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+func (vm *VM) RegisterUp(name string, value Value, level int) Value {
|
|
|
+ scope := vm.ScopeUp(level)
|
|
|
+ return scope.Register(name, value)
|
|
|
+}
|
|
|
+
|
|
|
func (vm *VM) Register(name string, value Value) Value {
|
|
|
return vm.Scope.Register(name, value)
|
|
|
}
|
|
|
|
|
|
-func (vm *VM) RegisterCover(name string) *CoverValue {
|
|
|
+func (vm *VM) RegisterCover(name string, level int) *CoverValue {
|
|
|
value := NewCoverValue(name)
|
|
|
- vm.Register(name, value)
|
|
|
+ vm.RegisterUp(name, value, level)
|
|
|
return value
|
|
|
}
|
|
|
|
|
@@ -610,9 +700,9 @@ func (vm *VM) RegisterBuiltin(name string, handler Handler) Value {
|
|
|
return vm.Register(name, value)
|
|
|
}
|
|
|
|
|
|
-func (vm *VM) RegisterDefined(name string, params []*Parameter, block *BlockValue) Value {
|
|
|
+func (vm *VM) RegisterDefined(name string, params []*Parameter, block *BlockValue, level int) Value {
|
|
|
value := NewDefinedValue(name, params, block)
|
|
|
- return vm.Register(name, value)
|
|
|
+ return vm.RegisterUp(name, value, level)
|
|
|
}
|
|
|
|
|
|
|
|
@@ -638,6 +728,11 @@ func (vm *VM) RunChildren(ast Ast, args ...Value) []Value {
|
|
|
for _, child := range ast.Children() {
|
|
|
val := child.Run(vm, args...)
|
|
|
|
|
|
+ if vm.Frame.returned || vm.Frame.failed {
|
|
|
+ fmt.Printf("Returned.\n")
|
|
|
+ return vm.Frame.results
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
if len(val) < 1 {
|
|
|
continue
|
|
@@ -663,6 +758,12 @@ func (vm *VM) RunChildrenLastResult(ast Ast, args ...Value) Value {
|
|
|
var result Value = EmptyValue{}
|
|
|
for _, child := range ast.Children() {
|
|
|
val := child.Run(vm, args...)
|
|
|
+
|
|
|
+ if vm.Frame.returned || vm.Frame.failed {
|
|
|
+ fmt.Printf("Returned.\n")
|
|
|
+ res := vm.Frame.results
|
|
|
+ return res[len(res)-1]
|
|
|
+ }
|
|
|
|
|
|
|
|
|
if len(val) < 1 {
|
|
@@ -690,7 +791,13 @@ func (vm *VM) RunChildrenFirstResult(ast Ast, args ...Value) Value {
|
|
|
var result Value = EmptyValue{}
|
|
|
for _, child := range ast.Children() {
|
|
|
val := child.Run(vm, args...)
|
|
|
-
|
|
|
+
|
|
|
+ if vm.Frame.returned || vm.Frame.failed {
|
|
|
+ fmt.Printf("Returned.\n")
|
|
|
+ res := vm.Frame.results
|
|
|
+ return res[0]
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
if len(val) < 1 {
|
|
|
continue
|