Rust で最適化ブレインファック コンパイラを作成しようとしています。現在、トークンはフラットなベクトルに格納されていますが、これは機能しますが、構文ツリーを使用するように変更するのに問題があります:
#[derive(Clone, PartialEq, Eq)]
pub enum Token {
Output,
Input,
Loop(Vec<Token>),
Move(i32),
Add(i32, i32),
LoadOut(i32, i32),
}
use Token::*;
pub fn parse(code: &str) -> Vec<Token> {
let mut alltokens = Vec::new();
let mut tokens = &mut alltokens;
let mut tokvecs: Vec<&mut Vec<Token>> = Vec::new();
for i in code.chars() {
match i {
'+' => tokens.push(Add(0, 1)),
'-' => tokens.push(Add(0, -1)),
'>' => tokens.push(Move(1)),
'<' => tokens.push(Move(-1)),
'[' => {
tokens.push(Loop(Vec::new()));
tokvecs.push(&mut tokens);
if let &mut Loop(mut newtokens) = tokens.last_mut().unwrap() {
tokens = &mut newtokens;
}
},
']' => {
tokens = tokvecs.pop().unwrap();
},
',' => tokens.push(Input),
'.' => {
tokens.push(LoadOut(0, 0));
tokens.push(Output);
}
_ => (),
};
}
alltokens
}
私が理解するのに苦労しているのは、[
コマンドの処理方法です。コード内の現在の実装は、私が試したいくつかの実装のうちの 1 つですが、すべて失敗しました。Rust の を使用する必要があると思いますが、それがBox
どのように使用されているのかよくわかりません。
コマンドを処理するブランチ[
はおそらく完全に間違っていますが、どうすればよいかわかりません。ベクトルを含む (列挙Loop
型のバリアント) をベクトルにプッシュします。問題は、そのベクトルの変更可能な借用を取得することです。これは、ステートメントが実行することになっています。Token
tokens
Loop
if let
ブロックnewtokens
の最後まで存続しないため、コードはコンパイルに失敗します。if let
内部のベクトルへの変更可能な参照を取得してLoop
、それに設定tokens
することは可能ですか? そうでない場合、代わりに何ができますか?