3

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

'(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.

4

1 回答 1

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将是一个语法对象,这对于执行您的分析可能更有用。

于 2013-06-20T21:09:08.877 回答