Add cli option for optimization

This commit is contained in:
Dominic Grimm 2022-09-10 10:43:29 +02:00
parent 17eaeb1a2f
commit d27acb2fa7
No known key found for this signature in database
GPG key ID: A6C051C716D2CE65
3 changed files with 17 additions and 9 deletions

View file

@ -1 +1,2 @@
random . cr depth dup dup dup dup dup debug

View file

@ -30,6 +30,8 @@ enum Commands {
src: String, src: String,
#[clap(value_parser)] #[clap(value_parser)]
out: Option<String>, out: Option<String>,
#[clap(short, long, action)]
optimize: Option<bool>,
#[clap(long, action)] #[clap(long, action)]
dump: bool, dump: bool,
}, },
@ -53,11 +55,16 @@ fn main() -> Result<()> {
Ok(()) Ok(())
} }
Commands::Compile { src, out, dump } => { Commands::Compile {
src,
out,
optimize,
dump,
} => {
let source = fs::read_to_string(&src)?; let source = fs::read_to_string(&src)?;
let tokens = lexer::lex(source)?; let tokens = lexer::lex(source)?;
let ast = parser::parse(tokens)?; let ast = parser::parse(tokens)?;
let ast = compiler::compile(ast)?; let ast = compiler::compile(ast, optimize.unwrap_or(true))?;
let assembly = ast.to_code(); let assembly = ast.to_code();
if let Some(x) = out { if let Some(x) = out {

View file

@ -33,16 +33,16 @@ impl Data {
} }
} }
pub fn generate_instructions(&mut self, body: parser::ast::Body) -> Result<Vec<Instruction>> { pub fn generate_instructions(&mut self, body: parser::ast::Body, optimize: bool) -> Result<Vec<Instruction>> {
let mut instructions: Vec<Instruction> = vec![]; let mut instructions: Vec<Instruction> = vec![];
let mut iter = body.into_iter().peekable(); let mut iter = body.into_iter().peekable();
while let Some(node) = iter.next() { while let Some(node) = iter.next() {
match node { match node {
_ if iter.next_if_eq(&node).is_some() => { _ if optimize && iter.next_if_eq(&node).is_some() => {
let count = iter.by_ref().peeking_take_while(|n| *n == node).count() + 2; let count = iter.by_ref().peeking_take_while(|n| *n == node).count() + 2;
instructions.push(Instruction::Multiple { instructions.push(Instruction::Multiple {
instruction: Box::new( instruction: Box::new(
self.generate_instructions(vec![node])? self.generate_instructions(vec![node], optimize)?
.into_iter() .into_iter()
.next() .next()
.unwrap(), .unwrap(),
@ -75,7 +75,7 @@ impl Data {
bail!("Word already exists as user word definition: {}", name); bail!("Word already exists as user word definition: {}", name);
} }
let ins = self.generate_instructions(body)?; let ins = self.generate_instructions(body, optimize)?;
self.words.insert( self.words.insert(
name, name,
@ -326,9 +326,9 @@ impl Data {
} }
} }
pub fn compile(ast: parser::ast::AST) -> Result<hence::parser::ast::AST> { pub fn compile(ast: parser::ast::AST, optimize: bool) -> Result<hence::parser::ast::AST> {
let mut data = Data::default(); let mut data = Data::default();
let instructions = data.generate_instructions(ast.body)?; let instructions = data.generate_instructions(ast.body, optimize)?;
Ok(hence::parser::ast::AST { Ok(hence::parser::ast::AST {
body: data.embed( body: data.embed(