方案中代码的部分扩展

时间:2013-06-20 21:07:15

标签: scheme eval racket

我需要在没有完全评估的情况下部分扩展方案代码。我想要一个像这样的函数:

'(let [(my-number 8)
       (my-function (lambda args 'value))]
  (cond
    ((> my-number 10) (my-function 'x 'y 'z))
    ((= my-number 10) (my-function 'a 'b 'c))
    (else my-number)))

并将其变为:

'(cond
  ((> 8 10) 'value)
  ((= 8 10) 'value)
  (else 8))

换句话说,我想要一些扩展定义,let,letrecs等的东西,而不做任何危险的评估。我计划对一些不同的方案代码进行一些静态分析,如果所有代码都是相对规范化的形式,那就太好了。我想尽可能多地进行扩展,而不会冒任何I / O风险。

这需要的是基本上编写一个方案评估员。我宁愿不。是否有任何方案功能可以帮助我开箱即用?

我应该澄清一点,我无法控制输入。我按原样给出了输入,我必须分析它;在进行分析之前,我更愿意将其标准化。这就是我想在这里实现的目标。我不可能手动重写输入,以使生活更轻松。

我正在使用球拍,但不幸的是我的代码必须与#lang scheme一起运行。

1 个答案:

答案 0 :(得分:1)

也许expand正是您要找的? 会产生问题中的输出,但它会:

  

以顶级形式展开所有非原语语法,并返回仅包含核心表单的扩展表单的语法对象,与完全扩展程序指定的语法匹配

这是一个用法示例:

(define src
  '(let [(my-number 8)
         (my-function (lambda args 'value))]
     (cond
       ((> my-number 10) (my-function 'x 'y 'z))
       ((= my-number 10) (my-function 'a 'b 'c))
       (else my-number))))

(syntax->datum
 (parameterize ([current-namespace (make-base-namespace)])
   (expand (datum->syntax #f src))))

使用此输出:

(let-values (((my-number) '8) ((my-function) (lambda args 'value)))
  (if (#%app > my-number '10)
    (let-values () (#%app my-function 'x 'y 'z))
    (if (#%app = my-number '10)
      (let-values () (#%app my-function 'a 'b 'c))
      (let-values () my-number))))

请注意,如果我们移除syntax->datum转化,则expand返回的值将为syntax object,这对于执行您想要的分析可能更有用。