User-defined Operators

The “operator overloading” that we will add to Kaleidoscope is more general than languages like C++. In C++, we are only allowed to redefine existing operators: we can’t programatically change the grammar, introduce new operators, change precedence levels, etc. In this chapter, we will add this capability to Kaleidoscope, which will let the user round out the set of operators that are supported.

The two specific features we’ll add are programmable unary operators (right now, Kaleidoscope has no unary operators at all) as well as binary operators. An example of this is:

  1. # Logical unary not.
  2. def unary!(v)
  3. if v then
  4. 0
  5. else
  6. 1;
  7. # Define > with the same precedence as <.
  8. def binary> 10 (LHS RHS)
  9. RHS < LHS;
  10. # Binary "logical or", (note that it does not "short circuit")
  11. def binary| 5 (LHS RHS)
  12. if LHS then
  13. 1
  14. else if RHS then
  15. 1
  16. else
  17. 0;
  18. # Define = with slightly lower precedence than relationals.
  19. def binary= 9 (LHS RHS)
  20. !(LHS < RHS | LHS > RHS);

Many languages aspire to being able to implement their standard runtime library in the language itself. In Kaleidoscope, we can implement significant parts of the language in the library!

We will break down implementation of these features into two parts: implementing support for user-defined binary operators and adding unary operators.