我需要在没有完全评估的情况下部分扩展方案代码。我想要一个像这样的函数:
'(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
一起运行。
答案 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,这对于执行您想要的分析可能更有用。