Compare commits
4 Commits
kurt-reduc
...
achalmers/
Author | SHA1 | Date | |
---|---|---|---|
c530a19719 | |||
c5e1119752 | |||
3e22e3a115 | |||
5b8ad29e7d |
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -8,275 +8,275 @@ property float z
|
|||||||
element face 68
|
element face 68
|
||||||
property list uchar uint vertex_indices
|
property list uchar uint vertex_indices
|
||||||
end_header
|
end_header
|
||||||
0 0 4
|
0 0 4
|
||||||
0 0 0
|
0 0 0
|
||||||
0 -1 4
|
0 -1 4
|
||||||
0 -1 4
|
0 -1 4
|
||||||
0 0 0
|
0 0 0
|
||||||
0 -1 0
|
0 -1 0
|
||||||
0 -1 4
|
0 -1 4
|
||||||
0 -1 0
|
0 -1 0
|
||||||
3.0950184 -1 4
|
3.0950184 -1 4
|
||||||
3.0950184 -1 4
|
3.0950184 -1 4
|
||||||
0 -1 0
|
0 -1 0
|
||||||
3.0950184 -1 0
|
3.0950184 -1 0
|
||||||
3.0950184 -1 4
|
3.0950184 -1 4
|
||||||
3.0950184 -1 0
|
3.0950184 -1 0
|
||||||
5.9513144 -3 4
|
5.9513144 -3 4
|
||||||
5.9513144 -3 4
|
5.9513144 -3 4
|
||||||
3.0950184 -1 0
|
3.0950184 -1 0
|
||||||
5.9513144 -3 0
|
5.9513144 -3 0
|
||||||
5.9513144 -3 4
|
5.9513144 -3 4
|
||||||
5.9513144 -3 0
|
5.9513144 -3 0
|
||||||
9.5 -3 4
|
9.5 -3 4
|
||||||
9.5 -3 4
|
9.5 -3 4
|
||||||
5.9513144 -3 0
|
5.9513144 -3 0
|
||||||
9.5 -3 0
|
9.5 -3 0
|
||||||
9.5 -3 4
|
9.5 -3 4
|
||||||
9.5 -3 0
|
9.5 -3 0
|
||||||
9.5 -2.5 4
|
9.5 -2.5 4
|
||||||
9.5 -2.5 4
|
9.5 -2.5 4
|
||||||
9.5 -3 0
|
9.5 -3 0
|
||||||
9.5 -2.5 0
|
9.5 -2.5 0
|
||||||
9.5 -2.5 4
|
9.5 -2.5 4
|
||||||
9.5 -2.5 0
|
9.5 -2.5 0
|
||||||
6.108964 -2.5 4
|
6.108964 -2.5 4
|
||||||
6.108964 -2.5 4
|
6.108964 -2.5 4
|
||||||
9.5 -2.5 0
|
9.5 -2.5 0
|
||||||
6.108964 -2.5 0
|
6.108964 -2.5 0
|
||||||
3.4311862 -0.625 4
|
3.4311862 -0.625 4
|
||||||
4.323779 -1.25 4
|
4.323779 -1.25 4
|
||||||
4.323779 -1.25 0
|
4.323779 -1.25 0
|
||||||
4.323779 -1.25 4
|
4.323779 -1.25 4
|
||||||
6.108964 -2.5 4
|
6.108964 -2.5 4
|
||||||
6.108964 -2.5 0
|
6.108964 -2.5 0
|
||||||
3.4311862 -0.625 0
|
3.4311862 -0.625 0
|
||||||
2.5385938 0 0
|
2.5385938 0 0
|
||||||
2.5385938 0 4
|
2.5385938 0 4
|
||||||
3.4311862 -0.625 4
|
3.4311862 -0.625 4
|
||||||
3.4311862 -0.625 0
|
3.4311862 -0.625 0
|
||||||
2.5385938 0 4
|
2.5385938 0 4
|
||||||
4.323779 -1.25 4
|
4.323779 -1.25 4
|
||||||
6.108964 -2.5 0
|
6.108964 -2.5 0
|
||||||
4.323779 -1.25 0
|
4.323779 -1.25 0
|
||||||
3.4311862 -0.625 0
|
3.4311862 -0.625 0
|
||||||
3.4311862 -0.625 4
|
3.4311862 -0.625 4
|
||||||
4.323779 -1.25 0
|
4.323779 -1.25 0
|
||||||
3.342784 0.375 4
|
3.342784 0.375 4
|
||||||
2.5385938 0 4
|
2.5385938 0 4
|
||||||
2.5385938 0 0
|
2.5385938 0 0
|
||||||
4.146974 0.75 4
|
4.146974 0.75 4
|
||||||
3.342784 0.375 4
|
3.342784 0.375 4
|
||||||
3.342784 0.375 0
|
3.342784 0.375 0
|
||||||
3.342784 0.375 0
|
3.342784 0.375 0
|
||||||
4.146974 0.75 0
|
4.146974 0.75 0
|
||||||
4.146974 0.75 4
|
4.146974 0.75 4
|
||||||
4.146974 0.75 0
|
4.146974 0.75 0
|
||||||
5.755354 1.5 0
|
5.755354 1.5 0
|
||||||
5.755354 1.5 4
|
5.755354 1.5 4
|
||||||
3.342784 0.375 4
|
3.342784 0.375 4
|
||||||
2.5385938 0 0
|
2.5385938 0 0
|
||||||
3.342784 0.375 0
|
3.342784 0.375 0
|
||||||
5.755354 1.5 4
|
5.755354 1.5 4
|
||||||
4.146974 0.75 4
|
4.146974 0.75 4
|
||||||
4.146974 0.75 0
|
4.146974 0.75 0
|
||||||
5.755354 1.5 4
|
5.755354 1.5 4
|
||||||
5.755354 1.5 0
|
5.755354 1.5 0
|
||||||
9.5 1.5 4
|
9.5 1.5 4
|
||||||
9.5 1.5 4
|
9.5 1.5 4
|
||||||
5.755354 1.5 0
|
5.755354 1.5 0
|
||||||
9.5 1.5 0
|
9.5 1.5 0
|
||||||
9.5 1.5 4
|
9.5 1.5 4
|
||||||
9.5 1.5 0
|
9.5 1.5 0
|
||||||
9.5 2 4
|
9.5 2 4
|
||||||
9.5 2 4
|
9.5 2 4
|
||||||
9.5 1.5 0
|
9.5 1.5 0
|
||||||
9.5 2 0
|
9.5 2 0
|
||||||
9.5 2 4
|
9.5 2 4
|
||||||
9.5 2 0
|
9.5 2 0
|
||||||
5.644507 2 4
|
5.644507 2 4
|
||||||
5.644507 2 4
|
5.644507 2 4
|
||||||
9.5 2 0
|
9.5 2 0
|
||||||
5.644507 2 0
|
5.644507 2 0
|
||||||
5.644507 2 4
|
5.644507 2 4
|
||||||
5.644507 2 0
|
5.644507 2 0
|
||||||
3.5 1 4
|
3.5 1 4
|
||||||
3.5 1 4
|
3.5 1 4
|
||||||
5.644507 2 0
|
5.644507 2 0
|
||||||
3.5 1 0
|
3.5 1 0
|
||||||
3.5 1 4
|
3.5 1 4
|
||||||
3.5 1 0
|
3.5 1 0
|
||||||
0 1 4
|
0 1 4
|
||||||
0 1 4
|
0 1 4
|
||||||
3.5 1 0
|
3.5 1 0
|
||||||
0 1 0
|
0 1 0
|
||||||
0 1 4
|
0 1 4
|
||||||
0 1 0
|
0 1 0
|
||||||
0 0 4
|
0 0 4
|
||||||
0 0 4
|
0 0 4
|
||||||
0 1 0
|
0 1 0
|
||||||
0 0 0
|
0 0 0
|
||||||
3.342784 0.375 0
|
3.342784 0.375 0
|
||||||
2.5385938 0 0
|
2.5385938 0 0
|
||||||
3.5 1 0
|
3.5 1 0
|
||||||
3.4311862 -0.625 0
|
3.4311862 -0.625 0
|
||||||
4.323779 -1.25 0
|
4.323779 -1.25 0
|
||||||
3.0950184 -1 0
|
3.0950184 -1 0
|
||||||
3.342784 0.375 0
|
3.342784 0.375 0
|
||||||
3.5 1 0
|
3.5 1 0
|
||||||
4.146974 0.75 0
|
4.146974 0.75 0
|
||||||
4.323779 -1.25 0
|
4.323779 -1.25 0
|
||||||
5.9513144 -3 0
|
5.9513144 -3 0
|
||||||
3.0950184 -1 0
|
3.0950184 -1 0
|
||||||
0 -1 0
|
0 -1 0
|
||||||
2.5385938 0 0
|
2.5385938 0 0
|
||||||
3.0950184 -1 0
|
3.0950184 -1 0
|
||||||
0 -1 0
|
0 -1 0
|
||||||
0 0 0
|
0 0 0
|
||||||
2.5385938 0 0
|
2.5385938 0 0
|
||||||
9.5 -3 0
|
9.5 -3 0
|
||||||
6.108964 -2.5 0
|
6.108964 -2.5 0
|
||||||
9.5 -2.5 0
|
9.5 -2.5 0
|
||||||
9.5 -3 0
|
9.5 -3 0
|
||||||
5.9513144 -3 0
|
5.9513144 -3 0
|
||||||
6.108964 -2.5 0
|
6.108964 -2.5 0
|
||||||
5.9513144 -3 0
|
5.9513144 -3 0
|
||||||
4.323779 -1.25 0
|
4.323779 -1.25 0
|
||||||
6.108964 -2.5 0
|
6.108964 -2.5 0
|
||||||
5.644507 2 0
|
5.644507 2 0
|
||||||
5.755354 1.5 0
|
5.755354 1.5 0
|
||||||
4.146974 0.75 0
|
4.146974 0.75 0
|
||||||
3.0950184 -1 0
|
3.0950184 -1 0
|
||||||
2.5385938 0 0
|
2.5385938 0 0
|
||||||
3.4311862 -0.625 0
|
3.4311862 -0.625 0
|
||||||
4.146974 0.75 0
|
4.146974 0.75 0
|
||||||
3.5 1 0
|
3.5 1 0
|
||||||
5.644507 2 0
|
5.644507 2 0
|
||||||
9.5 1.5 0
|
9.5 1.5 0
|
||||||
5.755354 1.5 0
|
5.755354 1.5 0
|
||||||
9.5 2 0
|
9.5 2 0
|
||||||
5.755354 1.5 0
|
5.755354 1.5 0
|
||||||
5.644507 2 0
|
5.644507 2 0
|
||||||
9.5 2 0
|
9.5 2 0
|
||||||
2.5385938 0 0
|
2.5385938 0 0
|
||||||
0 0 0
|
0 0 0
|
||||||
0 1 0
|
0 1 0
|
||||||
3.5 1 0
|
3.5 1 0
|
||||||
2.5385938 0 0
|
2.5385938 0 0
|
||||||
0 1 0
|
0 1 0
|
||||||
3.342784 0.375 4
|
3.342784 0.375 4
|
||||||
3.5 1 4
|
3.5 1 4
|
||||||
2.5385938 0 4
|
2.5385938 0 4
|
||||||
4.146974 0.75 4
|
4.146974 0.75 4
|
||||||
3.5 1 4
|
3.5 1 4
|
||||||
3.342784 0.375 4
|
3.342784 0.375 4
|
||||||
3.4311862 -0.625 4
|
3.4311862 -0.625 4
|
||||||
3.0950184 -1 4
|
3.0950184 -1 4
|
||||||
4.323779 -1.25 4
|
4.323779 -1.25 4
|
||||||
4.146974 0.75 4
|
4.146974 0.75 4
|
||||||
5.755354 1.5 4
|
5.755354 1.5 4
|
||||||
5.644507 2 4
|
5.644507 2 4
|
||||||
0 1 4
|
0 1 4
|
||||||
2.5385938 0 4
|
2.5385938 0 4
|
||||||
3.5 1 4
|
3.5 1 4
|
||||||
0 1 4
|
0 1 4
|
||||||
0 0 4
|
0 0 4
|
||||||
2.5385938 0 4
|
2.5385938 0 4
|
||||||
5.644507 2 4
|
5.644507 2 4
|
||||||
5.755354 1.5 4
|
5.755354 1.5 4
|
||||||
9.5 2 4
|
9.5 2 4
|
||||||
9.5 2 4
|
9.5 2 4
|
||||||
5.755354 1.5 4
|
5.755354 1.5 4
|
||||||
9.5 1.5 4
|
9.5 1.5 4
|
||||||
4.146974 0.75 4
|
4.146974 0.75 4
|
||||||
5.644507 2 4
|
5.644507 2 4
|
||||||
3.5 1 4
|
3.5 1 4
|
||||||
2.5385938 0 4
|
2.5385938 0 4
|
||||||
3.0950184 -1 4
|
3.0950184 -1 4
|
||||||
3.4311862 -0.625 4
|
3.4311862 -0.625 4
|
||||||
4.323779 -1.25 4
|
4.323779 -1.25 4
|
||||||
3.0950184 -1 4
|
3.0950184 -1 4
|
||||||
5.9513144 -3 4
|
5.9513144 -3 4
|
||||||
6.108964 -2.5 4
|
6.108964 -2.5 4
|
||||||
4.323779 -1.25 4
|
4.323779 -1.25 4
|
||||||
5.9513144 -3 4
|
5.9513144 -3 4
|
||||||
9.5 -2.5 4
|
9.5 -2.5 4
|
||||||
6.108964 -2.5 4
|
6.108964 -2.5 4
|
||||||
9.5 -3 4
|
9.5 -3 4
|
||||||
6.108964 -2.5 4
|
6.108964 -2.5 4
|
||||||
5.9513144 -3 4
|
5.9513144 -3 4
|
||||||
9.5 -3 4
|
9.5 -3 4
|
||||||
2.5385938 0 4
|
2.5385938 0 4
|
||||||
0 -1 4
|
0 -1 4
|
||||||
3.0950184 -1 4
|
3.0950184 -1 4
|
||||||
0 -1 4
|
0 -1 4
|
||||||
2.5385938 0 4
|
2.5385938 0 4
|
||||||
0 0 4
|
0 0 4
|
||||||
3 0 1 2
|
3 0 1 2
|
||||||
3 3 4 5
|
3 3 4 5
|
||||||
3 6 7 8
|
3 6 7 8
|
||||||
3 9 10 11
|
3 9 10 11
|
||||||
3 12 13 14
|
3 12 13 14
|
||||||
3 15 16 17
|
3 15 16 17
|
||||||
3 18 19 20
|
3 18 19 20
|
||||||
3 21 22 23
|
3 21 22 23
|
||||||
3 24 25 26
|
3 24 25 26
|
||||||
3 27 28 29
|
3 27 28 29
|
||||||
3 30 31 32
|
3 30 31 32
|
||||||
3 33 34 35
|
3 33 34 35
|
||||||
3 36 37 38
|
3 36 37 38
|
||||||
3 39 40 41
|
3 39 40 41
|
||||||
3 42 43 44
|
3 42 43 44
|
||||||
3 45 46 47
|
3 45 46 47
|
||||||
3 48 49 50
|
3 48 49 50
|
||||||
3 51 52 53
|
3 51 52 53
|
||||||
3 54 55 56
|
3 54 55 56
|
||||||
3 57 58 59
|
3 57 58 59
|
||||||
3 60 61 62
|
3 60 61 62
|
||||||
3 63 64 65
|
3 63 64 65
|
||||||
3 66 67 68
|
3 66 67 68
|
||||||
3 69 70 71
|
3 69 70 71
|
||||||
3 72 73 74
|
3 72 73 74
|
||||||
3 75 76 77
|
3 75 76 77
|
||||||
3 78 79 80
|
3 78 79 80
|
||||||
3 81 82 83
|
3 81 82 83
|
||||||
3 84 85 86
|
3 84 85 86
|
||||||
3 87 88 89
|
3 87 88 89
|
||||||
3 90 91 92
|
3 90 91 92
|
||||||
3 93 94 95
|
3 93 94 95
|
||||||
3 96 97 98
|
3 96 97 98
|
||||||
3 99 100 101
|
3 99 100 101
|
||||||
3 102 103 104
|
3 102 103 104
|
||||||
3 105 106 107
|
3 105 106 107
|
||||||
3 108 109 110
|
3 108 109 110
|
||||||
3 111 112 113
|
3 111 112 113
|
||||||
3 114 115 116
|
3 114 115 116
|
||||||
3 117 118 119
|
3 117 118 119
|
||||||
3 120 121 122
|
3 120 121 122
|
||||||
3 123 124 125
|
3 123 124 125
|
||||||
3 126 127 128
|
3 126 127 128
|
||||||
3 129 130 131
|
3 129 130 131
|
||||||
3 132 133 134
|
3 132 133 134
|
||||||
3 135 136 137
|
3 135 136 137
|
||||||
3 138 139 140
|
3 138 139 140
|
||||||
3 141 142 143
|
3 141 142 143
|
||||||
3 144 145 146
|
3 144 145 146
|
||||||
3 147 148 149
|
3 147 148 149
|
||||||
3 150 151 152
|
3 150 151 152
|
||||||
3 153 154 155
|
3 153 154 155
|
||||||
3 156 157 158
|
3 156 157 158
|
||||||
3 159 160 161
|
3 159 160 161
|
||||||
3 162 163 164
|
3 162 163 164
|
||||||
3 165 166 167
|
3 165 166 167
|
||||||
3 168 169 170
|
3 168 169 170
|
||||||
3 171 172 173
|
3 171 172 173
|
||||||
3 174 175 176
|
3 174 175 176
|
||||||
3 177 178 179
|
3 177 178 179
|
||||||
3 180 181 182
|
3 180 181 182
|
||||||
3 183 184 185
|
3 183 184 185
|
||||||
3 186 187 188
|
3 186 187 188
|
||||||
3 189 190 191
|
3 189 190 191
|
||||||
3 192 193 194
|
3 192 193 194
|
||||||
3 195 196 197
|
3 195 196 197
|
||||||
3 198 199 200
|
3 198 199 200
|
||||||
3 201 202 203
|
3 201 202 203
|
||||||
|
Binary file not shown.
Binary file not shown.
69
src/wasm-lib/execution-plan/src/arithmetic.rs
Normal file
69
src/wasm-lib/execution-plan/src/arithmetic.rs
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
use crate::primitive::{NumericPrimitive, Primitive};
|
||||||
|
use crate::{ExecutionError, Memory, Operand, Operation};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
/// Instruction to perform arithmetic on values in memory.
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
|
pub struct Arithmetic {
|
||||||
|
/// Apply this operation
|
||||||
|
pub operation: Operation,
|
||||||
|
/// First operand for the operation
|
||||||
|
pub operand0: Operand,
|
||||||
|
/// Second operand for the operation
|
||||||
|
pub operand1: Operand,
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! arithmetic_body {
|
||||||
|
($arith:ident, $mem:ident, $method:ident) => {
|
||||||
|
match (
|
||||||
|
$arith.operand0.eval(&$mem)?.clone(),
|
||||||
|
$arith.operand1.eval(&$mem)?.clone(),
|
||||||
|
) {
|
||||||
|
// If both operands are numeric, then do the arithmetic operation.
|
||||||
|
(Primitive::NumericValue(x), Primitive::NumericValue(y)) => {
|
||||||
|
let num = match (x, y) {
|
||||||
|
(NumericPrimitive::Integer(x), NumericPrimitive::Integer(y)) => {
|
||||||
|
NumericPrimitive::Integer(x.$method(y))
|
||||||
|
}
|
||||||
|
(NumericPrimitive::Integer(x), NumericPrimitive::Float(y)) => {
|
||||||
|
NumericPrimitive::Float((x as f64).$method(y))
|
||||||
|
}
|
||||||
|
(NumericPrimitive::Float(x), NumericPrimitive::Integer(y)) => {
|
||||||
|
NumericPrimitive::Float(x.$method(y as f64))
|
||||||
|
}
|
||||||
|
(NumericPrimitive::Float(x), NumericPrimitive::Float(y)) => NumericPrimitive::Float(x.$method(y)),
|
||||||
|
};
|
||||||
|
Ok(Primitive::NumericValue(num))
|
||||||
|
}
|
||||||
|
// This operation can only be done on numeric types.
|
||||||
|
_ => Err(ExecutionError::CannotApplyOperation {
|
||||||
|
op: $arith.operation,
|
||||||
|
operands: vec![
|
||||||
|
$arith.operand0.eval(&$mem)?.clone().to_owned(),
|
||||||
|
$arith.operand1.eval(&$mem)?.clone().to_owned(),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
impl Arithmetic {
|
||||||
|
/// Calculate the the arithmetic equation.
|
||||||
|
/// May read values from the given memory.
|
||||||
|
pub fn calculate(self, mem: &Memory) -> Result<Primitive, ExecutionError> {
|
||||||
|
use std::ops::{Add, Div, Mul, Sub};
|
||||||
|
match self.operation {
|
||||||
|
Operation::Add => {
|
||||||
|
arithmetic_body!(self, mem, add)
|
||||||
|
}
|
||||||
|
Operation::Mul => {
|
||||||
|
arithmetic_body!(self, mem, mul)
|
||||||
|
}
|
||||||
|
Operation::Sub => {
|
||||||
|
arithmetic_body!(self, mem, sub)
|
||||||
|
}
|
||||||
|
Operation::Div => {
|
||||||
|
arithmetic_body!(self, mem, div)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,13 +0,0 @@
|
|||||||
use crate::{ExecutionError, Value};
|
|
||||||
|
|
||||||
mod impls;
|
|
||||||
|
|
||||||
/// Types that can be written to or read from KCEP program memory,
|
|
||||||
/// but require multiple values to store.
|
|
||||||
/// They get laid out into multiple consecutive memory addresses.
|
|
||||||
pub trait Composite: Sized {
|
|
||||||
/// Store the value in memory.
|
|
||||||
fn into_parts(self) -> Vec<Value>;
|
|
||||||
/// Read the value from memory.
|
|
||||||
fn from_parts(values: &[Option<Value>]) -> Result<Self, ExecutionError>;
|
|
||||||
}
|
|
@ -6,19 +6,22 @@
|
|||||||
//! You can think of it as a domain-specific language for making KittyCAD API calls and using
|
//! You can think of it as a domain-specific language for making KittyCAD API calls and using
|
||||||
//! the results to make other API calls.
|
//! the results to make other API calls.
|
||||||
|
|
||||||
use composite::Composite;
|
use self::arithmetic::Arithmetic;
|
||||||
|
use self::primitive::Primitive;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use uuid::Uuid;
|
use value::Value;
|
||||||
|
|
||||||
mod composite;
|
mod arithmetic;
|
||||||
|
mod primitive;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
mod value;
|
||||||
|
|
||||||
/// KCEP's program memory. A flat, linear list of values.
|
/// KCEP's program memory. A flat, linear list of values.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(test, derive(PartialEq))]
|
#[cfg_attr(test, derive(PartialEq))]
|
||||||
pub struct Memory(Vec<Option<Value>>);
|
pub struct Memory(Vec<Option<Primitive>>);
|
||||||
|
|
||||||
impl Default for Memory {
|
impl Default for Memory {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
@ -44,12 +47,12 @@ impl From<usize> for Address {
|
|||||||
|
|
||||||
impl Memory {
|
impl Memory {
|
||||||
/// Get a value from KCEP's program memory.
|
/// Get a value from KCEP's program memory.
|
||||||
pub fn get(&self, Address(addr): &Address) -> Option<&Value> {
|
pub fn get(&self, Address(addr): &Address) -> Option<&Primitive> {
|
||||||
self.0[*addr].as_ref()
|
self.0[*addr].as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Store a value in KCEP's program memory.
|
/// Store a value in KCEP's program memory.
|
||||||
pub fn set(&mut self, Address(addr): Address, value: Value) {
|
pub fn set(&mut self, Address(addr): Address, value: Primitive) {
|
||||||
// If isn't big enough for this value, double the size of memory until it is.
|
// If isn't big enough for this value, double the size of memory until it is.
|
||||||
while addr > self.0.len() {
|
while addr > self.0.len() {
|
||||||
self.0.extend(vec![None; self.0.len()]);
|
self.0.extend(vec![None; self.0.len()]);
|
||||||
@ -57,113 +60,30 @@ impl Memory {
|
|||||||
self.0[addr] = Some(value);
|
self.0[addr] = Some(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Store a composite value (i.e. a value which takes up multiple addresses in memory).
|
/// Store a value value (i.e. a value which takes up multiple addresses in memory).
|
||||||
/// Store its parts in consecutive memory addresses starting at `start`.
|
/// Store its parts in consecutive memory addresses starting at `start`.
|
||||||
pub fn set_composite<T: Composite>(&mut self, composite_value: T, start: Address) {
|
pub fn set_composite<T: Value>(&mut self, composite_value: T, start: Address) {
|
||||||
let parts = composite_value.into_parts().into_iter();
|
let parts = composite_value.into_parts().into_iter();
|
||||||
for (value, addr) in parts.zip(start.0..) {
|
for (value, addr) in parts.zip(start.0..) {
|
||||||
self.0[addr] = Some(value);
|
self.0[addr] = Some(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a composite value (i.e. a value which takes up multiple addresses in memory).
|
/// Get a value value (i.e. a value which takes up multiple addresses in memory).
|
||||||
/// Its parts are stored in consecutive memory addresses starting at `start`.
|
/// Its parts are stored in consecutive memory addresses starting at `start`.
|
||||||
pub fn get_composite<T: Composite>(&self, start: Address) -> Result<T, ExecutionError> {
|
pub fn get_composite<T: Value>(&self, start: Address) -> Result<T, ExecutionError> {
|
||||||
let values = &self.0[start.0..];
|
let values = &self.0[start.0..];
|
||||||
T::from_parts(values)
|
T::from_parts(values)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A value stored in KCEP program memory.
|
|
||||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
|
||||||
pub enum Value {
|
|
||||||
String(String),
|
|
||||||
NumericValue(NumericValue),
|
|
||||||
Uuid(Uuid),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Uuid> for Value {
|
|
||||||
fn from(u: Uuid) -> Self {
|
|
||||||
Self::Uuid(u)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<String> for Value {
|
|
||||||
fn from(value: String) -> Self {
|
|
||||||
Self::String(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<f64> for Value {
|
|
||||||
fn from(value: f64) -> Self {
|
|
||||||
Self::NumericValue(NumericValue::Float(value))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<Value> for String {
|
|
||||||
type Error = ExecutionError;
|
|
||||||
|
|
||||||
fn try_from(value: Value) -> Result<Self, Self::Error> {
|
|
||||||
if let Value::String(s) = value {
|
|
||||||
Ok(s)
|
|
||||||
} else {
|
|
||||||
Err(ExecutionError::MemoryWrongType {
|
|
||||||
expected: "string",
|
|
||||||
actual: format!("{value:?}"),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<Value> for Uuid {
|
|
||||||
type Error = ExecutionError;
|
|
||||||
|
|
||||||
fn try_from(value: Value) -> Result<Self, Self::Error> {
|
|
||||||
if let Value::Uuid(u) = value {
|
|
||||||
Ok(u)
|
|
||||||
} else {
|
|
||||||
Err(ExecutionError::MemoryWrongType {
|
|
||||||
expected: "uuid",
|
|
||||||
actual: format!("{value:?}"),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl TryFrom<Value> for f64 {
|
|
||||||
type Error = ExecutionError;
|
|
||||||
|
|
||||||
fn try_from(value: Value) -> Result<Self, Self::Error> {
|
|
||||||
if let Value::NumericValue(NumericValue::Float(x)) = value {
|
|
||||||
Ok(x)
|
|
||||||
} else {
|
|
||||||
Err(ExecutionError::MemoryWrongType {
|
|
||||||
expected: "float",
|
|
||||||
actual: format!("{value:?}"),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
impl From<usize> for Value {
|
|
||||||
fn from(value: usize) -> Self {
|
|
||||||
Self::NumericValue(NumericValue::Integer(value))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
|
||||||
pub enum NumericValue {
|
|
||||||
Integer(usize),
|
|
||||||
Float(f64),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// One step of the execution plan.
|
/// One step of the execution plan.
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub enum Instruction {
|
pub enum Instruction {
|
||||||
/// Call the KittyCAD API.
|
/// Call the KittyCAD API.
|
||||||
ApiRequest {
|
ApiRequest {
|
||||||
/// Which ModelingCmd to call.
|
/// Which ModelingCmd to call.
|
||||||
/// It's a composite value starting at the given address.
|
/// It's a value value starting at the given address.
|
||||||
endpoint: Address,
|
endpoint: Address,
|
||||||
/// Which address should the response be stored in?
|
/// Which address should the response be stored in?
|
||||||
store_response: Option<usize>,
|
store_response: Option<usize>,
|
||||||
@ -175,7 +95,7 @@ pub enum Instruction {
|
|||||||
/// Which memory address to set.
|
/// Which memory address to set.
|
||||||
address: Address,
|
address: Address,
|
||||||
/// What value to set the memory address to.
|
/// What value to set the memory address to.
|
||||||
value: Value,
|
value: Primitive,
|
||||||
},
|
},
|
||||||
/// Perform arithmetic on values in memory.
|
/// Perform arithmetic on values in memory.
|
||||||
Arithmetic {
|
Arithmetic {
|
||||||
@ -186,66 +106,6 @@ pub enum Instruction {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Instruction to perform arithmetic on values in memory.
|
|
||||||
#[derive(Deserialize, Serialize)]
|
|
||||||
pub struct Arithmetic {
|
|
||||||
/// Apply this operation
|
|
||||||
pub operation: Operation,
|
|
||||||
/// First operand for the operation
|
|
||||||
pub operand0: Operand,
|
|
||||||
/// Second operand for the operation
|
|
||||||
pub operand1: Operand,
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! arithmetic_body {
|
|
||||||
($arith:ident, $mem:ident, $method:ident) => {
|
|
||||||
match (
|
|
||||||
$arith.operand0.eval(&$mem)?.clone(),
|
|
||||||
$arith.operand1.eval(&$mem)?.clone(),
|
|
||||||
) {
|
|
||||||
// If both operands are numeric, then do the arithmetic operation.
|
|
||||||
(Value::NumericValue(x), Value::NumericValue(y)) => {
|
|
||||||
let num = match (x, y) {
|
|
||||||
(NumericValue::Integer(x), NumericValue::Integer(y)) => NumericValue::Integer(x.$method(y)),
|
|
||||||
(NumericValue::Integer(x), NumericValue::Float(y)) => NumericValue::Float((x as f64).$method(y)),
|
|
||||||
(NumericValue::Float(x), NumericValue::Integer(y)) => NumericValue::Float(x.$method(y as f64)),
|
|
||||||
(NumericValue::Float(x), NumericValue::Float(y)) => NumericValue::Float(x.$method(y)),
|
|
||||||
};
|
|
||||||
Ok(Value::NumericValue(num))
|
|
||||||
}
|
|
||||||
// This operation can only be done on numeric types.
|
|
||||||
_ => Err(ExecutionError::CannotApplyOperation {
|
|
||||||
op: $arith.operation,
|
|
||||||
operands: vec![
|
|
||||||
$arith.operand0.eval(&$mem)?.clone().to_owned(),
|
|
||||||
$arith.operand1.eval(&$mem)?.clone().to_owned(),
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
impl Arithmetic {
|
|
||||||
/// Calculate the the arithmetic equation.
|
|
||||||
/// May read values from the given memory.
|
|
||||||
fn calculate(self, mem: &Memory) -> Result<Value, ExecutionError> {
|
|
||||||
use std::ops::{Add, Div, Mul, Sub};
|
|
||||||
match self.operation {
|
|
||||||
Operation::Add => {
|
|
||||||
arithmetic_body!(self, mem, add)
|
|
||||||
}
|
|
||||||
Operation::Mul => {
|
|
||||||
arithmetic_body!(self, mem, mul)
|
|
||||||
}
|
|
||||||
Operation::Sub => {
|
|
||||||
arithmetic_body!(self, mem, sub)
|
|
||||||
}
|
|
||||||
Operation::Div => {
|
|
||||||
arithmetic_body!(self, mem, div)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Operations that can be applied to values in memory.
|
/// Operations that can be applied to values in memory.
|
||||||
#[derive(Debug, Deserialize, Serialize, Clone, Copy)]
|
#[derive(Debug, Deserialize, Serialize, Clone, Copy)]
|
||||||
pub enum Operation {
|
pub enum Operation {
|
||||||
@ -270,13 +130,13 @@ impl fmt::Display for Operation {
|
|||||||
/// Argument to an operation.
|
/// Argument to an operation.
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize)]
|
||||||
pub enum Operand {
|
pub enum Operand {
|
||||||
Literal(Value),
|
Literal(Primitive),
|
||||||
Reference(Address),
|
Reference(Address),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Operand {
|
impl Operand {
|
||||||
/// Evaluate the operand, getting its value.
|
/// Evaluate the operand, getting its value.
|
||||||
fn eval(&self, mem: &Memory) -> Result<Value, ExecutionError> {
|
fn eval(&self, mem: &Memory) -> Result<Primitive, ExecutionError> {
|
||||||
match self {
|
match self {
|
||||||
Operand::Literal(v) => Ok(v.to_owned()),
|
Operand::Literal(v) => Ok(v.to_owned()),
|
||||||
Operand::Reference(addr) => match mem.get(addr) {
|
Operand::Reference(addr) => match mem.get(addr) {
|
||||||
@ -313,7 +173,7 @@ pub enum ExecutionError {
|
|||||||
#[error("Memory address {addr} was not set")]
|
#[error("Memory address {addr} was not set")]
|
||||||
MemoryEmpty { addr: Address },
|
MemoryEmpty { addr: Address },
|
||||||
#[error("Cannot apply operation {op} to operands {operands:?}")]
|
#[error("Cannot apply operation {op} to operands {operands:?}")]
|
||||||
CannotApplyOperation { op: Operation, operands: Vec<Value> },
|
CannotApplyOperation { op: Operation, operands: Vec<Primitive> },
|
||||||
#[error("Tried to read a '{expected}' from KCEP program memory, found an '{actual}' instead")]
|
#[error("Tried to read a '{expected}' from KCEP program memory, found an '{actual}' instead")]
|
||||||
MemoryWrongType { expected: &'static str, actual: String },
|
MemoryWrongType { expected: &'static str, actual: String },
|
||||||
#[error("Wanted {expected} values but did not get enough")]
|
#[error("Wanted {expected} values but did not get enough")]
|
||||||
|
98
src/wasm-lib/execution-plan/src/primitive.rs
Normal file
98
src/wasm-lib/execution-plan/src/primitive.rs
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
use crate::ExecutionError;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
/// A value stored in KCEP program memory.
|
||||||
|
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
||||||
|
pub enum Primitive {
|
||||||
|
String(String),
|
||||||
|
NumericValue(NumericPrimitive),
|
||||||
|
Uuid(Uuid),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Uuid> for Primitive {
|
||||||
|
fn from(u: Uuid) -> Self {
|
||||||
|
Self::Uuid(u)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<String> for Primitive {
|
||||||
|
fn from(value: String) -> Self {
|
||||||
|
Self::String(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<f64> for Primitive {
|
||||||
|
fn from(value: f64) -> Self {
|
||||||
|
Self::NumericValue(NumericPrimitive::Float(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Primitive> for String {
|
||||||
|
type Error = ExecutionError;
|
||||||
|
|
||||||
|
fn try_from(value: Primitive) -> Result<Self, Self::Error> {
|
||||||
|
if let Primitive::String(s) = value {
|
||||||
|
Ok(s)
|
||||||
|
} else {
|
||||||
|
Err(ExecutionError::MemoryWrongType {
|
||||||
|
expected: "string",
|
||||||
|
actual: format!("{value:?}"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Primitive> for Uuid {
|
||||||
|
type Error = ExecutionError;
|
||||||
|
|
||||||
|
fn try_from(value: Primitive) -> Result<Self, Self::Error> {
|
||||||
|
if let Primitive::Uuid(u) = value {
|
||||||
|
Ok(u)
|
||||||
|
} else {
|
||||||
|
Err(ExecutionError::MemoryWrongType {
|
||||||
|
expected: "uuid",
|
||||||
|
actual: format!("{value:?}"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Primitive> for f64 {
|
||||||
|
type Error = ExecutionError;
|
||||||
|
|
||||||
|
fn try_from(value: Primitive) -> Result<Self, Self::Error> {
|
||||||
|
if let Primitive::NumericValue(NumericPrimitive::Float(x)) = value {
|
||||||
|
Ok(x)
|
||||||
|
} else {
|
||||||
|
Err(ExecutionError::MemoryWrongType {
|
||||||
|
expected: "float",
|
||||||
|
actual: format!("{value:?}"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
impl From<usize> for Primitive {
|
||||||
|
fn from(value: usize) -> Self {
|
||||||
|
Self::NumericValue(NumericPrimitive::Integer(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
||||||
|
pub enum NumericPrimitive {
|
||||||
|
Integer(usize),
|
||||||
|
Float(f64),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl crate::value::Value for Primitive {
|
||||||
|
fn into_parts(self) -> Vec<Primitive> {
|
||||||
|
vec![self]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_parts(values: &[Option<Primitive>]) -> Result<Self, ExecutionError> {
|
||||||
|
let v = values.get(0).ok_or(ExecutionError::MemoryWrongSize { expected: 1 })?;
|
||||||
|
v.to_owned().ok_or(ExecutionError::MemoryWrongSize { expected: 1 })
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
use kittycad_modeling_cmds::{id::ModelingCmdId, shared::Point3d, ModelingCmd, MovePathPen};
|
use kittycad_modeling_cmds::{id::ModelingCmdId, shared::Point3d, ModelingCmd, MovePathPen};
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
13
src/wasm-lib/execution-plan/src/value.rs
Normal file
13
src/wasm-lib/execution-plan/src/value.rs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
use crate::{ExecutionError, Primitive};
|
||||||
|
|
||||||
|
mod impls;
|
||||||
|
|
||||||
|
/// Types that can be written to or read from KCEP program memory.
|
||||||
|
/// If they require multiple memory addresses, they will be laid out
|
||||||
|
/// into multiple consecutive memory addresses.
|
||||||
|
pub trait Value: Sized {
|
||||||
|
/// Store the value in memory.
|
||||||
|
fn into_parts(self) -> Vec<Primitive>;
|
||||||
|
/// Read the value from memory.
|
||||||
|
fn from_parts(values: &[Option<Primitive>]) -> Result<Self, ExecutionError>;
|
||||||
|
}
|
@ -1,21 +1,21 @@
|
|||||||
use kittycad_modeling_cmds::{id::ModelingCmdId, shared::Point3d, MovePathPen};
|
use kittycad_modeling_cmds::{id::ModelingCmdId, shared::Point3d, MovePathPen};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::{Address, ExecutionError, Value};
|
use crate::{Address, ExecutionError, Primitive};
|
||||||
|
|
||||||
use super::Composite;
|
use super::Value;
|
||||||
|
|
||||||
impl<T> Composite for kittycad_modeling_cmds::shared::Point3d<T>
|
impl<T> Value for kittycad_modeling_cmds::shared::Point3d<T>
|
||||||
where
|
where
|
||||||
Value: From<T>,
|
Primitive: From<T>,
|
||||||
T: TryFrom<Value, Error = ExecutionError>,
|
T: TryFrom<Primitive, Error = ExecutionError>,
|
||||||
{
|
{
|
||||||
fn into_parts(self) -> Vec<Value> {
|
fn into_parts(self) -> Vec<Primitive> {
|
||||||
let points = [self.x, self.y, self.z];
|
let points = [self.x, self.y, self.z];
|
||||||
points.into_iter().map(|component| component.into()).collect()
|
points.into_iter().map(|component| component.into()).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_parts(values: &[Option<Value>]) -> Result<Self, ExecutionError> {
|
fn from_parts(values: &[Option<Primitive>]) -> Result<Self, ExecutionError> {
|
||||||
let err = ExecutionError::MemoryWrongSize { expected: 3 };
|
let err = ExecutionError::MemoryWrongSize { expected: 3 };
|
||||||
let [x, y, z] = [0, 1, 2].map(|n| values.get(n).ok_or(err.clone()));
|
let [x, y, z] = [0, 1, 2].map(|n| values.get(n).ok_or(err.clone()));
|
||||||
let x = x?.to_owned().ok_or(err.clone())?.try_into()?;
|
let x = x?.to_owned().ok_or(err.clone())?.try_into()?;
|
||||||
@ -28,17 +28,17 @@ where
|
|||||||
const START_PATH: &str = "StartPath";
|
const START_PATH: &str = "StartPath";
|
||||||
const MOVE_PATH_PEN: &str = "MovePathPen";
|
const MOVE_PATH_PEN: &str = "MovePathPen";
|
||||||
|
|
||||||
impl Composite for MovePathPen {
|
impl Value for MovePathPen {
|
||||||
fn into_parts(self) -> Vec<Value> {
|
fn into_parts(self) -> Vec<Primitive> {
|
||||||
let MovePathPen { path, to } = self;
|
let MovePathPen { path, to } = self;
|
||||||
let to = to.into_parts();
|
let to = to.into_parts();
|
||||||
let mut vals = Vec::with_capacity(1 + to.len());
|
let mut vals = Vec::with_capacity(1 + to.len());
|
||||||
vals.push(Value::Uuid(path.into()));
|
vals.push(Primitive::Uuid(path.into()));
|
||||||
vals.extend(to);
|
vals.extend(to);
|
||||||
vals
|
vals
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_parts(values: &[Option<Value>]) -> Result<Self, ExecutionError> {
|
fn from_parts(values: &[Option<Primitive>]) -> Result<Self, ExecutionError> {
|
||||||
let path = get_some(values, 0)?;
|
let path = get_some(values, 0)?;
|
||||||
let path = Uuid::try_from(path)?;
|
let path = Uuid::try_from(path)?;
|
||||||
let path = ModelingCmdId::from(path);
|
let path = ModelingCmdId::from(path);
|
||||||
@ -51,14 +51,14 @@ impl Composite for MovePathPen {
|
|||||||
/// Memory layout for modeling commands:
|
/// Memory layout for modeling commands:
|
||||||
/// Field 0 is the command's name.
|
/// Field 0 is the command's name.
|
||||||
/// Fields 1 onwards are the command's fields.
|
/// Fields 1 onwards are the command's fields.
|
||||||
impl Composite for kittycad_modeling_cmds::ModelingCmd {
|
impl Value for kittycad_modeling_cmds::ModelingCmd {
|
||||||
fn into_parts(self) -> Vec<Value> {
|
fn into_parts(self) -> Vec<Primitive> {
|
||||||
let (endpoint_name, params) = match self {
|
let (endpoint_name, params) = match self {
|
||||||
kittycad_modeling_cmds::ModelingCmd::StartPath => (START_PATH, vec![]),
|
kittycad_modeling_cmds::ModelingCmd::StartPath => (START_PATH, vec![]),
|
||||||
kittycad_modeling_cmds::ModelingCmd::MovePathPen(MovePathPen { path, to }) => {
|
kittycad_modeling_cmds::ModelingCmd::MovePathPen(MovePathPen { path, to }) => {
|
||||||
let to = to.into_parts();
|
let to = to.into_parts();
|
||||||
let mut vals = Vec::with_capacity(1 + to.len());
|
let mut vals = Vec::with_capacity(1 + to.len());
|
||||||
vals.push(Value::Uuid(path.into()));
|
vals.push(Primitive::Uuid(path.into()));
|
||||||
vals.extend(to);
|
vals.extend(to);
|
||||||
(MOVE_PATH_PEN, vals)
|
(MOVE_PATH_PEN, vals)
|
||||||
}
|
}
|
||||||
@ -70,7 +70,7 @@ impl Composite for kittycad_modeling_cmds::ModelingCmd {
|
|||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_parts(values: &[Option<Value>]) -> Result<Self, ExecutionError> {
|
fn from_parts(values: &[Option<Primitive>]) -> Result<Self, ExecutionError> {
|
||||||
// Check the array has an element at index 0
|
// Check the array has an element at index 0
|
||||||
let first_memory = values
|
let first_memory = values
|
||||||
.get(0)
|
.get(0)
|
||||||
@ -90,7 +90,7 @@ impl Composite for kittycad_modeling_cmds::ModelingCmd {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_some(values: &[Option<Value>], i: usize) -> Result<Value, ExecutionError> {
|
fn get_some(values: &[Option<Primitive>], i: usize) -> Result<Primitive, ExecutionError> {
|
||||||
let addr = Address(0); // TODO: pass the `start` addr in
|
let addr = Address(0); // TODO: pass the `start` addr in
|
||||||
let v = values.get(i).ok_or(ExecutionError::MemoryEmpty { addr })?.to_owned();
|
let v = values.get(i).ok_or(ExecutionError::MemoryEmpty { addr })?.to_owned();
|
||||||
let v = v.ok_or(ExecutionError::MemoryEmpty { addr })?.to_owned();
|
let v = v.ok_or(ExecutionError::MemoryEmpty { addr })?.to_owned();
|
Reference in New Issue
Block a user