we can now start to make terms that do all sorts of funky things.
this language bites off "pasta" or "pizza".
TRANSLATED:
this is done by making an "or" term.
the "or" term takes two terms as ARGUMENTS. it checks if either term matches.
class OrTerm extends Term {
constructor(term1, term2) {
super()
this.term1 = term1
this.term2 = term2
}
//...
}
then we need to IMPLEMENT all of the different term methods! as always,
check is the EASIEST.
class OrTerm extends Term {
//...
check(text) {
return this.term1.check(text) || this.term2.check(text)
}
}
bite is easy too. we try the first term first. if it doesn't
work, we try the second one.
class OrTerm extends Term {
//...
bite(text) {
if (this.term1.check(text)) {
return this.term1.bite(text)
}
if (this.term2.check(text)) {
return this.term2.bite(text)
}
return null
}
}
travel is similar, but if nothing matches, we use the longest
travel.
class OrTerm extends Term {
//...
travel(text) {
if (this.term1.check(text)) {
return this.term1.bite(text)
}
if (this.term2.check(text)) {
return this.term2.bite(text)
}
const travel1 = this.term1.travel(text)
const travel2 = this.term2.travel(text)
return travel1.length > travel2.length ? travel1 : travel2
}
}
there's a sneaky trick for tail. you can [just] get the bite
and then take what's left over.
class OrTerm extends Term {
//...
tail(text) {
const bite = this.bite(text)
if (bite === null) return null
return text.slice(bite.length)
}
}
we can't give a helpful error message yet.
class OrTerm extends Term {
//...
error(text) {
if (this.check(text)) {
return null
}
return `FRIGHTENING error: expected one of two terms but found '${text}'!`
}
}
back to the dream