33
|
1 {
|
|
2 _classifNode <- :vals prog startIdx child? {
|
|
3 if: startIdx < (vals length) {
|
|
4 _dict <- dict linear
|
|
5 _const <- #[]
|
|
6 _first <- false
|
|
7 _hasFirst? <- false
|
|
8 _val <- vals get: startIdx
|
|
9 #{
|
|
10 input <- { _val }
|
|
11 valmap <- { _dict }
|
|
12 constantProgs <- { _const }
|
|
13 append <- :tree {
|
|
14 if: child? && (tree constant?) {
|
|
15 _const append: tree
|
|
16 } else: {
|
|
17 if: (_dict length) > 0 {
|
|
18 prog root!: tree
|
|
19 res <- prog run: _val
|
|
20 node <- _dict get: res elseSet: {
|
|
21 _classifNode: vals prog startIdx + 1 true
|
|
22 }
|
|
23 node append: tree
|
|
24 } else: {
|
|
25 if: _hasFirst? {
|
|
26 prog root!: _first
|
|
27 res <- prog run: _val
|
|
28 node <- _classifNode: vals prog startIdx + 1 true
|
|
29 _dict set: res node
|
|
30 node append: _first
|
|
31 append: tree
|
|
32 } else: {
|
|
33 _first <- tree
|
|
34 _hasFirst? <- true
|
|
35 }
|
|
36 }
|
|
37 }
|
|
38 }
|
|
39 length <- {
|
|
40 len <- _dict length
|
|
41 if: len = 0 && _hasFirst? {
|
|
42 len <- 1
|
|
43 }
|
|
44 len + _const length
|
|
45 }
|
|
46 printwithIndent <- :indent {
|
|
47 print: indent . "Input: " . (hex: _val) . "\n"
|
|
48 nextindent <- indent . " "
|
|
49 if: (_const length) > 0 {
|
|
50 print: indent . "Constants:\n"
|
|
51 foreach: _const :idx val {
|
|
52 print: nextindent . (string: val) . "\n"
|
|
53 }
|
|
54 }
|
|
55 if: (_dict length) > 0 {
|
|
56 foreach: _dict :key val {
|
|
57 print: indent . (hex: key) . " ->\n"
|
|
58 val printwithIndent: nextindent
|
|
59 }
|
|
60 } else: {
|
|
61 if: _hasFirst? {
|
|
62 print: nextindent . (string: _first) . "\n"
|
|
63 }
|
|
64 }
|
|
65 }
|
|
66 print <- {
|
|
67 printwithIndent: ""
|
|
68 }
|
|
69 }
|
|
70 } else: {
|
|
71 _arr <- #[]
|
|
72 #{
|
|
73 append <- :tree {
|
|
74 _arr append: tree
|
|
75 }
|
|
76 length <- { _arr length }
|
|
77 printwithIndent <- :indent {
|
|
78 print: indent . "No more values for these:\n"
|
|
79 indent <- indent . " "
|
|
80 foreach: _arr :idx val {
|
|
81 print: indent . (string: val) . "\n"
|
|
82 }
|
|
83 }
|
|
84 print <- {
|
|
85 printwithIndent: ""
|
|
86 }
|
32
|
87 }
|
|
88 }
|
|
89 }
|
33
|
90 #{
|
|
91 classify <- :prog trees numTests {
|
|
92 testvals <- #[]
|
|
93 i <- 0
|
|
94 (os srand: (os time))
|
|
95 while: {i < numTests} do: {
|
|
96 i <- i + 1
|
|
97 testvals append: (uint64: (os rand64))
|
|
98 }
|
|
99 root <- _classifNode: testvals prog 0 false
|
|
100 foreach: trees :idx tree {
|
|
101 root append: tree
|
|
102 }
|
|
103 root
|
32
|
104 }
|
33
|
105
|
|
106 main <- :args {
|
|
107 size <- 3
|
|
108 if: (args length) > 1 {
|
|
109 size <- int32: (args get: 1)
|
32
|
110 }
|
33
|
111 prog <- bv program
|
|
112 if: size >= 2 {
|
|
113 trees <- (prog allOfSize: size)
|
|
114 numTests <- 0
|
|
115 if: (args length) > 2 {
|
|
116 numTests <- int32: (args get: 2)
|
|
117 }
|
|
118 if: numTests <= 0 {
|
|
119 numTests <- 16
|
|
120 }
|
|
121 if: (args length) > 3 {
|
|
122 ops <- (args get: 3) splitOn: ","
|
|
123 trees <- prog filterTrees: trees ops
|
|
124 }
|
|
125 info <- classify: prog trees numTests
|
|
126 print: info
|
32
|
127 }
|
|
128 }
|
|
129 }
|
|
130 }
|