예제 #1
0
파일: argparse.go 프로젝트: catb0t/gelo
func MaybeArgumentParser(_ *gelo.VM, args *gelo.List, ac uint) gelo.Word {
	parser := extensions.MakeArgParser(_args_to_spec(args, ac))
	return gelo.Alien(func(vm *gelo.VM, args *gelo.List, _ uint) gelo.Word {
		Args, ok := parser(args)
		if !ok {
			return gelo.NewList(gelo.False)
		}
		return gelo.NewList(gelo.True, gelo.NewDictFrom(Args))
	})
}
예제 #2
0
파일: dict.go 프로젝트: catb0t/gelo
func Dict_items(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word {
	if ac != 1 {
		gelo.ArgumentError(vm, "dict.values", "dictionary", args)
	}
	d, list := vm.API.DictOrElse(args.Value), extensions.ListBuilder()
	for k, v := range d.Map() {
		list.Push(gelo.NewList(gelo.NewList(gelo.StrToSym(k), v)))
	}
	return list.List()
}
예제 #3
0
파일: regexp.go 프로젝트: catb0t/gelo
func Re_replace_by(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word {
	if ac != 3 {
		gelo.ArgumentError(vm, "replace-all", "regexp string replace-cmd", args)
	}
	r := ReOrElse(vm, args.Value)
	src := args.Next.Value.Ser().Bytes()
	repl := args.Next.Next.Value
	return gelo.BytesToSym(r.ReplaceAllFunc(src, func(s []byte) []byte {
		args := gelo.NewList(gelo.BytesToSym(s))
		return vm.API.InvokeCmdOrElse(repl, args).Ser().Bytes()
	}))
}
예제 #4
0
파일: argparse.go 프로젝트: catb0t/gelo
func MakeArgParser(spec string) func(*gelo.List) (map[string]gelo.Word, bool) {
	if len(spec) == 0 || gelo.SlurpWS([]byte(spec), 0) == len(spec) {
		return _empty_parser
	}
	pp := &__arg_parserparser{
		make(map[string]bool), nil, []byte(spec), _char, -1, new(bytes.Buffer)}
	p := pp._parse_seq(true)
	pp.buf = nil //allow these to be garbage collected
	pp.spec = nil
	//TODO pass map[string]bool around instead of pp
	return func(args *gelo.List) (map[string]gelo.Word, bool) {
		//don't want old matches skewing results so we create an l map each time
		pp.l = make(map[string]bool)
		//attempt to match
		ok, m := p.match(args, pp)
		if !ok || m.cont != nil {
			return nil, false
		}
		defer func() { pp.l = nil }()
		out := make(map[string]gelo.Word)
		repeat := make(map[string]*gelo.List)
		//process matches
		for kv := m.head; kv != nil; kv = kv.next {
			key, val := kv.key, kv.val
			if pp.s[key] { //symbol
				out[key] = gelo.Null
			} else if pp.l[key] { //list
				if tail, ok := repeat[key]; ok {
					tail.Next = &gelo.List{val, nil}
					repeat[key] = tail.Next
				} else { //not seen yet
					l := &gelo.List{val, nil}
					out[key] = l
					repeat[key] = l
				}
			} else { //single var
				if v, ok := out[key]; ok { //promote to list
					pp.l[key] = true
					l := gelo.NewList(v, val)
					out[key] = l
					repeat[key] = l.Next
				} else { //just assign
					out[key] = val
				}
			}
		}
		return out, true
	}
}