-
Notifications
You must be signed in to change notification settings - Fork 0
/
fib_tree.rs
124 lines (109 loc) · 4.2 KB
/
fib_tree.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
use std::collections::HashMap;
use std::iter::FromIterator;
use Expression::{
Number, Variable,
Sub, Add, /*Mul, Div,*/ Equal,
If, Function, Call, Return
};
#[derive(Clone)]
enum Expression {
Call(i128, Vec<Box<Expression>>),
Function(i128, Vec<Box<Expression>>, Box<Expression>),
If(Box<Expression>, Box<Expression>, Box<Expression>), // if(cond, true, false)
Number(i128),
Return(Box<Expression>),
Equal(Box<Expression>, Box<Expression>),
Add(Box<Expression>, Box<Expression>),
Sub(Box<Expression>, Box<Expression>),
// Mul(Box<Expression>, Box<Expression>),
// Div(Box<Expression>, Box<Expression>),
Variable(i128)
}
fn make_closure(
vmap: &HashMap<i128, i128>,
fmap: &HashMap<i128, Expression>,
args: Vec<Box<Expression>>) -> HashMap<i128, i128> {
// argument index start from 1
let mut index = 1;
let mut closure: HashMap<i128,i128> = HashMap::new();
for arg in args {
let v = evaluate(vmap, fmap, *arg);
closure.insert(index, v);
// println!("[make_closure] #{} = {}", &index, &v);
index += 1;
}
return closure;
}
/// Evaluate expression by vmap && fmap
fn evaluate(vmap: &HashMap<i128, i128>, fmap: &HashMap<i128, Expression>, exp: Expression) -> i128 {
match exp {
Number(num) => num,
Sub(x, y) => evaluate(vmap, fmap, *x) - evaluate(vmap, fmap, *y),
Add(x, y) => evaluate(vmap, fmap, *x) + evaluate(vmap, fmap, *y),
// Mul(x, y) => evaluate(vmap, fmap, *x) * evaluate(vmap, fmap, *y),
// Div(x, y) => evaluate(vmap, fmap, *x) / evaluate(vmap, fmap, *y),
Equal(x, y) => {
if evaluate(vmap, fmap, *x) == evaluate(vmap, fmap, *y)
{ 1 } else { 0 }
},
Variable(id) => {
*vmap.get(&id)
.expect(&format!("variable not found: {}", id))
},
Return(ret) => evaluate(vmap, fmap, *ret),
Function(_, args, body) => {
let closure = make_closure(vmap, fmap, args);
return evaluate(&closure, fmap, *body);
},
If(cond, _true, _false) => {
if evaluate(vmap, fmap, *cond) == 1
{evaluate(vmap, fmap, *_true)} else {evaluate(vmap, fmap, *_false)}
},
Call(id, args) => {
let f = &*fmap.get(&id).expect(&format!("function not found: {}", id));
let closure = make_closure(vmap, fmap, args);
return evaluate(&closure, fmap, (*f).clone());
}
}
}
fn main() {
let f =
Function(0x1,
vec![Box::new(Variable(0x1))],
Box::new(If(
Box::new(Equal(
Box::new(Variable(0x1)),
Box::new(Number(0)))),
Box::new(Return(Box::new(Number(0)))),
Box::new(If(
Box::new(Equal(
Box::new(Variable(0x1)),
Box::new(Number(1)))),
Box::new(Return(Box::new(Number(1)))),
Box::new(Return(
Box::new(Add(
Box::new(Call(0x1,
vec![
Box::new(Sub(
Box::new(Variable(0x1)),
Box::new(Number(1))))
])
),
Box::new(Call(0x1,
vec![
Box::new(Sub(
Box::new(Variable(0x1)),
Box::new(Number(2))))
])
)
))
))
))
))
);
let fmap: HashMap<i128, Expression> = HashMap::from_iter(vec![(0x1, f)]);
let vmap: HashMap<i128, i128> = HashMap::new(); // empty
let expr = Call(0x1, vec![Box::new(Number(100))]);
// println!("result = {}",evaluate(&vmap, &fmap, expr));
evaluate(&vmap, &fmap, expr);
}