如何使用Scheme中的行号打印列表?

时间:2017-04-17 19:26:49

标签: scheme racket

我尝试格式化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

1 个答案:

答案 0 :(得分:0)

我认为最好的方法是编写格式代码以返回字符串,每个输出一行,而不是直接打印到控制台。然后,您可以将生成的字符串列表传递给在插入行号和换行符时连接它们的函数。最后,将该字符串显示到控制台。

(注意:出于必要,我已经对您的代码进行了一些重构。此外,我还使用了一些特定于Racket的构造,例如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