mirror of
https://github.com/Dummi26/mers.git
synced 2025-04-28 18:16:05 +02:00
125 lines
3.3 KiB
Rust
Executable File
125 lines
3.3 KiB
Rust
Executable File
use std::{
|
|
fmt::{Debug, Display},
|
|
sync::{Arc, Mutex},
|
|
};
|
|
|
|
use crate::{
|
|
data::{self, Data, Type},
|
|
info,
|
|
parsing::SourcePos,
|
|
};
|
|
|
|
#[cfg(feature = "run")]
|
|
pub mod assign_to;
|
|
#[cfg(feature = "run")]
|
|
pub mod block;
|
|
#[cfg(feature = "run")]
|
|
pub mod chain;
|
|
#[cfg(feature = "run")]
|
|
pub mod function;
|
|
#[cfg(feature = "run")]
|
|
pub mod r#if;
|
|
#[cfg(feature = "run")]
|
|
pub mod tuple;
|
|
#[cfg(feature = "run")]
|
|
pub mod value;
|
|
#[cfg(feature = "run")]
|
|
pub mod variable;
|
|
|
|
pub trait MersStatement: Debug + Send + Sync {
|
|
fn check_custom(
|
|
&self,
|
|
info: &mut CheckInfo,
|
|
init_to: Option<&Type>,
|
|
) -> Result<Type, CheckError>;
|
|
fn run_custom(&self, info: &mut Info) -> Data;
|
|
/// if true, local variables etc. will be contained inside their own scope.
|
|
fn has_scope(&self) -> bool;
|
|
fn pos_in_src(&self) -> &SourcePos;
|
|
fn check(&self, info: &mut CheckInfo, assign: Option<&Type>) -> Result<Type, CheckError> {
|
|
if self.has_scope() {
|
|
info.create_scope();
|
|
}
|
|
let o = self.check_custom(info, assign);
|
|
if self.has_scope() {
|
|
info.end_scope();
|
|
}
|
|
o
|
|
}
|
|
fn run(&self, info: &mut Info) -> Data {
|
|
if self.has_scope() {
|
|
info.create_scope();
|
|
}
|
|
let o = self.run_custom(info);
|
|
if self.has_scope() {
|
|
info.end_scope();
|
|
}
|
|
o
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub struct CheckError(pub String);
|
|
impl Display for CheckError {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
write!(f, "{}", self.0)
|
|
}
|
|
}
|
|
|
|
pub type Info = info::Info<Local>;
|
|
pub type CheckInfo = info::Info<CheckLocal>;
|
|
|
|
#[derive(Default, Clone, Debug)]
|
|
pub struct Local {
|
|
vars: Vec<Arc<Mutex<Data>>>,
|
|
}
|
|
#[derive(Default, Clone, Debug)]
|
|
pub struct CheckLocal {
|
|
vars: Vec<Type>,
|
|
}
|
|
impl info::Local for Local {
|
|
type VariableIdentifier = usize;
|
|
type VariableData = Arc<Mutex<Data>>;
|
|
fn init_var(&mut self, id: Self::VariableIdentifier, value: Self::VariableData) {
|
|
let nothing = Arc::new(Mutex::new(Data::new(data::bool::Bool(false))));
|
|
while self.vars.len() <= id {
|
|
self.vars.push(Arc::clone(¬hing));
|
|
}
|
|
self.vars[id] = value;
|
|
}
|
|
fn get_var(&self, id: &Self::VariableIdentifier) -> Option<&Self::VariableData> {
|
|
match self.vars.get(*id) {
|
|
Some(v) => Some(v),
|
|
None => None,
|
|
}
|
|
}
|
|
fn get_var_mut(&mut self, id: &Self::VariableIdentifier) -> Option<&mut Self::VariableData> {
|
|
match self.vars.get_mut(*id) {
|
|
Some(v) => Some(v),
|
|
None => None,
|
|
}
|
|
}
|
|
}
|
|
impl info::Local for CheckLocal {
|
|
type VariableIdentifier = usize;
|
|
type VariableData = Type;
|
|
fn init_var(&mut self, id: Self::VariableIdentifier, value: Self::VariableData) {
|
|
while self.vars.len() <= id {
|
|
self.vars.push(Type::empty());
|
|
}
|
|
self.vars[id] = value;
|
|
}
|
|
fn get_var(&self, id: &Self::VariableIdentifier) -> Option<&Self::VariableData> {
|
|
match self.vars.get(*id) {
|
|
Some(v) => Some(v),
|
|
None => None,
|
|
}
|
|
}
|
|
fn get_var_mut(&mut self, id: &Self::VariableIdentifier) -> Option<&mut Self::VariableData> {
|
|
match self.vars.get_mut(*id) {
|
|
Some(v) => Some(v),
|
|
None => None,
|
|
}
|
|
}
|
|
}
|