nqp::if(
nqp::istype(nqp::atpos($task,3),$!Block),
QAST::Op.new( :op<call>,
QAST::WVal.new(:value(nqp::atpos($task,3))),
$self,
$getattr
),
nqp::if(
nqp::iseq_i($code,5),
QAST::IVal.new(:value(nqp::atpos($task,3))),
QAST::NVal.new(:value(nqp::atpos($task,3)))
)
),
Run Code Online (Sandbox Code Playgroud)
if $invocant_type =:= $!acc_sig_cache_type {
$sig := $!acc_sig_cache;
}
# First time, create new signature and mark it cached
else {
$sig := $!w.create_signature_and_params(
NQPMu, %sig_empty, $block, 'Any', :method, :$invocant_type);
$!acc_sig_cache := $sig;
$!acc_sig_cache_type := $invocant_type;
}
Run Code Online (Sandbox Code Playgroud)
我以为前面的最后一种形式if(不带nqp::)是不允许的,除非if内置了?请参阅NQP内置订阅者列表。
第一种形式,nqp::if在NQP操作码列表中进行了描述,但是我找不到第二种形式的文档,尽管它似乎是Rakudo源代码树中最常见的形式。
为什么if在NQP 中有两种形式的陈述?
ifNQP中的语句是语言语法的一部分,而不是任何内置例程。它由NQP编译器的语法解析,并编译成AST节点。就条件而言,它产生的AST节点与会产生的AST节点相同nqp::if(nqp::foo语法只是创建OpAST节点的一种手段)。该cond() ?? foo() !! bar()语法也可以编译成相同类型的节点。完整的Perl 6也是如此。
显着的区别是:
if语句只能出现在语句级别,而nqp::if(...)可以出现在任何位置if声明的形式介绍了大括号的一个新的词汇范围内,而nqp::if表格没有做到这一点在链接的示例中,需要表达形式,因此需要nqp::if构建体的使用。但是,??/ !!也可能已被使用,并且可以说更具可读性。通常,由代码的作者决定他们认为最能传达最佳信息或与周围环境相匹配的内容。