From 664de5c347b85f33bf0828a29a6817f302fa822c Mon Sep 17 00:00:00 2001 From: Dummi26 Date: Fri, 17 Mar 2023 14:23:54 +0100 Subject: [PATCH] cleaned up script/value.rs by splitting it up into val_data and val_type. --- src/main.rs | 17 --- src/parse/parse.rs | 3 +- src/script/block.rs | 9 +- src/script/builtins.rs | 3 +- src/script/mod.rs | 2 + src/script/value.rs | 315 +---------------------------------------- 6 files changed, 13 insertions(+), 336 deletions(-) diff --git a/src/main.rs b/src/main.rs index 15865a4..16de734 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,26 +1,9 @@ use std::time::Instant; -use crate::script::value::{VSingleType, VType}; - pub(crate) mod parse; pub(crate) mod script; fn main() { - let val: VType = VSingleType::Tuple(vec![ - VSingleType::Int.into(), - VSingleType::String.into(), - VSingleType::String.into(), - ]) - .into(); - let case: VType = VSingleType::Tuple(vec![ - VType { - types: vec![VSingleType::Tuple(vec![]).into(), VSingleType::Int.into()], - }, - VSingleType::String.into(), - VSingleType::String.into(), - ]) - .into(); - assert!(val.fits_in(&case).is_empty()); let script = parse::parse::parse(&mut parse::file::File::new( std::fs::read_to_string(std::env::args().nth(1).unwrap()).unwrap(), )) diff --git a/src/parse/parse.rs b/src/parse/parse.rs index 09c79d9..1943c55 100644 --- a/src/parse/parse.rs +++ b/src/parse/parse.rs @@ -3,7 +3,8 @@ use crate::script::{ to_runnable, to_runnable::ToRunnableError, RScript, SBlock, SFunction, SStatement, SStatementEnum, }, - value::{VDataEnum, VSingleType, VType}, + val_data::VDataEnum, + val_type::{VSingleType, VType}, }; use super::file::File; diff --git a/src/script/block.rs b/src/script/block.rs index 7bcf893..2461231 100644 --- a/src/script/block.rs +++ b/src/script/block.rs @@ -2,7 +2,6 @@ // Types starting with S are directly parsed from Strings and unchecked. Types starting with T are type-checked templates for R-types. Types starting with R are runnable. S are converted to T after parsing is done, and T are converted to R whenever they need to run. use std::{ - collections::HashSet, fmt::Display, sync::{Arc, Mutex}, }; @@ -11,7 +10,8 @@ use self::to_runnable::ToRunnableError; use super::{ builtins::BuiltinFunction, - value::{VData, VDataEnum, VSingleType, VType}, + val_data::{VData, VDataEnum}, + val_type::{VSingleType, VType}, }; // Represents a block of code @@ -95,7 +95,10 @@ pub mod to_runnable { sync::Arc, }; - use crate::script::value::{VDataEnum, VSingleType, VType}; + use crate::script::{ + val_data::VDataEnum, + val_type::{VSingleType, VType}, + }; use super::{ BuiltinFunction, RBlock, RFunction, RScript, RStatement, RStatementEnum, SBlock, SFunction, diff --git a/src/script/builtins.rs b/src/script/builtins.rs index 81d842f..ba57c15 100644 --- a/src/script/builtins.rs +++ b/src/script/builtins.rs @@ -6,7 +6,8 @@ use std::{ use super::{ block::RStatement, - value::{VData, VDataEnum, VDataThreadEnum, VSingleType, VType}, + val_data::{VData, VDataEnum, VDataThreadEnum}, + val_type::{VSingleType, VType}, }; #[derive(Clone, Debug)] diff --git a/src/script/mod.rs b/src/script/mod.rs index 429f283..40451b6 100644 --- a/src/script/mod.rs +++ b/src/script/mod.rs @@ -1,3 +1,5 @@ pub mod block; pub mod builtins; +pub mod val_data; +pub mod val_type; pub mod value; diff --git a/src/script/value.rs b/src/script/value.rs index e7819fe..92da94a 100644 --- a/src/script/value.rs +++ b/src/script/value.rs @@ -1,314 +1 @@ -use std::{ - fmt::Debug, - ops::BitOr, - sync::{Arc, Mutex}, - thread::JoinHandle, - time::Duration, -}; - -use super::block::RFunction; - -#[derive(Clone, Debug)] -pub struct VData { - // parents: Vec<()>, - pub data: VDataEnum, -} -impl VData { - pub fn out(&self) -> VType { - VType { - types: vec![self.out_single()], - } - } - pub fn out_single(&self) -> VSingleType { - match &self.data { - VDataEnum::Bool(..) => VSingleType::Bool, - VDataEnum::Int(..) => VSingleType::Int, - VDataEnum::Float(..) => VSingleType::Float, - VDataEnum::String(..) => VSingleType::String, - VDataEnum::Tuple(v) => VSingleType::Tuple(v.iter().map(|v| v.out()).collect()), - VDataEnum::List(t, _) => VSingleType::List(t.clone()), - VDataEnum::Function(f) => VSingleType::Function(f.input_output_map.clone()), - VDataEnum::Thread(_, o) => VSingleType::Thread(o.clone()), - VDataEnum::Reference(r) => r.lock().unwrap().out_single(), - } - } - pub fn get(&self, i: usize) -> Option { - self.data.get(i) - } -} - -#[derive(Clone, Debug)] -pub enum VDataEnum { - Bool(bool), - Int(isize), - Float(f64), - String(String), - Tuple(Vec), - List(VType, Vec), - Function(RFunction), - Thread(VDataThread, VType), - Reference(Arc>), -} - -#[derive(Clone)] -pub struct VDataThread(Arc>); -impl VDataThread { - pub fn try_get(&self) -> Option { - match &*self.lock() { - VDataThreadEnum::Running(_) => None, - VDataThreadEnum::Finished(v) => Some(v.clone()), - } - } - pub fn get(&self) -> VData { - let dur = Duration::from_millis(100); - loop { - match &*self.lock() { - VDataThreadEnum::Running(v) => { - while !v.is_finished() { - std::thread::sleep(dur); - } - } - VDataThreadEnum::Finished(v) => return v.clone(), - } - } - } - pub fn lock(&self) -> std::sync::MutexGuard { - let mut mg = self.0.lock().unwrap(); - match &*mg { - VDataThreadEnum::Running(v) => { - if v.is_finished() { - let m = std::mem::replace( - &mut *mg, - VDataThreadEnum::Finished(VData { - data: VDataEnum::Bool(false), - }), - ); - match m { - VDataThreadEnum::Running(v) => { - *mg = VDataThreadEnum::Finished(v.join().unwrap()) - } - _ => unreachable!(), - } - } - } - _ => (), - } - mg - } -} -impl Debug for VDataThread { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match &*self.lock() { - VDataThreadEnum::Running(_) => write!(f, "(thread running)"), - VDataThreadEnum::Finished(v) => write!(f, "(thread finished: {v})"), - } - } -} -pub enum VDataThreadEnum { - Running(JoinHandle), - Finished(VData), -} -impl VDataThreadEnum { - pub fn to(self) -> VDataThread { - VDataThread(Arc::new(Mutex::new(self))) - } -} - -impl VDataEnum { - pub fn to(self) -> VData { - VData { data: self } - } -} - -// get() -impl VDataEnum { - pub fn get(&self, i: usize) -> Option { - match self { - Self::Bool(..) - | Self::Int(..) - | Self::Float(..) - | Self::Function(..) - | Self::Thread(..) => None, - Self::String(s) => match s.chars().nth(i) { - // Slow! - Some(ch) => Some(Self::String(format!("{ch}")).to()), - None => None, - }, - Self::Tuple(v) | Self::List(_, v) => v.get(i).cloned(), - Self::Reference(r) => r.lock().unwrap().get(i), - } - } -} -impl VSingleType { - // None => Cannot get, Some(t) => getting can return t or nothing - pub fn get(&self, i: usize) -> Option { - match self { - Self::Bool | Self::Int | Self::Float | Self::Function(..) | Self::Thread(..) => None, - Self::String => Some(VSingleType::String.into()), - Self::Tuple(t) => t.get(i).cloned(), - Self::List(t) => Some(t.clone()), - Self::Reference(r) => r.get(i), - } - } - pub fn get_any(&self) -> Option { - match self { - Self::Bool | Self::Int | Self::Float | Self::Function(..) | Self::Thread(..) => None, - Self::String => Some(VSingleType::String.into()), - Self::Tuple(t) => Some(t.iter().fold(VType { types: vec![] }, |a, b| a | b)), - Self::List(t) => Some(t.clone()), - Self::Reference(r) => r.get_any(), - } - } -} -impl VType { - pub fn get(&self, i: usize) -> Option { - let mut out = VType { types: vec![] }; - for t in &self.types { - out = out | t.get(i)?; // if we can't use *get* on one type, we can't use it at all. - } - Some(out) - } - pub fn get_any(&self) -> Option { - let mut out = VType { types: vec![] }; - for t in &self.types { - out = out | t.get_any()?; // if we can't use *get* on one type, we can't use it at all. - } - Some(out) - } -} - -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct VType { - pub types: Vec, -} -impl VType { - /// Returns a vec with all types in self that aren't covered by rhs. If the returned vec is empty, self fits in rhs. - pub fn fits_in(&self, rhs: &Self) -> Vec { - let mut no = vec![]; - for t in &self.types { - // if t doesnt fit in any of rhs's types - if !rhs.types.iter().any(|r| t.fits_in(r)) { - no.push(t.clone()) - } - } - no - } - pub fn inner_types(&self) -> VType { - let mut out = VType { types: vec![] }; - for t in &self.types { - for it in t.inner_types() { - out = out | it.to(); - } - } - out - } - pub fn contains(&self, t: &VSingleType) -> bool { - self.types.contains(t) - } -} -impl BitOr for VType { - type Output = Self; - fn bitor(self, rhs: Self) -> Self::Output { - let mut types = self.types; - for t in rhs.types { - if !types.contains(&t) { - types.push(t) - } - } - Self { types } - } -} -impl BitOr<&VType> for VType { - type Output = Self; - fn bitor(self, rhs: &Self) -> Self::Output { - let mut types = self.types; - for t in &rhs.types { - if !types.contains(t) { - types.push(t.clone()) - } - } - Self { types } - } -} - -#[derive(Clone, Debug, PartialEq, Eq)] -pub enum VSingleType { - Bool, - Int, - Float, - String, - Tuple(Vec), - List(VType), - Function(Vec<(Vec, VType)>), - Thread(VType), - Reference(Box), -} -impl VSingleType { - pub fn to(self) -> VType { - VType { types: vec![self] } - } - pub fn inner_types(&self) -> Vec { - match self { - Self::Tuple(v) => { - let mut types = vec![]; - for it in v { - // the tuple values - for it in &it.types { - // the possible types for each value - if !types.contains(it) { - types.push(it.clone()); - } - } - } - types - } - Self::List(v) => v.types.clone(), - _ => vec![], - } - } - pub fn fits_in(&self, rhs: &Self) -> bool { - match (self, rhs) { - (Self::Bool, Self::Bool) - | (Self::Int, Self::Int) - | (Self::Float, Self::Float) - | (Self::String, Self::String) => true, - (Self::Bool | Self::Int | Self::Float | Self::String, _) => false, - (Self::Tuple(a), Self::Tuple(b)) => { - if a.len() == b.len() { - a.iter().zip(b.iter()).all(|(a, b)| a.fits_in(b).is_empty()) - } else { - false - } - } - (Self::Tuple(_), _) => false, - (Self::List(a), Self::List(b)) => a.fits_in(b).is_empty(), - (Self::List(_), _) => false, - (Self::Function(a), Self::Function(b)) => 'func_out: { - for a in a { - 'search: { - for b in b { - if a.1.fits_in(&b.1).is_empty() - && a.0.iter().zip(b.0.iter()).all(|(a, b)| *a == *b) - { - break 'search; - } - } - break 'func_out false; - } - } - true - } - (Self::Function(..), _) => false, - (Self::Thread(a), Self::Thread(b)) => a.fits_in(b).is_empty(), - (Self::Thread(..), _) => false, - (Self::Reference(r), Self::Reference(b)) => r.fits_in(b), - (Self::Reference(_), _) => false, - } - } -} - -impl Into for VSingleType { - fn into(self) -> VType { - VType { types: vec![self] } - } -} +// moved to val_data and val_type