func (p *ConfigParser) plugin(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word { if ac != 2 { gelo.ArgumentError(vm, "plugin", "<name> {body}", args) } name := args.Value.Ser().String() body := vm.API.QuoteOrElse(args.Next.Value) checkInSection(vm, "plugin", "plugins") insideSection(vm, "plugin", name, func() { p.conf.Plugins[name] = new(conf.PluginConf) p.conf.Plugins[name].Name = name vm.API.InvokeCmdOrElse(body, args) p.conf.Plugins[name].Options = make(map[string][]string) d := getOrMakeDict(vm, "data") for k, v := range d.Map() { var elements []string args.Slice() for e := vm.API.ListOrElse(v); e != nil; e = e.Next { elements = append(elements, e.Value.Ser()) } p.conf.Plugins[name].Options[k] = elements } }, ) return nil }
//For each item, Value acts as the identity unless the item is a quote. //If it is a quote attempt to invoke and return result if there were no errors //If invocation fails for any reason Value returns the quote as a literal. func Value(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word { if ac == 0 { gelo.ArgumentError(vm, "value", "items+", "") } return args.MapOrApply(func(w gelo.Word) gelo.Word { return vm.API.TailInvokeWordOrReturn(w) }) }
func Copy(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word { if ac == 0 { gelo.ArgumentError(vm, "copy", "values+", "") } return args.MapOrApply(func(w gelo.Word) gelo.Word { return w.Copy() }) }
func Type_of(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word { if ac == 0 { gelo.ArgumentError(vm, "type-of", "value+", "") } return args.MapOrApply(func(w gelo.Word) gelo.Word { return w.Type() }) }
func NaNp(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word { if ac == 0 { return gelo.False } return args.MapOrApply(func(w gelo.Word) gelo.Word { return gelo.ToBool(math.IsNaN(vm.API.NumberOrElse(w).Real())) }) }
func Negativep(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word { if ac == 0 { return gelo.False } return args.MapOrApply(func(w gelo.Word) gelo.Word { return gelo.ToBool(vm.API.NumberOrElse(w).Real() < 0) }) }
// Unlike And and Or, Not only works on bools func Not(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word { if ac == 0 { return gelo.False } return args.MapOrApply(func(w gelo.Word) gelo.Word { return gelo.ToBool(!vm.API.BoolOrElse(w).True()) }) }
func Setp(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word { if ac == 0 { gelo.ArgumentError(vm, "set?", "name+", args) } return args.MapOrApply(func(w gelo.Word) gelo.Word { _, ok := vm.Ns.Lookup(w) return gelo.ToBool(ok) }) }
func Abs(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word { if ac == 0 { return gelo.NewNumber(0) } return args.MapOrApply(func(w gelo.Word) gelo.Word { n := vm.API.NumberOrElse(w).Real() return gelo.NewNumber(math.Abs(n)) }) }
func Invokablep(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word { if ac == 0 { return gelo.False } return args.MapOrApply(func(w gelo.Word) gelo.Word { _, ok := vm.API.IsInvokable(w) return gelo.ToBool(ok) }) }
func Integerp(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word { if ac == 0 { return gelo.False } return args.MapOrApply(func(w gelo.Word) gelo.Word { n := vm.API.NumberOrElse(w) _, ok := n.Int() return gelo.ToBool(ok) }) }
func Unsetx(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word { if ac == 0 { gelo.ArgumentError(vm, "unset!", "name+", args) } return args.MapOrApply(func(w gelo.Word) gelo.Word { val, ok := vm.Ns.Del(w) if !ok { gelo.VariableUndefined(vm, w) } return val }) }
func InvokableOrId(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word { if ac == 0 { return gelo.Null } return args.MapOrApply(func(w gelo.Word) gelo.Word { i, ok := vm.API.IsInvokable(w) if !ok { return w } return i }) }
func NumberCon(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word { if ac == 0 { return gelo.NewNumber(0) } return args.MapOrApply(func(w gelo.Word) gelo.Word { if n, ok := w.(*gelo.Number); ok { return n } if n, ok := gelo.NewNumberFromBytes(w.Ser().Bytes()); ok { return n } return gelo.False }) }
func Sgn(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word { if ac == 0 { gelo.ArgumentError(vm, "sgn", "number+", "") } return args.MapOrApply(func(w gelo.Word) gelo.Word { n := vm.API.NumberOrElse(w).Real() switch { case n < 0: n = -1 case n > 0: n = 1 case n == 0: n = 0 } return gelo.NewNumber(n) }) }
func MakeInvokable(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word { if ac == 0 { return gelo.Noop } return args.MapOrApply(func(w gelo.Word) gelo.Word { i, ok := vm.API.IsInvokable(w) if !ok { return gelo.Alien( func(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word { if ac != 0 { gelo.ArgumentError(vm, w.Ser(), "", args) } return w }) } return i }) }
func (b *LBuilder) ExtendFront(l *gelo.List) { if l == nil { return } middle := b.head b.head = l for ; l.Next != nil; l = l.Next { b.n++ } l.Next = middle }
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()) }) }