変数と同じように、関数名とinstructionをhashmapに保存する
/x 2 def /double { x 2 * } fn
"fn" => {
let tmp = func(&mut stack, instructions.clone());
for (key, value) in &tmp {
funcs.insert(key.to_string(), value.to_vec());
}
println!("{:?}", funcs);
}
// 省略
fn func(stack: &mut Vec<String>, instructions: Vec<String>) -> HashMap<String, Vec<String>> {
let mut funcs: HashMap<String, Vec<String>> = HashMap::new();
let name = stack.pop().unwrap();
funcs.insert(name, instructions);
funcs
}
{“double”: [“x”, “2”, “*”]}
関数名と式をhashmapに保存したので、後は関数名が書かれていた際に、関数の内容を呼び出すだけ
} else if funcs.contains_key(word) {
let _ = op_fn(&mut stack, funcs.get(word).unwrap(), vars.clone());
//
fn op_fn(stack: &mut Vec<String>, input: &Vec<String>, vars: HashMap<String, String>) {
let mut words = input.clone();
while let Some((&ref word, rest)) = words.split_first() {
if word.is_empty() {
break;
}
if let Ok(parsed) = word.parse::<i32>() {
stack.push(parsed.to_string());
} else if word.starts_with("/") {
stack.push((word[1..]).to_string());
} else if vars.contains_key(word) {
stack.push(vars.get(word).unwrap().to_string());
} else {
match word.as_str() {
"+" => add(stack),
"-" => sub(stack),
"*" => mul(stack),
"/" => div(stack),
"%" => r#mod(stack),
"<" => lt(stack),
">" => rt(stack),
"==" => equal(stack),
"!=" => nequal(stack),
"sqrt" => r#sqrt(stack),
"if" => op_if(stack),
_ => todo!(),
}
}
words = rest.to_vec();
}
}
/x 2 def /double { x 2 * } fn double
=> [“4”]