tangled
alpha
login
or
join now
tjh.dev
/
um32
1
fork
atom
Implementation of the UM-32 "Universal Machine" as described by the
Cult of the Bound Variable
1
fork
atom
overview
issues
pulls
pipelines
move operations to lib
tjh
1 year ago
2677baf0
92e16e4c
+105
-103
2 changed files
expand all
collapse all
unified
split
src
lib.rs
main.rs
+102
src/lib.rs
···
1
1
+
pub type Platter = u32;
2
2
+
pub type Parameter = u8;
3
3
+
4
4
+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
5
5
+
pub enum Operation {
6
6
+
ConditionalMove {
7
7
+
a: Parameter,
8
8
+
b: Parameter,
9
9
+
c: Parameter,
10
10
+
},
11
11
+
ArrayIndex {
12
12
+
a: Parameter,
13
13
+
b: Parameter,
14
14
+
c: Parameter,
15
15
+
},
16
16
+
ArrayAmendment {
17
17
+
a: Parameter,
18
18
+
b: Parameter,
19
19
+
c: Parameter,
20
20
+
},
21
21
+
Addition {
22
22
+
a: Parameter,
23
23
+
b: Parameter,
24
24
+
c: Parameter,
25
25
+
},
26
26
+
Multiplication {
27
27
+
a: Parameter,
28
28
+
b: Parameter,
29
29
+
c: Parameter,
30
30
+
},
31
31
+
Division {
32
32
+
a: Parameter,
33
33
+
b: Parameter,
34
34
+
c: Parameter,
35
35
+
},
36
36
+
NotAnd {
37
37
+
a: Parameter,
38
38
+
b: Parameter,
39
39
+
c: Parameter,
40
40
+
},
41
41
+
Halt,
42
42
+
Allocation {
43
43
+
b: Parameter,
44
44
+
c: Parameter,
45
45
+
},
46
46
+
Abandonment {
47
47
+
c: Parameter,
48
48
+
},
49
49
+
Output {
50
50
+
c: Parameter,
51
51
+
},
52
52
+
Input {
53
53
+
c: Parameter,
54
54
+
},
55
55
+
LoadProgram {
56
56
+
b: Parameter,
57
57
+
c: Parameter,
58
58
+
},
59
59
+
Orthography {
60
60
+
a: Parameter,
61
61
+
value: u32,
62
62
+
},
63
63
+
IllegalInstruction,
64
64
+
}
65
65
+
66
66
+
impl From<Platter> for Operation {
67
67
+
#[inline]
68
68
+
fn from(value: Platter) -> Self {
69
69
+
let a = ((value >> 6) & 0x07) as Parameter;
70
70
+
let b = ((value >> 3) & 0x07) as Parameter;
71
71
+
let c = ((value >> 0) & 0x07) as Parameter;
72
72
+
73
73
+
match value & 0xf0000000 {
74
74
+
0x00000000 => Self::ConditionalMove { a, b, c },
75
75
+
0x10000000 => Self::ArrayIndex { a, b, c },
76
76
+
0x20000000 => Self::ArrayAmendment { a, b, c },
77
77
+
0x30000000 => Self::Addition { a, b, c },
78
78
+
0x40000000 => Self::Multiplication { a, b, c },
79
79
+
0x50000000 => Self::Division { a, b, c },
80
80
+
0x60000000 => Self::NotAnd { a, b, c },
81
81
+
0x70000000 => Self::Halt,
82
82
+
0x80000000 => Self::Allocation { b, c },
83
83
+
0x90000000 => Self::Abandonment { c },
84
84
+
0xa0000000 => Self::Output { c },
85
85
+
0xb0000000 => Self::Input { c },
86
86
+
0xc0000000 => Self::LoadProgram { b, c },
87
87
+
0xd0000000 => {
88
88
+
let a = ((value >> 25) & 0x07) as Parameter;
89
89
+
let value = value & 0x01ffffff;
90
90
+
Self::Orthography { a, value }
91
91
+
}
92
92
+
_ => Self::IllegalInstruction,
93
93
+
}
94
94
+
}
95
95
+
}
96
96
+
97
97
+
#[inline]
98
98
+
pub fn decode_ops(ops: &[Platter]) -> Vec<Operation> {
99
99
+
ops.iter()
100
100
+
.map(|&encoded| Operation::from(encoded))
101
101
+
.collect()
102
102
+
}
+3
-103
src/main.rs
···
2
2
use smallvec::SmallVec;
3
3
#[cfg(feature = "timing")]
4
4
use std::time::Instant;
5
5
+
use um::{Operation, Parameter, Platter};
5
6
6
7
#[cfg(feature = "smallvec")]
7
8
const SMALLVEC_SIZE: usize = 24;
···
19
20
.run();
20
21
}
21
22
22
22
-
type Platter = u32;
23
23
-
type Parameter = u8;
24
24
-
25
25
-
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
26
26
-
enum Operation {
27
27
-
ConditionalMove {
28
28
-
a: Parameter,
29
29
-
b: Parameter,
30
30
-
c: Parameter,
31
31
-
},
32
32
-
ArrayIndex {
33
33
-
a: Parameter,
34
34
-
b: Parameter,
35
35
-
c: Parameter,
36
36
-
},
37
37
-
ArrayAmendment {
38
38
-
a: Parameter,
39
39
-
b: Parameter,
40
40
-
c: Parameter,
41
41
-
},
42
42
-
Addition {
43
43
-
a: Parameter,
44
44
-
b: Parameter,
45
45
-
c: Parameter,
46
46
-
},
47
47
-
Multiplication {
48
48
-
a: Parameter,
49
49
-
b: Parameter,
50
50
-
c: Parameter,
51
51
-
},
52
52
-
Division {
53
53
-
a: Parameter,
54
54
-
b: Parameter,
55
55
-
c: Parameter,
56
56
-
},
57
57
-
NotAnd {
58
58
-
a: Parameter,
59
59
-
b: Parameter,
60
60
-
c: Parameter,
61
61
-
},
62
62
-
Halt,
63
63
-
Allocation {
64
64
-
b: Parameter,
65
65
-
c: Parameter,
66
66
-
},
67
67
-
Abandonment {
68
68
-
c: Parameter,
69
69
-
},
70
70
-
Output {
71
71
-
c: Parameter,
72
72
-
},
73
73
-
Input {
74
74
-
c: Parameter,
75
75
-
},
76
76
-
LoadProgram {
77
77
-
b: Parameter,
78
78
-
c: Parameter,
79
79
-
},
80
80
-
Orthography {
81
81
-
a: Parameter,
82
82
-
value: u32,
83
83
-
},
84
84
-
IllegalInstruction,
85
85
-
}
86
86
-
87
87
-
impl From<Platter> for Operation {
88
88
-
fn from(value: Platter) -> Self {
89
89
-
let a = ((value >> 6) & 0x07) as Parameter;
90
90
-
let b = ((value >> 3) & 0x07) as Parameter;
91
91
-
let c = ((value >> 0) & 0x07) as Parameter;
92
92
-
93
93
-
match value & 0xf0000000 {
94
94
-
0x00000000 => Self::ConditionalMove { a, b, c },
95
95
-
0x10000000 => Self::ArrayIndex { a, b, c },
96
96
-
0x20000000 => Self::ArrayAmendment { a, b, c },
97
97
-
0x30000000 => Self::Addition { a, b, c },
98
98
-
0x40000000 => Self::Multiplication { a, b, c },
99
99
-
0x50000000 => Self::Division { a, b, c },
100
100
-
0x60000000 => Self::NotAnd { a, b, c },
101
101
-
0x70000000 => Self::Halt,
102
102
-
0x80000000 => Self::Allocation { b, c },
103
103
-
0x90000000 => Self::Abandonment { c },
104
104
-
0xa0000000 => Self::Output { c },
105
105
-
0xb0000000 => Self::Input { c },
106
106
-
0xc0000000 => Self::LoadProgram { b, c },
107
107
-
0xd0000000 => {
108
108
-
let a = ((value >> 25) & 0x07) as Parameter;
109
109
-
let value = value & 0x01ffffff;
110
110
-
Self::Orthography { a, value }
111
111
-
}
112
112
-
_ => Self::IllegalInstruction,
113
113
-
}
114
114
-
}
115
115
-
}
116
116
-
117
117
-
fn decode_ops(ops: &[Platter]) -> Vec<Operation> {
118
118
-
ops.iter()
119
119
-
.map(|&encoded| Operation::from(encoded))
120
120
-
.collect()
121
121
-
}
122
122
-
123
23
#[derive(Default)]
124
24
pub struct Um {
125
25
program_counter: Platter,
···
138
38
impl Um {
139
39
/// Initialise a Universal Machine with the specified program scroll.
140
40
pub fn new(program: Vec<Platter>) -> Self {
141
141
-
let ops = decode_ops(&program);
41
41
+
let ops = um::decode_ops(&program);
142
42
Self {
143
43
memory: vec![program.into()],
144
44
ops,
···
343
243
// is no point copying array[0] to array[0].
344
244
if block != 0 {
345
245
let duplicated = self.duplicate_memory(block);
346
346
-
let ops = decode_ops(&duplicated);
246
246
+
let ops = um::decode_ops(&duplicated);
347
247
self.ops = ops;
348
248
}
349
249