0

I am working on the metacircular evaluator, and I'm trying to add primitive procedures. I am almost done, except I'm not sure how to add the error. Here is what I have so far:

(define primitive-procedures
  (list (list 'car car)
        (list 'cdr cdr)
        (list 'cons cons)
        (list 'null? null?)
        (list '+ +)
        (list '* *)
        (list '- -)
        (list '/ /)
        (list '< <)
        (list '<= <=)
        (list '= =)
        (list '>= >=)
        (list '> >)))

This works so far. I tried adding (list '(error) (error "Metacircular Interpreter Aborted")) for error, but it's obviously not working... How do I go about that?

Thanks!

Flux
  • 9,805
  • 5
  • 46
  • 92
Isaac
  • 273
  • 3
  • 19
  • You add `'(error)` but not `'(car)`. Why is that? I'm pretty sure you use `symbol?` to determine if it is a primitive and then `(symbol? '(error)) ; ==> #f` – Sylwester Feb 04 '20 at 21:57
  • it was given from the SICP book. I also tried implementing `'error`, but no luck. – Isaac Feb 04 '20 at 22:00
  • Where in the book does it say to implement `error`? It uses `error` extensively, but I don't remember it being given as a procedure in the intepreter. If you take zero arguments `(list 'error error)` won't work withe `(error)` since it expects an argument. `(list 'error (lambda () (error "Metacircular Interpreter Aborted")))` will make the expected arity 0. . – Sylwester Feb 04 '20 at 22:04
  • 1
    ah! I have to put lambda! It solved the problem... Thank you so much! Please answer it so I can accept it! – Isaac Feb 04 '20 at 22:30

3 Answers3

3

It's the same as with the other primitives, you just have to add it like this:

(list 'error error)
Óscar López
  • 232,561
  • 37
  • 312
  • 386
2

When you advance something more, you will learn how to catch errors in the target language, without using the error from the source language.

This can be done using concepts like monads, current-continuation, continuation passing style, control with shift/reset, etc.

alinsoar
  • 15,386
  • 4
  • 57
  • 74
1

There is no difference than with the other primitives.

 (define primitive-procedures
  (list (list 'car car)
        ...
        (list '> >)
        (list 'error error)))

As with the all the others the arity is checked in the underlying implementation. That means that you need to supply an argument eg. (error "something bad happened") will work from the interpreter. From the try to use (error) I'm guessing you are expecting to use it without an argument you need to supply a procedure that takes no arguments. Here is how I would have done that:

 (define (error-primitive)
   (error "Metacircular Interpreter Aborted"))

 (define primitive-procedures
  (list (list 'car car)
        ...
        (list '> >)
        (list 'error error-primitive)))

Now when you call (error) it will call the lambda and it will call (error "Metacircular Interpreter Aborted"). You can also just put a lambda in the primitive-procedures definition, but if you are doing a more data driver version of the interpreter later giving it a name will help with that since at this moment it is treated the same as >.

Sylwester
  • 47,942
  • 4
  • 47
  • 79