cpclib_asm/assembler/
matrix.rs

1use cpclib_tokens::ExprResult;
2
3use crate::assembler::list::list_new;
4use crate::error::{AssemblerError, ExpressionError};
5
6/// Create a new matrix
7pub fn matrix_new(height: usize, width: usize, value: ExprResult) -> ExprResult {
8    ExprResult::Matrix {
9        content: vec![list_new(width, value); height],
10        width,
11        height
12    }
13}
14
15pub fn matrix_col(matrix: &ExprResult, x: usize) -> Result<ExprResult, crate::AssemblerError> {
16    match matrix {
17        ExprResult::Matrix { .. } => {
18            if x >= matrix.matrix_width() {
19                return Err(AssemblerError::ExpressionError(
20                    ExpressionError::InvalidSize(matrix.matrix_width(), x)
21                ));
22            }
23
24            Ok(matrix.matrix_col(x))
25        },
26
27        _ => {
28            Err(AssemblerError::ExpressionError(ExpressionError::OwnError(
29                Box::new(AssemblerError::AssemblingError {
30                    msg: format!("{} is not a matrix", matrix)
31                })
32            )))
33        },
34    }
35}
36
37pub fn matrix_set_col(
38    mut matrix: ExprResult,
39    x: usize,
40    col: &ExprResult
41) -> Result<ExprResult, crate::AssemblerError> {
42    match matrix {
43        ExprResult::Matrix { width, .. } => {
44            if x >= width {
45                return Err(AssemblerError::ExpressionError(
46                    ExpressionError::InvalidSize(width, x)
47                ));
48            }
49
50            match col {
51                ExprResult::List(_) => {
52                    if col.list_len() != width {
53                        return Err(AssemblerError::ExpressionError(
54                            ExpressionError::InvalidSize(width, col.list_len())
55                        ));
56                    }
57
58                    matrix.matrix_set_col(x, col.list_content());
59                    Ok(matrix)
60                },
61                _ => {
62                    Err(AssemblerError::ExpressionError(ExpressionError::OwnError(
63                        Box::new(AssemblerError::AssemblingError {
64                            msg: format!("{} is not a list", matrix)
65                        })
66                    )))
67                },
68            }
69        },
70
71        _ => {
72            Err(AssemblerError::ExpressionError(ExpressionError::OwnError(
73                Box::new(AssemblerError::AssemblingError {
74                    msg: format!("{} is not a matrix", matrix)
75                })
76            )))
77        },
78    }
79}
80
81pub fn matrix_row(matrix: &ExprResult, y: usize) -> Result<ExprResult, crate::AssemblerError> {
82    match matrix {
83        ExprResult::Matrix { .. } => {
84            if y >= matrix.matrix_height() {
85                return Err(AssemblerError::ExpressionError(
86                    ExpressionError::InvalidSize(matrix.matrix_height(), y)
87                ));
88            }
89
90            Ok(matrix.matrix_row(y).clone())
91        },
92
93        _ => {
94            Err(AssemblerError::ExpressionError(ExpressionError::OwnError(
95                Box::new(AssemblerError::AssemblingError {
96                    msg: format!("{} is not a matrix", matrix)
97                })
98            )))
99        },
100    }
101}
102
103pub fn matrix_set_row(
104    mut matrix: ExprResult,
105    y: usize,
106    row: &ExprResult
107) -> Result<ExprResult, crate::AssemblerError> {
108    match matrix {
109        ExprResult::Matrix {
110            ref mut content,
111            height,
112            ..
113        } => {
114            if y >= height {
115                return Err(AssemblerError::ExpressionError(
116                    ExpressionError::InvalidSize(height, y)
117                ));
118            }
119
120            match row {
121                ExprResult::List(_) => {
122                    if row.list_len() != height {
123                        return Err(AssemblerError::ExpressionError(
124                            ExpressionError::InvalidSize(height, row.list_len())
125                        ));
126                    }
127
128                    content[y] = row.clone();
129                    Ok(matrix)
130                },
131                _ => {
132                    Err(AssemblerError::ExpressionError(ExpressionError::OwnError(
133                        Box::new(AssemblerError::AssemblingError {
134                            msg: format!("{} is not a list", matrix)
135                        })
136                    )))
137                },
138            }
139        },
140
141        _ => {
142            Err(AssemblerError::ExpressionError(ExpressionError::OwnError(
143                Box::new(AssemblerError::AssemblingError {
144                    msg: format!("{} is not a matrix", matrix)
145                })
146            )))
147        },
148    }
149}
150
151pub fn matrix_set(
152    mut matrix: ExprResult,
153    y: usize,
154    x: usize,
155    value: ExprResult
156) -> Result<ExprResult, crate::AssemblerError> {
157    match matrix {
158        ExprResult::Matrix { .. } => {
159            if y >= matrix.matrix_height() {
160                return Err(AssemblerError::ExpressionError(
161                    ExpressionError::InvalidSize(matrix.matrix_height(), y)
162                ));
163            }
164            if x >= matrix.matrix_width() {
165                return Err(AssemblerError::ExpressionError(
166                    ExpressionError::InvalidSize(matrix.matrix_width(), x)
167                ));
168            }
169            matrix.matrix_set(y, x, value);
170            Ok(matrix)
171        },
172
173        _ => {
174            Err(AssemblerError::ExpressionError(ExpressionError::OwnError(
175                Box::new(AssemblerError::AssemblingError {
176                    msg: format!("{} is not a matrix", matrix)
177                })
178            )))
179        },
180    }
181}
182
183pub fn matrix_get(
184    matrix: &ExprResult,
185    y: usize,
186    x: usize
187) -> Result<ExprResult, crate::AssemblerError> {
188    match matrix {
189        ExprResult::Matrix { .. } => {
190            if y >= matrix.matrix_height() {
191                return Err(AssemblerError::ExpressionError(
192                    ExpressionError::InvalidSize(matrix.matrix_height(), y)
193                ));
194            }
195            if x >= matrix.matrix_width() {
196                return Err(AssemblerError::ExpressionError(
197                    ExpressionError::InvalidSize(matrix.matrix_width(), x)
198                ));
199            }
200            Ok(matrix.matrix_get(y, x).clone())
201        },
202
203        _ => {
204            Err(AssemblerError::ExpressionError(ExpressionError::OwnError(
205                Box::new(AssemblerError::AssemblingError {
206                    msg: format!("{} is not a matrix", matrix)
207                })
208            )))
209        },
210    }
211}
212
213pub fn matrix_width(matrix: &ExprResult) -> Result<ExprResult, crate::AssemblerError> {
214    match matrix {
215        ExprResult::Matrix { width, .. } => Ok((*width as i32).into()),
216        _ => {
217            Err(AssemblerError::ExpressionError(ExpressionError::OwnError(
218                Box::new(AssemblerError::AssemblingError {
219                    msg: format!("{} is not a matrix", matrix)
220                })
221            )))
222        },
223    }
224}
225
226pub fn matrix_height(matrix: &ExprResult) -> Result<ExprResult, crate::AssemblerError> {
227    match matrix {
228        ExprResult::Matrix { height, .. } => Ok((*height as i32).into()),
229        _ => {
230            Err(AssemblerError::ExpressionError(ExpressionError::OwnError(
231                Box::new(AssemblerError::AssemblingError {
232                    msg: format!("{} is not a matrix", matrix)
233                })
234            )))
235        },
236    }
237}