2017-04-17 49 views
0

我試圖在Scheme中格式化一個列表,並在每個結果之前用行號打印格式化列表。如何使用Scheme中的行號打印列表?

給出的列表:

(define tree ' 
    ("S" 
    ;;;inside S node 
    (
    ("-" ("A" 3333) ("A" 4444)) 
    ;;;inside W node 
    ("W" 
    (
     ("+" ("R" 0) ("R" 1)) 
     ("+" ("R" 1) ("R" 2)) 
     ("+" ("R" 2) ("R" 3)) 
     ("+" ("R" 3) ("R" 4)) 
     ("+" ("R" 4) ("R" 5)));;;end of adds 
    (("-" ("R" 0) ("R" 1)) 
     ("-" ("R" 1) ("R" 2)) 
     ("-" ("R" 2) ("R" 3)) 
     ("-" ("R" 3) ("R" 4)) 
     ("-" ("A" 1000) ("A" 2000)));;;end of subs 
    );;;end of W node 
    );;;end of S node 
) 
) 

(這是一個大 「S」 名單2分列出 「 - 」 和 「W」 內)。 這裏是我的代碼:

(define (visit a) 
    (bigDumpNode a) 
) 
;;;open the big S list 
(define (bigDumpNode a) 
    (cond 
    ((eq? (car a) "S") 
    (bigSDumpList (cadr a)) 
    ) 
) 
) 
;;;Loop the inner list 
;;;There will be "-" list and "W" list 
(define (bigSDumpList a) 
    (for-each (lambda (x) 
       (intoSmall x) 
)a) 
) 


(define (intoSmall a) 
    ;;;inside W list, we do have more smaller lists 
    (cond 
    ((eq? (car a) "W") 
    (dumpWhile (cdr a)) 
    ) 
    ((or 
     (eq? (car a) "+") 
     (eq? (car a) "-") 
     (eq? (car a) "*") 
     (eq? (car a) "/")) 
     (dumpTwoOperand a) 
    ) 
) 
) 


(define (dumpWhile a) 
    (dumpWhileLoop a) 
) 
;;;loop through the inner W list 
(define (dumpWhileLoop a) 
    (for-each (lambda (x) 
       (operandLoop x) 
       (display "\nbne $00000000") 
      )a) 
) 

(define (operandLoop a) 
    (for-each (lambda (x) 
       (dumpTwoOperand x) 
      )a) 
) 
;;;format the + - */and print add sub mul div console 
(define (dumpTwoOperand a) 
    (cond 
    ((eq? (car a) "+") 
    (display "\nadd") 
    (twoOP(cdr a)) 
    ) 
    ((eq? (car a) "-") 
    (display "\nsub") 
    (twoOP(cdr a)) 
    ) 
    ((eq? (car a) "*") 
    (display "\nmul") 
    (twoOP(cdr a)) 
    ) 
    ((eq? (car a) "/") 
    (display "\ndiv") 
    (twoOP(cdr a)) 
    ) 
    ) 
) 
;;;format A to $ and R is still R 
(define (twoOP a) 
    (oprand1 a) 
    (oprand2 a) 
) 

(define (oprand1 a) 
    (cond 
    ((eq? (caar a) "A") 
    (display " $") 
    (display (cadar a)) 
    ) 
    ((eq? (caar a) "R") 
    (display " R") 
    (display (cadar a)) 
    ) 
    ) 
) 

(define (oprand2 a) 
    (cond 
    ((eq? (caadr a) "A") 
    (display " $") 
    (display (cadadr a)) 
    ) 
    ((eq? (caadr a) "R") 
    (display " R") 
    (display (cadadr a)) 
    ) 
    ) 
) 

當我在控制檯輸入(訪問樹),這將在下面的輸出:

sub $3333 $4444 
add R0 R1 
add R1 R2 
add R2 R3 
add R3 R4 
add R4 R5 
bne $00000000 
sub R0 R1 
sub R1 R2 
sub R2 R3 
sub R3 R4 
sub $1000 $2000 
bne $00000000 

我想是每個輸出前添加行號,例如:

0: sub $3333,$4444 
1: add R0,R1 
2: add R1,R2 
3: add R2,R3 
4: add R3,R4 
5: add R4,R5 
6: bne $00000000 
... 

我該怎麼做? 謝謝:D

回答

0

我認爲最好的方法是編寫格式化代碼來返回字符串,每行輸出一個,而不是直接打印到控制檯。然後,您可以將結果列表的字符串傳遞給一個函數,在插入行號和換行符時將它們連接起來。最後,將該字符串顯示到控制檯。

(注意:出於需要,我重構你的代碼有點此外,我使用了一些特定的球拍結構,例如,for/list,所以你可能要改變這些零件的其他方案)

(define (visit a) 
    (let* ([line*  (format-node a)] 
     [formatted (format-line* line* 0)]) 
    (display formatted))) 

(define (format-node a) 
    (case (car a) 
     [("S") (append* (map format-group a))])) 

(define (format-group a) 
    (case (car a) 
    [("W")    (append* (map format-while (cdr a)))] 
    [("+" "-" "*" "/") (list (format-two-operand a))])) 

(define (format-while a) 
    (let* ([formatted-op* (map format-two-operand a)]) 
    (append formatted-op* '("bne $00000000")))) 

(define (format-two-operand a) 
    (let* ([operator (car a)] 
     [op-name (case operator 
        [("+") "add"] 
        [("-") "sub"] 
        [("*") "mul"] 
        [("/") "div"])] 
     [operand1 (cadr a)] 
     [operand2 (caddr a)]) 
    (format "~a ~a ~a" op-name (format-operand operand1) (format-operand operand2)))) 

(define (format-operand operand) 
    (let* ([type (car operand)] 
     [value (cadr operand)] 
     [prefix (case type 
        [("A") "$"] 
        [("R") "R"])]) 
    (format "~a~a" prefix value))) 

(define (format-line* line* initial-line#) 
    (let ([formatted-line* (for/list ([line line*] 
            [line# (in-naturals initial-line#)]) 
          (format "~a:\t~a\n" line# line))]) 
    (string-append* formatted-line*))) 

這給了我下面的輸出爲您的樣品數據:

0: sub $3333 $4444 
1: add R0 R1 
2: add R1 R2 
3: add R2 R3 
4: add R3 R4 
5: add R4 R5 
6: bne $00000000 
7: sub R0 R1 
8: sub R1 R2 
9: sub R2 R3 
10: sub R3 R4 
11: sub $1000 $2000 
12: bne $00000000 
+0

非常感謝!這看起來很甜蜜! –

+0

@zuolizhu不客氣!如果您對我的回答滿意,感謝我的一個好方法是將其標記爲已接受。 –