Exemple #1
0
func DictToCommand(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word {
	if ac != 1 {
		gelo.ArgumentError(vm, "dict->command", "dictionary", args)
	}
	m := vm.API.DictOrElse(args.Value).Map()
	return gelo.Alien(func(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word {
		if ac == 0 {
			gelo.ArgumentError(vm, "command generated by dict->command",
				"argument+", args)
		}
		name := args.Value.Ser().String()
		if v, ok := m[name]; ok {
			if args.Next != nil {
				return vm.API.TailInvokeCmd(v, args.Next)
			} else {
				return vm.API.TailInvokeWordOrReturn(v)
			}
		} else if args.Next != nil {
			gelo.RuntimeError(vm, name, "is not a valid subcommand")
		} else {
			gelo.RuntimeError(vm, name, "is not a valid subcommand or entry")
		}
		panic("command generated by dict->command in impossible state") //Issue 65
	})
}
Exemple #2
0
func Die(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word {
	if ac == 0 {
		args = gelo.AsList(gelo.StrToSym("die"))
	}
	gelo.RuntimeError(vm, args)
	return gelo.Null //Issue 65
}
Exemple #3
0
func NS_unfork(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word {
	if ac != 0 {
		gelo.ArgumentError(vm, "ns.unfork", "", args)
	}
	if _, ok := vm.Ns.Unfork(); !ok {
		gelo.RuntimeError(vm, "Fatal: Last namespace destroyed")
	}
	vm.API.Trace("Namespace destroyed")
	return gelo.Null
}
Exemple #4
0
func PortReadx(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word {
	if ac != 1 {
		gelo.ArgumentError(vm, "read!", "port", args)
	}
	p := vm.API.PortOrElse(args.Value)
	if p.Closed() {
		gelo.RuntimeError(vm, "attempted to read from a closed port")
	}
	return p.Recv()
}
Exemple #5
0
func PortClosex(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word {
	if ac != 1 {
		gelo.ArgumentError(vm, "close!", "port", args)
	}
	p := vm.API.PortOrElse(args.Value)
	if p.Closed() {
		gelo.RuntimeError(vm, "port already closed")
	}
	p.Close()
	return gelo.Null
}
Exemple #6
0
func checkNotInSection(vm *gelo.VM, command string) {
	k := gelo.StrToSym("section")
	if s, ok := vm.Ns.Get(0, k); ok {
		gelo.RuntimeError(
			vm,
			fmt.Sprintf(
				"%s command is used inside a section %s while it should be toplevel",
				command, s.Ser().String(),
			),
		)
	}
}
Exemple #7
0
func Exportx(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word {
	lvl := 1
	if ac == 4 {
		lvl, args = _export_parser(vm, args)
	} else if ac != 2 {
		gelo.ArgumentError(vm, "export!", "[up levels]? name value", args)
	}
	value := args.Next.Value
	if !vm.Ns.Set(lvl, args.Value, value) {
		gelo.RuntimeError(vm, "invalid namespace specified")
	}
	return value
}
Exemple #8
0
func DictCon(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word {
	if ac == 0 {
		return gelo.NewDict()
	}
	if ac != 1 {
		gelo.ArgumentError(vm, "Dict", "{{k1 v1} {k2 v2} ... {kn vn}}", args)
	}
	d, ok := gelo.UnserializeDictFrom(args.Value)
	if !ok {
		gelo.RuntimeError(vm, "Cannot unserialize", args.Value, "into a dict")
	}
	return d
}
Exemple #9
0
func Dict_unsetx(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word {
	if ac != 2 {
		gelo.ArgumentError(vm, "dict.unset!", "dictionary key", args)
	}
	d := vm.API.DictOrElse(args.Value)
	k := args.Next.Value
	v, ok := d.Get(k)
	if !ok {
		gelo.RuntimeError(vm,
			"dict.unset! attempted to unset a key not in dictionary")
	}
	d.Del(k)
	return v
}
Exemple #10
0
//Left-to-right
func Quotient(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word {
	if ac == 0 {
		return gelo.NewNumber(0)
	}
	acc := vm.API.NumberOrElse(args.Value).Real()
	for args = args.Next; args != nil; args = args.Next {
		n := vm.API.NumberOrElse(args.Value).Real()
		if n == 0 {
			gelo.RuntimeError(vm, "Division by 0")
		}
		acc /= n
	}
	return gelo.NewNumber(acc)
}
Exemple #11
0
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"
}
Exemple #12
0
func Exportsx(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word {
	lvls, args := _export_parser(vm, args)
	m := make(map[string]gelo.Word)
	for ; args != nil; args = args.Next {
		//Ns Ser's value anyway so no point in doing it twice
		k := args.Value.Ser()
		v := vm.Ns.LookupOrElse(k)
		m[k.String()] = v
	}
	d := gelo.NewDictFrom(m)
	if !vm.Ns.Inject(lvls, d) {
		gelo.RuntimeError(vm, "invalid namespace specified")
	}
	return d
}
Exemple #13
0
func Dict_get(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word {
	if !(ac == 2 || ac == 3) {
		gelo.ArgumentError(vm, "dict.get", "dictionary key default?", args)
	}
	d := vm.API.DictOrElse(args.Value)
	k := args.Next.Value
	ret, ok := d.Get(k)
	if !ok {
		if ac == 3 {
			//return default value
			return args.Next.Next.Value
		}
		gelo.RuntimeError(vm, "dictionary does not contain", k)
	}
	return ret
}
Exemple #14
0
func PortWritex(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word {
	if ac < 2 {
		gelo.ArgumentError(vm, "write!", "port rest+", args)
	}
	p := vm.API.PortOrElse(args.Value)
	if p.Closed() {
		gelo.RuntimeError(vm, "attempted to write to a closed port")
	}
	var msg gelo.Word
	if ac == 2 {
		msg = args.Next.Value
	} else {
		msg = args.Next
	}
	p.Send(msg)
	return msg
}
Exemple #15
0
func booleanOption(vm *gelo.VM, args *gelo.List, ac uint, dst *bool, command string, sections ...string) {
	if ac > 1 {
		gelo.ArgumentError(vm, command, "[true | false]", args)
	}

	// Check whether we're in the specified sections
	checkInSection(vm, command, sections...)

	if ac > 0 {
		enabled, ok := args.Value.(gelo.Bool)
		if !ok {
			gelo.RuntimeError(vm, command, "argument should be equal to true or false or be absent")
		}
		*dst = enabled.True()
	} else {
		*dst = true
	}
}
Exemple #16
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
}
Exemple #17
0
func IndexError(vm *gelo.VM, idx int, w gelo.Word) {
	gelo.RuntimeError(vm, "Invalid index", idx, "in", w)
}
Exemple #18
0
func runtimeError(vm *gelo.VM, fmt string, args ...interface{}) {
	gelo.RuntimeError(vm, fmt.Sprintf(fmt, args...))
}