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 {
|
2023-11-18 13:09:30 -07:00
|
|
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-18 13:09:30 -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,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-18 13:09:30 -07:00
|
|
|
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,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-18 13:09:30 -07:00
|
|
|
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,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-18 13:09:30 -07:00
|
|
|
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,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-18 13:09:30 -07:00
|
|
|
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,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-18 13:09:30 -07:00
|
|
|
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,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-18 13:09:30 -07:00
|
|
|
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,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-18 13:09:30 -07:00
|
|
|
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,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-18 13:09:30 -07:00
|
|
|
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,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-18 13:09:30 -07:00
|
|
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-18 13:09:30 -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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-18 13:09:30 -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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-18 13:09:30 -07:00
|
|
|
impl Dev {
|
|
|
|
fn verify(&self) -> Result<(), String> {
|
|
|
|
Ok(())
|
2023-11-16 14:59:51 -07:00
|
|
|
}
|
|
|
|
}
|