我正在创建一个函数
(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)))
)
)
其中"参数"将是一串参数或表示程序参数的空列表'()。"参数"中的每个参数将按位置绑定到程序字符串中的变量,即 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),将"right(5)"绑定到arg0....等,给定任意数量的 argN 和每个参数的相应数量的输入。
run 函数基本上需要为每个参数分配其相应的参数并运行最终字符串。
我试图准备一个适合这个问题的答案。
我将假设所有像up(3)
这样的东西实际上都应该是像(up 3)
这样的s表达式。 如果没有,那就太糟糕了。
你没有说你的示例的预期输出是什么。我希望我的数学没问题,并规定它的位置(14 -7)。
问题似乎假设只有以(move (0 0) ...)
开头的程序才是合法的。我抓住了这个假设;我不放手。
有了这个序幕,我提出了我对家庭作业练习的解释:
printf
和eval
的可怕小爱孩子 .
#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...