sorted mers_lib/src/program/configs/ and added cargo features

This commit is contained in:
Mark
2023-07-28 15:20:02 +02:00
parent b81dac682e
commit 07745488b3
14 changed files with 267 additions and 140 deletions

View File

@@ -7,8 +7,11 @@ use crate::{
};
mod with_command_running;
mod with_get;
mod with_iters;
mod with_list;
mod with_math;
mod with_prints;
/// Usage: create an empty Config using Config::new(), use the methods to customize it, then get the Infos using Config::infos()
/// bundle_* for bundles (combines multiple groups or even bundles)
@@ -27,14 +30,6 @@ pub struct Config {
}
impl Config {
pub fn new() -> Self {
Self {
globals: 0,
info_parsed: Default::default(),
info_run: Default::default(),
}
}
/// standard utilitis used in many programs
/// `bundle_base()`
/// `with_list()`
@@ -51,134 +46,12 @@ impl Config {
self.with_iters().with_get().with_math().with_prints()
}
/// `println: fn` prints to stdout and adds a newline to the end
/// `print: fn` prints to stdout
/// `eprintln: fn` prints to stderr and adds a newline to the end
/// `eprint: fn` prints to stderr
/// `debug: fn` debug-prints any value
pub fn with_prints(self) -> Self {
self.add_var(
"debug".to_string(),
Data::new(data::function::Function {
info: program::run::Info::neverused(),
out: Arc::new(|_a| todo!()),
run: Arc::new(|a, _i| {
eprintln!("{:#?}", a.get());
Data::empty_tuple()
}),
}),
)
.add_var(
"eprint".to_string(),
Data::new(data::function::Function {
info: program::run::Info::neverused(),
out: Arc::new(|_a| todo!()),
run: Arc::new(|a, _i| {
eprint!("{}", a.get());
Data::empty_tuple()
}),
}),
)
.add_var(
"eprintln".to_string(),
Data::new(data::function::Function {
info: program::run::Info::neverused(),
out: Arc::new(|_a| todo!()),
run: Arc::new(|a, _i| {
eprintln!("{}", a.get());
Data::empty_tuple()
}),
}),
)
.add_var(
"print".to_string(),
Data::new(data::function::Function {
info: program::run::Info::neverused(),
out: Arc::new(|_a| todo!()),
run: Arc::new(|a, _i| {
print!("{}", a.get());
Data::empty_tuple()
}),
}),
)
.add_var(
"println".to_string(),
Data::new(data::function::Function {
info: program::run::Info::neverused(),
out: Arc::new(|_a| todo!()),
run: Arc::new(|a, _i| {
println!("{}", a.get());
Data::empty_tuple()
}),
}),
)
}
/// `sum: fn` returns the sum of all the numbers in the tuple
pub fn with_math(self) -> Self {
self.add_var(
"sum".to_string(),
Data::new(data::function::Function {
info: program::run::Info::neverused(),
out: Arc::new(|_a| todo!()),
run: Arc::new(|a, _i| {
if let Some(tuple) = a.get().as_any().downcast_ref::<data::tuple::Tuple>() {
let mut sumi = 0;
let mut sumf = 0.0;
let mut usef = false;
for val in &tuple.0 {
if let Some(i) = val.get().as_any().downcast_ref::<data::int::Int>() {
sumi += i.0;
} else if let Some(i) =
val.get().as_any().downcast_ref::<data::float::Float>()
{
sumf += i.0;
usef = true;
}
}
if usef {
Data::new(data::float::Float(sumi as f64 + sumf))
} else {
Data::new(data::int::Int(sumi))
}
} else {
unreachable!("sum called on non-tuple")
}
}),
}),
)
}
/// `get: fn` is used to retrieve elements from collections
pub fn with_get(self) -> Self {
self.add_var(
"get".to_string(),
Data::new(data::function::Function {
info: program::run::Info::neverused(),
out: Arc::new(|_a| todo!()),
run: Arc::new(|a, _i| {
if let Some(tuple) = a.get().as_any().downcast_ref::<data::tuple::Tuple>() {
if let (Some(v), Some(i)) = (tuple.get(0), tuple.get(1)) {
if let Some(i) = i.get().as_any().downcast_ref::<data::int::Int>() {
if let Ok(i) = i.0.try_into() {
if let Some(v) = v.get().get(i) {
Data::one_tuple(v)
} else {
Data::empty_tuple()
}
} else {
Data::empty_tuple()
}
} else {
unreachable!("get called with non-int index")
}
} else {
unreachable!("get called on tuple with len < 2")
}
} else {
unreachable!("get called on non-tuple, arg must be (_, index)")
}
}),
}),
)
pub fn new() -> Self {
Self {
globals: 0,
info_parsed: Default::default(),
info_run: Default::default(),
}
}
pub fn add_var(mut self, name: String, val: Data) -> Self {
@@ -187,7 +60,7 @@ impl Config {
self.globals += 1;
self
}
pub fn add_type(mut self, name: String, t: Type) -> Self {
pub fn add_type(self, _name: String, _t: Type) -> Self {
// TODO! needed for type syntax in the parser, everything else probably(?) works already
self
}

View File

@@ -0,0 +1,41 @@
use std::sync::Arc;
use crate::{
data::{self, Data},
program,
};
use super::Config;
impl Config {
/// `get: fn` is used to retrieve elements from collections
pub fn with_get(self) -> Self {
self.add_var(
"get".to_string(),
Data::new(data::function::Function {
info: program::run::Info::neverused(),
out: Arc::new(|_a| todo!()),
run: Arc::new(|a, _i| {
let a = a.get();
if let (Some(v), Some(i)) = (a.get(0), a.get(1)) {
if let Some(i) = i.get().as_any().downcast_ref::<data::int::Int>() {
if let Ok(i) = i.0.try_into() {
if let Some(v) = v.get().get(i) {
Data::one_tuple(v)
} else {
Data::empty_tuple()
}
} else {
Data::empty_tuple()
}
} else {
unreachable!("get called with non-int index")
}
} else {
unreachable!("get called with less than 2 args")
}
}),
}),
)
}
}

View File

@@ -10,6 +10,10 @@ use super::Config;
impl Config {
/// Adds functions to deal with iterables
/// `iter: fn` executes a function once for each element of the iterable
/// `map: fn` maps each value in the iterable to a new one by applying a transformation function
/// `filter: fn` filters the iterable by removing all elements where the filter function doesn't return true
/// `filter_map: fn` combines filter and map via matching
/// `enumerate: fn` transforms an iterator over T into one over (Int, T), where Int is the index of the element
pub fn with_iters(self) -> Self {
self.add_var(
"iter".to_string(),
@@ -113,6 +117,14 @@ impl Config {
}),
}),
)
.add_var(
"enumerate".to_string(),
Data::new(data::function::Function {
info: program::run::Info::neverused(),
out: Arc::new(|_a| todo!()),
run: Arc::new(|a, _i| Data::new(Iter(Iters::Enumerate, a.clone()))),
}),
)
}
}
@@ -121,6 +133,7 @@ pub enum Iters {
Map(data::function::Function),
Filter(data::function::Function),
FilterMap(data::function::Function),
Enumerate,
}
#[derive(Clone, Debug)]
pub struct Iter(Iters, Data);
@@ -152,6 +165,12 @@ impl MersData for Iter {
.filter_map(move |v| f.run(v).get().matches()),
)
}
Iters::Enumerate => Box::new(self.1.get().iterable()?.enumerate().map(|(i, v)| {
Data::new(data::tuple::Tuple(vec![
Data::new(data::int::Int(i as _)),
v,
]))
})),
_ => todo!(),
})
}

View File

@@ -0,0 +1,45 @@
use std::sync::Arc;
use crate::{
data::{self, Data},
program,
};
use super::Config;
impl Config {
/// `sum: fn` returns the sum of all the numbers in the tuple
pub fn with_math(self) -> Self {
self.add_var(
"sum".to_string(),
Data::new(data::function::Function {
info: program::run::Info::neverused(),
out: Arc::new(|_a| todo!()),
run: Arc::new(|a, _i| {
if let Some(i) = a.get().iterable() {
let mut sumi = 0;
let mut sumf = 0.0;
let mut usef = false;
for val in i {
if let Some(i) = val.get().as_any().downcast_ref::<data::int::Int>() {
sumi += i.0;
} else if let Some(i) =
val.get().as_any().downcast_ref::<data::float::Float>()
{
sumf += i.0;
usef = true;
}
}
if usef {
Data::new(data::float::Float(sumi as f64 + sumf))
} else {
Data::new(data::int::Int(sumi))
}
} else {
unreachable!("sum called on non-tuple")
}
}),
}),
)
}
}

View File

@@ -0,0 +1,73 @@
use std::sync::Arc;
use crate::{
data::{self, Data},
program,
};
use super::Config;
impl Config {
/// `println: fn` prints to stdout and adds a newline to the end
/// `print: fn` prints to stdout
/// `eprintln: fn` prints to stderr and adds a newline to the end
/// `eprint: fn` prints to stderr
/// `debug: fn` debug-prints any value
pub fn with_prints(self) -> Self {
self.add_var(
"debug".to_string(),
Data::new(data::function::Function {
info: program::run::Info::neverused(),
out: Arc::new(|_a| todo!()),
run: Arc::new(|a, _i| {
eprintln!("{:#?}", a.get());
Data::empty_tuple()
}),
}),
)
.add_var(
"eprint".to_string(),
Data::new(data::function::Function {
info: program::run::Info::neverused(),
out: Arc::new(|_a| todo!()),
run: Arc::new(|a, _i| {
eprint!("{}", a.get());
Data::empty_tuple()
}),
}),
)
.add_var(
"eprintln".to_string(),
Data::new(data::function::Function {
info: program::run::Info::neverused(),
out: Arc::new(|_a| todo!()),
run: Arc::new(|a, _i| {
eprintln!("{}", a.get());
Data::empty_tuple()
}),
}),
)
.add_var(
"print".to_string(),
Data::new(data::function::Function {
info: program::run::Info::neverused(),
out: Arc::new(|_a| todo!()),
run: Arc::new(|a, _i| {
print!("{}", a.get());
Data::empty_tuple()
}),
}),
)
.add_var(
"println".to_string(),
Data::new(data::function::Function {
info: program::run::Info::neverused(),
out: Arc::new(|_a| todo!()),
run: Arc::new(|a, _i| {
println!("{}", a.get());
Data::empty_tuple()
}),
}),
)
}
}

View File

@@ -1,3 +1,6 @@
/// generates `Info`s required to compile and then run a program
pub mod configs;
/// used to represent a parsed program
pub mod parsed;
/// used to represent an executable program
pub mod run;

View File

@@ -2,16 +2,27 @@ use std::{collections::HashMap, fmt::Debug};
use crate::info;
#[cfg(feature = "parse")]
pub mod assign_to;
#[cfg(feature = "parse")]
pub mod block;
#[cfg(feature = "parse")]
pub mod chain;
#[cfg(feature = "parse")]
pub mod function;
#[cfg(feature = "parse")]
pub mod r#if;
#[cfg(feature = "parse")]
pub mod init_to;
#[cfg(feature = "parse")]
pub mod r#loop;
#[cfg(feature = "parse")]
pub mod switch;
#[cfg(feature = "parse")]
pub mod tuple;
#[cfg(feature = "parse")]
pub mod value;
#[cfg(feature = "parse")]
pub mod variable;
pub trait MersStatement: Debug {

View File

@@ -5,15 +5,25 @@ use crate::{
info,
};
#[cfg(feature = "run")]
pub mod assign_to;
#[cfg(feature = "run")]
pub mod block;
#[cfg(feature = "run")]
pub mod chain;
#[cfg(feature = "run")]
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 {