Compare commits
2 commits
f9e4e554b6
...
fb2866223a
Author | SHA1 | Date | |
---|---|---|---|
Akemi Izuko | fb2866223a | ||
Akemi Izuko | 4006e0778c |
|
@ -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]
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(¶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)
|
||||
|
|
Loading…
Reference in a new issue