|
@@ -1,7 +1,7 @@
|
|
// vm, the virtual low level machine that runs MUESLI.
|
|
// vm, the virtual low level machine that runs MUESLI.
|
|
package muesli
|
|
package muesli
|
|
|
|
|
|
-// import "fmt"
|
|
|
|
|
|
+import "fmt"
|
|
|
|
|
|
// Handler function
|
|
// Handler function
|
|
type Handler func(vm *VM, arguments ...Value) []Value
|
|
type Handler func(vm *VM, arguments ...Value) []Value
|
|
@@ -46,8 +46,8 @@ func NewCallableValue(name string) CallableValue {
|
|
return CallableValue{name}
|
|
return CallableValue{name}
|
|
}
|
|
}
|
|
|
|
|
|
-func NewBuiltinValue(name string, handler Handler) BuiltinValue {
|
|
|
|
- result := BuiltinValue{}
|
|
|
|
|
|
+func NewBuiltinValue(name string, handler Handler) *BuiltinValue {
|
|
|
|
+ result := &BuiltinValue{}
|
|
result.Name = name
|
|
result.Name = name
|
|
result.Handler = handler
|
|
result.Handler = handler
|
|
return result
|
|
return result
|
|
@@ -63,8 +63,8 @@ type DefinedValue struct {
|
|
Definition *Ast
|
|
Definition *Ast
|
|
}
|
|
}
|
|
|
|
|
|
-func NewDefinedValue(name string, definition *Ast) DefinedValue {
|
|
|
|
- result := DefinedValue{}
|
|
|
|
|
|
+func NewDefinedValue(name string, definition *Ast) *DefinedValue {
|
|
|
|
+ result := &DefinedValue{}
|
|
result.Name = name
|
|
result.Name = name
|
|
result.Definition = definition
|
|
result.Definition = definition
|
|
return result
|
|
return result
|
|
@@ -87,31 +87,40 @@ type Signature struct {
|
|
|
|
|
|
func CalculateSignature(arguments ...Value) Signature {
|
|
func CalculateSignature(arguments ...Value) Signature {
|
|
signature := Signature{}
|
|
signature := Signature{}
|
|
- for i := 0; i < cap(signature.Types); i++ {
|
|
|
|
- if i > len(arguments) {
|
|
|
|
- signature.Types[i] = AnyTypeValue
|
|
|
|
- } else {
|
|
|
|
|
|
+ for i := 0; i < len(signature.Types); i++ {
|
|
|
|
+ if i < len(arguments) {
|
|
signature.Types[i] = arguments[i].Type()
|
|
signature.Types[i] = arguments[i].Type()
|
|
|
|
+ } else {
|
|
|
|
+ signature.Types[i] = AnyTypeValue
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return signature
|
|
return signature
|
|
}
|
|
}
|
|
|
|
|
|
-func (signature *Signature) IsMatch(arguments ...Value) bool {
|
|
|
|
|
|
+func (tv TypeValue) IsMatch(other TypeValue) bool {
|
|
|
|
+ if tv == AnyTypeValue || other == AnyTypeValue {
|
|
|
|
+ return true
|
|
|
|
+ }
|
|
|
|
+ if tv == ZeroTypeValue || other == ZeroTypeValue {
|
|
|
|
+ return true
|
|
|
|
+ }
|
|
|
|
+ return tv == other
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (signature Signature) IsMatch(other Signature) bool {
|
|
for i, kind := range signature.Types {
|
|
for i, kind := range signature.Types {
|
|
- if i > len(arguments) || arguments[i] == nil {
|
|
|
|
- return false
|
|
|
|
- }
|
|
|
|
- if kind != arguments[i].Type() && kind != AnyTypeValue {
|
|
|
|
|
|
+ t1 := kind
|
|
|
|
+ t2 := other.Types[i]
|
|
|
|
+ if !t1.IsMatch(t2) {
|
|
return false
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return true
|
|
return true
|
|
}
|
|
}
|
|
|
|
|
|
-/* An overload is an overloaded callable value that can be called. */
|
|
|
|
|
|
+/* An overload is an overloaded value that can be called. */
|
|
type Overload struct {
|
|
type Overload struct {
|
|
- CallableValue
|
|
|
|
|
|
+ Caller
|
|
}
|
|
}
|
|
|
|
|
|
/* A cover is a callable that dispatches to other callables depending on
|
|
/* A cover is a callable that dispatches to other callables depending on
|
|
@@ -123,8 +132,17 @@ type CoverValue struct {
|
|
Overloads map[Signature]Overload
|
|
Overloads map[Signature]Overload
|
|
}
|
|
}
|
|
|
|
|
|
-func NewCoverValue(name string) CoverValue {
|
|
|
|
- result := CoverValue{}
|
|
|
|
|
|
+func (cv CoverValue) String() string {
|
|
|
|
+ res := fmt.Sprintf("cover %s [ ", cv.Name)
|
|
|
|
+ for k, v := range cv.Overloads {
|
|
|
|
+ res = fmt.Sprintf("%s [%v] %v", res, k, v.Caller)
|
|
|
|
+ }
|
|
|
|
+ res = fmt.Sprintf("%s].", res)
|
|
|
|
+ return res;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func NewCoverValue(name string) *CoverValue {
|
|
|
|
+ result := &CoverValue{}
|
|
result.Name = name
|
|
result.Name = name
|
|
result.Overloads = make(map[Signature]Overload)
|
|
result.Overloads = make(map[Signature]Overload)
|
|
return result
|
|
return result
|
|
@@ -135,14 +153,14 @@ func (cover *CoverValue) Call(vm *VM, arguments ...Value) []Value {
|
|
if overload, ok := cover.Overloads[signature]; ok {
|
|
if overload, ok := cover.Overloads[signature]; ok {
|
|
return overload.Call(vm, arguments...)
|
|
return overload.Call(vm, arguments...)
|
|
} else {
|
|
} else {
|
|
- for signature, overload := range cover.Overloads {
|
|
|
|
- if signature.IsMatch(arguments...) {
|
|
|
|
|
|
+ for overloadSignature, overload := range cover.Overloads {
|
|
|
|
+ if signature.IsMatch(overloadSignature) {
|
|
return overload.Call(vm, arguments...)
|
|
return overload.Call(vm, arguments...)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
vm.Fail()
|
|
vm.Fail()
|
|
- return ReturnError(NewErrorValuef("Could not match cover %s with arguments.", cover.Name))
|
|
|
|
|
|
+ return Fail(NewErrorValuef("Could not match cover %s with arguments: %s<->%v", cover.String(), signature))
|
|
}
|
|
}
|
|
|
|
|
|
const (
|
|
const (
|
|
@@ -167,8 +185,54 @@ func (from DefinedValue) Convert(to interface{}) error {
|
|
return NewErrorValuef("Cannot convert the defined value %v to %v", from, to)
|
|
return NewErrorValuef("Cannot convert the defined value %v to %v", from, to)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+func (cv * CoverValue) AddOverload(callable Caller, tv ... TypeValue) error {
|
|
|
|
+ fmt.Printf("AddOverload: %v\n", tv)
|
|
|
|
+
|
|
|
|
+ signature := Signature{}
|
|
|
|
+ length := len(tv)
|
|
|
|
+ if length > len(signature.Types) {
|
|
|
|
+ length = len(signature.Types)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for i := 0; i < length; i++ {
|
|
|
|
+ signature.Types[i] = tv[i]
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ cv.Overloads[signature] = Overload { callable }
|
|
|
|
+
|
|
|
|
+ fmt.Printf("Overloads: %v\n", cv.Overloads)
|
|
|
|
+
|
|
|
|
+ return nil
|
|
|
|
+}
|
|
|
|
|
|
-
|
|
|
|
|
|
+func (vm * VM) AddOverload(from, target string, tv... TypeValue) error {
|
|
|
|
+ var cover *CoverValue
|
|
|
|
+ var callable Caller
|
|
|
|
+ var ok bool
|
|
|
|
+ lookup := vm.Lookup(from)
|
|
|
|
+ if lookup == nil {
|
|
|
|
+ cover = vm.RegisterCover(from)
|
|
|
|
+ } else if cover, ok = lookup.(*CoverValue) ; !ok {
|
|
|
|
+ return fmt.Errorf("%s exists and is not a cover value", from)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fmt.Printf("AddOverload: %v %v\n", lookup, cover)
|
|
|
|
+
|
|
|
|
+ lookup = vm.Lookup(target)
|
|
|
|
+ if lookup == nil {
|
|
|
|
+ return fmt.Errorf("target %s is not defined", target)
|
|
|
|
+ }
|
|
|
|
+ fmt.Printf("AddOverload lookup: %v\n", lookup)
|
|
|
|
+
|
|
|
|
+ if callable, ok = lookup.(Caller) ; !ok {
|
|
|
|
+ return fmt.Errorf("%s is not a callable value", target)
|
|
|
|
+ }
|
|
|
|
+ res := cover.AddOverload(callable, tv...)
|
|
|
|
+
|
|
|
|
+ fmt.Printf("AddOverload: %v %v\n", lookup, cover)
|
|
|
|
+
|
|
|
|
+ return res
|
|
|
|
+}
|
|
|
|
|
|
// Scope of symbols defined in the VM, hierarchical
|
|
// Scope of symbols defined in the VM, hierarchical
|
|
type Scope struct {
|
|
type Scope struct {
|
|
@@ -280,7 +344,7 @@ func (vm *VM) CallBuiltin(handler Handler, arguments ...Value) []Value {
|
|
return handler.Call(vm, arguments...)
|
|
return handler.Call(vm, arguments...)
|
|
}
|
|
}
|
|
|
|
|
|
-func (vm *VM) CallCover(cover CoverValue, arguments ...Value) []Value {
|
|
|
|
|
|
+func (vm *VM) CallCover(cover * CoverValue, arguments ...Value) []Value {
|
|
return cover.Call(vm, arguments...)
|
|
return cover.Call(vm, arguments...)
|
|
}
|
|
}
|
|
|
|
|
|
@@ -288,11 +352,11 @@ func (vm *VM) CallCover(cover CoverValue, arguments ...Value) []Value {
|
|
func (vm *VM) CallNamed(name string, arguments ...Value) []Value {
|
|
func (vm *VM) CallNamed(name string, arguments ...Value) []Value {
|
|
value := vm.Lookup(name)
|
|
value := vm.Lookup(name)
|
|
switch toCall := value.(type) {
|
|
switch toCall := value.(type) {
|
|
- case BuiltinValue:
|
|
|
|
|
|
+ case *BuiltinValue:
|
|
return vm.CallBuiltin(toCall.Handler, arguments...)
|
|
return vm.CallBuiltin(toCall.Handler, arguments...)
|
|
- case DefinedValue:
|
|
|
|
|
|
+ case *DefinedValue:
|
|
return vm.CallDefined(toCall.Definition, arguments...)
|
|
return vm.CallDefined(toCall.Definition, arguments...)
|
|
- case CoverValue:
|
|
|
|
|
|
+ case *CoverValue:
|
|
return vm.CallCover(toCall, arguments...)
|
|
return vm.CallCover(toCall, arguments...)
|
|
default:
|
|
default:
|
|
return ReturnError(NewErrorValuef("Cannot call %s: %v", name, value))
|
|
return ReturnError(NewErrorValuef("Cannot call %s: %v", name, value))
|
|
@@ -310,9 +374,10 @@ func (vm *VM) Register(name string, value Value) Value {
|
|
return vm.Scope.Register(name, value)
|
|
return vm.Scope.Register(name, value)
|
|
}
|
|
}
|
|
|
|
|
|
-func (vm *VM) RegisterCover(name string) Value {
|
|
|
|
|
|
+func (vm *VM) RegisterCover(name string) *CoverValue {
|
|
value := NewCoverValue(name)
|
|
value := NewCoverValue(name)
|
|
- return vm.Register(name, value)
|
|
|
|
|
|
+ vm.Register(name, value)
|
|
|
|
+ return value
|
|
}
|
|
}
|
|
|
|
|
|
func (vm *VM) RegisterBuiltin(name string, handler Handler) Value {
|
|
func (vm *VM) RegisterBuiltin(name string, handler Handler) Value {
|