Add cli option for optimization
This commit is contained in:
parent
17eaeb1a2f
commit
d27acb2fa7
3 changed files with 17 additions and 9 deletions
|
@ -1 +1,2 @@
|
||||||
random . cr
|
depth dup dup dup dup dup debug
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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(
|
||||||
|
|
Loading…
Reference in a new issue