Printing Expressions


We are now so close to trying out all of our new changes. We need to modify our print function to print out S-Expressions types. Using this we can double check that the reading phase is working correctly by printing out the S-Expressions we read in and verifying they match those we input.

To print out S-Expressions we can create another function that loops over all the sub-expressions of an expression and prints these individually separated by spaces, in the same way they are input.

  1. void lval_expr_print(lval* v, char open, char close) {
  2. putchar(open);
  3. for (int i = 0; i < v->count; i++) {
  4. /* Print Value contained within */
  5. lval_print(v->cell[i]);
  6. /* Don't print trailing space if last element */
  7. if (i != (v->count-1)) {
  8. putchar(' ');
  9. }
  10. }
  11. putchar(close);
  12. }
  1. void lval_print(lval* v) {
  2. switch (v->type) {
  3. case LVAL_NUM: printf("%li", v->num); break;
  4. case LVAL_ERR: printf("Error: %s", v->err); break;
  5. case LVAL_SYM: printf("%s", v->sym); break;
  6. case LVAL_SEXPR: lval_expr_print(v, '(', ')'); break;
  7. }
  8. }
  9. void lval_println(lval* v) { lval_print(v); putchar('\n'); }

I can’t declare these functions because they call each other.

The lval_expr_print function calls the lval_print function and vice-versa. There is no way we can order them in the source file to resolve this dependency. Instead we need to forward declare one of them. This is declaring a function without giving it a body. It lets other functions call it, while allowing you to define it properly later on. To write a forward declaration, write the function definition but instead of the body put a semicolon ;. In this example we should put void lval_print(lval* v); somewhere in the source file before lval_expr_print.

You’ll definitely run into this later, and I won’t always alert you to it, so try to remember how to fix it!

In our main loop, we can remove the evaluation for now, and instead try reading in the result and printing out what we have read.

  1. lval* x = lval_read(r.output);
  2. lval_println(x);
  3. lval_del(x);

If this is successful you should see something like the following when entering input to your program.

  1. lispy> + 2 2
  2. (+ 2 2)
  3. lispy> + 2 (* 7 6) (* 2 5)
  4. (+ 2 (* 7 6) (* 2 5))
  5. lispy> * 55 101 (+ 0 0 0)
  6. (* 55 101 (+ 0 0 0))
  7. lispy>