1
1
Fork 0
mirror of https://github.com/azur1s/bobbylisp.git synced 2024-10-16 02:37:40 -05:00

bool -> stdbool, refactor emit

This commit is contained in:
Natapat Samutpong 2022-02-24 21:59:21 +07:00
parent 39b79b8c61
commit 5809a4949f
2 changed files with 24 additions and 22 deletions

View file

@ -1,9 +1,16 @@
use std::fmt::Display;
use crate::front::parse::Expr; use crate::front::parse::Expr;
pub struct Codegen { pub struct Codegen {
pub emitted: String, pub emitted: String,
} }
const HEADER_INCLUDES: [&str; 2] = [
"#include <stdio.h>",
"#include <hycron/stdbool.h>",
];
impl Codegen { impl Codegen {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
@ -11,33 +18,30 @@ impl Codegen {
} }
} }
fn emit(&mut self, s: String) { fn emit<T: Display>(&mut self, s: T) {
self.emitted.push_str(s.as_str()); self.emitted.push_str(&s.to_string());
}
fn emit_str(&mut self, s: &str) {
self.emitted.push_str(s);
} }
pub fn gen(&mut self, exprs: &[Expr]) { pub fn gen(&mut self, exprs: &[Expr]) {
self.emit_str("#include <stdio.h>\n"); for header in HEADER_INCLUDES.iter() {
self.emit_str("#include <hycron/bool.h>\n"); self.emit(header);
self.emit_str("int main() {\n"); }
self.emit("int main() {");
for expr in exprs { for expr in exprs {
self.gen_expr(expr); self.gen_expr(expr);
} }
self.emit_str("return 0;\n"); self.emit("return 0;");
self.emit_str("}\n"); self.emit("}");
} }
fn gen_expr(&mut self, expr: &Expr) { fn gen_expr(&mut self, expr: &Expr) {
match expr { match expr {
Expr::Let { name, value } => { Expr::Let { name, value } => {
match &**value { match &**value {
Expr::Int(i) => self.emit(format!("int {} = {};\n", name, i)), Expr::Int(i) => self.emit(format!("int {} = {};", name, i)),
Expr::Float(f) => self.emit(format!("double {} = {};\n", name, f)), Expr::Float(f) => self.emit(format!("double {} = {};", name, f)),
Expr::Boolean(b) => self.emit(format!("bool {} = {};\n", name, b)), Expr::Boolean(b) => self.emit(format!("bool {} = {};", name, b)),
Expr::String(s) => self.emit(format!("char *{} = \"{}\";\n", name, s)), Expr::String(s) => self.emit(format!("char *{} = \"{}\";", name, s)),
_ => todo!(), _ => todo!(),
} }
}, },
@ -46,7 +50,7 @@ impl Codegen {
Expr::Ident(func) => { Expr::Ident(func) => {
match func.as_str() { match func.as_str() {
"print" => { "print" => {
self.emit(format!("printf({});\n", match &args[0] { self.emit(format!("printf({});", match &args[0] {
Expr::String(s) => format!("\"{}\"", s), Expr::String(s) => format!("\"{}\"", s),
Expr::Ident(s) => format!("\"%s\", {}", s), Expr::Ident(s) => format!("\"%s\", {}", s),
_ => todo!(), _ => todo!(),
@ -59,20 +63,18 @@ impl Codegen {
} }
}, },
Expr::If { cond, then, else_ } => { Expr::If { cond, then, else_ } => {
self.emit("if ".to_string()); self.emit("if (".to_string());
self.gen_expr(&cond); self.gen_expr(&cond);
self.emit(" {\n".to_string()); self.emit(") {".to_string());
self.gen_expr(&then); self.gen_expr(&then);
self.emit("} else {\n".to_string()); self.emit("} else {".to_string());
self.gen_expr(&else_); self.gen_expr(&else_);
self.emit("}\n".to_string()); self.emit("}".to_string());
}, },
Expr::Binary { left, op, right } => { Expr::Binary { left, op, right } => {
self.emit("(".to_string());
self.gen_expr(&left); self.gen_expr(&left);
self.emit(format!(" {} ", op.to_string())); self.emit(format!(" {} ", op.to_string()));
self.gen_expr(&right); self.gen_expr(&right);
self.emit(")".to_string());
}, },
Expr::Ident(s) => self.emit(s.to_string()), Expr::Ident(s) => self.emit(s.to_string()),
Expr::Boolean(b) => self.emit(format!("{}", b)), Expr::Boolean(b) => self.emit(format!("{}", b)),