mers rewrite is starting to be usable

This commit is contained in:
Mark
2023-08-14 17:17:08 +02:00
parent e549b1a5be
commit 2a7cb08596
50 changed files with 1411 additions and 407 deletions

View File

@@ -1,4 +1,7 @@
use std::sync::Arc;
use std::{
fmt::{Debug, Display},
sync::{Arc, Mutex},
};
use crate::{
data::{self, Data, Type},
@@ -16,21 +19,31 @@ pub mod function;
#[cfg(feature = "run")]
pub mod r#if;
#[cfg(feature = "run")]
pub mod r#loop;
#[cfg(feature = "run")]
pub mod switch;
#[cfg(feature = "run")]
pub mod tuple;
#[cfg(feature = "run")]
pub mod value;
#[cfg(feature = "run")]
pub mod variable;
pub trait MersStatement: std::fmt::Debug {
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 outputs(&self) -> Type;
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();
@@ -43,18 +56,54 @@ pub trait MersStatement: std::fmt::Debug {
}
}
#[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<Data>,
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 = Data;
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(Data::new(data::bool::Bool(false)));
self.vars.push(Arc::clone(&nothing));
}
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;
}