<commit_before>package pisc

var ModLoopCore = Module{
	Author:    "<NAME>",
	Name:      "LoopCore",
	License:   "MIT",
	DocString: "times is the standard counted loop, while takes two conditions",
	Load:      loadLoopCore,
}

func loadLoopCore(m *Machine) error {
	m.PredefinedWords["times"] = GoWord(func(m *Machine) error {
		toExec := m.PopValue().(*Quotation)
		nOfTimes := m.PopValue().(Integer)
		for i := int(0); i < int(nOfTimes); i++ {
			m.PushValue(toExec)
			err := m.ExecuteQuotation()
			if err != nil {
				return err
			}
		}
		return nil
	})

	// ( pred body -- .. )
	m.PredefinedWords["while"] = GoWord(func(m *Machine) error {
		body := m.PopValue().(*Quotation).toCode()
		pred := m.PopValue().(*Quotation).toCode()

		for {
			pred.Idx = 0
			err := m.execute(pred)
			if err != nil {
				return err
			}

			if !bool(m.PopValue().(Boolean)) {
				break
			}
			body.Idx = 0
			err = m.execute(body)
			if err != nil {
				return err
			}
		}
		return nil
	})

	return m.importPISCAsset("stdlib/loops.pisc")
}<commit_msg>Refactored while and times to be a little more stack-trace friendly. As a side-effect, slightly faster<commit_after>package pisc

var ModLoopCore = Module{
	Author:    "<NAME>",
	Name:      "LoopCore",
	License:   "MIT",
	DocString: "times is the standard counted loop, while takes two conditions",
	Load:      loadLoopCore,
}

func _doTimes(m *Machine) error {
	toExec := m.PopValue().(*Quotation)
	nOfTimes := m.PopValue().(Integer)
	for i := int(0); i < int(nOfTimes); i++ {
		m.PushValue(toExec)
		err := m.ExecuteQuotation()
		if err != nil {
			return err
		}
	}
	return nil
}

func _doWhile(m *Machine) error {
	body := m.PopValue().(*Quotation).toCode()
	pred := m.PopValue().(*Quotation).toCode()
	for {
		pred.Idx = 0
		err := m.execute(pred)
		if err != nil {
			return err
		}

		if !bool(m.PopValue().(Boolean)) {
			break
		}
		body.Idx = 0
		err = m.execute(body)
		if err != nil {
			return err
		}
	}
	return nil
}

func loadLoopCore(m *Machine) error {
	m.AddGoWord("times", "( times quot -- ... ) ", _doTimes)
	// ( pred body -- .. )
	m.AddGoWord("while", "( pred quot -- ... )", _doWhile)

	return m.importPISCAsset("stdlib/loops.pisc")
}
{'fraction_non_alphanumeric': 0.16628805088596094, 'fraction_numerical': 0.0027260336210813267, 'mean_word_length': 3.0182481751824817, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3237389', 'n_tokens_mistral': 904, 'n_tokens_neox': 820, 'n_words': 199}