walpurgis/src/params.rs

357 lines
7.8 KiB
Rust
Raw Normal View History

2023-11-16 14:59:51 -07:00
use std::fs;
use std::path::PathBuf;
use serde::Deserialize;
2023-11-18 01:12:52 -07:00
/// Additive less than. Updates probability after comparing
pub fn a_lt(p: &mut f64, additive: f64) -> bool {
let is_lt = *p < additive;
*p -= additive;
is_lt
}
2023-11-16 14:59:51 -07:00
// Makes all these structs public and deserializable
macro_rules! toml_struct {
(struct $name:ident {$($field:ident: $t:ty,)*}) => {
#[derive(Deserialize, Clone)]
pub struct $name {
$(pub $field: $t),*
}
}
}
toml_struct!{
struct Params {
verify_config: bool,
2023-11-16 14:59:51 -07:00
global_flow: GlobalFlow,
statements: Statments,
types: Types,
2023-11-16 21:22:48 -07:00
dev: Dev,
2023-11-16 14:59:51 -07:00
}
}
impl Params {
pub fn parse(p: &PathBuf) -> Self {
let file_string = fs::read_to_string(p)
.expect("Failed to read parameters file into string");
let params: Params = toml::from_str(&file_string)
.expect("Failed to parse TOML from parameters file");
params
}
pub fn verify(&self) -> Result<(), String> {
let global_flow = self.global_flow.verify();
let statements = self.statements.verify();
let types = self.types.verify();
let dev = self.dev.verify();
if global_flow.is_err() {
global_flow
} else if statements.is_err() {
statements
} else if types.is_err() {
types
} else if dev.is_err() {
dev
} else {
Ok(())
}
}
}
2023-11-16 14:59:51 -07:00
toml_struct!{
struct GlobalFlow {
gen_decl: f64,
gen_subroutine: f64,
gen_typedef: f64,
end_generation: f64,
}
}
impl GlobalFlow {
fn verify(&self) -> Result<(), String> {
let sum = self.gen_decl + self.gen_subroutine + self.gen_typedef + self.end_generation;
if (sum - 1.0).abs() > f64::EPSILON {
Err(format!("global_flow probability sum is = {}", sum))
} else {
Ok(())
}
}
}
2023-11-16 14:59:51 -07:00
toml_struct!{
struct Statments {
gen_assign: GenAssign,
gen_decl: GenDecl,
gen_global_decl: GenGlobalDecl,
gen_if_statement: GenIfStatement,
gen_loop: GenLoop,
}
}
impl Statments {
fn verify(&self) -> Result<(), String> {
let gen_assign = self.gen_assign.verify();
let gen_decl = self.gen_decl.verify();
let gen_global_decl = self.gen_global_decl.verify();
let gen_if_statement = self.gen_if_statement.verify();
let gen_loop = self.gen_loop.verify();
if gen_assign.is_err() {
gen_assign
} else if gen_decl.is_err() {
gen_decl
} else if gen_global_decl.is_err() {
gen_global_decl
} else if gen_if_statement.is_err() {
gen_if_statement
} else if gen_loop.is_err() {
gen_loop
} else {
Ok(())
}
}
}
2023-11-16 14:59:51 -07:00
toml_struct!{
struct GenAssign {
gen_boolean: f64,
gen_character: f64,
gen_integer: f64,
gen_real: f64,
gen_tuple: f64,
}
}
impl GenAssign {
fn verify(&self) -> Result<(), String> {
Ok(())
}
}
2023-11-16 14:59:51 -07:00
toml_struct!{
struct GenDecl {
gen_boolean: f64,
gen_character: f64,
gen_integer: f64,
gen_real: f64,
gen_tuple: f64,
qual_const: f64,
qual_var: f64,
}
}
impl GenDecl {
fn verify(&self) -> Result<(), String> {
let sum_type = self.gen_boolean
+ self.gen_character
+ self.gen_integer
+ self.gen_real
+ self.gen_tuple;
let sum_qual = self.qual_const + self.qual_var;
if (sum_type - 1.0).abs() > f64::EPSILON {
Err(format!("statements.gen_decl probability sum for types is = {}", sum_type))
} else if (sum_qual - 1.0).abs() > f64::EPSILON {
Err(format!("statements.gen_decl probability sum for qualifiers is = {}", sum_qual))
} else {
Ok(())
}
}
}
2023-11-16 14:59:51 -07:00
toml_struct!{
struct GenGlobalDecl {
gen_boolean: f64,
gen_character: f64,
gen_integer: f64,
gen_real: f64,
gen_tuple: f64,
}
}
impl GenGlobalDecl {
fn verify(&self) -> Result<(), String> {
Ok(())
}
}
2023-11-16 14:59:51 -07:00
toml_struct!{
struct GenIfStatement {
gen_statement: f64,
end_gen_statement: f64,
fork_elif: f64,
fork_else: f64,
fork_end: f64,
}
}
impl GenIfStatement {
fn verify(&self) -> Result<(), String> {
Ok(())
}
}
2023-11-16 14:59:51 -07:00
toml_struct!{
struct GenLoop {
gen_inf_loop: f64,
gen_cond_loop: f64,
gen_statement: f64,
end_gen_statement: f64,
}
}
impl GenLoop {
fn verify(&self) -> Result<(), String> {
Ok(())
}
}
2023-11-16 14:59:51 -07:00
toml_struct!{
struct Types {
gen_boolean: GenBoolean,
gen_integer: GenInteger,
gen_real: GenReal,
}
}
impl Types {
fn verify(&self) -> Result<(), String> {
let gen_boolean = self.gen_boolean.verify();
let gen_integer = self.gen_integer.verify();
let gen_real = self.gen_real.verify();
if gen_boolean.is_err() {
gen_boolean
} else if gen_integer.is_err() {
gen_integer
} else if gen_real.is_err() {
gen_real
} else {
Ok(())
}
}
}
2023-11-16 14:59:51 -07:00
toml_struct!{
struct GenBoolean {
expr_and: f64,
expr_or: f64,
expr_not: f64,
expr_gt: f64,
expr_ge: f64,
expr_lt: f64,
expr_le: f64,
expr_eq: f64,
expr_eq_real: f64,
expr_eq_char: f64,
expr_eq_tuple: f64,
expr_ne: f64,
expr_ne_real: f64,
expr_ne_char: f64,
expr_ne_tuple: f64,
get_instant: f64,
}
}
impl GenBoolean {
fn verify(&self) -> Result<(), String> {
Ok(())
}
}
2023-11-16 14:59:51 -07:00
toml_struct!{
struct GenInteger {
expr_add: f64,
expr_sub: f64,
expr_mul: f64,
expr_div: f64,
expr_rem: f64,
expr_exp: f64,
expr_pos: f64,
expr_neg: f64,
get_instant: f64,
2023-11-18 00:14:44 -07:00
max_depth: u32,
2023-11-16 14:59:51 -07:00
}
}
impl GenInteger {
fn verify(&self) -> Result<(), String> {
let sum = self.expr_add
+ self.expr_sub
+ self.expr_mul
+ self.expr_div
+ self.expr_rem
+ self.expr_exp
+ self.expr_pos
+ self.expr_neg
+ self.get_instant;
if self.max_depth <= 0 {
Err("types.gen_integer.max_depth must be at least 1".to_string())
} else if (sum - 1.0).abs() > f64::EPSILON {
Err(format!("types.gen_integer probability sum is = {}", sum))
} else {
Ok(())
}
}
}
2023-11-16 14:59:51 -07:00
toml_struct!{
struct GenReal {
expr_add: f64,
expr_sub: f64,
expr_mul: f64,
expr_div: f64,
expr_rem: f64,
expr_exp: f64,
expr_pos: f64,
expr_neg: f64,
gen_integer: f64,
get_instant: f64,
2023-11-18 00:28:55 -07:00
max_depth: u32,
2023-11-16 14:59:51 -07:00
}
}
impl GenReal {
fn verify(&self) -> Result<(), String> {
let sum = self.expr_add
+ self.expr_sub
+ self.expr_mul
+ self.expr_div
+ self.expr_rem
+ self.expr_exp
+ self.expr_pos
+ self.expr_neg
+ self.gen_integer
+ self.get_instant;
if self.max_depth <= 0 {
Err("types.gen_real.max_depth must be at least 1".to_string())
} else if (sum - 1.0).abs() > f64::EPSILON {
Err(format!("types.gen_real probability sum is = {}", sum))
} else {
Ok(())
}
}
}
2023-11-16 21:22:48 -07:00
toml_struct!{
struct Dev {
float_gen_distro_pos_stddiv: f32,
float_gen_distro_neg_stddiv: f32,
2023-11-16 21:47:27 -07:00
int_gen_distro_pos_stddiv: f32,
int_gen_distro_neg_stddiv: f32,
2023-11-16 21:22:48 -07:00
}
}
impl Dev {
fn verify(&self) -> Result<(), String> {
Ok(())
2023-11-16 14:59:51 -07:00
}
}