方案程序参数

时间:2013-11-08 19:29:01

标签: scheme racket

我正在创建一个功能

 (define (run program-string . arguments)
      (if (string? program-string)
          (value-of (create-ast program-string) (empty-env))
          (raise (string-append "expected a program as string, got: " (~a program-string)))
          )  
      )

其中"参数"将是一串参数一个空列表'(),表示程序参数。 " arguments"中的每个参数将按位置绑定到程序字符串中的变量,即argN,其中N是特定参数的位置(从0开始)。

Eg.

    (run "move((0 0) arg0 arg1 arg2 arg3 arg4 arg5 arg6)"
              "up(3)"
              "right(5)"
              "right(4)"
              "down(2)"
              "up(6)"
              "right(2)"
              "right(3)"
              )
Output: (coordinate-value '(point xcord ycord)) //

因此,假设所有这些函数和值都已经用我的语言定义,并且xcord和ycord是最终移动后的实际坐标。鉴于输入,我想绑定" up(3)"到(0 0),"右(5)"给arg0 ....等,给出任意数量的argN和每个args的相应数量的输入。

run函数基本上需要为每个arg分配相应的参数并运行该最终字符串。

1 个答案:

答案 0 :(得分:1)

我试着准备一个适合这个问题的答案。

我将假设所有像up(3)这样的东西真的应该是像(up 3)这样的s表达式。如果不是,那就太糟糕了。

您没有说出您的示例所需的输出是什么。我希望我的数学没问题并且规定它的位置(14 -7)。

问题似乎是假设只有以(move (0 0) ...)开头的程序才合法。我抓住了那个假设;我不放手。

有了这个序幕,我将对家庭作业进行解释:

printfeval 的可怕的小爱孩子。

#lang racket

;; the current position and functions to move it
(struct pos (x y) #:transparent)
(define the-pos (make-parameter (pos 0 0)))

(define (dx f n)
  (match (the-pos)
    [(pos x y) (the-pos (pos (f x n) y))]))
(define (dy f n)
  (match (the-pos)
    [(pos x y) (the-pos (pos x (f y n)))]))

(define (left n)  (dx - n))
(define (right n) (dx + n))
(define (up n)    (dy - n))
(define (down n)  (dy + n))

;; namespace for `eval`
(define-namespace-anchor a)
(define ns (namespace-anchor->namespace a))

;; start holding your nose
(define (run str . args)
  (define as (for/list ([a args])
               (read (open-input-string a))))
    (match (read (open-input-string str))
      [`(move (0 0) ,xs ...)
       (for ([x xs])
         (define n (match (symbol->string x)
                     [(pregexp "^arg(\\d)$" (list _ n)) (string->number n)]
                     [else (error 'run "bad argN")]))
         (unless (< -1 n (length as))
           (error 'run "bad argN"))
         (eval (list-ref as n) ns))
       (eval '(the-pos) ns)]))

;; a unit test to confirm our true evi^Hal
(require rackunit)
(the-pos (pos 0 0))
(check-equal?
 (run "(move (0 0) arg0 arg1 arg2 arg3 arg4 arg5 arg6)"
      "(up 3)"
      "(right 5)"
      "(right 4)"
      "(down 2)"
      "(up 6)"
      "(right 2)"
      "(right 3)")
 (pos 14 -7))

;; and since we went through all the argN nonsense, the reverse:
(the-pos (pos 0 0))
(check-equal?
 (run "(move (0 0) arg6 arg5 arg4 arg3 arg2 arg1 arg0)"
      "(right 3)"
      "(right 2)"
      "(up 6)"
      "(down 2)"
      "(right 4)"
      "(right 5)"
      "(up 3)")
 (pos 14 -7))
;; not that it matters with addition and subtraction...why am I even...