mers/mers_lib/src/program/run/variable.rs
Mark 12925fed67 improved error messages
- some small bugs are now fixed
- include comments in error messages (if this causes issues, use --hide-comments)
- colors should make more sense now
- error-related things moved to mers_lib/src/errors/
2023-11-16 14:50:09 +01:00

67 lines
1.9 KiB
Rust
Executable File

use std::sync::{Arc, RwLock};
use crate::{
data::{self, Data, Type},
errors::SourceRange,
};
use super::MersStatement;
#[derive(Debug)]
pub struct Variable {
pub pos_in_src: SourceRange,
pub is_init: bool,
pub is_ref: bool,
pub var: (usize, usize),
}
impl MersStatement for Variable {
fn has_scope(&self) -> bool {
false
}
fn check_custom(
&self,
info: &mut super::CheckInfo,
init_to: Option<&Type>,
) -> Result<data::Type, super::CheckError> {
if self.is_init {
while info.scopes[self.var.0].vars.len() <= self.var.1 {
info.scopes[self.var.0].vars.push(Type::empty());
}
info.scopes[self.var.0].vars[self.var.1] = init_to
.expect("variable's is_init was true, but check_custom's assign was None? How?")
.clone();
}
let val = if self.is_ref {
Type::new(data::reference::ReferenceT(
info.scopes[self.var.0].vars[self.var.1].clone(),
))
} else {
info.scopes[self.var.0].vars[self.var.1].clone()
};
Ok(val)
}
fn run_custom(&self, info: &mut super::Info) -> Data {
if self.is_init {
let nothing = Arc::new(RwLock::new(Data::new(data::bool::Bool(false))));
while info.scopes[self.var.0].vars.len() <= self.var.1 {
info.scopes[self.var.0].vars.push(Arc::clone(&nothing));
}
info.scopes[self.var.0].vars[self.var.1] = nothing;
}
if self.is_ref {
Data::new(data::reference::Reference(Arc::clone(
&info.scopes[self.var.0].vars[self.var.1],
)))
} else {
info.scopes[self.var.0].vars[self.var.1]
.write()
.unwrap()
.clone()
}
}
fn source_range(&self) -> SourceRange {
self.pos_in_src
}
}