-
Notifications
You must be signed in to change notification settings - Fork 159
Expand file tree
/
Copy pathtool_calculate.v
More file actions
98 lines (90 loc) · 2.17 KB
/
Copy pathtool_calculate.v
File metadata and controls
98 lines (90 loc) · 2.17 KB
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
module ui
import regex
// calculation of very simple numeric expression based on regex
// no parenthesis only digit real number
pub struct MiniCalc {
mut:
op_re []regex.RE
paren_re regex.RE
pub mut:
formula string
res_str string
res f32
}
pub fn mini_calc() MiniCalc {
mut mc := MiniCalc{}
for op in [r'\*', r'/', r'\+', r'\-'] {
query := r'(\-?[\d\.]+)\s*(' + op + r')\s*(\-?[\d\.]+)'
mc.op_re << regex.regex_opt(query) or { panic(err) }
}
mc.paren_re = regex.regex_opt(r'\(\s*([\d\.\+\-\*/]+)\s*\)') or { panic(err) }
return mc
}
fn compute_repl(re regex.RE, in_txt string, _ int, _ int) string {
left := re.get_group_by_id(in_txt, 0)
op := re.get_group_by_id(in_txt, 1)
right := re.get_group_by_id(in_txt, 2)
// println("<$left> <$op> <$right>")
res := match op {
'*' { left.f32() * right.f32() }
'/' { left.f32() / right.f32() }
'+' { left.f32() + right.f32() }
'-' { left.f32() - right.f32() }
else { f32(0) }
}
return res.str()
}
pub fn (mut mc MiniCalc) calculate(formula string) f32 {
mc.formula = formula
mc.res_str = formula
for {
if mc.res_str.contains_any('()') {
// simplify parenthesis
mc.simplify_paren()
} else {
break
}
}
// compute
mc.compute_ops()
mc.res = mc.res_str.f32()
return mc.res
}
fn (mut mc MiniCalc) compute_ops() {
for i in 0 .. 4 {
for {
// println("prop: $result $op ($query)")
start, _ := mc.op_re[i].find(mc.res_str)
if start >= 0 {
$if mini_calc ? {
print('res: ${['*', '/', '+', '-'][i]} -> ${mc.res_str}')
}
mc.res_str = mc.op_re[i].replace_by_fn(mc.res_str, compute_repl)
$if mini_calc ? {
println(' => ${mc.res_str}')
}
} else {
break
}
}
}
}
fn (mut mc MiniCalc) simplify_paren() {
for {
start, stop := mc.paren_re.find(mc.res_str)
if start >= 0 {
// print("res: $op -> $result")
formula := mc.res_str[(start + 1)..(stop - 1)]
// if formula.contains_any("+-*/") {
mut mc_expr := mini_calc()
_ := mc_expr.calculate(formula)
mc.res_str = mc.paren_re.replace_simple(mc.res_str, mc_expr.res_str)
// } else {
// mc.res_str = mc.paren_re.replace_simple(mc.res_str,r'\0')
// }
// println("=> $result")
} else {
break
}
}
}