mirror of
https://github.com/Dummi26/mers.git
synced 2025-03-10 14:13:52 +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()) {
|
if builtin.can_take(&rargs.iter().map(|v| v.out()).collect()) {
|
||||||
RStatementEnum::BuiltinFunction(builtin, rargs)
|
RStatementEnum::BuiltinFunction(builtin, rargs)
|
||||||
} else {
|
} 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 {
|
} else {
|
||||||
return Err(ToRunnableError::UseOfUndefinedFunction(v.clone()));
|
return Err(ToRunnableError::UseOfUndefinedFunction(v.clone()));
|
||||||
|
@ -134,7 +134,7 @@ impl BuiltinFunction {
|
|||||||
if input.len() >= 1 {
|
if input.len() >= 1 {
|
||||||
input[0].types.iter().all(|v| {
|
input[0].types.iter().all(|v| {
|
||||||
if let VSingleType::Function(v) = 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!)");
|
eprintln!("Warn: Function inputs aren't type checked yet!)");
|
||||||
// TODO!
|
// TODO!
|
||||||
true
|
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