Scheme 方案中代码的部分展开
我需要在不完全评估的情况下部分扩展scheme代码。我想要一个这样的函数:Scheme 方案中代码的部分展开,scheme,eval,racket,Scheme,Eval,Racket,我需要在不完全评估的情况下部分扩展scheme代码。我想要一个这样的函数: '(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 ((&g
'(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、letrec等的东西,而不做任何危险的评估。我计划对一些不同的scheme代码进行一些静态分析,如果所有代码都是相对规范化的形式,那就太好了。我希望在不冒任何I/O风险的情况下尽可能多地进行扩展
这基本上需要编写一个方案评估器。我宁愿不要。是否有任何scheme函数可以帮助我开箱即用
我应该澄清,我无法控制输入。我得到了输入,我必须分析它;在进行分析之前,我更愿意将其正常化。这就是我在这里努力实现的目标。我不可能手工重新编写输入,以使生活更轻松
我正在使用racket,但不幸的是,我的代码必须使用#lang scheme
运行,也许这就是您要找的?它不会产生问题中的输出,但会:
展开顶级表单中的所有非基本语法,并返回仅包含核心表单的扩展表单的语法对象,与完全展开的程序指定的语法相匹配
下面是一个用法示例:
(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))))
请注意,如果我们删除
语法->数据
转换,则扩展
返回的值将是a,这对于执行您心目中的分析可能更有用。我不确定您是否完全理解这个问题。我想要一个函数,它接受第一个代码样本作为输入,返回第二个代码样本作为输出。我不生成代码示例:我将阅读一堆现有代码,在静态分析之前,我想对这些代码进行规范化。我仍然不认为您理解。我不能写输入。我无法控制输入。我想做一些扩展(对lambdas和define*和let*家族中的任何东西),没有更多的——我可以使用某种限制评估吗?扩展是一个开始——它当然会使部分评估更容易,通过缩小我自己编写部分评估器时必须处理的情况。是的,好像是这样。请看我答案的最后一段,这可能也很有用。但我不认为您会在问题中找到更接近预期输出的内容,“无危险评估”部分将很难找到对您来说什么是“危险评估”?改变全局范围、休眠、分叉或以其他方式进行I/O。我想在用户代码块中扩展用户自定义的定义,包括lambdas,定义、让和定义/让族中的任何内容。如果可能的话,我希望宏也能被扩展。理想情况下,我希望在不修改状态或I/O的情况下进行所有语法扩展,但白名单可能就足够了。你们知道一个全面的类似define和let的函数列表吗?若你们能做“静态分析”,那个么你们就可以做“部分评估”…我当然能。但我更愿意把时间花在手头问题更有趣的方面。不确定这是否有助于实现您的部分需求,但Racket有一个沙盒评估器: