123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486 |
- // vm, the virtual low level machine that runs MUESLI.
- package muesli
- // import "fmt"
- // Handler function
- type Handler func(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
- }
- // Callable value types
- type CallableValue struct {
- Name string
- }
- func (val CallableValue) String() string {
- return val.Name
- }
- func (val CallableValue) Type() TypeValue {
- return TypeValue("Callable")
- }
- 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 {
- panic("Not implemented")
- }
- // A struct to store a built in function
- type BuiltinValue struct {
- CallableValue
- Handler
- }
- func NewCallableValue(name string) CallableValue {
- return CallableValue{name}
- }
- func NewBuiltinValue(name string, handler Handler) BuiltinValue {
- result := BuiltinValue{}
- result.Name = name
- result.Handler = handler
- return result
- }
- func (builtin *BuiltinValue) Call(vm *VM, arguments ...Value) Value {
- return vm.CallBuiltin(builtin.Handler, arguments...)
- }
- // A script defined function
- type DefinedValue struct {
- CallableValue
- Definition *Ast
- }
- func NewDefinedValue(name string, definition *Ast) DefinedValue {
- result := DefinedValue{}
- result.Name = name
- result.Definition = definition
- return result
- }
- func (defined *DefinedValue) Call(vm *VM, arguments ...Value) Value {
- return vm.CallDefined(defined.Definition, arguments...)
- }
- /*
- Amount of types that will be considered inside a signature.
- Limited mosty to allow hashability.
- */
- const TypesInSignature = 8
- /* A signature describes the desired types of an overloaded function call. */
- type Signature struct {
- Types [TypesInSignature]TypeValue
- }
- func CalculateSignature(arguments ...Value) Signature {
- signature := Signature{}
- for i := 0; i < cap(signature.Types); i++ {
- if i > len(arguments) {
- signature.Types[i] = AnyTypeValue
- } else {
- signature.Types[i] = arguments[i].Type()
- }
- }
- return signature
- }
- func (signature *Signature) IsMatch(arguments ...Value) bool {
- for i, kind := range signature.Types {
- if i > len(arguments) || arguments[i] == nil {
- return false
- }
- if kind != arguments[i].Type() && kind != AnyTypeValue {
- return false
- }
- }
- return true
- }
- /* An overload is an overloaded callable value that can be called. */
- type Overload struct {
- CallableValue
- }
- /* A cover is a callable that dispatches to other callables depending on
- the types of the arguments, in particular the first one. The individual
- callable functions are the overloads
- */
- type CoverValue struct {
- CallableValue
- Overloads map[Signature]Overload
- }
- func NewCoverValue(name string) CoverValue {
- result := CoverValue{}
- result.Name = name
- result.Overloads = make(map[Signature]Overload)
- return result
- }
- 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 signature, overload := range cover.Overloads {
- if signature.IsMatch(arguments...) {
- return overload.Call(vm, arguments...)
- }
- }
- }
- vm.Fail()
- return NewListValue(NewErrorValuef("Could not match cover %s with arguments.", cover.Name))
- }
- const (
- CoverTypeValue = TypeValue("Cover")
- BuiltinTypeValue = TypeValue("Builtin")
- DefinedTypeValue = TypeValue("Defined")
- )
- func (v CoverValue) Type() TypeValue { return CoverTypeValue }
- func (v BuiltinValue) Type() TypeValue { return BuiltinTypeValue }
- func (v DefinedValue) Type() TypeValue { return DefinedTypeValue }
- func (from CoverValue) Convert(to interface{}) error {
- return NewErrorValuef("Cannot convert the cover value %v to %v", from, to)
- }
- func (from BuiltinValue) Convert(to interface{}) error {
- return NewErrorValuef("Cannot convert the builtin value %v to %v", from, to)
- }
- func (from DefinedValue) Convert(to interface{}) error {
- return NewErrorValuef("Cannot convert the defined value %v to %v", from, to)
- }
- // Scope of symbols defined in the VM, hierarchical
- type Scope struct {
- parent *Scope
- children []*Scope
- symbols map[string]Value
- }
- 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]
- if ok {
- return value
- }
- if scope.parent != nil {
- return scope.parent.Lookup(name)
- }
- return NilValue
- }
- func (scope *Scope) Register(name string, value Value) Value {
- scope.symbols[name] = value
- return value
- }
- // Frame of execution of a function
- type Frame struct {
- parent *Frame
- arguments []Value
- results []Value
- failed bool
- }
- func NewFrame(parent *Frame) *Frame {
- return &Frame{parent, EmptyValueArray(), EmptyValueArray(), false}
- }
- type Tracer interface {
- Trace(vm VM, ast Ast, values ...Value) bool
- }
- // Virtual machine
- type VM struct {
- TopScope *Scope // Top level scope
- TopFrame *Frame // Top level scope
- *Scope // Current Scope
- *Frame // Current frame
- Tracer // Tracer to emit tracing info to, could be used for logging or debugging
- }
- func NewVM() *VM {
- vm := &VM{NewScope(nil), NewFrame(nil), nil, nil, nil}
- vm.Scope = vm.TopScope
- vm.Frame = vm.TopFrame
- return vm
- }
- func (vm *VM) PushNewFrame() *Frame {
- frame := NewFrame(vm.Frame)
- vm.Frame = frame
- return frame
- }
- func (vm *VM) PushNewScope() *Scope {
- scope := NewScope(vm.Scope)
- vm.Scope = scope
- return scope
- }
- func (vm *VM) PopFrame() *Frame {
- if (vm.Frame != vm.TopFrame) && (vm.Frame.parent != nil) {
- frame := vm.Frame
- vm.Frame = frame.parent
- return frame
- }
- return nil
- }
- func (vm *VM) PopScope() *Scope {
- if (vm.Scope != vm.TopScope) && (vm.Scope.parent != nil) {
- scope := vm.Scope
- vm.Scope = scope.parent
- return scope
- }
- return nil
- }
- 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 {
- return handler.Call(vm, arguments...)
- }
- func (vm *VM) CallCover(cover CoverValue, arguments ...Value) Value {
- return cover.Call(vm, arguments...)
- }
- func (vm *VM) CallNamed(name string, arguments ...Value) Value {
- value := vm.Lookup(name)
- switch toCall := value.(type) {
- case BuiltinValue:
- return vm.CallBuiltin(toCall.Handler, arguments...)
- case DefinedValue:
- return vm.CallDefined(toCall.Definition, arguments...)
- case CoverValue:
- return vm.CallCover(toCall, arguments...)
- default:
- return NewListValue(NewErrorValuef("Cannot call %s: %v", name, value))
- }
- }
- /*
- func (vm * VM) CallNamedFramed(name string, arguments ...) []Value {
- frame := vm.PushNewFrame()
- }
- */
- func (vm *VM) Register(name string, value Value) Value {
- return vm.Scope.Register(name, value)
- }
- func (vm *VM) RegisterCover(name string) Value {
- value := NewCoverValue(name)
- return vm.Register(name, value)
- }
- func (vm *VM) RegisterBuiltin(name string, handler Handler) Value {
- value := NewBuiltinValue(name, handler)
- return vm.Register(name, value)
- }
- func (vm *VM) RegisterDefined(name string, ast *Ast) Value {
- value := NewDefinedValue(name, ast)
- return vm.Register(name, value)
- }
- func (vm *VM) Fail() {
- vm.Frame.failed = true
- }
- func (vm *VM) RunChildren(ast Ast, args ...Value) Value {
- if ast.CountChildren() < 1 {
- return EmptyValue{}
- }
- /* if ast.CountChildren() == 1 {
- return ast.Child(0).Run(vm, args)
- }
- */
- result := NewListValue()
- for _, child := range ast.Children() {
- val := child.Run(vm, args...)
-
- // skip empty results
- if _, isEmpty := val.(EmptyValue); isEmpty {
- 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)
- }
- */
- result.Append(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...)
-
- // skip empty results
- if _, isEmpty := val.(EmptyValue); isEmpty {
- continue
- }
-
- // errors in the results take precendence and are propagated upwards.
- if err, isErr := val.(ErrorValue); isErr {
- return err
- }
- result = val
- }
- // The last non empty result is the result of this function.
- 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...)
-
- // skip empty results
- if _, isEmpty := val.(EmptyValue); isEmpty {
- continue
- }
- // otherwise if non empty return the result.
- return val
- }
- return result
- }
- func (vm *VM) RunAst(ast Ast, args ...Value) Value {
- return ast.Run(vm, args...)
- }
- /*
- 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)}}
- }
- }
- */
|