-
Notifications
You must be signed in to change notification settings - Fork 0
/
calc-example.mar
86 lines (79 loc) · 2.7 KB
/
calc-example.mar
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
import stdlib.mar
enum Term {
number: Int,
add: Operands,
subtract: Operands,
multiply: Operands,
divide: Operands,
}
struct Operands { left: &Term, right: &Term }
fun eval(term: Term): Int {
switch term
case number(num) num
case add(op) op.left.eval() + op.right.eval()
case subtract(op) op.left.eval() - op.right.eval()
case multiply(op) op.left.eval() * op.right.eval()
case divide(op) op.left.eval() / op.right.eval()
}
fun write[W](writer: W, term: Term) {
switch term
case number(num) writer."{num}"
case add(op) writer."{op.left} + {op.right}"
case subtract(op)
writer."{op.left} - {{
var needs_parens = op.right.* is add or {op.right.* is subtract}
if needs_parens then "({op.right})" else "{op.right}"
}}"
case multiply(op)
writer."{{
var needs_parens = op.left.* is add or {op.left.* is subtract}
if needs_parens then "({op.left})" else "{op.left}"
}} * {{
var needs_parens = op.right.* is add or {op.right.* is subtract}
if needs_parens then "({op.right})" else "{op.right}"
}}"
case divide(op)
writer."{{
var needs_parens = op.left.* is add or {op.left.* is subtract}
if needs_parens then "({op.left})" else "{op.left}"
}} / {{
var needs_parens = not(op.right.* is number)
if needs_parens then "({op.right})" else "{op.right}"
}}"
}
fun write_debug[W](writer: W, term: Term) { writer."{term}" }
fun ops(left: Term, right: Term): Operands {
Operands { left = left.put_on_heap(), right = right.put_on_heap() }
}
fun print_generate_table() {
println("Generate table:")
var random = random_number_generator()
for complexity in list(0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200, 300, 400, 500) do {
var term = static[Term]().generate(random.&, complexity)
print("{complexity} & {term} & {switch try term.eval() case ok(num) "{num}" case error "-"} \\\\ \\hline \n")
}
}
fun print_mutate_table() {
var random = random_number_generator()
| -2 * 4 * -9 * -5 / (-6 * -2 * -9 / -5)
var term = Term.divide(ops(
Term.multiply(ops(
Term.multiply(ops(Term.number(0-2), Term.number(4))),
Term.multiply(ops(Term.number(0-9), Term.number(0-5))),
)),
Term.multiply(ops(
Term.multiply(ops(Term.number(0-6), Term.number(0-2))),
Term.divide(ops(Term.number(0-9), Term.number(0-5))),
))
))
println("Original term: {term}")
println("Mutate table:")
for temperature in list(0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200, 300, 400, 500) do {
var term = term.mutate(random.&, temperature)
print("{temperature} & {term} & {switch try term.eval() case ok(num) "{num}" case error "-"} \\\\ \\hline \n")
}
}
fun main(): Never {
print_mutate_table()
exit(0)
}