diff --git a/params.toml b/params.toml index 24c02fc..dc8d0ed 100644 --- a/params.toml +++ b/params.toml @@ -1,7 +1,7 @@ [global_flow] - gen_decl = 0.7 + gen_decl = 0.5 gen_subroutine = 0.0 - gen_typedef = 0.0 + gen_typedef = 0.4 end_generation = 0.1 [statements] diff --git a/src/ast_builder.rs b/src/ast_builder.rs index 52c637c..bd683bb 100644 --- a/src/ast_builder.rs +++ b/src/ast_builder.rs @@ -1,26 +1,18 @@ use rand::Rng; +use rand::seq::SliceRandom; use rand_distr::Distribution; +use std::collections::HashMap; use crate::params::Params; -use crate::ast::{ - Expr, - Stat, - Quantifier, - BaseType, - GlobalBlock, - Block, - Literal, - Declaration, - DeclarationBuilder, - Variable, - VariableBuilder, - BinaryOperator, -}; +use crate::ast::*; pub struct AstBuilder { params: Params, ast: GlobalBlock, name_counter: u64, + typedef_map: HashMap, + typedef_vec: Vec<(String, BaseType)>, + // Random generation rng: rand::rngs::ThreadRng, rng_float: FloatGenerator, rng_int: IntGenerator, @@ -28,9 +20,19 @@ pub struct AstBuilder { impl AstBuilder { pub fn from(params: Params) -> Self { + let mut typedef_map = HashMap::new(); + let mut typedef_vec = Vec::new(); + + typedef_map.insert("integer".to_string(), BaseType::Int); + typedef_map.insert("real".to_string(), BaseType::Real); + typedef_vec.push(("integer".to_string(), BaseType::Int)); + typedef_vec.push(("real".to_string(), BaseType::Real)); + Self { ast: GlobalBlock::default(), name_counter: 0, + typedef_map, + typedef_vec, rng: rand::thread_rng(), rng_float: FloatGenerator::new(¶ms), rng_int: IntGenerator::new(¶ms), @@ -41,11 +43,17 @@ impl AstBuilder { pub fn generate(&mut self) { let mut p: f64; + let p1 = self.params.global_flow.end_generation; + let p2 = p1 + self.params.global_flow.gen_typedef; + loop { p = self.rng.gen(); - if p < self.params.global_flow.end_generation { + if p < p1 { break; + } else if p < p2 { + let typedef = self.gen_typedef(); + self.ast.push(typedef); } else { let decl = self.gen_decl(); self.ast.push(decl); @@ -79,6 +87,27 @@ impl AstBuilder { ) } + fn gen_typedef(&mut self) -> Stat { + let new_name = self.gen_name(); + let (old_name, basetype) = self.typedef_vec + .as_slice() + .choose(&mut self.rng) + .unwrap() + .clone(); + + self.typedef_map.insert(new_name.clone(), basetype); + self.typedef_vec.push((new_name.clone(), basetype)); + + Stat::new_typedef( + TypeDefBuilder::default() + .old_name(old_name) + .new_name(new_name) + .basetype(basetype) + .build() + .unwrap() + ) + } + fn gen_variable_quantified(&mut self, t: BaseType, q: Quantifier) -> Variable { VariableBuilder::default() .type_(t)