【问题标题】:Designing data structures for a child-first lazy evaluator which prints procedure为打印过程的子优先惰性求值器设计数据结构
【发布时间】:2017-04-26 20:57:38
【问题描述】:

我正在使用编译器插件构建一个惰性表达式评估器like Python's

我想打印如下日志:

assert ( left == vec![1, 2, 3, 4] )
assert ( vec![1, 2, 3, 4] == vec![1, 2, 3, 4] );

并尝试过:

// crate rt
pub struct Expr<T, F: FnMut() -> T> {
    // I noticed that this must be changed to fn with format!() call, to
    // support updating child.
    src: &'static str, // holds value
}
pub trait EvalTo: Display {
    /// Type of expression
    type Type;

    /// Returns Some(val) when done
    /// Accepts &mut self as it might be called many time.
    fn eval_one_level(&mut self) -> Some<T>;
}

impl<T, F> EvalTo for Expr<T, F> {
    type Type = T;
}
/// Prints source before evaluation, (it must be changed)
/// and value after evaluation.
impl<T, F> Display for Expr<T, F> {}

使用编译器插件在编译时创建它们。但是当我这样做时

let left = vec![1, 2, 3, 4];
lazy_expr!(left == vec![1, 2, 3, 4]);

它扩展到

::rt::binary({
   ::rt::Expr::wrap(::rt::Source{ expr: "left" }, || Some(left))
}, { 
   ::rt::Expr::wrap(::rt::Source{ expr: "vec!(1, 2, 3, 4)" },
   || vec![1, 2, 3, 4])
}).eq()

并且编译器不喜欢它。上面写着cannot move out of captured outer variable in an `FnMut` closure

所以我不能使用FnMut,但是需要多次调用,并且需要能够修改子表达式。

是否有允许捕获局部变量但可以使用&amp;mut self 多次调用的数据结构?我应该使用FnOnce(&amp;mut Context)吗?

【问题讨论】:

标签: rust lazy-evaluation


【解决方案1】:

我不再需要这个了,因为我使用了另一种方法。但为了完整起见,您可以使用 (&amp;mut self) 定义一个特征并使用 [std::mem::replace][] 获取拥有的值,Option 有一个名为 .take() 的辅助方法。

想用编译器插件构建惰性可评估引擎,我did some more on compile time

它调用

fn capture<T :?Sized>(&mut self, expr: &'static str, val: &T)

来自生成的代码,如

ctx.capture("f()", &_var_of_expr)

所以上下文可以用它写表达式和值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-14
    • 1970-01-01
    相关资源
    最近更新 更多