2

IU でのコンパイラ コースを終了したばかりで、私の小さな「スキーム」にさらにいくつかのフォームを追加しようとしています。構文糖衣を介していくつかの形式を言語に追加しましたが、完全なスキームでは通常マクロ展開が使用されます (and or or が主なものでした)。私が遭遇した問題は、cond ステートメントの脱糖です。

注: 私は仕事をしながら Chez と Petite Chez の間を行ったり来たりしています。

すべての条件句フォームを処理しようとしています。(test => expr) フォームを処理するとき、=> の操作で問題が発生しているようです。間違った aux キーワード エラーが発生したり、マッチ ステートメントの次の行に句が落ちたりしない限り、何もできないようです。

このキーワードを検出する方法についてのアイデアはありますか?

4

1 に答える 1

2

私は少し前に独自のScheme metacircular インタプリタを書き、特別な形式の=>構文をサポートしました。cond本質的に、これは私がしなければならなかったことです:

(define (expand-actions clause)
  (let ((exp (sequence->exp (cond-actions clause))))
    (if (cond-has-then? clause)
        (make-application exp
                          (if (cond-else-clause? clause)
                              #t
                              (list (cond-predicate clause))))
        exp)))

式のすべての句 (述語とアクションのペア) を反復するとき、各アクションを展開し、トークンが句に存在condするかどうかを尋ねます (を使用)。が見つかった場合は、節のアクション部分を述語に適用します。=>cond-has-then?=>

condこれは、私のインタープリターで式を評価するコードの完全な部分です。メイン プロシージャ ( から呼び出されるものeval) は、式を一連のネストされた式にcond->if変換し、構文も処理します。これがお役に立てば幸いです:condif=>

(define (cond->if exp)
  (expand-clauses (cond-clauses exp)))

(define cond-clauses cdr)

(define (cond-has-then? clause)
  (eq? (cadr clause) '=>))

(define cond-predicate car)

(define (cond-actions clause)
  (if (cond-has-then? clause)
      (cddr clause)
      (cdr clause)))

(define (cond-else-clause? clause)
  (eq? (cond-predicate clause) 'else))

(define (expand-clauses clauses)
  (if (null? clauses)
      (void)
      (let ((first (car clauses))
            (rest  (cdr clauses)))
        (if (cond-else-clause? first)
            (if (null? rest)
                (expand-actions first)
                (error "ELSE clause isn't last -- COND->IF" clauses))
            (make-if (cond-predicate first)
                     (expand-actions first)
                     (expand-clauses rest))))))

(define (expand-actions clause)
  (let ((exp (sequence->exp (cond-actions clause))))
    (if (cond-has-then? clause)
        (make-application exp
                          (if (cond-else-clause? clause)
                              #t
                              (list (cond-predicate clause))))
        exp)))

(define (make-if predicate consequent alternative)
  (list 'if predicate consequent alternative))

(define (sequence->exp seq)
  (cond ((null? seq) '())
        ((last-exp? seq) (first-exp seq))
        (else (make-begin seq))))

(define (last-exp? seq)
  (null? (cdr seq)))

(define first-exp car)

(define (make-application proc . args)
  (cond ((null? args) (list proc))
        ((list? (car args)) (cons proc (car args)))
    (else (cons proc args))))

(define (make-begin seq)
  (cons 'begin seq))
于 2012-05-02T14:17:09.363 に答える