add configs/bundle_pure

This commit is contained in:
Mark 2024-06-23 22:14:29 +02:00
parent 4d570ec5a5
commit 94111a5eaa
8 changed files with 60 additions and 33 deletions

View File

@ -1,6 +1,6 @@
[package]
name = "mers"
version = "0.8.12"
version = "0.8.13"
edition = "2021"
license = "MIT OR Apache-2.0"
description = "dynamically typed but type-checked programming language"
@ -11,7 +11,7 @@ repository = "https://github.com/Dummi26/mers"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
mers_lib = "0.8.12"
# mers_lib = { path = "../mers_lib" }
# mers_lib = "0.8.13"
mers_lib = { path = "../mers_lib" }
clap = { version = "4.3.19", features = ["derive"] }
colored = "2.1.0"

View File

@ -52,6 +52,7 @@ enum From {
enum Configs {
None,
Base,
Pure,
Std,
}
@ -60,6 +61,7 @@ fn main() {
let config = cfg_globals::add_general(match args.config {
Configs::None => Config::new(),
Configs::Base => Config::new().bundle_base(),
Configs::Pure => Config::new().bundle_pure(),
Configs::Std => Config::new().bundle_std(),
});
fn get_source(source: From) -> Source {

View File

@ -1,6 +1,6 @@
[package]
name = "mers_lib"
version = "0.8.12"
version = "0.8.13"
edition = "2021"
license = "MIT OR Apache-2.0"
description = "library to use the mers language in other projects"

View File

@ -90,6 +90,8 @@ pub mod error_colors {
pub const StacktraceDescend: Color = Color::Yellow;
pub const StacktraceDescendHashInclude: Color = Color::Red;
pub const MaximumRuntimeExceeded: Color = Color::BrightYellow;
}
#[derive(Clone)]
pub enum CheckErrorComponent {

View File

@ -22,12 +22,6 @@ pub mod with_string;
/// bundle_* for bundles (combines multiple groups or even bundles)
/// with_* for usage-oriented groups
/// add_* to add custom things
///
/// For doc-comments:
/// Description
/// `bundle_std()`
/// `type` - description
/// `var: type` - description
pub struct Config {
globals: usize,
info_parsed: super::parsed::Info,
@ -37,25 +31,32 @@ pub struct Config {
impl Config {
/// standard utilitis used in many programs
/// `bundle_base()`
/// `with_stdio()`
/// `with_list()`
/// `with_string()`
/// `with_command_running()`
/// `with_multithreading()`
///
/// - `bundle_pure()`
/// - `with_stdio()`
/// - `with_command_running()`
/// - `with_multithreading()`
pub fn bundle_std(self) -> Self {
self.with_multithreading()
.with_command_running()
.with_string()
.with_list()
.with_stdio()
.bundle_base()
.bundle_pure()
}
/// standard utilities, but don't allow code to do any I/O.
/// (multithreading can be added using `.with_multithreading()`)
///
/// - `bundle_base()`
/// - `with_list()`
/// - `with_string()`
pub fn bundle_pure(self) -> Self {
self.with_string().with_list().bundle_base()
}
/// base utilities used in most programs
/// `with_base()`
/// `with_math()`
/// `with_get()`
/// `with_iters()`
///
/// - `with_base()`
/// - `with_math()`
/// - `with_get()`
/// - `with_iters()`
pub fn bundle_base(self) -> Self {
self.with_iters().with_get().with_math().with_base()
}
@ -86,6 +87,7 @@ impl Config {
}
}
/// Add a variable. Its type will be that of the value stored in `val`.
pub fn add_var(self, name: String, val: Data) -> Self {
let t = val.get().as_type();
self.add_var_arc(name, Arc::new(RwLock::new(val)), t)

View File

@ -1,6 +1,6 @@
use std::{
sync::{Arc, Mutex, RwLock},
time::Duration,
time::{Duration, Instant},
};
use crate::{
@ -86,15 +86,20 @@ impl Config {
} else {
Err(format!("cannot call sleep with non-int or non-float argument.").into())
}),
run: Arc::new(|a, _i| {
run: Arc::new(|a, i| {
let a = a.get();
std::thread::sleep(if let Some(data::int::Int(n)) = a.as_any().downcast_ref() {
let mut sleep_dur = if let Some(data::int::Int(n)) = a.as_any().downcast_ref() {
Duration::from_secs(*n as _)
} else if let Some(data::float::Float(n)) = a.as_any().downcast_ref() {
Duration::from_secs_f64(*n)
} else {
return Err("sleep called on non-int/non-float".into());
});
};
// limit how long sleep can take
if let Some(cutoff) = i.global.limit_runtime {
sleep_dur = sleep_dur.min(cutoff.saturating_duration_since(Instant::now()));
}
std::thread::sleep(sleep_dur);
Ok(Data::empty_tuple())
}),
inner_statements: None,

View File

@ -464,7 +464,7 @@ fn genfunc_iter_in_val_out(
name: String,
iter_type: impl MersType + 'static,
out_type: Type,
run: impl Fn(Data, &mut crate::info::Info<program::run::Local>) -> Result<Data, CheckError>
run: impl Fn(Data, &mut crate::info::Info<program::run::RunLocal>) -> Result<Data, CheckError>
+ Send
+ Sync
+ 'static,

View File

@ -2,11 +2,12 @@ use std::{
collections::HashMap,
fmt::Debug,
sync::{Arc, Mutex, RwLock},
time::Instant,
};
use crate::{
data::{self, Data, Type},
errors::{CheckError, SourceRange},
errors::{error_colors, CheckError, SourceRange},
info,
};
@ -94,6 +95,16 @@ pub trait MersStatement: Debug + Send + Sync {
o
}
fn run(&self, info: &mut Info) -> Result<Data, CheckError> {
if let Some(cutoff) = info.global.limit_runtime {
if Instant::now() >= cutoff {
return Err(CheckError::new()
.msg("maximum runtime exceeded".to_owned())
.src(vec![(
self.source_range(),
Some(error_colors::MaximumRuntimeExceeded),
)]));
}
}
if self.has_scope() {
info.create_scope();
}
@ -108,13 +119,18 @@ pub trait MersStatement: Debug + Send + Sync {
fn as_any(&self) -> &dyn std::any::Any;
}
pub type Info = info::Info<Local>;
pub type Info = info::Info<RunLocal>;
pub type CheckInfo = info::Info<CheckLocal>;
#[derive(Default, Clone, Debug)]
pub struct Local {
pub struct RunLocal {
pub vars: Vec<Arc<RwLock<Data>>>,
}
#[derive(Default, Clone, Debug)]
pub struct RunLocalGlobalInfo {
/// if set, if `Instant::now()` is equal to or after the set `Instant`, stop the program with an error.
pub limit_runtime: Option<Instant>,
}
#[derive(Default, Clone)]
pub struct CheckLocal {
pub vars: Vec<Type>,
@ -149,10 +165,10 @@ impl Debug for CheckLocal {
write!(f, "CheckLocal {:?}, {:?}", self.vars, self.types.keys())
}
}
impl info::Local for Local {
impl info::Local for RunLocal {
type VariableIdentifier = usize;
type VariableData = Arc<RwLock<Data>>;
type Global = ();
type Global = RunLocalGlobalInfo;
fn init_var(&mut self, id: Self::VariableIdentifier, value: Self::VariableData) {
let nothing = Arc::new(RwLock::new(Data::new(data::bool::Bool(false))));
while self.vars.len() <= id {