Beispiel #1
0
func (d *Dwimmer) Run(setting *term.SettingT) term.T {
	goMeta := func() {
		StartShell(d, Interrupted.T(represent.SettingT(setting)))
	}
	for {
		//d.watchdog(setting)
		char, sent := d.CheckCh()
		if sent {
			if char == 'q' {
				panic("interrupted")
			} else if char == 's' {
				goMeta()
			} else {
				d.Clear()
				d.Debug("(Type [s] to interrupt execution and drop into a shell)")
				d.Debug("(Type [q] to interrupt execution and quit)")
			}
		}
		transition, ok := d.Get(setting.Setting)
		if !ok {
			transition = ElicitAction(d, setting.Copy(), setting.Setting)
		}
		result := transition.Step(d, setting)
		if result != nil {
			return result
		}
	}
}
Beispiel #2
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)
	}
}
Beispiel #3
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))
}
Beispiel #4
0
func (d *Dwimmer) watchdog(setting *term.SettingT) {
	if rand.Int()%(watchFrequency<<(3*watcherDepth)) == 0 {
		watcherDepth++
		defer func() { watcherDepth-- }()
		parent := setting.Copy().AppendAction(term.MetaC())
		oldWatcher := d.lastWatcher
		newWatcher := term.InitT()
		var Q term.T
		if d.lastWatcher == nil {
			Q = IsAllWell.T(term.MakeChannel(parent))
		} else {
			Q = IsAllWellPred.T(term.MakeChannel(parent), term.MakeChannel(oldWatcher))
		}
		d.lastWatcher = newWatcher
		dynamics.SubRun(d, Q, parent, newWatcher)
	}
}
Beispiel #5
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
}
Beispiel #6
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))
	}
}
Beispiel #7
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")
}
Beispiel #8
0
func (t SimpleTransition) Step(d Dwimmer, s *term.SettingT) term.T {
	actC := t.Action
	s.AppendAction(actC)
	actT := actC.Instantiate(s.Args)
	return d.Do(actT, s)
}