如何覆盖 NQPMatch.Str 函数 [英] How to override the NQPMatch.Str function

查看:31
本文介绍了如何覆盖 NQPMatch.Str 函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

... 或者如何改变 $.Str 值从 token sigil { ... } 独立于匹配的文本.是的,我在问如何欺骗上面的语法(即调用)我.

... Or how to change $<sigil>.Str value from token sigil { ... } idependently from the matched text. Yes I'm asking how to cheat grammars above (i.e. calling) me.

我正在尝试编写一个没有印记的 Raku 俚语.

所以我想要 nogil 令牌,匹配任何 <?> 以返回字符串化的 NqpMatch:$.Str 到 '$'.

So I want the nogil token, matching anything <?> to return NqpMatch that stringifies: $<sigil>.Str to '$'.

目前,我的令牌符号看起来像那样

Currently, my token sigil look like that

token sigil {
    | <[$@%&]>
    | <nogil> { say "Nogil returned: ", lk($/, 'nogil').Str; # Here It should print "$"
              }
}
token nogil-proxy {
    | '€'
    | <?>
    {log "No sigil:", get-stack; }
}

并且该方法应该返回一个 NQPMatch 方法 Str 被覆盖

And the method with that should return a NQPMatch with method Str overwritten

method nogil {
    my $cursor := self.nogil-proxy;
    # .. This si where Nqp expertise would be nice
    say "string is:", $cursor.Str;    # here also it should print "$"
    return $cursor;
}

尝试失败:

$cursor.^cache_add('Str', sub { return '$'; } );
$cursor.^publish_method_cache;
for $cursor.^attributes { .name.say };
for $cursor.^methods { .name.say };
say $cursor.WHAT.Str;
nqp::setmethcacheauth($cursor, 0);

目前,我的大部分测试都可以工作,但是我在没有我的(no strict)的声明中遇到了问题,比如 my-var = 42; 因为它们被认为是方法打电话.

Currently, most of my tests work but I have problems in declarations without my (with no strict) like my-var = 42; because they are considered as method call.

@Arne-Sommer 已经发布了帖子文章.这是密切相关的.但这个问题的目的是:

@Arne-Sommer already made a post and an article. This is closely related. But this questions aims:

我们如何自定义编译时标记的返回值,而不是如何声明它.

推荐答案

简介:@JonathanWorthington 指出的答案:

Intro: The answer, pointed by @JonathanWorthington:

简介: 使用 mixin 元函数.(并且不是但是需要compose 方法.)

Brief: Use the mixin meta function. (And NOT the but requiring compose method.)

演示:

  1. 通过检索另一个令牌来创建一个 NQPMatch 对象:这里是令牌 sigil-myself.sigil-my 调用.
  2. 使用带有角色的^mixin
  1. Create a NQPMatch object by retrieving another token: here the token sigil-my called by self.sigil-my.
  2. Use ^mixin with a role

method sigil { return self.sigil-my.^mixin(Nogil::StrGil); }

上下文:完整的可重现代码:

所以你可以看到 sigil-myNogil::StrGil 是什么类型.但我告诉过你:token(不仅仅是方法)和 角色(不可实例化的类).

So you can see what type are sigil-my and Nogil::StrGil. But I told you: token (more than method) and role (uninstantiable classes).

role Nogil::StrGil {
    method Str() {
        return sigilize(callsame);
    }
}


sub EXPORT(|) {

# Save: main raku grammar
my $main-grammar = $*LANG.slang_grammar('MAIN');
my $main-actions = $*LANG.slang_actions('MAIN');

role Nogil::NogilGrammar {
    method sigil {
        return self.sigil-my.^mixin(Nogil::StrGil);
    }
}

token sigil-my { | <[$@%&]> | <?> }

# Mix
my $grammar = $main-grammar.^mixin(Nogil::NogilGrammar);
my $actions = $main-actions.^mixin(Nogil::NogilActions);
$*LANG.define_slang('MAIN', $grammar, $actions);

# Return empty hash -> specify that we’re not exporting anything extra
return {};

}

注意:这为解决更多问题打开了大门(也由 jnthn 问题评论指出)-> -0fun !

Note: This opens the door to mush more problems (also pointed by jnthn question comments) -> -0fun !

这篇关于如何覆盖 NQPMatch.Str 函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆