now it's time to do "or" properly.
this language bites "pasta" or "pizza" or "pie".
TRANSLATED:
let's recap...
we're making a term that matches any term you pass to it.
class OrTerm extends Term {
constructor(terms) {
super()
this.terms = terms
}
}
we give it a name.
class OrTerm extends Term {
//...
name() {
return `${this.terms.map(term => term.name()).join(" or ")}`
}
}
check is easy.
class OrTerm extends Term {
//...
check(text) {
return this.terms.some(term => term.check(text))
}
}
we bite the first term that matches.
class OrTerm extends Term {
//...
bite(text) {
for (const term of this.terms) {
const bite = term.bite(text)
if (bite !== null) {
return bite
}
}
return null
}
}
for travel, we first try the bite. if there's no bite, we travel all terms and use the longest travel.
class OrTerm extends Term {
//...
travel(text) {
const bite = this.bite(text)
if (bite !== null) {
return bite
}
const travels = this.terms.map(term => term.travel(text))
return travels.reduce((a, b) => a.length > b.length ? a : b)
}
}
oh woah we haven't talked about emit much yet! but we need to emit the matching term.
class OrTerm extends Term {
//...
emit(text) {
for (const term of this.terms) {
const emit = term.emit(text)
if (emit !== null) {
return emit
}
}
return null
}
}
oh and for preview, we use the longest one.
class OrTerm extends Term {
//...
preview(text) {
const previews = this.terms.map(term => term.preview(text))
return previews.reduce((a, b) => a.length > b.length ? a : b)
}
}
oh boy that was quite a lot of work! i think i might need to REFACTOR.
but either way it works
const pastaTerm = new StringTerm("pasta")
const pizzaTerm = new StringTerm("pizza")
const pieTerm = new StringTerm("pie")
const orTerm = new OrTerm([pastaTerm, pizzaTerm, pieTerm])
function translate(text) {
return orTerm.translate(text)
}
back to the dream