Example #1
0
File: error.go Project: catb0t/gelo
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
}
Example #2
0
func Compose(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word {
	if ac == 0 {
		return gelo.Alien(Id) //defined in eval.go
	} else if ac == 1 {
		return vm.API.InvokableOrElse(args.Value)
	}
	//reverse and type check (as much as possible)
	builder := extensions.ListBuilder()
	defer builder.Destroy()
	for ; args != nil; args = args.Next {
		builder.PushFront(vm.API.InvokableOrElse(args.Value))
	}
	fs := builder.List()
	return gelo.Alien(func(vm *gelo.VM, args *gelo.List, ac uint) gelo.Word {
		c := fs
		var ret gelo.Word = args
		for ; c.Next != nil; c = c.Next {
			ret = gelo.AsList(vm.API.InvokeCmdOrElse(c.Value, ret.(*gelo.List)))
		}
		return vm.API.TailInvokeCmd(c.Value, ret.(*gelo.List))
	})
}
Example #3
0
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
}