func (p *ConfigParser) startDebugPlugin(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word { if ac < 2 || !gelo.StrEqualsSym("on", args.Value.Ser()) { gelo.ArgumentError(vm, "start-debug-plugin", "on <listener> [<listener> ...]", args) } // Check whether we're in common section checkInSection(vm, "start-debug-plugin", "common") // Collect listener names from arguments var names []string for p := args; p != nil; p = p.Next { name := p.Value.Ser() names = append(names, name.String()) } p.conf.Common.StartDebugPlugin = names return nil }
func (p *ConfigParser) discoverable(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word { if ac < 2 || !gelo.StrEqualsSym("at", args.Value.Ser()) { gelo.ArgumentError(vm, "discoverable", "at <port> [<port> ...]", args) } // Check whether we're in common section checkInSection(vm, "discoverable", "common") args = args.Next // Skip first 'at' symbol // Collect all port numbers from the arguments var ports []uint16 for p := args; p != nil; p = p.Next { port, ok := p.Value.(*gelo.Number) if !ok { gelo.RuntimeError(vm, "discoverable arguments should be numbers") } ports = append(ports, uint16(port.Int())) } p.conf.Common.Discoverable = ports return nil }
func Case_of(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word { Args := _cases_parser(vm, args) key := Args["value"] arguments := gelo.AsList(key) cases, ok := vm.API.PartialEval(vm.API.QuoteOrElse(Args["cases"])) if !ok || cases.Next == nil && cases.Value == nil { gelo.SyntaxError(vm, "Expected:", _cases_parser, "{[value+ => resultant\n]+ [otherwise result]?} Got:", args) } //Give val a name, specified by var, in clauses of the cases block //XXX This disallows us from making tail calls if name, there := Args["var"]; there { if d, there := vm.Ns.DepthOf(name); there && d == 0 { defer vm.Ns.Set(0, name, vm.Ns.LookupOrElse(name)) } else { defer vm.Ns.Del(name) } vm.Ns.Set(0, name, key) } //run val through cmd before comparing if cmd, there := Args["cmd"]; there { key = vm.API.InvokeCmdOrElse(cmd, arguments) } //Parse lines for ; cases != nil; cases = cases.Next { //if last line, see if it's the otherwise clause if cases.Next == nil { item := cases.Value.(*gelo.List) s, ok := item.Value.(gelo.Symbol) if ok && gelo.StrEqualsSym("otherwise", s) { if item.Next == nil || item.Next.Next != nil { _cases_synerr() } return _case_eval(vm, item.Next.Value, arguments) } } item := cases.Value.(*gelo.List) //line is too short if item.Next == nil || item.Next.Next == nil { _cases_synerr() } //Parse a single line list := extensions.ListBuilder() var resultant gelo.Word for ; item != nil; item = item.Next { if item.Next == nil { //ultimate cell resultant = item.Value } else if item.Next.Next == nil { //penultimate cell s, ok := item.Value.(gelo.Symbol) if ok && gelo.StrEqualsSym("=>", s) { continue } _cases_synerr() } else { list.Push(item.Value) } } //see if key matches any of the items we found on this line for head := list.List(); head != nil; head = head.Next { if key.Equals(head.Value) { return _case_eval(vm, resultant, arguments) } } } return gelo.Null //no match, no otherwise }
func Partial(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word { //TODO all of the argument errors in this function could be more informative if ac < 2 { gelo.ArgumentError(vm, "partial", "command [args*|'*|'X]+", args) } cmd, args := vm.API.InvokableOrElse(args.Value), args.Next a_star := false var val gelo.Word var kind _partial_kind var ph, pt *_partial for ; args != nil; args = args.Next { kind, val = _pk_fill, nil if sym, ok := args.Value.(gelo.Symbol); ok { if gelo.StrEqualsSym("X", sym) { if a_star { gelo.ArgumentError(vm, "partial", "there will be no arguments left after *", args) } kind = _pk_hole } else if gelo.StrEqualsSym("*", sym) { if a_star { gelo.ArgumentError(vm, "partial", "only one * can be specfied", args) } kind, a_star = _pk_slurp, true } else { val = sym } } else { val = args.Value } if ph != nil { pt.next = &_partial{kind, val, nil} pt = pt.next } else { ph = &_partial{kind, val, nil} pt = ph } } pt = nil return gelo.Alien(func(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word { real_args := extensions.ListBuilder(cmd) for pls := ph; pls != nil; pls = pls.next { switch pls.kind { case _pk_fill: real_args.Push(pls.item) case _pk_hole: if args == nil { gelo.ArgumentError(vm, "partial function", "requires at least one more argument", args) } real_args.Push(args.Value) args = args.Next case _pk_slurp: real_args.Extend(args.Copy().(*gelo.List)) args = nil } } if args != nil { gelo.ArgumentError(vm, "partial function", "got too many arguments", args) } return vm.API.InvokeOrElse(real_args.List()) }) }