ソースを参照

ListValue should not be used by the VM itself, only as a value in the user program.

Beoran 5 年 前
コミット
3855318888
5 ファイル変更134 行追加104 行削除
  1. 51 47
      ast.go
  2. 20 20
      builtin.go
  3. 3 1
      cmd/muesli/main.go
  4. 12 0
      value.go
  5. 48 36
      vm.go

+ 51 - 47
ast.go

@@ -66,8 +66,8 @@ func (astkind AstBasicMetaKind) String() string {
 	return string(astkind)
 }
 
-func (astkind AstBasicMetaKind) Run(vm *VM, ast Ast, val ...Value) Value {
-	return EmptyListValue()
+func (astkind AstBasicMetaKind) Run(vm *VM, ast Ast, val ...Value) []Value {
+	return []Value{}
 }
 
 func (astkind AstMetaKindNone) String() string        { return "AstNone       " }
@@ -95,110 +95,114 @@ func (astkind AstMetaKindError) String() string       { return "AstError      "
 func (astkind AstMetaKindFlatten) String() string     { return "AstFlatten    " }
 
 
-func (astkind AstMetaKindNone) Run(vm *VM, ast Ast, val ...Value) Value { return EmptyValue{} }
+func (astkind AstMetaKindNone) Run(vm *VM, ast Ast, val ...Value) []Value { return ReturnEmpty() }
 
-func (astkind AstMetaKindProgram) Run(vm *VM, ast Ast, val ...Value) Value {
-	return vm.RunChildrenLastResult(ast, val...)
+func (astkind AstMetaKindProgram) Run(vm *VM, ast Ast, val ...Value) []Value {
+	return []Value{vm.RunChildrenLastResult(ast, val...)}
 }
 
-func (astkind AstMetaKindStatements) Run(vm *VM, ast Ast, val ...Value) Value {
-	return vm.RunChildrenLastResult(ast, val...)
+func (astkind AstMetaKindStatements) Run(vm *VM, ast Ast, val ...Value) []Value {
+	return []Value{vm.RunChildrenLastResult(ast, val...)}
 }
 
-func (astkind AstMetaKindStatement) Run(vm *VM, ast Ast, val ...Value) Value {
+func (astkind AstMetaKindStatement) Run(vm *VM, ast Ast, val ...Value) []Value {
 	panic("AstMetaKindStatement")
 	return vm.RunChildren(ast, val...)
 }
 
-func (astkind AstMetaKindClosed) Run(vm *VM, ast Ast, val ...Value) Value {return EmptyListValue() }
-func (astkind AstMetaKindSet) 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)
+	vm.Register(varName.String(), value[0])
 	return value
 }
 
-func (astkind AstMetaKindGet) Run(vm *VM, ast Ast, val ...Value) Value {
+func (astkind AstMetaKindGet) Run(vm *VM, ast Ast, val ...Value) []Value {
 	target := vm.RunChildrenFirstResult(ast, val...).(ListValue)
-	return vm.Lookup(target.String())
+	return []Value{vm.Lookup(target.String())}
 }
 
-func (astkind AstMetaKindTarget) Run(vm *VM, ast Ast, val ...Value) Value {
-	return ast.Value()
+func (astkind AstMetaKindTarget) Run(vm *VM, ast Ast, val ...Value) []Value {
+	return []Value{ast.Value()}
 }
 
-func (astkind AstMetaKindCommand) Run(vm *VM, ast Ast, val ...Value) Value {
+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)
+		return vm.CallNamed(commandName.String(), argList.List...)
+	} else if _, isEmpty := arguments.(EmptyValue) ; isEmpty {
+		return vm.CallNamed(commandName.String())
 	} else {
-		return NewErrorValuef("Internal error when calling %s.", commandName.String())
+		return []Value{NewErrorValuef("Internal error when calling %s.", commandName.String())}
 	}
 }
 
-func (astkind AstMetaKindArguments) Run(vm *VM, ast Ast, val ...Value) Value {	
+func (astkind AstMetaKindArguments) Run(vm *VM, ast Ast, val ...Value) []Value {	
 	return vm.RunChildren(ast, val...)
 }
 
-func (astkind AstMetaKindArgument) Run(vm *VM, ast Ast, val ...Value) Value {
+func (astkind AstMetaKindArgument) Run(vm *VM, ast Ast, val ...Value) []Value {
 	panic("AstMetaKindArgument")
-	return vm.RunChildrenFirstResult(ast, val...)
+	return []Value{vm.RunChildrenFirstResult(ast, val...)}
 }
 
-func (astkind AstMetaKindExpression) Run(vm *VM, ast Ast, val ...Value) Value {
+func (astkind AstMetaKindExpression) Run(vm *VM, ast Ast, val ...Value) []Value {
 	panic("AstMetaKindExpression")
-	return vm.RunChildrenLastResult(ast, val...)
+	return []Value{vm.RunChildrenLastResult(ast, val...)}
 }
 
-func (astkind AstMetaKindBlock) Run(vm *VM, ast Ast, val ...Value) Value {
-	return vm.RunChildrenLastResult(ast, val...)
+func (astkind AstMetaKindBlock) Run(vm *VM, ast Ast, val ...Value) []Value {
+	return []Value{vm.RunChildrenLastResult(ast, val...)}
 }
 
-func (astkind AstMetaKindParenthesis) Run(vm *VM, ast Ast, val ...Value) Value {
-	return vm.RunChildrenLastResult(ast, val...)
+func (astkind AstMetaKindParenthesis) Run(vm *VM, ast Ast, val ...Value) []Value {
+	return []Value{vm.RunChildrenLastResult(ast, val...)}
 }
 
-func (astkind AstMetaKindList) Run(vm *VM, ast Ast, val ...Value) Value {
-	return vm.RunChildren(ast, val...)
+func (astkind AstMetaKindList) Run(vm *VM, ast Ast, val ...Value) []Value {	
+	result := vm.RunChildren(ast, val...)
+	list := ListValue{List:result}
+	return []Value{list}
 }
 
-func (astkind AstMetaKindCapture) Run(vm *VM, ast Ast, val ...Value) Value {
+func (astkind AstMetaKindCapture) Run(vm *VM, ast Ast, val ...Value) []Value {
 	return vm.RunChildren(ast, val...)
 }
 
-func (astkind AstMetaKindWordValue) Run(vm *VM, ast Ast, val ...Value) Value {
-	return ast.Value()
+func (astkind AstMetaKindWordValue) Run(vm *VM, ast Ast, val ...Value) []Value {
+	return []Value{ast.Value()}
 }
 
-func (astkind AstMetaKindWord) Run(vm *VM, ast Ast, val ...Value) Value {
-	return ast.Value()
+func (astkind AstMetaKindWord) Run(vm *VM, ast Ast, val ...Value) []Value {
+	return []Value{ast.Value()}
 }
-func (astkind AstMetaKindType) Run(vm *VM, ast Ast, val ...Value) Value {
-	return ast.Value()
+func (astkind AstMetaKindType) Run(vm *VM, ast Ast, val ...Value) []Value {
+	return []Value{ast.Value()}
 }
-func (astkind AstMetaKindValue) Run(vm *VM, ast Ast, val ...Value) Value {
-	return ast.Value()
+func (astkind AstMetaKindValue) Run(vm *VM, ast Ast, val ...Value) []Value {
+	return []Value{ast.Value()}
 }
 
-func (astkind AstMetaKindEnd) Run(vm *VM, ast Ast, val ...Value) Value {
-	return EmptyValue{}
+func (astkind AstMetaKindEnd) Run(vm *VM, ast Ast, val ...Value) []Value {
+	return []Value{EmptyValue{}}
 }
 
-func (astkind AstMetaKindError) Run(vm *VM, ast Ast, val ...Value) Value {
-	return ast.Value()
+func (astkind AstMetaKindError) Run(vm *VM, ast Ast, val ...Value) []Value {
+	return []Value{ast.Value()}
 }
 
-func (astkind AstMetaKindFlatten) Run(vm *VM, ast Ast, val ...Value) Value {
-	return EmptyListValue()
+func (astkind AstMetaKindFlatten) Run(vm *VM, ast Ast, val ...Value) []Value {
+	return ReturnEmpty()
 }
 
 
 
 type AstKind interface {
 	String() string
-	Run(vm *VM, ast Ast, val ...Value) Value
+	Run(vm *VM, ast Ast, val ...Value) []Value
 }
 
 /*
@@ -343,10 +347,10 @@ func (ast Ast) Child(index int) *Ast {
 	return ast.children[index]
 }
 
-func (ast Ast) Run(vm *VM, val ...Value) Value {
+func (ast Ast) Run(vm *VM, val ...Value) []Value {
 	res := ast.AstKind.Run(vm, ast, val...)
 	if vm != nil && vm.Tracer != nil {
-		vm.Trace(*vm, ast, res)
+		vm.Trace(*vm, ast, res...)
 	}
 	return res
 }

+ 20 - 20
builtin.go

@@ -26,41 +26,41 @@ func (t FmtTracer) Trace(vm VM, ast Ast, args ... Value) bool {
 	return false
 }
 
-func printf(vm *VM, args ...Value) Value {
+func printf(vm *VM, args ...Value) []Value {
 	var format string
 	rest, err := ParseArgs(args, &format)
 	if err != nil {
-		return ErrorValue{err}
+		return Return(ErrorValue{err})
 	}
 	fmt.Printf(format, rest...)
-	return EmptyValue{}
+	return []Value{EmptyValue{}}
 }
 
-func println(vm *VM, args ...Value) Value {
+func println(vm *VM, args ...Value) []Value {
 	var msg string
 	_, err := ParseArgs(args, &msg)
 	if err != nil {
-		return ErrorValue{err}
+		return Return(ErrorValue{err})
 	} else {
 		fmt.Println(msg)
 	}
-	return EmptyValue{}
+	return Return(EmptyValue{})
 }
 
-func p(vm *VM, args ...Value) Value {	
+func p(vm *VM, args ...Value) []Value {	
 	for _, arg := range args {
 		fmt.Printf("%v\n", arg)
 	}	
-	return EmptyValue{}
+	return Return(EmptyValue{})
 }
 
-func trace(vm *VM, args ...Value) Value {
+func trace(vm *VM, args ...Value) []Value {
 	var b bool = true
 	fmt.Printf("command trace: %v\n", args)
 	_, err := ParseArgs(args, &b)
 	if err != nil {
 		fmt.Printf("Error: %s\n", err.Error())
-		return ErrorValue{err}
+		return Return(ErrorValue{err})
 	}
 	fmt.Printf("command trace: bool: %v\n", b)
 	if b {
@@ -68,34 +68,34 @@ func trace(vm *VM, args ...Value) Value {
 	} else {
 		vm.Tracer = nil
 	}
-	return BoolValue(b)
+	return Return(BoolValue(b))
 }
 
-func addi(vm *VM, args ...Value) Value {
+func addi(vm *VM, args ...Value) []Value {
 	var i1, i2 int
 	_, err := ParseArgs(args, &i1, &i2)
 	if err != nil {
 		fmt.Printf("Error: %s\n", err.Error())
-		return ErrorValue{err}
+		return Return(ErrorValue{err})
 	}
-	return IntValue(i1 + i2)
+	return Return(IntValue(i1 + i2))
 }
 
-func addf(vm *VM, args ...Value) Value {
+func addf(vm *VM, args ...Value) []Value {
 	var f1, f2 float64
 	_, err := ParseArgs(args, &f1, &f2)
 	if err != nil {
 		fmt.Printf("Error: %s\n", err.Error())
-		return ErrorValue{err}
+		return Return(ErrorValue{err})
 	}
-	return FloatValue(f1 + f2)
+	return Return(FloatValue(f1 + f2))
 }
 
-func val(vm *VM, args ...Value) Value {
+func val(vm *VM, args ...Value) []Value {
 	if len(args) < 1 {
-		return NewErrorValuef("val requres one argument.")
+		return []Value{NewErrorValuef("val requres at least one argument.")}
 	}
-	return args[0]
+	return args
 }
 
 

+ 3 - 1
cmd/muesli/main.go

@@ -18,7 +18,9 @@ func runLine(vm *muesli.VM, in string) error {
 	}
 	result := vm.RunAst(*ast, muesli.NewListValue())
 	if result != nil { 
-		fmt.Printf(">>%s\n", result.String())
+		for _, val := range result { 
+			fmt.Printf(">>%s\n", val.String())
+		}
 	}
 	
 	return nil

+ 12 - 0
value.go

@@ -361,3 +361,15 @@ func ListFromList(froms []Value) []interface{} {
 	}
 	return res
 }
+
+func Return(args ... Value) []Value {
+	return args
+}
+
+func ReturnEmpty() []Value {
+	return []Value{EmptyValue{}}
+}
+
+func ReturnError(err error) []Value {
+	return []Value{ErrorValue{err}}
+}

+ 48 - 36
vm.go

@@ -4,15 +4,15 @@ package muesli
 // import "fmt"
 
 // Handler function
-type Handler func(vm *VM, arguments ...Value) Value
+type Handler func(vm *VM, arguments ...Value) []Value
 
-func (handler *Handler) Call(vm *VM, arguments ...Value) Value {
+func (handler *Handler) Call(vm *VM, arguments ...Value) []Value {
 	return (*handler)(vm, arguments...)
 }
 
 // A callable Value must implement the Caller interface
 type Caller interface {
-	Call(vm *VM, arguments ...Value) Value
+	Call(vm *VM, arguments ...Value) []Value
 }
 
 // Callable value types
@@ -32,7 +32,7 @@ func (from CallableValue) Convert(to interface{}) error {
 	return NewErrorValuef("Cannot convert the callable value %v to %v", from, to)
 }
 
-func (val *CallableValue) Call(vm *VM, arguments ...Value) Value {
+func (val *CallableValue) Call(vm *VM, arguments ...Value) []Value {
 	panic("Not implemented")
 }
 
@@ -53,7 +53,7 @@ func NewBuiltinValue(name string, handler Handler) BuiltinValue {
 	return result
 }
 
-func (builtin *BuiltinValue) Call(vm *VM, arguments ...Value) Value {
+func (builtin *BuiltinValue) Call(vm *VM, arguments ...Value) []Value {
 	return vm.CallBuiltin(builtin.Handler, arguments...)
 }
 
@@ -70,7 +70,7 @@ func NewDefinedValue(name string, definition *Ast) DefinedValue {
 	return result
 }
 
-func (defined *DefinedValue) Call(vm *VM, arguments ...Value) Value {
+func (defined *DefinedValue) Call(vm *VM, arguments ...Value) []Value {
 	return vm.CallDefined(defined.Definition, arguments...)
 }
 
@@ -130,7 +130,7 @@ func NewCoverValue(name string) CoverValue {
 	return result
 }
 
-func (cover *CoverValue) Call(vm *VM, arguments ...Value) Value {
+func (cover *CoverValue) Call(vm *VM, arguments ...Value) []Value {
 	signature := CalculateSignature(arguments...)
 	if overload, ok := cover.Overloads[signature]; ok {
 		return overload.Call(vm, arguments...)
@@ -142,7 +142,7 @@ func (cover *CoverValue) Call(vm *VM, arguments ...Value) Value {
 		}
 	}
 	vm.Fail()
-	return NewListValue(NewErrorValuef("Could not match cover %s with arguments.", cover.Name))
+	return ReturnError(NewErrorValuef("Could not match cover %s with arguments.", cover.Name))
 }
 
 const (
@@ -271,21 +271,21 @@ func (vm *VM) PopScope() *Scope {
 	return nil
 }
 
-func (vm *VM) CallDefined(ast *Ast, arguments ...Value) Value {
+func (vm *VM) CallDefined(ast *Ast, arguments ...Value) []Value {
 	arr := ast.Run(vm, NewListValue(arguments...))
 	return arr
 }
 
-func (vm *VM) CallBuiltin(handler Handler, arguments ...Value) Value {
+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...)
 }
 
 
-func (vm *VM) CallNamed(name string, arguments ...Value) Value {
+func (vm *VM) CallNamed(name string, arguments ...Value) []Value {
 	value := vm.Lookup(name)
 	switch toCall := value.(type) {
 	case BuiltinValue:
@@ -295,7 +295,7 @@ func (vm *VM) CallNamed(name string, arguments ...Value) Value {
 	case CoverValue:
 		return vm.CallCover(toCall, arguments...)
 	default:
-		return NewListValue(NewErrorValuef("Cannot call %s: %v", name, value))
+		return ReturnError(NewErrorValuef("Cannot call %s: %v", name, value))
 	}
 }
 
@@ -329,35 +329,35 @@ func (vm *VM) Fail() {
 	vm.Frame.failed = true
 }
 
-func (vm *VM) RunChildren(ast Ast, args ...Value) Value {	
+func (vm *VM) RunChildren(ast Ast, args ...Value) []Value {	
 	if ast.CountChildren() < 1 {
-		return EmptyValue{}
+		return ReturnEmpty()
 	}
 	/* if ast.CountChildren() == 1 {
 		return ast.Child(0).Run(vm, args)
 	}
 	*/	
-	result := NewListValue()
+	result := []Value{}
 	for _, child := range ast.Children() {
 		val := child.Run(vm, args...)
 		
 		// skip empty results
-		if _, isEmpty := val.(EmptyValue); isEmpty  {
+		if len(val) < 1  {
 			continue
 		}
 		
-		// errors in the results take precendence and are propagated upwards.
-		if err, isErr := val.(ErrorValue); isErr  {			
-			return err
-		}	
-	
-		// Flatten lists
-		/*
-		if reslist, isList := val.(ListValue) ; isList && reslist.Length() > 0 {
-			result.AppendList(reslist)
+		first := val[0]
+		if _, isEmpty := first.(EmptyValue); isEmpty  {
+			continue
+		}
+		
+		last := val[len(val) -1]
+		// errors in the results at the last position take precendence and are propagated upwards.
+		if _, isErr := last.(ErrorValue); isErr  {
+			return val
 		}
-		*/ 
-		result.Append(val)
+			
+		result = append(result, val...)
 	}
 	return result
 }
@@ -368,15 +368,22 @@ func (vm *VM) RunChildrenLastResult(ast Ast, args ...Value) Value {
 		val := child.Run(vm, args...)
 				
 		// skip empty results
-		if _, isEmpty := val.(EmptyValue); isEmpty  {
+		if len(val) < 1  {
+			continue
+		}
+		
+		first := val[0]
+		if _, isEmpty := first.(EmptyValue); isEmpty  {
 			continue
 		}
 		
-		// errors in the results take precendence and are propagated upwards.
-		if err, isErr := val.(ErrorValue); isErr  {			
-			return err
+		last := val[len(val) -1]
+		// errors in the results at the last position take precendence and are propagated upwards.
+		if _, isErr := last.(ErrorValue); isErr  {
+			return last
 		}
-		result = val	
+
+		result = last
 	}
 	// The last non empty result is the result of this function.
 	return result
@@ -388,11 +395,16 @@ func (vm *VM) RunChildrenFirstResult(ast Ast, args ...Value) Value {
 		val := child.Run(vm, args...)
 				
 		// skip empty results
-		if _, isEmpty := val.(EmptyValue); isEmpty  {
+		if len(val) < 1  {
+			continue
+		}
+		
+		first := val[0]
+		if _, isEmpty := first.(EmptyValue); isEmpty  {
 			continue
 		}
 		// otherwise if non empty return the result. 
-		return val
+		return first
 	}
 	return result
 }
@@ -400,7 +412,7 @@ func (vm *VM) RunChildrenFirstResult(ast Ast, args ...Value) Value {
 
 
 
-func (vm *VM) RunAst(ast Ast, args ...Value) Value {
+func (vm *VM) RunAst(ast Ast, args ...Value) []Value {
 	return ast.Run(vm, args...)
 }