|
|
|
@ -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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|