Initial work on function compilation API for the frontend

Also one forgotten cargo fmt
master
itycodes 2 weeks ago
parent ac6ed71482
commit 7382e9185f

@ -1,7 +1,7 @@
#[cfg(test)]
mod tests;
use crate::compiler::Module;
use crate::compiler::{Instruction, Module};
use std::fmt;
use std::fmt::Write;
@ -395,16 +395,24 @@ pub fn compile_ast_ssa(
));
}
"/" => {
compile_biop("OpFDiv", &mut lst, vars, constants, types, counter, stack, out);
compile_biop(
"OpFDiv", &mut lst, vars, constants, types, counter, stack, out,
);
}
"*" => {
compile_biop("OpFMul", &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(
"OpFAdd", &mut lst, vars, constants, types, counter, stack, out,
);
}
"-" => {
compile_biop("OpFSub", &mut lst, vars, constants, types, counter, stack, out);
compile_biop(
"OpFSub", &mut lst, vars, constants, types, counter, stack, out,
);
}
s => {
panic!(
@ -466,3 +474,61 @@ pub fn compile_ast_ssa(
}
}
}
pub fn compile_fun_ssa(module: &mut Module) {
for fun in module.functions.iter_mut() {
assert!(fun.ast.is_some());
let ast = fun.ast.as_mut().unwrap();
let block = ast.clone().list().unwrap().get(0).unwrap().clone();
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_op = vec![];
for v in &module.globals {
vars.push((v.name.clone(), v.typ.clone()));
}
compile_ast_ssa(
block,
&mut vars,
&mut constants,
&mut types,
&mut counter,
&mut stack,
&mut out_op,
);
let mut out_pre = vec![];
for t in &types {
let typ = parse_type(t);
let mut type_ops = vec![];
emit_type(typ, &mut type_ops);
for type_op in type_ops {
out_pre.push((Some(type_op.0), type_op.1));
}
}
for c in &constants {
out_pre.push((Some(fix_name(&c.0.clone())), c.1.clone()));
}
let mut out_ops = out_pre.clone();
for op in out_op {
if op.0.is_some() {
out_ops.push((Some(fix_name(&op.0.unwrap())), op.1));
} else {
out_ops.push((None, op.1));
}
}
for op in out_ops {
let split: Vec<String> = op.1.split(" ").map(|s| s.to_string()).collect();
let op_name: String = (&split[0]).clone();
let op_args: Vec<String> = split[1..].iter().map(|s| s.clone()).collect();
let op_id = op.0.clone();
let ins: Instruction = Instruction {
result_id: op_id,
op: op_name,
operands: op_args,
};
fun.body.as_mut().unwrap().push(ins);
}
}
}

@ -103,3 +103,58 @@ fn test_block_ssa() {
println!("----------");
assert!(stack.is_empty());
}
#[test]
fn test_fun_ssa() {
use crate::compiler::backend::*;
use crate::compiler::*;
use crate::parser::*;
let src = "
(module Shader Logical GLSL450)
(import :std GLSL.std.450)
(bind (out-color:*f32) (Location 0))
(dec out-color:*f32 Output)
(entry main Fragment OriginUpperLeft (:out-color))
(fun (main) :<>
(store-ptr out-color (/ 1.0 (+ 1.0 1.0))))
";
let ast = parse(tokenize(src));
let mut module = meta_compile(ast.unwrap()).unwrap();
compile_fun_ssa(&mut module);
let res = module.functions.pop().unwrap();
let res = res.body.unwrap();
println!("{:#?}", res);
// TODO we need to unify the place where we call fix_name
let res_spv: Vec<Instruction> = vec![
Instruction {
result_id: Some("%f32".to_string()),
op: "OpTypeFloat".to_string(),
operands: vec!["32".to_string()],
},
Instruction {
result_id: Some("%f32_1".to_string()),
op: "OpConstant".to_string(),
operands: vec!["%f32".to_string(), "1".to_string()],
},
Instruction {
result_id: Some("%0".to_string()),
op: "OpFAdd".to_string(),
operands: vec![
"%f32".to_string(),
"%f32_1".to_string(),
"%f32_1".to_string(),
],
},
Instruction {
result_id: Some("%1".to_string()),
op: "OpFDiv".to_string(),
operands: vec!["%f32".to_string(), "%f32_1".to_string(), "%0".to_string()],
},
Instruction {
result_id: None,
op: "OpStore".to_string(),
operands: vec!["%out_color".to_string(), "%1".to_string()],
},
];
assert_eq!(res, res_spv);
}

Loading…
Cancel
Save