我试图编写带有语法符号的超细小对象的系统,主要是为了学习它。无论如何,我试图引入一个"这个"变量。这是我想做的:
(oo-class Counter
(
(attr value 0)
(attr skip 1)
)
(
(method (next) (set! value (+ value skip)) value)
(method (nextnext) (this 'next) (this 'next))
(method (set-value newval) (set! value newval))
(method (set-skip newskip) (set! skip newskip))
)
)
(define c (Counter))
((c 'set-value) 23)
((c 'next))
((c 'nextnext))
除了"这个",我可以使一切工作。似乎语法规则不允许介绍。我想到我可以通过将其定义为语法符号中的文字之一,但这似乎不起作用。
以下是我面向对象的系统:
(define-syntax oo-class
(syntax-rules (attr method this)
(
(oo-class class-name
((attr attr-name initial-val) ...)
((method (meth-name meth-arg ...) body ...) ...))
(define class-name
(lambda ()
(letrec
(
(this #f)
(attr-name initial-val)
...
(funcmap
(list
(cons (quote meth-name) (cons (lambda (meth-arg ...) body ...) '()))
...
)
)
)
(set! this (lambda (methname)
(cadr (assoc methname funcmap))
))
this
)
)
)
)
)
)
这适用于除'NextNext以外的所有事物,当它试图引用" this"。
时,它会出现错误这是正确的方法吗?还有其他方法吗?我认识到这有点不卫生,但这至少不是指定文字的一部分?
我在鸡肉方案和R5RS模式下尝试过此此事(其他模式对" this"感到抱怨(。
以下是整个文件。您可以用" CSI对象"在鸡上运行它。
https://gist.github.com/johnnyb/211E105882248E892FA485327039CC90
我还尝试使用let-syntax并使用(this(作为语法说明符,以引用(this(变量。但是,据我所知,这并不是让我直接在语法重写中访问自己的自身制作变量。
奖励问题:看到调试的语法勒勒斯转换结果的简便方法是什么?有什么方法可以让鸡肉(或其他东西(进行转换并吐出结果?我在drracket上尝试了一些东西,但它在R5RS模式下不起作用。
我认识到这有点不卫生,但这至少不是指定文字的一部分?
否,文字存在,因此您可以在关键字上进行字面的匹配,例如=>
或cond
子句中的else
。它仍然是卫生的,因为如果=>
或else
在词法上绑定到某种值,则具有优先级:
(let ((else #f))
(cond (else (display "hi!n")))) ;; Will not print
现在,您可以写一个非常乏味的宏,它在扩展中的任何可能位置和嵌套级别匹配this
,但它永远不会完成,并且它也不会词汇嵌套。<<<<<<<<
它是可以使用所谓的Petrofsky提取的事情来做您尝试做的事情,但这是一个完全而完全的攻击和滥用语法 - 行为,并且行不通(它行不通(一贯(在实施中都有模块存在的情况下(例如,正是在鸡中,我们有人抱怨说我们不小心"破产"了此功能(。
我建议的是编写一个语法符号宏,该语法在其输入中接受标识符,该标识符将绑定到当前对象,然后编写一个琐碎的不卫生宏,该宏称其为其他宏,用硬编码的标识符this
作为输入。
什么是一种简单的方法来查看调试语法规则转换的结果?有什么方法可以让鸡肉(或其他东西(进行转换并吐出结果?我在drracket上尝试了一些东西,但它在R5RS模式下不起作用。
在CSI中,您可以使用,x (macro-call)
,但它只能进行一个级别的扩展。
在每个方案实现中都起作用的常见技巧是更改您的宏定义以引用其输出。因此,它不扩展到(foo)
,而是向'(foo)
扩展。这样,您只需在替补中调用宏即可立即查看其结果。