2016-03-05 28 views
0

我有一个带有多个变体的ExprC语言,我希望能够解释seqC变体。 seqC变体返回给定表达式列表中的最后一个表达式。(球拍)解释序列返回列表中的最后一个表达式

(define-type ExprC 
    [numC (n : number)] 
    [idC (s : symbol)] 
    [plusC (left : ExprC) (right : ExprC)] 
    [multC (left : ExprC) (right : ExprC)] 
    [letC (id : symbol) (value : ExprC) (expr : ExprC)] 
    [appC (func : ExprC) (arg : ExprC)] 
    [lamC (param : symbol) (body : ExprC)] 
    [boxC (val : ExprC)] 
    [unboxC (bx : ExprC)] 
    [setboxC (bx : ExprC) (val : ExprC)] 
    [seqC (e : (listof ExprC)] 
) 

目前,我能够得到它的解释,如基本的序列:

(test (interp (seqC (list (numC 1) (numC 2) (numC 3))) mt-env mt-store) 
     (v*s (numV 3) mt-store)) 

然而,当我尝试更复杂的顺序,比如这一个不断设置的值一箱“X”:

(test (interp {letC 'x {boxC {numC 1}} {seqC {list {setboxC {idC 'x} 
                 {plusC {numC 2} 
                   {unboxC {idC 'x}}}} 
               {setboxC {idC 'x} 
                 {multC {numC 4} 
                   {unboxC {idC 'x}}}} 
               {setboxC {idC 'x} 
                 {plusC {numC 1} 
                   {unboxC {idC 'x}}}} 
               {unboxC {idC 'x}}}}} mt-env mt-store) 
     (v*s (numV 13) (mem 2 (list (cell 1 (numV 13)) 
            (cell 1 (numV 12)) 
            (cell 1 (numV 3)) 
            (cell 2 (boxV 1)) 
            (cell 1 (numV 1)))))) 

这只是评估第一个表达式并返回一个值,而不是做每一组/拆箱和返回的最终值。错误说法:

(bad (interp (letC 'x (boxC (numC 1)) 
(seqC (list (setboxC (idC 'x) (plusC (numC 2) (unboxC (idC 'x)))) 
(setboxC (idC 'x) (multC (numC 4) (unboxC (idC 'x)))) 
(setboxC (idC 'x) (plusC (numC 1) (unboxC (idC 'x)))) 
(unboxC (idC 'x))))) mt-env mt-store) 
//Value the interpreter is getting 
(v*s (numV 3) (mem 2 (list (cell 1 (numV 3)) (cell 2 (boxV 1)) (cell 1 (numV 1))))) 
//Value it should be 
(v*s (numV 13) (mem 2 (list (cell 1 (numV 13)) (cell 1 (numV 12)) 
(cell 1 (numV 3)) (cell 2 (boxV 1)) (cell 1 (numV 1))))) 

我对SEQC解释如下:

(define (interp [expr : ExprC] [env : Env] [sto : Store]) : Result 
    (type-case ExprC expr 
... 
[seqC (m) (type-case Result (interp (firstE m) env sto) 
        [v*s (first-v first-s) 
          (cond 
          [(empty? (rest m)) ;no more left to be sequenced 
          (v*s first-v first-s)] 
          [(not (empty? (rest m))) ;not empty 
          (interp (lastE m) env first-s)])])] ;call function on next item in list 

firstE和乐特是只是一个基本的辅助函数返回ExprC的给定的列表中的第一个或最后一个表达式。如果您需要更多信息来了解代码,请告诉我,我可以提供/解释它。

回答

2

您的代码与您的评论不符。你说你想“在列表中的下一个项目上调用函数”,但是你的代码直接解释最后一个元素,跳过m中的(中)元素,这显然是错误的。

如果你递归思考,你会发现根本不需要lastE。在递归的每一步中,您都会解释序列中的第一个元素。如果(rest m)为空,那么很酷,您只需返回该值。否则,您可以构建seqC其中包含(rest m)并解释它(与新的商店)。

+0

我明白了,谢谢! – BrxttB