我正在创建一个功能
(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分配相应的参数并运行该最终字符串。
答案 0 :(得分:1)
我试着准备一个适合这个问题的答案。
我将假设所有像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...