many

there is ANOTHER way to bite many things, one after the other. you can do it by using a custom term.

yet again, this language bites of "hahahahahaha" with as many "ha"s as you want. but this time, we do it with the "many" term.

TRANSLATED:



let's make a "many" term. it accepts a term as an argument.

class ManyTerm extends Term {
	constructor(term) {
		super()
		this.term = term
	}
}

give it a name.

class ManyTerm extends Term {
	//...
	name() {
		return `${this.term.name()}+`
	}
}

check is easy. as long as there's one matching term, it's a pass!

class ManyTerm extends Term {
	//...
	check(text) {
		return this.term.check(text)
	}
}

we can do bite RECURSIVELY. we try biting once. if it matches, we try biting again using the bite function from inside the bite function. if the second bite doesn't match, we just return the first bite. if it does match, then we join the bites together.

class ManyTerm extends Term {
	//...
	bite(text) {
		const [bite, tail] = this.term.eat(text)
		if (bite === null) {
			return null
		}

		const nextBite = this.bite(tail)
		if (nextBite === null) {
			return bite
		}
	
		return bite + nextBite
	}
}

i think it's bad to do this one RECURSIVELY because it's CONFUSING and it uses a lot of MEMORY when doing more COMPLICATED things.

i prefer to do it ITERATIVELY. keep biting and COLLECTING up the bites within a VARIABLE until we can't bite no more. then return the COLLECTED bites.

class ManyTerm extends Term {
	//...
	bite(text) {
		let bite = null

		while (true) {
			const [nextBite, nextTail] = this.term.eat(text)
			if (nextBite === null) {
				break
			}
			bite = (bite ?? "") + nextBite
			text = nextTail
		}

		return bite
	}
}

yes.

back to the dream