diff --git a/src/compiler/backend/mod.rs b/src/compiler/backend/mod.rs index 598914c..5b6ada9 100644 --- a/src/compiler/backend/mod.rs +++ b/src/compiler/backend/mod.rs @@ -330,11 +330,44 @@ fn match_number(s: &str) -> Number { } } +fn compile_biop( + op: &str, + lst: &mut Vec, + vars: &mut Vec<(String, String)>, + constants: &mut Vec<(String, String)>, + types: &mut Vec, + counter: &mut i32, + stack: &mut Vec, + out: &mut Vec<(Option, String)>, +) { + assert!(lst.len() == 2); + let rhs = lst.pop().unwrap(); + let lhs = lst.pop().unwrap(); + compile_ast_ssa(lhs, vars, constants, types, counter, stack, out); + compile_ast_ssa(rhs, vars, constants, types, counter, stack, out); + let rhs_id = stack.pop().unwrap(); + let lhs_id = stack.pop().unwrap(); + let id = String::from(counter.to_string()); + *counter += 1; + out.push(( + Some(id.clone()), + format!( + "{} {} {} {}", + op, + fix_name(&String::from("f32")), + fix_name(&lhs_id), + fix_name(&rhs_id), + ), + )); + stack.push(id); +} + pub fn compile_ast_ssa( ast: Ast, vars: &mut Vec<(String, String)>, constants: &mut Vec<(String, String)>, - counter: &mut Box, + types: &mut Vec, + counter: &mut i32, stack: &mut Vec, out: &mut Vec<(Option, String)>, ) { @@ -352,8 +385,8 @@ pub fn compile_ast_ssa( assert!(lst.len() == 2); let ptr = lst.pop().unwrap(); let val = lst.pop().unwrap(); - compile_ast_ssa(ptr, vars, constants, counter, stack, out); - compile_ast_ssa(val, vars, constants, counter, stack, out); + compile_ast_ssa(ptr, vars, constants, types, counter, stack, out); + compile_ast_ssa(val, vars, constants, types, counter, stack, out); let val_id = stack.pop().unwrap(); let ptr_id = stack.pop().unwrap(); out.push(( @@ -361,6 +394,18 @@ pub fn compile_ast_ssa( format!("OpStore {} {}", fix_name(&val_id), fix_name(&ptr_id)), )); } + "/" => { + compile_biop("OpFDiv", &mut lst, vars, constants, types, counter, stack, out); + } + "*" => { + compile_biop("OpFMul", &mut lst, vars, constants, types, counter, stack, out); + } + "+" => { + compile_biop("OpFAdd", &mut lst, vars, constants, types, counter, stack, out); + } + "-" => { + compile_biop("OpFSub", &mut lst, vars, constants, types, counter, stack, out); + } s => { panic!( "Unknown function: {} with params {:#?} in context:\n{:#?}", @@ -382,7 +427,7 @@ pub fn compile_ast_ssa( contains = true; } } - if contains { + if !contains { constants.push((key.clone(), format!("OpConstant %i32 {}", i.to_string()))); } stack.push(key); @@ -395,9 +440,17 @@ pub fn compile_ast_ssa( contains = true; } } - if contains { + if !contains { constants.push((key.clone(), format!("OpConstant %f32 {}", f.to_string()))); } + for t in types.iter() { + if t == "f32" { + contains = true; + } + } + if !contains { + types.push("f32".to_string()); + } stack.push(key); } Number::NotANumber => { diff --git a/src/compiler/backend/tests.rs b/src/compiler/backend/tests.rs index 15164f9..b8e775c 100644 --- a/src/compiler/backend/tests.rs +++ b/src/compiler/backend/tests.rs @@ -62,7 +62,7 @@ fn test_block_ssa() { (dec out-color:*f32 Output) (entry main Fragment OriginUpperLeft (:out-color)) (fun (main) :<> - (store-ptr out-color 1.0)) + (store-ptr out-color (/ 1.0 (+ 1.0 1.0)))) "; let ast = parse(tokenize(src)); let mut module = meta_compile(ast.unwrap()).unwrap(); @@ -72,6 +72,7 @@ fn test_block_ssa() { println!("{:#?}", block); let mut vars = vec![]; let mut constants = vec![]; + let mut types = vec![]; let mut counter = Box::new(0); let mut stack = vec![]; let mut out = vec![]; @@ -82,20 +83,23 @@ fn test_block_ssa() { block, &mut vars, &mut constants, + &mut types, &mut counter, &mut stack, &mut out, ); - println!("\n---constants:---\n{:#?}\n------", constants); - println!("\n---vars:---\n{:#?}\n------", vars); - println!("\n---stack:---\n{:#?}\n------", stack); - println!("\n---counter---\n{}\n------", counter); - println!("\n---out---"); + println!("\n---vars:---\n{:#?}\n-----------", vars); + println!("\n---constants:---\n{:#?}\n----------------", constants); + println!("\n---types:---\n{:#?}\n------------", types); + println!("\n---stack:---\n{:#?}\n------------", stack); + println!("\n---counter:---\n{}\n--------------", counter); + println!("\n---out:---"); for (a, b) in &out { match a { Some(a) => println!("%{} = {}", a, b), None => println!("{}", b), } } - println!("------"); + println!("----------"); + assert!(stack.is_empty()); }