Compare commits

...

2 commits

Author SHA1 Message Date
Akemi Izuko fb2866223a
AstBuilder: typedef statements
All checks were successful
ci/woodpecker/push/build_rust Pipeline was successful
2023-11-17 15:32:12 -07:00
Akemi Izuko 4006e0778c
Ast: typedef statements 2023-11-17 15:31:47 -07:00
4 changed files with 72 additions and 17 deletions

View file

@ -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]

View file

@ -14,6 +14,8 @@ pub use statement::Block;
pub use statement::GlobalBlock;
pub use statement::Declaration;
pub use statement::DeclarationBuilder;
pub use statement::TypeDef;
pub use statement::TypeDefBuilder;
pub trait GazType {
fn get_base(&self) -> BaseType;

View file

@ -9,6 +9,7 @@ use super::GazType;
pub enum Stat {
Block(Box<Block>),
Declaration(Box<Declaration>),
TypeDef(Box<TypeDef>),
}
impl Stat {
@ -19,6 +20,10 @@ impl Stat {
pub fn new_decl(x: Declaration) -> Self {
Self::Declaration(Box::new(x))
}
pub fn new_typedef(x: TypeDef) -> Self {
Self::TypeDef(Box::new(x))
}
}
impl ToString for Stat {
@ -26,6 +31,7 @@ impl ToString for Stat {
match self {
Stat::Block(x) => x.to_string(),
Stat::Declaration(x) => x.to_string(),
Stat::TypeDef(x) => x.to_string(),
}
}
}
@ -101,3 +107,21 @@ impl ToString for Declaration {
s
}
}
#[derive(Clone, Default, Builder)]
pub struct TypeDef {
old_name: String,
new_name: String,
basetype: BaseType,
}
impl ToString for TypeDef {
fn to_string(&self) -> String {
let mut s = String::from("typedef ");
s.push_str(&self.old_name);
s.push(' ');
s.push_str(&self.new_name);
s.push(';');
s
}
}

View file

@ -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<String, BaseType>,
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(&params),
rng_int: IntGenerator::new(&params),
@ -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)