Browse Source

Finally function cals, covers, and get and set work.

Beoran 4 years ago
parent
commit
c4c3fc521c
5 changed files with 296 additions and 62 deletions
  1. 15 15
      ast.go
  2. 126 17
      builtin.go
  3. 6 2
      cmd/muesli/main.go
  4. 56 0
      value.go
  5. 93 28
      vm.go

+ 15 - 15
ast.go

@@ -112,32 +112,32 @@ func (astkind AstMetaKindStatement) Run(vm *VM, ast Ast, val ...Value) []Value {
 
 func (astkind AstMetaKindClosed) Run(vm *VM, ast Ast, val ...Value) []Value {return ReturnEmpty() }
 func (astkind AstMetaKindSet) Run(vm *VM, ast Ast, val ...Value) []Value {
-	varName := ast.Value()
-	value := vm.RunChildren(ast, val...)
-	vm.Register(varName.String(), value[0])
-	return value
+	values := vm.RunChildren(ast, val...)
+	if len(values) < 2 { 
+		return Fail(fmt.Errorf("set needs at least 2 arguments: received %v", values)) 
+	}
+	log.Printf("(astkind AstMetaKindSet) Run: %v %v", values[0].String(), values[1])
+	vm.Register(values[0].String(), values[1])
+	return Ok(values[1])
 }
 
 func (astkind AstMetaKindGet) Run(vm *VM, ast Ast, val ...Value) []Value {
-	target := vm.RunChildrenFirstResult(ast, val...).(ListValue)
+	target := vm.RunChildrenFirstResult(ast, val...)
+	log.Printf("(astkind AstMetaKindGet) Run: target %v", target)
 	return []Value{vm.Lookup(target.String())}
 }
 
 func (astkind AstMetaKindTarget) Run(vm *VM, ast Ast, val ...Value) []Value {
-	return []Value{ast.Value()}
+	values := vm.RunChildren(ast, val...)
+	values = append([]Value{ast.Value()}, values...)  
+	return values
 }
 
 func (astkind AstMetaKindCommand) Run(vm *VM, ast Ast, val ...Value) []Value {
 	commandName := ast.Value()	
-	arguments := vm.RunChildrenFirstResult(ast, val...)
-	if argList, isList := arguments.(ListValue) ; isList {
-		log.Printf("Command execute: %s %v", commandName.String(), argList)
-		return vm.CallNamed(commandName.String(), argList.List...)
-	} else if _, isEmpty := arguments.(EmptyValue) ; isEmpty {
-		return vm.CallNamed(commandName.String())
-	} else {
-		return []Value{NewErrorValuef("Internal error when calling %s.", commandName.String())}
-	}
+	arguments := vm.RunChildren(ast, val...)
+	log.Printf("Command execute: %s %v", commandName.String(), arguments)
+	return vm.CallNamed(commandName.String(), arguments...)
 }
 
 func (astkind AstMetaKindArguments) Run(vm *VM, ast Ast, val ...Value) []Value {	

+ 126 - 17
builtin.go

@@ -30,28 +30,28 @@ func printf(vm *VM, args ...Value) []Value {
 	var format string
 	rest, err := ParseArgs(args, &format)
 	if err != nil {
-		return Return(ErrorValue{err})
+		return Fail(err)
 	}
 	fmt.Printf(format, rest...)
-	return []Value{EmptyValue{}}
+	return None()
 }
 
 func println(vm *VM, args ...Value) []Value {
 	var msg string
 	_, err := ParseArgs(args, &msg)
 	if err != nil {
-		return Return(ErrorValue{err})
+		return Fail(err)
 	} else {
 		fmt.Println(msg)
 	}
-	return Return(EmptyValue{})
+	return None()
 }
 
 func p(vm *VM, args ...Value) []Value {	
 	for _, arg := range args {
 		fmt.Printf("%v\n", arg)
 	}	
-	return Return(EmptyValue{})
+	return None()
 }
 
 func trace(vm *VM, args ...Value) []Value {
@@ -60,7 +60,7 @@ func trace(vm *VM, args ...Value) []Value {
 	_, err := ParseArgs(args, &b)
 	if err != nil {
 		fmt.Printf("Error: %s\n", err.Error())
-		return Return(ErrorValue{err})
+		return Fail(err)
 	}
 	fmt.Printf("command trace: bool: %v\n", b)
 	if b {
@@ -68,29 +68,113 @@ func trace(vm *VM, args ...Value) []Value {
 	} else {
 		vm.Tracer = nil
 	}
-	return Return(BoolValue(b))
+	return Ok(BoolValue(b))
 }
 
-func addi(vm *VM, args ...Value) []Value {
-	var i1, i2 int
-	_, err := ParseArgs(args, &i1, &i2)
+func sumi(vm *VM, args ...Value) []Value {
+	slice, err := ParseArgsToIntSlice(args)
 	if err != nil {
 		fmt.Printf("Error: %s\n", err.Error())
-		return Return(ErrorValue{err})
+		return Fail(err)
 	}
-	return Return(IntValue(i1 + i2))
+	res := int(0)
+	for _, val := range slice {
+		res += val
+	} 
+	return IntOk(res)
 }
 
-func addf(vm *VM, args ...Value) []Value {
-	var f1, f2 float64
-	_, err := ParseArgs(args, &f1, &f2)
+func sumf(vm *VM, args ...Value) []Value {
+	slice, err := ParseArgsToFloat64Slice(args)
 	if err != nil {
 		fmt.Printf("Error: %s\n", err.Error())
-		return Return(ErrorValue{err})
+		return Fail(err)
 	}
-	return Return(FloatValue(f1 + f2))
+	res := float64(0)
+	for _, val := range slice {
+		res += val
+	} 
+	return FloatOk(res)
+}
+
+func addi(vm *VM, args ...Value) []Value {
+	var v1, v2 int
+	_, err := ParseArgs(args, &v1, &v2)
+	if err != nil {
+		return Fail(err)
+	}	
+	return IntOk(v1 + v2)
+}
+
+
+func addf(vm *VM, args ...Value) []Value {
+	var v1, v2 float64
+	_, err := ParseArgs(args, &v1, &v2)
+	if err != nil {
+		return Fail(err)
+	}	
+	return FloatOk(v1 + v2)
+}
+
+func subi(vm *VM, args ...Value) []Value {
+	var v1, v2 int
+	_, err := ParseArgs(args, &v1, &v2)
+	if err != nil {
+		return Fail(err)
+	}	
+	return IntOk(v1 - v2)
+}
+
+
+func subf(vm *VM, args ...Value) []Value {
+	var v1, v2 float64
+	_, err := ParseArgs(args, &v1, &v2)
+	if err != nil {
+		return Fail(err)
+	}	
+	return FloatOk(v1 - v2)
+}
+
+func muli(vm *VM, args ...Value) []Value {
+	var v1, v2 int
+	_, err := ParseArgs(args, &v1, &v2)
+	if err != nil {
+		return Fail(err)
+	}	
+	return IntOk(v1 * v2)
 }
 
+
+func mulf(vm *VM, args ...Value) []Value {
+	var v1, v2 float64
+	_, err := ParseArgs(args, &v1, &v2)
+	if err != nil {
+		return Fail(err)
+	}	
+	return FloatOk(v1 * v2)
+}
+
+
+func divi(vm *VM, args ...Value) []Value {
+	var v1, v2 int
+	_, err := ParseArgs(args, &v1, &v2)
+	if err != nil {
+		return Fail(err)
+	}	
+	return IntOk(v1 / v2)
+}
+
+
+func divf(vm *VM, args ...Value) []Value {
+	var v1, v2 float64
+	_, err := ParseArgs(args, &v1, &v2)
+	if err != nil {
+		return Fail(err)
+	}	
+	return FloatOk(v1 / v2)
+}
+
+
 func val(vm *VM, args ...Value) []Value {
 	if len(args) < 1 {
 		return []Value{NewErrorValuef("val requres at least one argument.")}
@@ -102,6 +186,31 @@ func val(vm *VM, args ...Value) []Value {
 func (vm *VM) RegisterBuiltins() {
 	vm.RegisterBuiltin("addi", addi)
 	vm.RegisterBuiltin("addf", addf)
+	vm.RegisterBuiltin("sumi", sumi)
+	vm.RegisterBuiltin("sumf", sumf)
+	vm.RegisterBuiltin("subi", subi)
+	vm.RegisterBuiltin("subf", subf)
+	vm.RegisterBuiltin("divi", divi)
+	vm.RegisterBuiltin("divf", divf)
+	vm.RegisterBuiltin("muli", muli)
+	vm.RegisterBuiltin("mulf", mulf)
+	err := vm.AddOverload("mul", "mulf", FloatTypeValue, FloatTypeValue)
+	if err != nil {
+		fmt.Printf("Errror registering overload: %s", err)
+	}
+	err = vm.AddOverload("mul", "muli", IntTypeValue, IntTypeValue)
+	if err != nil {
+		fmt.Printf("Errror registering overload: %s", err)
+	}
+	err = vm.AddOverload("mul", "mulf", FloatTypeValue, IntTypeValue)
+	if err != nil {
+		fmt.Printf("Errror registering overload: %s", err)
+	}
+	err = vm.AddOverload("mul", "mulf", IntTypeValue, FloatTypeValue)
+	if err != nil {
+		fmt.Printf("Errror registering overload: %s", err)
+	}
+	
 	// vm.RegisterCover("add")
 	vm.RegisterBuiltin("p", p)
 	vm.RegisterBuiltin("println", println)

+ 6 - 2
cmd/muesli/main.go

@@ -19,7 +19,11 @@ func runLine(vm *muesli.VM, in string) error {
 	result := vm.RunAst(*ast, muesli.NewListValue())
 	if result != nil { 
 		for _, val := range result { 
-			fmt.Printf(">>%s\n", val.String())
+			if val != nil { 
+				fmt.Printf(">>%s\n", val.String())
+			} else {
+				fmt.Printf(">>nil\n")
+			}
 		}
 	}
 	
@@ -46,7 +50,7 @@ func runLines(vm *muesli.VM, line *liner.State) error {
 
 func main() {
 	vm := muesli.NewVM()
-	vm.Tracer = &muesli.FmtTracer{}
+	// vm.Tracer = &muesli.FmtTracer{}
 	vm.RegisterBuiltins() 
 	line := liner.NewLiner()
 	defer line.Close()

+ 56 - 0
value.go

@@ -46,6 +46,7 @@ const (
 	EmptyTypeValue  = TypeValue("Empty")
 	ListTypeValue   = TypeValue("List")
 	AnyTypeValue    = TypeValue("Any")
+	ZeroTypeValue   = TypeValue("")
 )
 
 var NilValue = Value(nil)
@@ -302,6 +303,36 @@ func ParseArgs(args []Value, to...interface{}) ([]interface{}, error) {
 	return ListFromList(rest), nil
 }
 
+/* Helpers to easily convert Muesli value lists to "normal" Go values in slices. */
+func ParseArgsToIntSlice(args []Value) ([]int, error) {
+	res := []int{}
+	for _, arg := range args{
+		value := int(0)
+		err := arg.Convert(&value)
+		if err != nil  {
+			return res, err
+		}
+		res = append(res, value)
+	}
+	
+	return res, nil
+}
+
+/* Helpers to easily convert Muesli value lists to "normal" Go values in slices. */
+func ParseArgsToFloat64Slice(args []Value) ([]float64, error) {
+	res := []float64{}
+	for _, arg := range args{
+		value := float64(0.0)
+		err := arg.Convert(&value)
+		if err != nil  {
+			return res, err
+		}
+		res = append(res, value)
+	}
+	
+	return res, nil
+}
+
 /* Helpers to easily convert Muesli values from "normal" Go values. */
 func To(from interface{}) Value {
 	switch val := from.(type) {
@@ -373,3 +404,28 @@ func ReturnEmpty() []Value {
 func ReturnError(err error) []Value {
 	return []Value{ErrorValue{err}}
 }
+
+func Ok(args ... Value) []Value {
+	return args
+}
+
+func Fail(err error) []Value {
+	return []Value{ErrorValue{err}}
+}
+
+func None() []Value {
+	return []Value{EmptyValue{}}
+}
+
+func BoolOk(b bool) []Value{
+	return []Value{BoolValue(b)}
+}
+
+func IntOk(i int) []Value{
+	return []Value{IntValue(i)}
+}
+
+func FloatOk(f float64) []Value{
+	return []Value{FloatValue(f)}
+}
+

+ 93 - 28
vm.go

@@ -1,7 +1,7 @@
 // vm, the virtual low level machine that runs MUESLI.
 package muesli
 
-// import "fmt"
+import "fmt"
 
 // Handler function
 type Handler func(vm *VM, arguments ...Value) []Value
@@ -46,8 +46,8 @@ func NewCallableValue(name string) CallableValue {
 	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.Handler = handler
 	return result
@@ -63,8 +63,8 @@ type DefinedValue struct {
 	Definition *Ast
 }
 
-func NewDefinedValue(name string, definition *Ast) DefinedValue {
-	result := DefinedValue{}
+func NewDefinedValue(name string, definition *Ast) *DefinedValue {
+	result := &DefinedValue{}
 	result.Name = name
 	result.Definition = definition
 	return result
@@ -87,31 +87,40 @@ type Signature struct {
 
 func CalculateSignature(arguments ...Value) 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()
+		} else {			
+			signature.Types[i] = AnyTypeValue
 		}
 	}
 	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 {
-		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 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 {
-	CallableValue
+	Caller
 }
 
 /* A cover is a callable that dispatches to other callables depending on
@@ -123,8 +132,17 @@ type CoverValue struct {
 	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.Overloads = make(map[Signature]Overload)
 	return result
@@ -135,14 +153,14 @@ func (cover *CoverValue) Call(vm *VM, arguments ...Value) []Value {
 	if overload, ok := cover.Overloads[signature]; ok {
 		return overload.Call(vm, arguments...)
 	} 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...)
 			}
 		}
 	}
 	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 (
@@ -167,8 +185,54 @@ func (from DefinedValue) Convert(to interface{}) error {
 	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
 type Scope struct {
@@ -280,7 +344,7 @@ func (vm *VM) CallBuiltin(handler Handler, arguments ...Value) []Value {
 	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...)
 }
 
@@ -288,11 +352,11 @@ func (vm *VM) CallCover(cover CoverValue, arguments ...Value) []Value {
 func (vm *VM) CallNamed(name string, arguments ...Value) []Value {
 	value := vm.Lookup(name)
 	switch toCall := value.(type) {
-	case BuiltinValue:
+	case *BuiltinValue:
 		return vm.CallBuiltin(toCall.Handler, arguments...)
-	case DefinedValue:
+	case *DefinedValue:
 		return vm.CallDefined(toCall.Definition, arguments...)
-	case CoverValue:
+	case *CoverValue:
 		return vm.CallCover(toCall, arguments...)
 	default:
 		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)
 }
 
-func (vm *VM) RegisterCover(name string) Value {
+func (vm *VM) RegisterCover(name string) *CoverValue {
 	value := NewCoverValue(name)
-	return vm.Register(name, value)
+	vm.Register(name, value)
+	return value
 }
 
 func (vm *VM) RegisterBuiltin(name string, handler Handler) Value {