mirror of
https://github.com/Dummi26/mers.git
synced 2025-03-10 05:43:53 +01:00
added files and fixed a bug in run() and thread()
This commit is contained in:
parent
04b9cbc4c7
commit
fff0b868ce
@ -310,7 +310,7 @@ pub mod to_runnable {
|
||||
if builtin.can_take(&rargs.iter().map(|v| v.out()).collect()) {
|
||||
RStatementEnum::BuiltinFunction(builtin, rargs)
|
||||
} else {
|
||||
todo!("ERR: Builtin function with wrong args - this isn't a proper error yet, sorry.");
|
||||
todo!("ERR: Builtin function \"{v}\" with wrong args - this isn't a proper error yet, sorry.");
|
||||
}
|
||||
} else {
|
||||
return Err(ToRunnableError::UseOfUndefinedFunction(v.clone()));
|
||||
|
@ -134,7 +134,7 @@ impl BuiltinFunction {
|
||||
if input.len() >= 1 {
|
||||
input[0].types.iter().all(|v| {
|
||||
if let VSingleType::Function(v) = v {
|
||||
if v.iter().any(|(i, _)| i.len() == input.len()) {
|
||||
if v.iter().any(|(i, _)| i.len() == input.len() - 1) {
|
||||
eprintln!("Warn: Function inputs aren't type checked yet!)");
|
||||
// TODO!
|
||||
true
|
||||
|
143
src/script/val_data.rs
Normal file
143
src/script/val_data.rs
Normal file
@ -0,0 +1,143 @@
|
||||
use std::{
|
||||
fmt::Debug,
|
||||
sync::{Arc, Mutex},
|
||||
thread::JoinHandle,
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use super::{
|
||||
block::RFunction,
|
||||
val_type::{VSingleType, VType},
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct VData {
|
||||
// parents: Vec<()>,
|
||||
pub data: VDataEnum,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum VDataEnum {
|
||||
Bool(bool),
|
||||
Int(isize),
|
||||
Float(f64),
|
||||
String(String),
|
||||
Tuple(Vec<VData>),
|
||||
List(VType, Vec<VData>),
|
||||
Function(RFunction),
|
||||
Thread(VDataThread, VType),
|
||||
Reference(Arc<Mutex<VData>>),
|
||||
}
|
||||
|
||||
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> {
|
||||
self.data.get(i)
|
||||
}
|
||||
}
|
||||
|
||||
impl VDataEnum {
|
||||
pub fn to(self) -> VData {
|
||||
VData { data: self }
|
||||
}
|
||||
}
|
||||
|
||||
// get()
|
||||
impl VDataEnum {
|
||||
pub fn get(&self, i: usize) -> Option<VData> {
|
||||
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),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Clone)]
|
||||
pub struct VDataThread(Arc<Mutex<VDataThreadEnum>>);
|
||||
impl VDataThread {
|
||||
pub fn try_get(&self) -> Option<VData> {
|
||||
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<VDataThreadEnum> {
|
||||
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<VData>),
|
||||
Finished(VData),
|
||||
}
|
||||
impl VDataThreadEnum {
|
||||
pub fn to(self) -> VDataThread {
|
||||
VDataThread(Arc::new(Mutex::new(self)))
|
||||
}
|
||||
}
|
182
src/script/val_type.rs
Normal file
182
src/script/val_type.rs
Normal file
@ -0,0 +1,182 @@
|
||||
use std::{fmt::Debug, ops::BitOr};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct VType {
|
||||
pub types: Vec<VSingleType>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum VSingleType {
|
||||
Bool,
|
||||
Int,
|
||||
Float,
|
||||
String,
|
||||
Tuple(Vec<VType>),
|
||||
List(VType),
|
||||
Function(Vec<(Vec<VSingleType>, VType)>),
|
||||
Thread(VType),
|
||||
Reference(Box<Self>),
|
||||
}
|
||||
|
||||
impl VSingleType {
|
||||
// None => Cannot get, Some(t) => getting can return t or nothing
|
||||
pub fn get(&self, i: usize) -> Option<VType> {
|
||||
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),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl VType {
|
||||
pub fn get(&self, i: usize) -> Option<VType> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
impl VSingleType {
|
||||
pub fn get_any(&self) -> Option<VType> {
|
||||
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_any(&self) -> Option<VType> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
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<VSingleType> {
|
||||
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 }
|
||||
}
|
||||
}
|
||||
|
||||
impl VSingleType {
|
||||
pub fn to(self) -> VType {
|
||||
VType { types: vec![self] }
|
||||
}
|
||||
pub fn inner_types(&self) -> Vec<VSingleType> {
|
||||
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<VType> for VSingleType {
|
||||
fn into(self) -> VType {
|
||||
VType { types: vec![self] }
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user