func Updatex(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word { if ac != 2 { gelo.ArgumentError(vm, "update!", "name value", args) } toreset := args.Value val := args.Next.Value if !vm.Ns.Mutate(toreset, val) { gelo.VariableUndefined(vm, toreset) } return val }
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 Swapx(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word { if ac != 2 { gelo.ArgumentError(vm, "swap!", "name name", args) } fst, snd := args.Value, args.Next.Value sndw, _, ok := vm.Ns.Swap(fst, snd) //don't need fstw if !ok { //we've lost our locks so this may produce nonsense _, fstb := vm.Ns.Lookup(fst) _, sndb := vm.Ns.Lookup(snd) if fstb && sndb { gelo.RuntimeError(vm, "Neither", fst, "nor", snd, "are defined") } if fstb { gelo.VariableUndefined(vm, fst) } if sndb { gelo.VariableUndefined(vm, snd) } gelo.RuntimeError(vm, "swap failed but both operands were defined") } return sndw //returned because this is now the "closest" }
func Decrx(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word { if ac != 1 { gelo.ArgumentError(vm, "decr!", "reference to number", args) } n, ok := vm.Ns.MutateBy(args.Value, func(w gelo.Word) (gelo.Word, bool) { n := vm.API.NumberOrElse(w) return gelo.NewNumber(n.Real() - 1), true }) if !ok { gelo.VariableUndefined(vm, args.Value) } return n }