예제 #1
0
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
}
예제 #2
0
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
}
예제 #3
0
파일: control.go 프로젝트: catb0t/gelo
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
}
예제 #4
0
파일: combinator.go 프로젝트: catb0t/gelo
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())
	})
}