The language has two more literal kinds - the booleans true and false, and string literals. Today you parse both as leaf expressions so they can appear anywhere a value can.
Parse boolean and string literals as leaf expressions that print as their own value.
Booleans and strings are leaf expressions, just like integers and
identifiers: they have no children, and they print as their own value. Register a
prefix parse function for the true and false keywords that builds a Boolean
node, and one for STRING tokens that builds a StringLiteral carrying the
text.
The headline is the boolean, because it slots straight into the precedence
machinery: 3 > 5 == false parses as ((3 > 5) == false), with the comparison
binding before the equality - a boolean can appear anywhere a value can. String
literals are the same idea with less to say; both are simple, but they complete
the set of atoms your expressions are built from.
type Boolean struct { Value bool }func (b *Boolean) String() string { if b.Value { return "true" }; return "false" }// StringLiteral{ Value string } is the same shape - String returns the text.// register 'true'/'false' and STRING as prefix parse functions.