|
@@ -33,7 +33,8 @@ type Helper interface {
|
|
|
}
|
|
|
|
|
|
|
|
|
-
|
|
|
+
|
|
|
+
|
|
|
type BasicCallable struct {
|
|
|
|
|
|
Name string
|
|
@@ -80,8 +81,9 @@ func (bc * BasicCallable) Takes(arguments ...TypeValue) *BasicCallable {
|
|
|
return bc
|
|
|
}
|
|
|
|
|
|
-func (bc * BasicCallable) Returns(arguments ...TypeValue) {
|
|
|
+func (bc * BasicCallable) Returns(arguments ...TypeValue) *BasicCallable {
|
|
|
bc.signature.SetReturns(arguments...)
|
|
|
+ return bc
|
|
|
}
|
|
|
|
|
|
|
|
@@ -94,7 +96,7 @@ func (val BasicCallable) Type() TypeValue {
|
|
|
}
|
|
|
|
|
|
func (from BasicCallable) Convert(to interface{}) error {
|
|
|
- return NewErrorValuef("Cannot convert the callable value %v to %v", from, to)
|
|
|
+ return NewErrorValuef("Cannot convert the callable value %v to %v: Not implemented.", from, to)
|
|
|
}
|
|
|
|
|
|
func (val *BasicCallable) Call(vm *VM, arguments ...Value) []Value {
|
|
@@ -207,64 +209,6 @@ func (defined *DefinedValue) Help() string {
|
|
|
|
|
|
var _ Callable = &DefinedValue{}
|
|
|
|
|
|
-
|
|
|
-type Overload struct {
|
|
|
- Name string
|
|
|
- Callable
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-the types of the arguments, in particular the first one. The individual
|
|
|
-callable functions are the overloads
|
|
|
-*/
|
|
|
-type CoverValue struct {
|
|
|
- BasicCallable
|
|
|
- Overloads map[Signature]Overload
|
|
|
-}
|
|
|
-
|
|
|
-func (cv CoverValue) String() string {
|
|
|
- res := fmt.Sprintf("cover %s [ ", cv.Name)
|
|
|
- for k, v := range cv.Overloads {
|
|
|
- res = fmt.Sprintf("%s [%v] %s", res, k, v.Name)
|
|
|
- }
|
|
|
- res = fmt.Sprintf("%s].", res)
|
|
|
- return res;
|
|
|
-}
|
|
|
-
|
|
|
-func NewCoverValue(name string) *CoverValue {
|
|
|
- result := &CoverValue{}
|
|
|
- result.Name = name
|
|
|
- result.Overloads = make(map[Signature]Overload)
|
|
|
- return result
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-func (cover *CoverValue) Help() string {
|
|
|
- help := cover.BasicCallable.Help()
|
|
|
- extra := "\n"
|
|
|
- for signature, overload := range cover.Overloads {
|
|
|
-
|
|
|
- extra = extra + fmt.Sprintf("* %v -> %s\n", signature.String(), overload.Name)
|
|
|
- }
|
|
|
- return help + extra
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-func (cover *CoverValue) Call(vm *VM, arguments ...Value) []Value {
|
|
|
- signature := CalculateSignature(arguments...)
|
|
|
- if overload, ok := cover.Overloads[signature]; ok {
|
|
|
- return overload.Call(vm, arguments...)
|
|
|
- } else {
|
|
|
- for overloadSignature, overload := range cover.Overloads {
|
|
|
- if signature.IsMatch(overloadSignature) {
|
|
|
- return overload.Call(vm, arguments...)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- vm.Fail()
|
|
|
- return Fail(NewErrorValuef("Could not match cover %s with arguments: %s<->%v", cover.String(), signature, arguments))
|
|
|
-}
|
|
|
|
|
|
const (
|
|
|
CoverTypeValue = TypeValue("Cover")
|
|
@@ -298,10 +242,18 @@ func (from BlockValue) Convert(to interface{}) error {
|
|
|
return NewErrorValuef("Cannot convert the block value %v to %v", from, to)
|
|
|
}
|
|
|
|
|
|
+func (cv * CoverValue) AddOverloadWithSignature(name string, callable Callable, signature Signature) Overload {
|
|
|
+ ov := Overload { Name: name, Callable: callable }
|
|
|
+ cv.Overloads[signature] = ov
|
|
|
+ return ov
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+func (cv * CoverValue) AddOverloadCallable(name string, callable Callable) Overload {
|
|
|
+ return cv.AddOverloadWithSignature(name, callable, callable.Signature())
|
|
|
+}
|
|
|
|
|
|
func (cv * CoverValue) AddOverload(name string, callable Callable, tv ... TypeValue) error {
|
|
|
-
|
|
|
-
|
|
|
signature := Signature{}
|
|
|
length := len(tv)
|
|
|
if length > len(signature.Parameters) {
|
|
@@ -311,17 +263,13 @@ func (cv * CoverValue) AddOverload(name string, callable Callable, tv ... TypeVa
|
|
|
for i := 0; i < length; i++ {
|
|
|
signature.Parameters[i].Type = tv[i]
|
|
|
}
|
|
|
-
|
|
|
- cv.Overloads[signature] = Overload { Name: name, Callable: callable }
|
|
|
-
|
|
|
-
|
|
|
|
|
|
+ cv.AddOverloadWithSignature(name, callable, signature)
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-func (vm * VM) AddOverload(from, target string, level int, tv... TypeValue) error {
|
|
|
+func (vm * VM) AddOverloadCallable(from, target string, level int, callable Callable) error {
|
|
|
var cover *CoverValue
|
|
|
- var callable Callable
|
|
|
var ok bool
|
|
|
lookup := vm.Lookup(from)
|
|
|
if lookup == nil {
|
|
@@ -329,23 +277,57 @@ func (vm * VM) AddOverload(from, target string, level int, tv... TypeValue) erro
|
|
|
} else if cover, ok = lookup.(*CoverValue) ; !ok {
|
|
|
return fmt.Errorf("%s exists and is not a cover value", from)
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- lookup = vm.Lookup(target)
|
|
|
+
|
|
|
+ cover.AddOverloadCallable(target, callable)
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+func (vm *VM) LookupCallable(target string) (Callable, error) {
|
|
|
+ var callable Callable
|
|
|
+ var ok bool
|
|
|
+ lookup := vm.Lookup(target)
|
|
|
if lookup == nil {
|
|
|
- return fmt.Errorf("target %s is not defined", target)
|
|
|
+ return nil, fmt.Errorf("%s is not defined", target)
|
|
|
}
|
|
|
-
|
|
|
|
|
|
if callable, ok = lookup.(Callable) ; !ok {
|
|
|
- return fmt.Errorf("%s is not a callable value", target)
|
|
|
+ return nil, fmt.Errorf("%s is not a callable value", target)
|
|
|
+ }
|
|
|
+ return callable, nil
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+func (vm * VM) AddOverload(from, target string, level int, tv... TypeValue) error {
|
|
|
+ var cover *CoverValue
|
|
|
+ var callable Callable
|
|
|
+ var ok bool
|
|
|
+ var err error
|
|
|
+
|
|
|
+ lookup := vm.Lookup(from)
|
|
|
+ if lookup == nil {
|
|
|
+ cover = vm.RegisterCover(from, level)
|
|
|
+ } else if cover, ok = lookup.(*CoverValue) ; !ok {
|
|
|
+ return fmt.Errorf("%s exists and is not a cover value", from)
|
|
|
}
|
|
|
- res := cover.AddOverload(target, callable, tv...)
|
|
|
|
|
|
-
|
|
|
+ callable, err = vm.LookupCallable(target)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
|
|
|
- return res
|
|
|
+ return cover.AddOverload(target, callable, tv...)
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+func (vm * VM) AddOverloadByName(from, target string, level int) error {
|
|
|
+ callable, err := vm.LookupCallable(target)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ return vm.AddOverloadCallable(from, target, level, callable)
|
|
|
}
|
|
|
|
|
|
type OverloadDescription struct {
|
|
@@ -560,17 +542,9 @@ func (block * BlockValue) Call(vm *VM, arguments ...Value) []Value {
|
|
|
}
|
|
|
|
|
|
func (builtin * BuiltinValue) Call(vm *VM, arguments ...Value) []Value {
|
|
|
- for i , arg := range arguments {
|
|
|
- if i >= len(builtin.signature.Parameters) {
|
|
|
- break
|
|
|
- }
|
|
|
- param := builtin.signature.Parameters[i]
|
|
|
- expectedType := param.Type
|
|
|
- vm.Trace("Signature check: %d %v", i, param)
|
|
|
-
|
|
|
- if !expectedType.IsMatch(arg.Type()) {
|
|
|
- return Fail(NewErrorValuef("Argument %d type mismatch: %s<->%s", i, expectedType, arg.Type()))
|
|
|
- }
|
|
|
+ err := builtin.signature.TypeCheck(arguments...)
|
|
|
+ if err != nil {
|
|
|
+ return Fail(ErrorValue{err})
|
|
|
}
|
|
|
handler := builtin.Handler
|
|
|
return handler.Call(vm, arguments...)
|
|
@@ -632,6 +606,12 @@ func (vm * VM) ScopeUp(level int) *Scope {
|
|
|
return scope
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+func (vm *VM) RegisterTop(name string, value Value) Value {
|
|
|
+ scope := vm.TopScope
|
|
|
+ return scope.Register(name, value)
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
|
|
|
func (vm *VM) RegisterUp(name string, value Value, level int) Value {
|
|
@@ -672,100 +652,6 @@ func (vm *VM) Fail() {
|
|
|
vm.Frame.failed = true
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-func (vm *VM) RunChildren(ast Ast, args ...Value) []Value {
|
|
|
- if ast.CountChildren() < 1 {
|
|
|
- return ReturnEmpty()
|
|
|
- }
|
|
|
- result := []Value{}
|
|
|
- for _, child := range ast.Children() {
|
|
|
- val := child.Run(vm, args...)
|
|
|
-
|
|
|
- if vm.Frame.returned || vm.Frame.failed {
|
|
|
- return vm.Frame.results
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- if len(val) < 1 {
|
|
|
- continue
|
|
|
- }
|
|
|
-
|
|
|
- first := val[0]
|
|
|
- if _, isEmpty := first.(EmptyValue); isEmpty {
|
|
|
- continue
|
|
|
- }
|
|
|
-
|
|
|
- last := val[len(val) -1]
|
|
|
-
|
|
|
- if _, isErr := last.(ErrorValue); isErr {
|
|
|
- return val
|
|
|
- }
|
|
|
-
|
|
|
- result = append(result, val...)
|
|
|
- }
|
|
|
- return result
|
|
|
-}
|
|
|
-
|
|
|
-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 {
|
|
|
- res := vm.Frame.results
|
|
|
- return res[len(res)-1]
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- if len(val) < 1 {
|
|
|
- continue
|
|
|
- }
|
|
|
-
|
|
|
- first := val[0]
|
|
|
- if _, isEmpty := first.(EmptyValue); isEmpty {
|
|
|
- continue
|
|
|
- }
|
|
|
-
|
|
|
- last := val[len(val) -1]
|
|
|
-
|
|
|
- if _, isErr := last.(ErrorValue); isErr {
|
|
|
- return last
|
|
|
- }
|
|
|
-
|
|
|
- result = last
|
|
|
- }
|
|
|
-
|
|
|
- return result
|
|
|
-}
|
|
|
-
|
|
|
-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 {
|
|
|
- res := vm.Frame.results
|
|
|
- return res[0]
|
|
|
- }
|
|
|
-
|
|
|
- if len(val) < 1 {
|
|
|
- continue
|
|
|
- }
|
|
|
-
|
|
|
- first := val[0]
|
|
|
- if _, isEmpty := first.(EmptyValue); isEmpty {
|
|
|
- continue
|
|
|
- }
|
|
|
-
|
|
|
- return val[0]
|
|
|
- }
|
|
|
- return result
|
|
|
-}
|
|
|
-*/
|
|
|
-
|
|
|
-
|
|
|
func (vm *VM) RunAst(ast Ast, args ...Value) []Value {
|
|
|
var result []Value
|
|
|
|
|
@@ -790,7 +676,8 @@ func (vm *VM) RunAst(ast Ast, args ...Value) []Value {
|
|
|
vm.Trace("RunAst: %d %v %v %v\n", i, child, sub, vm.Frame)
|
|
|
|
|
|
if frame.failed && frame.parent != nil {
|
|
|
-
|
|
|
+
|
|
|
+ *
|
|
|
frame.parent.failed = true
|
|
|
frame.parent.results = frame.results
|
|
|
}
|
|
@@ -849,83 +736,3 @@ func (vm * VM) BackTrace() string {
|
|
|
return strings.Join(vm.BackTraceStrings(), "\n")
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-func (vm *VM) RunProgram(ast *BasicAst) ListValue {
|
|
|
- return vm.RunChildren(ast, (*VM).RunStatements)
|
|
|
-}
|
|
|
-
|
|
|
-func (vm *VM) RunStatements(ast *BasicAst) ListValue {
|
|
|
- return vm.RunChildren(ast, (*VM).RunStatement)
|
|
|
-}
|
|
|
-
|
|
|
-func (vm *VM) RunStatement(ast *BasicAst) ListValue {
|
|
|
- return NewListValue()
|
|
|
-}
|
|
|
-
|
|
|
-func (vm *VM) RunSet(ast *BasicAst) ListValue { return NewListValue() }
|
|
|
-func (vm *VM) RunGet(ast *BasicAst) ListValue { return NewListValue() }
|
|
|
-func (vm *VM) RunTarget(ast *BasicAst) ListValue { return NewListValue() }
|
|
|
-func (vm *VM) RunCommand(ast *BasicAst) ListValue { return NewListValue() }
|
|
|
-func (vm *VM) RunArguments(ast *BasicAst) ListValue { return NewListValue() }
|
|
|
-func (vm *VM) RunArgument(ast *BasicAst) ListValue { return NewListValue() }
|
|
|
-func (vm *VM) RunExpression(ast *BasicAst) ListValue { return NewListValue() }
|
|
|
-func (vm *VM) RunBlock(ast *BasicAst) ListValue { return NewListValue() }
|
|
|
-func (vm *VM) RunParenthesis(ast *BasicAst) ListValue { return NewListValue() }
|
|
|
-func (vm *VM) RunList(ast *BasicAst) ListValue { return NewListValue() }
|
|
|
-func (vm *VM) RunCapture(ast *BasicAst) ListValue { return NewListValue() }
|
|
|
-func (vm *VM) RunWordValue(ast *BasicAst) ListValue { return NewListValue() }
|
|
|
-func (vm *VM) RunWord(ast *BasicAst) ListValue { return NewListValue() }
|
|
|
-func (vm *VM) RunType(ast *BasicAst) ListValue { return NewListValue() }
|
|
|
-func (vm *VM) RunValue(ast *BasicAst) ListValue { return NewListValue() }
|
|
|
-func (vm *VM) RunEnd(ast *BasicAst) ListValue { return NewListValue() }
|
|
|
-func (vm *VM) RunError(ast *BasicAst) ListValue { return NewListValue() }
|
|
|
-
|
|
|
-func (vm *VM) Run(ast *BasicAst) ListValue {
|
|
|
- switch ast.AstKind {
|
|
|
- case AstKindProgram:
|
|
|
- return vm.RunProgram(ast)
|
|
|
- case AstKindStatements:
|
|
|
- return vm.RunStatements(ast)
|
|
|
- case AstKindStatement:
|
|
|
- return vm.RunStatement(ast)
|
|
|
- case AstKindSet:
|
|
|
- return vm.RunSet(ast)
|
|
|
- case AstKindGet:
|
|
|
- return vm.RunGet(ast)
|
|
|
- case AstKindTarget:
|
|
|
- return vm.RunTarget(ast)
|
|
|
- case AstKindCommand:
|
|
|
- return vm.RunCommand(ast)
|
|
|
- case AstKindArguments:
|
|
|
- return vm.RunArguments(ast)
|
|
|
- case AstKindArgument:
|
|
|
- return vm.RunArgument(ast)
|
|
|
- case AstKindExpression:
|
|
|
- return vm.RunExpression(ast)
|
|
|
- case AstKindBlock:
|
|
|
- return vm.RunBlock(ast)
|
|
|
- case AstKindParenthesis:
|
|
|
- return vm.RunParenthesis(ast)
|
|
|
- case AstKindList:
|
|
|
- return vm.RunList(ast)
|
|
|
- case AstKindCapture:
|
|
|
- return vm.RunCapture(ast)
|
|
|
- case AstKindWordValue:
|
|
|
- return vm.RunWordValue(ast)
|
|
|
- case AstKindWord:
|
|
|
- return vm.RunWord(ast)
|
|
|
- case AstKindType:
|
|
|
- return vm.RunType(ast)
|
|
|
- case AstKindValue:
|
|
|
- return vm.RunValue(ast)
|
|
|
- case AstKindEnd:
|
|
|
- return vm.RunEnd(ast)
|
|
|
- case AstKindError:
|
|
|
- return vm.RunError(ast)
|
|
|
- default:
|
|
|
- return ListValue{[]Value{NewErrorValuef("Unknown ast node type: %d", ast.AstKind)}}
|
|
|
- }
|
|
|
-}
|
|
|
-*/
|