Skip to main content

unlab_gpu/
interp.rs

1//
2// Copyright (c) 2025-2026 Ɓukasz Szpakowski
3//
4// This Source Code Form is subject to the terms of the Mozilla Public
5// License, v. 2.0. If a copy of the MPL was not distributed with this
6// file, You can obtain one at https://mozilla.org/MPL/2.0/.
7//
8//! An interpreter module.
9use std::collections::BTreeMap;
10use std::collections::BTreeSet;
11use std::sync::Arc;
12use std::sync::RwLock;
13use crate::env::*;
14use crate::error::*;
15use crate::tree::*;
16use crate::utils::*;
17use crate::value::*;
18
19/// An interpreter structure.
20///
21/// The interpreter interprets a syntax tree that can be produced by a parser while parsing
22/// tokens. If an interpreter error occurs while interpreting a script tree, the interpreter
23/// stores a stack trace that can contain functions and contains file positions. These functions
24/// are functons in which occurred the interpreter error. Also, the interpreter contains a return
25/// value that can be an error for an error propagation.
26#[derive(Clone, Debug)]
27pub struct Interp
28{
29    stack_trace: Vec<(Option<Value>, Pos)>,
30    ret_value: Value,
31}
32
33impl Interp
34{
35    /// Creates an interpreter.
36    pub fn new() -> Self
37    { Interp { stack_trace: Vec::new(), ret_value: Value::None, } }
38    
39    /// Returns the stack trace.
40    pub fn stack_trace(&self) -> &[(Option<Value>, Pos)]
41    { self.stack_trace.as_slice() }
42
43    /// Clears the stack trace.
44    pub fn clear_stack_trace(&mut self)
45    { self.stack_trace.clear(); }
46    
47    /// Return the return value.
48    pub fn ret_value(&self) -> &Value
49    { &self.ret_value }
50    
51    /// Interprets the script tree.
52    pub fn interpret(&mut self, env: &mut Env, tree: &Tree) -> Result<()>
53    { 
54        match tree {
55            Tree(nodes) => {
56                let res = match self.interpret_nodes(env, nodes) {
57                    Ok(()) => Ok(()),
58                    Err(Error::Stop(Stop::Break)) => Err(Error::Interp(String::from("break isn't in loop"))),
59                    Err(Error::Stop(Stop::Continue)) => Err(Error::Interp(String::from("continue isn't in loop"))),
60                    Err(Error::Stop(Stop::Return)) => Err(Error::Interp(String::from("return isn't in function"))),
61                    Err(err) => Err(err),
62                };
63                match res {
64                    Ok(()) => Ok(()),
65                    Err(err) => {
66                        env.reset()?;
67                        Err(err)
68                    },
69                }
70            },
71        }
72    }
73
74    /// Applies the function to the arguments.
75    ///
76    /// This method applies the function to the argument if the value is a function or a built-in
77    /// function, otherwise returns an error.
78    pub fn apply_fun(&mut self, env: &mut Env, fun_value: &Value, arg_values: &[Value]) -> Result<Value>
79    {
80        match fun_value {
81            Value::Object(fun_object) => {
82                match &**fun_object {
83                    Object::Fun(fun_mod_idents, _, fun) => {
84                        match &**fun {
85                            Fun(args, stats) => {
86                                match env.push_fun_mod_and_local_vars(fun_mod_idents.as_slice(), args, arg_values) {
87                                    Ok(true) => (),
88                                    Ok(false) => return Err(Error::Interp(String::from("invalid number of arguments"))),
89                                    Err(err) => return Err(err),
90                                }
91                                let res = match self.interpret_stats(env, stats.as_slice()) {
92                                    Ok(()) => Ok(self.ret_value.clone()),
93                                    Err(Error::Stop(Stop::Break)) => Err(Error::Interp(String::from("break isn't in loop"))),
94                                    Err(Error::Stop(Stop::Continue)) => Err(Error::Interp(String::from("continue isn't in loop"))),
95                                    Err(Error::Stop(Stop::Return | Stop::ErrorPropagation)) => {
96                                        self.stack_trace.clear();
97                                        Ok(self.ret_value.clone())
98                                    },
99                                    Err(err) => Err(err),
100                                };
101                                env.pop_fun_mod_and_local_vars();
102                                match res {
103                                    Ok(value) => Ok(value),
104                                    Err(err) => {
105                                        match self.stack_trace.pop() {
106                                            Some((_, pos)) => {
107                                                self.stack_trace.push((Some(fun_value.clone()), pos));
108                                            },
109                                            None => (),
110                                        }
111                                        Err(err)
112                                    },
113                                }
114                            },
115                        }
116                    },
117                    Object::BuiltinFun(_, f) => f(self, env, arg_values),
118                    _ => {
119                        self.ret_value = Value::None;
120                        Err(Error::Interp(format!("value isn't function")))
121                    },
122                }
123            },
124            _ => {
125                self.ret_value = Value::None;
126                Err(Error::Interp(format!("value isn't function")))
127            },
128        }
129    }
130
131    fn interpret_node(&mut self, env: &mut Env, node: &Node) -> Result<()>
132    {
133        match node {
134            Node::Def(def) => self.interpret_def(env, &**def),
135            Node::Stat(stat) => self.interpret_stat(env, &**stat),
136        }
137    }
138
139    fn interpret_nodes(&mut self, env: &mut Env, nodes: &[Node]) -> Result<()>
140    {
141        self.ret_value = Value::None;
142        for node in nodes {
143            let res = self.interpret_node(env, node);
144            match res {
145                Err(Error::Stop(Stop::ErrorPropagation)) => (),
146                _ => self.ret_value = Value::None,
147            }
148            res?;
149        }
150        Ok(())
151    }
152    
153    fn interpret_def(&mut self, env: &mut Env, def: &Def) -> Result<()>
154    {
155        match def {
156            Def::Mod(ident, mod1, pos) => {
157                match &**mod1 {
158                    Mod(nodes) => {
159                        match env.add_and_push_mod(ident.clone()) {
160                            Ok(true) => {
161                                self.interpret_nodes(env, nodes.as_slice())?;
162                                match env.pop_mod() {
163                                    Ok(true) => (),
164                                    Ok(false) => {
165                                        self.stack_trace.push((None, pos.clone()));
166                                        self.ret_value = Value::None;
167                                        return Err(Error::Interp(format!("can't pop module {}", ident)));
168                                    },
169                                    Err(err) => {
170                                        self.stack_trace.push((None, pos.clone()));
171                                        self.ret_value = Value::None;
172                                        return Err(err);
173                                    },
174                                }
175                            },
176                            Ok(false) => {
177                                self.stack_trace.push((None, pos.clone()));
178                                self.ret_value = Value::None;
179                                return Err(Error::Interp(format!("already defined module {}", ident)));
180                            },
181                            Err(err) => {
182                                self.stack_trace.push((None, pos.clone()));
183                                self.ret_value = Value::None;
184                                return Err(err);
185                            },
186                        }
187                    },
188                }
189            },
190            Def::Fun(ident, fun, pos) => {
191                match &**fun {
192                    Fun(args, _) => {
193                        let mut idents: BTreeSet<&String> = BTreeSet::new();
194                        for arg in args {
195                            match arg {
196                                Arg(ident, pos2) => {
197                                    if idents.contains(&ident) {
198                                        self.stack_trace.push((None, pos2.clone()));
199                                        self.ret_value = Value::None;
200                                        return Err(Error::Interp(format!("already defined argument {}", ident)));
201                                    }
202                                    idents.insert(ident);
203                                },
204                            }
205                        }
206                        match env.add_fun(ident.clone(), fun.clone()) {
207                            Ok(true) => (),
208                            Ok(false) => {
209                                self.stack_trace.push((None, pos.clone()));
210                                self.ret_value = Value::None;
211                                return Err(Error::Interp(format!("already variable {} is set", ident)));
212                            },
213                            Err(err) => {
214                                self.stack_trace.push((None, pos.clone()));
215                                self.ret_value = Value::None;
216                                return Err(err);
217                            },
218                        }
219                    },
220                }
221            },
222        }
223        Ok(())
224    }
225    
226    fn interpret_stat(&mut self, env: &mut Env, stat: &Stat) -> Result<()>
227    {
228        match stat {
229            Stat::Expr(expr, _) => self.ret_value = self.interpret_expr(env, &**expr)?,
230            Stat::Assign(expr, expr2, pos) => {
231                let value2 = self.interpret_expr(env, &**expr2)?;
232                match &**expr {
233                    Expr::Var(name, _) => {
234                        match env.set_var(name, value2) {
235                            Ok(true) => (),
236                            Ok(false) => {
237                                self.stack_trace.push((None, pos.clone()));
238                                self.ret_value = Value::None;
239                                return Err(Error::Interp(format!("undefined module for variable {}", name)));
240                            },
241                            Err(err) => {
242                                self.stack_trace.push((None, pos.clone()));
243                                self.ret_value = Value::None;
244                                return Err(err);
245                            },
246                        }
247                    },
248                    Expr::BinOp(BinOp::Index, expr3, expr4, _) => {
249                        let value = self.interpret_expr(env, expr3)?;
250                        let idx_value = self.interpret_expr(env, expr4)?;
251                        match value.set_elem(&idx_value, value2) {
252                            Ok(()) => (),
253                            Err(err) => {
254                                self.stack_trace.push((None, pos.clone()));
255                                self.ret_value = Value::None;
256                                return Err(err);
257                            },
258                        }
259                    },
260                    Expr::Field(expr3, ident, _) => {
261                        let value = self.interpret_expr(env, expr3)?;
262                        match value.set_field(ident.clone(), value2) {
263                            Ok(()) => (),
264                            Err(err) => {
265                                self.stack_trace.push((None, pos.clone()));
266                                self.ret_value = Value::None;
267                                return Err(err);
268                            },
269                        }
270                    },
271                    _ => {
272                        self.stack_trace.push((None, expr.pos().clone()));
273                        self.ret_value = Value::None;
274                        return Err(Error::Interp(String::from("expression isn't assignable")));
275                    },
276                }
277                self.ret_value = Value::None;
278            },
279            Stat::If(expr, stats, else_if_pairs, else_stats, _) => {
280                if self.interpret_expr(env, &**expr)?.to_bool() {
281                    self.interpret_stats(env, stats.as_slice())?;
282                } else {
283                    let mut is_else_if = false;
284                    for (else_if_expr, else_if_stats) in else_if_pairs {
285                        if self.interpret_expr(env, &**else_if_expr)?.to_bool() {
286                            self.interpret_stats(env, else_if_stats.as_slice())?;
287                            is_else_if = true;
288                            break;
289                        }
290                    }
291                    if !is_else_if {
292                        match else_stats {
293                            Some(else_stats) => self.interpret_stats(env, else_stats.as_slice())?,
294                            None => (),
295                        }
296                    }
297                }
298            },
299            Stat::For(ident, expr, stats, pos) => {
300                let value = self.interpret_expr(env, &**expr)?;
301                match value.iter() {
302                    Ok(Some(mut iter)) => {
303                        loop {
304                            match iter.next() {
305                                Some(Ok(elem)) => {
306                                    match env.set_var(&Name::Var(ident.clone()), elem.clone()) {
307                                        Ok(true) => (),
308                                        Ok(false) => {
309                                            self.stack_trace.push((None, pos.clone()));
310                                            self.ret_value = Value::None;
311                                            return Err(Error::Interp(format!("undefined module for variable {}", ident)));
312                                        },
313                                        Err(err) => {
314                                            self.stack_trace.push((None, pos.clone()));
315                                            self.ret_value = Value::None;
316                                            return Err(err);
317                                        },
318                                    }
319                                },
320                                Some(Err(err)) => {
321                                    self.stack_trace.push((None, pos.clone()));
322                                    self.ret_value = Value::None;
323                                    return Err(err);
324                                },
325                                None => break,
326                            }
327                            match self.interpret_stats(env, stats.as_slice()) {
328                                Ok(()) => (),
329                                Err(Error::Stop(Stop::Break)) => {
330                                    self.stack_trace.clear();
331                                    break;
332                                },
333                                Err(Error::Stop(Stop::Continue)) => {
334                                    self.stack_trace.clear();
335                                    continue;
336                                },
337                                Err(err) => return Err(err),                                
338                            }
339                        }
340                    },
341                    Ok(None) => {
342                        self.stack_trace.push((None, expr.pos().clone()));
343                        self.ret_value = Value::None;
344                        return Err(Error::Interp(String::from("value isn't iterable")));
345                    },
346                    Err(err) => {
347                        self.stack_trace.push((None, expr.pos().clone()));
348                        self.ret_value = Value::None;
349                        return Err(err);
350                    },
351                }
352            },
353            Stat::While(expr, stats, _) => {
354                while self.interpret_expr(env, &**expr)?.to_bool() {
355                    match self.interpret_stats(env, stats.as_slice()) {
356                        Ok(()) => (),
357                        Err(Error::Stop(Stop::Break)) => {
358                            self.stack_trace.clear();
359                            break;
360                        },
361                        Err(Error::Stop(Stop::Continue)) => {
362                            self.stack_trace.clear();
363                            continue;
364                        },
365                        Err(err) => return Err(err),                                
366                    }
367                }
368            },
369            Stat::Break(pos) => {
370                self.stack_trace.push((None, pos.clone()));
371                self.ret_value = Value::None;
372                return Err(Error::Stop(Stop::Break));
373            },
374            Stat::Continue(pos) => {
375                self.stack_trace.push((None, pos.clone()));
376                self.ret_value = Value::None;
377                return Err(Error::Stop(Stop::Continue));
378            },
379            Stat::Return(expr, pos) => {
380                match expr {
381                    Some(expr) => self.ret_value = self.interpret_expr(env, &**expr)?,
382                    None => self.ret_value = Value::None,
383                }
384                self.stack_trace.push((None, pos.clone()));
385                return Err(Error::Stop(Stop::Return));
386            },
387            Stat::Quit(pos) => {
388                self.stack_trace.push((None, pos.clone()));
389                self.ret_value = Value::None;
390                return Err(Error::Stop(Stop::Quit));
391            },
392        }
393        Ok(())
394    }
395
396    fn interpret_stats(&mut self, env: &mut Env, stats: &[Box<Stat>]) -> Result<()>
397    {
398        self.ret_value = Value::None;
399        for stat in stats {
400            self.interpret_stat(env, &**stat)?;
401        }
402        Ok(())
403    }
404    
405    fn interpret_expr(&mut self, env: &mut Env, expr: &Expr) -> Result<Value>
406    {
407        match expr {
408            Expr::Lit(lit, pos) => self.interpret_lit(env, lit, pos),
409            Expr::Var(name, pos) => {
410                match env.var(name) {
411                    Ok(Some(value)) => Ok(value),
412                    Ok(None) => {
413                        self.stack_trace.push((None, pos.clone()));
414                        self.ret_value = Value::None;
415                        Err(Error::Interp(format!("variable {} isn't set", name)))
416                    },
417                    Err(err) => {
418                        self.stack_trace.push((None, pos.clone()));
419                        self.ret_value = Value::None;
420                        Err(err)
421                    },
422                }
423            },
424            Expr::App(expr2, exprs, pos) => {
425                let fun_value = self.interpret_expr(env, &**expr2)?;
426                let mut arg_values: Vec<Value> = Vec::new();
427                for expr3 in exprs {
428                    arg_values.push(self.interpret_expr(env, &**expr3)?);
429                }
430                match self.apply_fun(env, &fun_value, arg_values.as_slice()) {
431                    Ok(value) => Ok(value),
432                    Err(err) => {
433                        self.stack_trace.push((None, pos.clone()));
434                        self.ret_value = Value::None;
435                        Err(err)
436                    },
437                }
438            },
439            Expr::UnaryOp(op, expr2, pos) => {
440                let value2 = self.interpret_expr(env, &**expr2)?;
441                match value2.unary_op(*op) {
442                    Ok(value) => Ok(value),
443                    Err(err) => {
444                        self.stack_trace.push((None, pos.clone()));
445                        self.ret_value = Value::None;
446                        Err(err)
447                    },
448                }
449            },
450            Expr::BinOp(op, expr2, expr3, pos) => {
451                let value2 = self.interpret_expr(env, &**expr2)?;
452                let value3 = self.interpret_expr(env, &**expr3)?;
453                match value2.bin_op(*op, &value3) {
454                    Ok(value) => Ok(value),
455                    Err(err) => {
456                        self.stack_trace.push((None, pos.clone()));
457                        self.ret_value = Value::None;
458                        Err(err)
459                    },
460                }
461            },
462            Expr::And(expr2, expr3, _) => {
463                let value2 = self.interpret_expr(env, &**expr2)?;
464                if value2.to_bool() {
465                    self.interpret_expr(env, &**expr3)
466                } else {
467                    Ok(value2)
468                }
469            },
470            Expr::Or(expr2, expr3, _) => {
471                let value2 = self.interpret_expr(env, &**expr2)?;
472                if value2.to_bool() {
473                    Ok(value2)
474                } else {
475                    self.interpret_expr(env, &**expr3)
476                }
477            },
478            Expr::Field(expr2, ident, pos) => {
479                let value2 = self.interpret_expr(env, &**expr2)?;
480                match value2.field(ident) {
481                    Ok(value) => Ok(value),
482                    Err(err) => {
483                        self.stack_trace.push((None, pos.clone()));
484                        self.ret_value = Value::None;
485                        Err(err)
486                    },
487                }
488            },
489            Expr::Range(expr2, expr3, expr4, pos) => {
490                let value2 = self.interpret_expr(env, &**expr2)?;
491                let value3 = self.interpret_expr(env, &**expr3)?;
492                let value4 = match expr4 {
493                    Some(expr4) => Some(self.interpret_expr(env, &**expr4)?),
494                    None => None,
495                };
496                match (&value2, &value3, &value4) {
497                    (Value::Int(a), Value::Int(b), None) => Ok(Value::Object(Arc::new(Object::IntRange(*a, *b, 1)))),
498                    (Value::Int(a), Value::Int(b), Some(Value::Int(c))) => Ok(Value::Object(Arc::new(Object::IntRange(*a, *b, *c)))),
499                    (Value::Int(_) | Value::Float(_), Value::Int(_) | Value::Float(_), None) => Ok(Value::Object(Arc::new(Object::FloatRange(value2.to_f32(), value3.to_f32(), 1.0)))),
500                    (Value::Int(_) | Value::Float(_), Value::Int(_) | Value::Float(_), Some(value4 @ (Value::Int(_) | Value::Float(_)))) => Ok(Value::Object(Arc::new(Object::FloatRange(value2.to_f32(), value3.to_f32(), value4.to_f32())))),
501                    (_, _, _) => {
502                        self.stack_trace.push((None, pos.clone()));
503                        self.ret_value = Value::None;
504                        Err(Error::Interp(String::from("unsupported types for range creation")))
505                    },
506                }
507            },
508            Expr::PropagateError(expr2, pos) => {
509                let value2 = self.interpret_expr(env, &**expr2)?;
510                match &value2 {
511                    Value::None => {
512                        self.stack_trace.push((None, pos.clone()));
513                        self.ret_value = value2.clone();
514                        Err(Error::Stop(Stop::ErrorPropagation))
515                    },
516                    Value::Object(object2) => {
517                        match &**object2 {
518                            Object::Error(_, _) => {
519                                self.stack_trace.push((None, pos.clone()));
520                                self.ret_value = value2.clone();
521                                Err(Error::Stop(Stop::ErrorPropagation))
522                            },
523                            _ => Ok(value2),
524                        }
525                    },
526                    _ => Ok(value2),
527                }
528            },
529        }
530    }
531
532    fn interpret_matrix_row(&mut self, env: &mut Env, matrix_row: &MatrixRow) -> Result<Vec<f32>>
533    {
534        match matrix_row {
535            MatrixRow::Row(exprs) => {
536                let mut xs: Vec<f32> = Vec::new();
537                for expr in exprs {
538                    let value = self.interpret_expr(env, &**expr)?;
539                    match value.to_opt_f32() {
540                        Some(x) => xs.push(x),
541                        None => {
542                            self.stack_trace.push((None, expr.pos().clone()));
543                            self.ret_value = Value::None;
544                            return Err(Error::Interp(String::from("can't convert value to floating-point number")));
545                        },
546                    }
547                }
548                Ok(xs)
549            },
550            MatrixRow::FilledRow(expr, expr2) => {
551                let value2 = self.interpret_expr(env, &**expr2)?;
552                match value2.to_opt_i64() {
553                    Some(n) => {
554                        let mut xs: Vec<f32> = Vec::new();
555                        for _ in 0..n {
556                            let value = self.interpret_expr(env, &**expr)?;
557                            match value.to_opt_f32() {
558                                Some(x) => xs.push(x),
559                                None => {
560                                    self.stack_trace.push((None, expr.pos().clone()));
561                                    self.ret_value = Value::None;
562                                    return Err(Error::Interp(String::from("can't convert value to floating-point number")));
563                                },
564                            }
565                        }
566                        Ok(xs)
567                    },
568                    None => {
569                        self.stack_trace.push((None, expr2.pos().clone()));
570                        self.ret_value = Value::None;
571                        Err(Error::Interp(String::from("can't convert value to integer number")))
572                    },
573                }
574            },
575        }
576    }
577
578    fn interpret_lit(&mut self, env: &mut Env, lit: &Lit, pos: &Pos) -> Result<Value>
579    {
580        match lit {
581            Lit::None => Ok(Value::None),
582            Lit::Bool(b) => Ok(Value::Bool(*b)),
583            Lit::Int(n) => Ok(Value::Int(*n)),
584            Lit::Float(n) => Ok(Value::Float(*n)),
585            Lit::String(s) => Ok(Value::Object(Arc::new(Object::String(s.clone())))),
586            Lit::Matrix(matrix_rows) => {
587                let mut xs: Vec<f32> = Vec::new();
588                let mut row_count = 0usize;
589                let mut col_count: Option<usize> = None;
590                for matrix_row in matrix_rows {
591                    let ys = self.interpret_matrix_row(env, matrix_row)?;
592                    if col_count.map(|n| n == ys.len()).unwrap_or(true) {
593                        xs.extend_from_slice(ys.as_slice());
594                        col_count = Some(ys.len());
595                    } else {
596                        self.stack_trace.push((None, pos.clone()));
597                        self.ret_value = Value::None;
598                        return Err(Error::Interp(String::from("numbers of columns of matrix rows aren't equal")));
599                    }
600                    match row_count.checked_add(1) {
601                        Some(new_row_count) => row_count = new_row_count,
602                        None => {
603                            self.stack_trace.push((None, pos.clone()));
604                            self.ret_value = Value::None;
605                            return Err(Error::Interp(String::from("too many matrix rows")));
606                        },
607                    }
608                }
609                match matrix_create_and_set_elems(row_count, col_count.unwrap_or(0), xs.as_slice()) {
610                    Ok(a) => Ok(Value::Object(Arc::new(Object::Matrix(a)))),
611                    Err(err) => {
612                        self.stack_trace.push((None, pos.clone()));
613                        self.ret_value = Value::None;
614                        Err(err)
615                    },
616                }
617            },
618            Lit::FilledMatrix(matrix_row, expr) => {
619                let value = self.interpret_expr(env, &**expr)?;
620                match value.to_opt_i64() {
621                    Some(n) => {
622                        let mut  xs: Vec<f32> = Vec::new();
623                        let mut row_count = 0usize;
624                        let mut col_count: Option<usize> = None;
625                        for _ in 0..n {
626                            let ys = self.interpret_matrix_row(env, matrix_row)?;
627                            if col_count.map(|n| n == ys.len()).unwrap_or(true) {
628                                xs.extend_from_slice(ys.as_slice());
629                                col_count = Some(ys.len());
630                            } else {
631                                self.stack_trace.push((None, pos.clone()));
632                                self.ret_value = Value::None;
633                                return Err(Error::Interp(String::from("numbers of columns of matrix rows aren't equal")));
634                            }
635                            match row_count.checked_add(1) {
636                                Some(new_row_count) => row_count = new_row_count,
637                                None => {
638                                    self.stack_trace.push((None, pos.clone()));
639                                    self.ret_value = Value::None;
640                                    return Err(Error::Interp(String::from("too many matrix rows")));
641                                },
642                            }
643                        }
644                        match matrix_create_and_set_elems(row_count, col_count.unwrap_or(0), xs.as_slice()) {
645                            Ok(a) => Ok(Value::Object(Arc::new(Object::Matrix(a)))),
646                            Err(err) => {
647                                self.stack_trace.push((None, pos.clone()));
648                                self.ret_value = Value::None;
649                                Err(err)
650                            },
651                        }
652                    },
653                    None => {
654                        self.stack_trace.push((None, expr.pos().clone()));
655                        self.ret_value = Value::None;
656                        Err(Error::Interp(String::from("can't convert value to integer number")))
657                    },
658                }
659            },
660            Lit::Array(exprs) => {
661                let mut elems: Vec<Value> = Vec::new();
662                for expr in exprs {
663                    elems.push(self.interpret_expr(env, &**expr)?);
664                }
665                Ok(Value::Ref(Arc::new(RwLock::new(MutObject::Array(elems)))))
666            },
667            Lit::FilledArray(expr, expr2) => {
668                let value2 = self.interpret_expr(env, &**expr2)?;
669                match value2.to_opt_i64() {
670                    Some(n) => {
671                        let mut elems: Vec<Value> = Vec::new();
672                        for _ in 0..n {
673                            elems.push(self.interpret_expr(env, &**expr)?);
674                        }
675                        Ok(Value::Ref(Arc::new(RwLock::new(MutObject::Array(elems)))))
676                    },
677                    None => {
678                        self.stack_trace.push((None, expr2.pos().clone()));
679                        self.ret_value = Value::None;
680                        Err(Error::Interp(String::from("can't convert value to integer number")))
681                    },
682                }
683            },
684            Lit::Struct(field_pairs) => {
685                let mut fields: BTreeMap<String, Value> = BTreeMap::new();
686                for field_pair in field_pairs {
687                    match field_pair {
688                        FieldPair(ident, expr, pos2) => {
689                            if fields.contains_key(ident) {
690                                self.stack_trace.push((None, pos2.clone()));
691                                self.ret_value = Value::None;
692                                return Err(Error::Interp(format!("already defined field {}", ident)));
693                            }
694                            fields.insert(ident.clone(), self.interpret_expr(env, &**expr)?);
695                        },
696                    }
697                }
698                Ok(Value::Ref(Arc::new(RwLock::new(MutObject::Struct(fields)))))
699            },
700        }
701    }
702}
703
704#[cfg(test)]
705mod tests;