123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991 |
- // vm, the virtual low level machine that runs MUESLI.
- package muesli
- import (
- "fmt"
- "strings"
- )
- // 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 Callable interface
- type Callable interface {
- // Callable can be called
- Call(vm *VM, arguments ...Value) []Value
- // Callable has a position here it was defined. Needed for tracebacks.
- Position() *Position
- // Callable has a signature.. but not yet!
- // Signature() *Signature
- }
- // A helper Value has a help text available.
- // This help text can be set as well.
- type Helper interface {
- HelperName() string
- Help() string
- SetHelp(string) string
- }
- // Callable value types
- type CallableValue struct {
- // Name of the callable
- Name string
- // Help string for the callable.
- HelpText string
- }
- // Implement Helper interface
- func (val CallableValue) Help() string {
- return val.HelpText
- }
- // Implement Helper interface
- func (val * CallableValue) SetHelp(help string) string {
- val.HelpText = help
- return val.HelpText
- }
- // Implement Helper interface
- func (val CallableValue) HelperName() string {
- return val.Name
- }
- // AppendHelp appends help to an existing helper.
- func AppendHelp(helper Helper, extra string) string {
- return helper.SetHelp( helper.Help() + extra)
- }
- // ClearHelp rresets the help text to an empty string.
- func ClearHelp(helper Helper, extra string) string {
- return helper.SetHelp("")
- }
- 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
- }
- // A block in a script.
- type BlockValue struct {
- CallableValue
- Ast *Ast
- }
- func NewBlockValue(definition *Ast) *BlockValue {
- result := &BlockValue{}
- result.Name = fmt.Sprintf("<block:%s>", definition.String())
- result.Ast = definition
- return result
- }
- func (block * BlockValue) Position() *Position {
- if block == nil {
- return nil
- }
- if block.Ast == nil {
- return nil
- }
- pos := block.Ast.Token().Position
- return &pos
- }
- func (defined * DefinedValue) Position() *Position {
- if defined == nil {
- return nil
- }
- if defined.Body == nil {
- return nil
- }
- return defined.Body.Position()
- }
- func (cv CallableValue) Position() *Position {
- pos := Position{cv.Name, 1, 1}
- return &pos
- }
- /* Parameters for a defined value */
- type Parameter struct {
- Name WordValue
- Type TypeValue
- }
- // A script defined function
- type DefinedValue struct {
- CallableValue
- Body *BlockValue
- Parameters []*Parameter
- }
- func NewDefinedValue(name string, params []*Parameter, body *BlockValue) *DefinedValue {
- result := &DefinedValue{}
- result.Name = name
- result.Body = body
- result.Parameters = params
- return result
- }
- func (defined *DefinedValue) Call(vm *VM, arguments ...Value) []Value {
- vm.Trace("Call defined value: %v %v %v", defined, defined.Parameters, arguments)
- for i , arg := range arguments {
- if i >= len(defined.Parameters) {
- break
- }
- param := defined.Parameters[i]
- expectedType := param.Type
- if !expectedType.IsMatch(arg.Type()) {
- return Fail(NewErrorValuef("Argument %d type mismatch: %s<->%s", i, expectedType, arg.Type()))
- }
- vm.Register(param.Name.String(), arg)
- vm.Trace("DefinedValue.Call: vm.Register: %v %v", param.Name.String(), arg)
- }
-
- res := defined.Body.Call(vm, arguments...)
- return res
- }
- func (defined *DefinedValue) Help() string {
- help := defined.CallableValue.Help()
- extra := "["
- for _, parameter := range defined.Parameters {
- extra = fmt.Sprintf("%s %s %s", extra, parameter.Name, parameter.Type)
- }
- extra = extra + "]:"
- return extra + help
- }
- /*
- Amount of types that will be considered inside a signature.
- Limited mosty to allow hashability, that is, Signature is a map key.
- */
- const TypesInSignature = 32
- /* Signature describes the types that a callable takes. */
- type Signature struct {
- Types [TypesInSignature]TypeValue
- }
- func (s Signature) String() string {
- res := "["
- sep := ""
- for _, typ := range s.Types {
- if typ != ZeroTypeValue {
- res = res + sep + typ.String()
- sep = " "
- }
- }
- res = res + "]"
- return res
- }
- func NewSignature(types ... TypeValue) Signature {
- signature := Signature{}
- for i := 0 ; i < len(types) && i < len(signature.Types) ; i ++ {
- signature.Types[i] = types[i]
- }
- return signature
- }
- func CalculateSignature(arguments ...Value) Signature {
- signature := Signature{}
- 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 (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 {
- t1 := kind
- t2 := other.Types[i]
- if !t1.IsMatch(t2) {
- return false
- }
- }
- return true
- }
- /* An overload is an overloaded value that can be called. */
- type Overload struct {
- Name string
- Callable
- }
- /* 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 (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.CallableValue.Help()
- extra := "\n"
- for signature, overload := range cover.Overloads {
- // fmt.Printf("overload: %v", signature)
- 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")
- BuiltinTypeValue = TypeValue("Builtin")
- DefinedTypeValue = TypeValue("Defined")
- BlockTypeValue = TypeValue("Block")
- )
- func (v CoverValue) Type() TypeValue { return CoverTypeValue }
- func (v BuiltinValue) Type() TypeValue { return BuiltinTypeValue }
- func (v DefinedValue) Type() TypeValue { return DefinedTypeValue }
- func (v BlockValue) Type() TypeValue { return BlockTypeValue }
- 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)
- }
- func (from BlockValue) Convert(to interface{}) error {
- if toValue, isOk := to.(*BlockValue) ; isOk {
- (*toValue) = from
- return nil
- }
- return NewErrorValuef("Cannot convert the block value %v to %v", from, to)
- }
- func (cv * CoverValue) AddOverload(name string, callable Callable, 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 { Name: name, Callable: callable }
-
- // fmt.Printf("Overloads: %v\n", cv.Overloads)
-
- return nil
- }
- func (vm * VM) AddOverload(from, target string, level int, tv... TypeValue) error {
- var cover *CoverValue
- var callable Callable
- var ok bool
- 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)
- }
-
- // 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.(Callable) ; !ok {
- return fmt.Errorf("%s is not a callable value", target)
- }
- res := cover.AddOverload(target, callable, tv...)
-
- // fmt.Printf("AddOverload: %v %v\n", lookup, cover)
-
- return res
- }
- type OverloadDescription struct {
- Target string
- Types []TypeValue
- Level int
- }
- func (vm * VM) AddOverloads(from string, descriptions ... OverloadDescription) error {
- for _, od := range descriptions {
- err := vm.AddOverload(from, od.Target, od.Level, od.Types...)
- if err != nil {
- panic(fmt.Errorf("internal error: could not register overloads: %s", err))
- }
- }
- return nil
- }
- func Over(target string, level int, types ... TypeValue) OverloadDescription {
- return OverloadDescription { Target: target, Level: level, Types: types}
- }
- func (vm * VM) SetHelp(target, help string) error {
- var helper Helper
- var ok bool
- lookup := vm.Lookup(target)
- if lookup == nil {
- return fmt.Errorf("%s not found", target)
- } else if helper, ok = lookup.(Helper) ; !ok {
- return fmt.Errorf("%s exists but cannot set help text.", target)
- }
- helper.SetHelp(help)
- return nil
- }
- // 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) 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
- }
- func (scope * Scope) Known(filter func(string, Value) bool) map[string]Value {
- res := make(map[string]Value)
- if scope.parent != nil {
- res = scope.parent.Known(filter)
- }
- for k, v := range scope.symbols {
- if (filter == nil) || filter(k, v) {
- res[k] = v
- }
- }
- return res
- }
- func (scope * Scope) ForEachDefined(do func(string, Value) (bool, error)) (bool, error) {
- var res bool = true
- var err error
-
- if (do == nil) {
- return false, fmt.Errorf("do may not be nil")
- }
-
- if scope.parent != nil {
- res, err = scope.parent.ForEachDefined(do)
- }
- if res == false || err != nil {
- return res, err
- }
- for k, v := range scope.symbols {
- res, err = do(k, v)
- if res == false || err != nil {
- return res, err
- }
- }
- return res, err
- }
- func (scope* Scope) DefinedHelpers() []Helper {
- res := []Helper{}
- scope.ForEachDefined(func (k string, v Value) (bool, error) {
- helper, hok := v.(Helper)
- if hok {
- res = append(res, helper)
- }
- return true, nil
- })
- return res
- }
- // Frame of execution of a function
- type Frame struct {
- parent *Frame
- arguments []Value
- results []Value
- failed bool
- returned bool
- position *Position
- }
- func NewFrame(parent *Frame, position *Position) *Frame {
- return &Frame{parent, EmptyValueArray(), EmptyValueArray(), false, false, position}
- }
- type Tracer interface {
- Trace(vm VM, fmt string, args ... interface{}) 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
- ExitStatus int
- }
- func NewVM() *VM {
- vm := &VM{NewScope(nil), NewFrame(nil, nil), nil, nil, nil, 0}
- vm.Scope = vm.TopScope
- vm.Frame = vm.TopFrame
- return vm
- }
- func (vm *VM) Trace(fm string, args ... interface{}) {
- if vm.Tracer != nil {
- vm.Tracer.Trace(*vm, fm, args...)
- }
- }
- func (vm *VM) PushNewFrame(position *Position) *Frame {
- frame := NewFrame(vm.Frame, position)
- vm.Trace("PushFrame %v->%v\n", vm.Frame, frame)
- vm.Frame = frame
- return frame
- }
- func (vm *VM) PushNewScope() *Scope {
- scope := NewScope(vm.Scope)
- vm.Scope = scope
- return scope
- }
- func (vm *VM) Return(results ...Value) []Value {
- return results
- }
- func (vm *VM) PopFrame() *Frame {
- oldFrame := vm.Frame
- vm.Trace("PopFrame %v->%v\n", vm.Frame, vm.Frame.parent)
- if (vm.Frame != vm.TopFrame) && (vm.Frame.parent != nil) {
- frame := vm.Frame
- vm.Frame = frame.parent
- // Copy frame results up.
- vm.Frame.returned = oldFrame.returned
- vm.Frame.failed = oldFrame.failed
- vm.Frame.results = oldFrame.results
- 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 (block * BlockValue) Call(vm *VM, arguments ...Value) []Value {
- ast := block.Ast
- // Now, don't run the bloc itself but the Statements node
- // that should be in it.
- children := ast.Children()
- if len(children) < 1 {
- return Fail(fmt.Errorf("Block has no statements."))
- }
- if len(children) > 1 {
- return Fail(fmt.Errorf("Block has too many statements."))
- }
- statements := children[0]
- arr := vm.RunAst(*statements, arguments...)
- return arr
- }
- func (builtin * BuiltinValue) Call(vm *VM, arguments ...Value) []Value {
- handler := builtin.Handler
- return handler.Call(vm, arguments...)
- }
- /*
- func (vm *VM) CallDefined(ast *Ast, arguments ...Value) []Value {
- arr := vm.RunChildren(*ast, arguments...)
- return arr
- }
- func (vm *VM) CallBlock(ast *Ast, arguments ...Value) []Value {
- arr := vm.RunChildren(*ast, 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) AddTrace(err error) error {
- res := ""
- for frame := vm.Frame; frame != nil; frame = frame.parent {
- if frame.position == nil {
- res = fmt.Sprintf("%s\nIn frame %v", res, frame)
- } else {
- res = fmt.Sprintf("%s\nIn %s", res, frame.position.String())
- }
- }
- return fmt.Errorf("%s: %s", res, err)
- }
- func (vm *VM) CallCallable(callable Callable, arguments ...Value) []Value {
- defer vm.PopScope()
- defer vm.PopFrame()
- vm.PushNewFrame(callable.Position())
- vm.PushNewScope()
- result := callable.Call(vm, arguments...)
- return result
- }
- func (vm *VM) CallNamed(name string, arguments ...Value) []Value {
- value := vm.Lookup(name)
- if value == nil {
- return ReturnError(vm.AddTrace(NewErrorValuef("Cannot call %s: not found.", name)))
- }
-
- if callable, ok := value.(Callable) ; ok {
- return vm.CallCallable(callable, arguments...)
- } else {
- return ReturnError(vm.AddTrace(NewErrorValuef("Cannot call %s: %v. Not callable", name, value)))
- }
- }
- /*
- func (vm * VM) CallNamedFramed(name string, arguments ...) []Value {
- frame := vm.PushNewFrame()
- }
- */
- // ScopeUp Returns the levelth scope up from the current one where 0 is the
- // current scope. Returns the toplevel scope if l is greater than the current
- // scope stack depth.
- func (vm * VM) ScopeUp(level int) *Scope {
- scope := vm.Scope
- for now := 0; now < level; now++ {
- if scope.parent == nil {
- return scope
- }
- scope = scope.parent
- }
- return scope
- }
- // RegisterUp registers in klevel scopes up from the current scope,
- // or at toplevel if the level is greater than the total depth
- func (vm *VM) RegisterUp(name string, value Value, level int) Value {
- scope := vm.ScopeUp(level)
- return scope.Register(name, value)
- }
- func (vm *VM) Register(name string, value Value) Value {
- return vm.Scope.Register(name, value)
- }
- func (vm *VM) RegisterCover(name string, level int) *CoverValue {
- value := NewCoverValue(name)
- vm.RegisterUp(name, value, level)
- return 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, params []*Parameter, block *BlockValue, level int) Value {
- value := NewDefinedValue(name, params, block)
- return vm.RegisterUp(name, value, level)
- }
- // RegisterBuiltinWithHelp
- func (vm *VM) RegisterBuiltinWithHelp(name string, handler Handler, help string) Value {
- res := vm.RegisterBuiltin(name, handler)
- vm.SetHelp(name, help)
- return res
- }
- 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
- }
-
- // skip empty results
- if len(val) < 1 {
- continue
- }
-
- 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(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]
- }
-
- // skip empty results
- if len(val) < 1 {
- continue
- }
-
- 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 last
- }
- result = last
- }
- // 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...)
-
- if vm.Frame.returned || vm.Frame.failed {
- res := vm.Frame.results
- return res[0]
- }
- // skip empty results
- if len(val) < 1 {
- continue
- }
-
- first := val[0]
- if _, isEmpty := first.(EmptyValue); isEmpty {
- continue
- }
- // otherwise if non empty return the result.
- return val[0]
- }
- return result
- }
- */
- func (vm *VM) RunAst(ast Ast, args ...Value) []Value {
- var result []Value
- /*pos := ast.Token().Position
- vm.PushNewFrame(&pos)
- defer vm.PopFrame()
- */
- // vm.Logf("RunAst: %s\n", ast.Kind().String())
- // Leaf nodes, both declared and in practice are self evaluating.
- if ast.Kind().IsLeaf() || ast.CountChildren() < 1 {
- result = ast.Eval(vm)
- if vm.Frame.returned || vm.Frame.failed {
- result = vm.Frame.results
- vm.Frame.returned = false
- vm.Frame.failed = false
- }
- } else {
- var subResult = []Value{}
- // Depth first recursion.
- for i, child := range ast.Children() {
- sub := vm.RunAst(*child)
- subResult = append(subResult, sub...)
- vm.Trace("RunAst: %d %v %v %v\n", i, child, sub, vm.Frame)
- /*
- if frame.failed && frame.parent != nil {
- // failures are like panics and propagate up the call tree
- frame.parent.failed = true
- frame.parent.results = frame.results
- }
- */
- if vm.Frame.returned || vm.Frame.failed {
- subResult = vm.Frame.results
- vm.Frame.returned = false
- vm.Frame.failed = false
- break;
- }
- }
- // vm.Logf("RunAst subResult: %v\n", subResult)
- result = ast.Eval(vm, subResult...)
- }
- // vm.Logf("RunAst result: %v\n", result)
- return result
- }
- func (vm *VM) DefinedHelpers() []Helper {
- return vm.Scope.DefinedHelpers()
- }
- func (vm * VM) BackTraceFrames() []*Frame {
- bt := []*Frame{}
-
- for frame := vm.Frame ; frame.parent != nil ; frame = frame.parent {
- bt = append(bt, frame)
- }
-
- return bt
- }
- func (vm * VM) BackTracePositions() []*Position {
- bt := []*Position{}
-
- for frame := vm.Frame ; frame.parent != nil ; frame = frame.parent {
- bt = append(bt, frame.position)
- }
-
- return bt
- }
- func (vm * VM) BackTraceStrings() []string {
- bt := []string{}
-
- for frame := vm.Frame ; frame.parent != nil ; frame = frame.parent {
- bt = append(bt, frame.position.String())
- }
-
- return bt
- }
- 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)}}
- }
- }
- */
|