Esempio n. 1
0
func (d *Dwimmer) Answer(q term.T, optionalSetting ...*term.SettingT) (term.T, term.T) {
	var s *term.SettingT
	if len(optionalSetting) == 1 {
		s = optionalSetting[0]
	} else {
		s = term.InitT()
		s.AppendTerm(BuiltinAnswerer.T(q))
	}
	a := dynamics.SubRun(d, q, s)
	switch a.Head() {
	case core.Answer:
		return a.Values()[0], nil
	case core.Yes, core.No:
		return a, nil
	}
	follow := term.InitT()
	isAnswer := dynamics.SubRun(d, IsAnswer.T(a, q), s, follow)
	for {
		switch isAnswer.Head() {
		case core.Yes:
			result, err := d.Answer(WhatAnswer.T(a, q))
			if err != nil {
				return nil, a
			}
			return result, nil
		case core.No:
			return nil, a
		}
		isAnswer = dynamics.SubRun(d, IsAnswerClarify.T(), s, follow)
	}
}
Esempio n. 2
0
func getInput(d dynamics.Dwimmer, context *term.SettingT, hintstrings, toolmap term.T) term.T {
	quotedHints, err := represent.ToList(d, hintstrings)
	if err != nil {
		return represent.ConversionError.T(hintstrings, err)
	}
	hints := make([]string, len(quotedHints))
	for i, quoted := range quotedHints {
		hints[i], err = represent.ToStr(d, quoted)
		if err != nil {
			return represent.ConversionError.T(quoted, err)
		}
	}
	tools := make(map[rune]string)
	for toolmap.Head() != maps.Empty {
		switch toolmap.Head() {
		case maps.Cons:
			vs := toolmap.Values()
			c, err := represent.ToRune(d, vs[0])
			if err != nil {
				return represent.ConversionError.T(vs[0], err)
			}
			s, err := represent.ToStr(d, vs[1])
			if err != nil {
				return represent.ConversionError.T(vs[1], err)
			}
			tools[c] = s
			toolmap = vs[2]
		default:
			context.AppendTerm(UnrecognizedDictionary.T())
			return nil
		}
	}
	input := d.Readln(" < ", hints, tools)
	return core.Answer.T(represent.Str(input))
}
Esempio n. 3
0
func SubRun(d Dwimmer, Q term.T, parent *term.SettingT, optionalChild ...*term.SettingT) term.T {
	var child *term.SettingT
	if len(optionalChild) == 1 {
		child = optionalChild[0]
	} else {
		child = term.InitT()
	}
	child.AppendTerm(Parent(parent))
	child.AppendTerm(Q)
	d.Push(Q)
	stackCheck()
	A := d.Run(child)
	parent.AppendTerm(OpenChannel.T(term.MakeChannel(child)))
	if A != nil {
		parent.AppendTerm(A)
	}
	d.Pop()
	return A
}
Esempio n. 4
0
func parseInput(d dynamics.Dwimmer, context *term.SettingT, quotedInput, quotedNames term.T) term.T {
	input, err := represent.ToStr(d, quotedInput)
	if err != nil {
		return represent.ConversionError.T(quotedInput, err)
	}
	quotedList, err := represent.ToList(d, quotedNames)
	if err != nil {
		return represent.ConversionError.T(quotedNames, err)
	}
	names := make([]string, len(quotedList))
	for i, quoted := range quotedList {
		names[i], err = represent.ToStr(d, quoted)
		if err != nil {
			return represent.ConversionError.T(quoted, err)
		}
	}
	if input == "jump up" {
		return GoMeta.T()
	}
	a := parsing.ParseAction(input, names)
	if a == nil {
		c := parsing.ParseTerm(input, names)
		if c != nil {
			switch c := c.(type) {
			case *term.CompoundC:
				if questionLike(c) {
					a = new(term.ActionC)
					*a = term.AskC(c)
				}
			case term.ReferenceC:
				a = new(term.ActionC)
				*a = term.ViewC(c)
			}
			context.AppendTerm(IsTerm.T())
			return nil
		} else {
			context.AppendTerm(ParseError.T())
			return nil
		}
	} else {
		for _, n := range a.IntArgs {
			if n < 0 {
				context.AppendTerm(ParseError.T())
				return nil
			}
		}
		return core.Answer.T(represent.ActionC(*a))
	}
}
Esempio n. 5
0
func (d *Dwimmer) Do(a term.ActionT, s *term.SettingT) term.T {
	switch a.Act {
	case term.Return:
		return a.Args[0]
	case term.Ask:
		Q := a.Args[0]
		child := term.InitT()
		dynamics.SubRun(d, Q, s, child)
		return nil
	case term.View:
		value := a.Args[0]
		if value != nil {
			s.AppendTerm(value)
		} else {
			s.AppendTerm(Closed.T())
		}
		return nil
	case term.Replace:
		//value := a.Args[0]
		//n := a.IntArgs[0]
		//s.Rollback(n).AppendTerm(value)
		return nil
	case term.Replay:
		n := a.IntArgs[0]
		s.Rollback(n)
		return nil
	case term.Clarify:
		Q := a.Args[1]
		//TODO handle null pointers much better...
		//(e.g. one part of an expression may refer to a deleted variable)
		if a.Args[0] == nil {
			s.AppendTerm(Closed.T())
			return nil
		}
		var target *term.SettingT
		channel, err := represent.ToChannel(d, a.Args[0])
		if err == nil {
			target = channel.(term.Channel).Instantiate()
		} else {
			var othererr term.T
			target, othererr = represent.ToSettingT(d, a.Args[0])
			if othererr != nil {
				s.AppendTerm(NotAChannel.T(err))
				return nil
			}
		}
		dynamics.SubRun(d, Q, s, target)
		return nil
	case term.Correct:
		n := a.IntArgs[0]
		old := s.Setting.Rollback(n)
		transition := ElicitAction(d, term.InitT(), old)
		d.Save(old, transition)
		s.AppendTerm(core.OK.T())
		return nil
	case term.Delete:
		n := a.IntArgs[0]
		s.Args[n] = nil
		s.AppendTerm(core.OK.T())
		return nil
	case term.Meta:
		s.AppendTerm(CurrentSetting.T(represent.SettingT(s)))
		return nil
	}
	panic("unknown kind of action")
}