Добавление примитивов в мета-круговой оценщик - PullRequest
0 голосов
/ 05 февраля 2020

Я работаю над метациклическим оценщиком и пытаюсь добавить примитивные процедуры. Я почти закончил, за исключением того, что я не уверен, как добавить ошибку. Вот что у меня есть:

(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 '> >)))

Пока это работает. Я попытался добавить (list '(error) (error "Metacircular Interpreter Aborted")) из-за ошибки, но она явно не работает ... Как мне go об этом?

Спасибо!

Ответы [ 3 ]

3 голосов
/ 05 февраля 2020

Это так же, как и с другими примитивами, вам просто нужно добавить это так:

(list 'error error)
2 голосов
/ 09 февраля 2020

Когда вы продвинетесь дальше, вы научитесь ловить ошибки на целевом языке, не используя error из исходного языка.

Это можно сделать с помощью таких понятий, как монады, текущее продолжение , стиль продолжения продолжения, управление со смещением / сбросом и т. д. c.

1 голос
/ 06 февраля 2020

Нет никакой разницы, чем с другими примитивами.

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

Как и для всех остальных, в базовой реализации проверяется арность. Это означает, что вам нужно предоставить аргумент, например. (error "something bad happened") будет работать от переводчика. При попытке использовать (error) я предполагаю, что вы ожидаете использовать его без аргументов, вам нужно предоставить процедуру, которая не принимает аргументов. Вот как я бы это сделал:

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

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

Теперь, когда вы звоните (error), он будет вызывать лямбду и (error "Metacircular Interpreter Aborted"). Вы также можете просто указать лямбду в определении primitive-procedures, но если вы используете более позднюю версию интерпретатора с драйвером данных, присвоение ему имени поможет с этим, поскольку в этот момент он обрабатывается так же, как >.

...