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

fun, return, do

This commit is contained in:
Natapat Samutpong 2022-03-07 15:47:03 +07:00
parent dccbe7c17c
commit 9f4cf84f34
3 changed files with 43 additions and 10 deletions

View file

@ -2,6 +2,12 @@ use std::fmt::Display;
use hir::{IR, IRKind, Value};
const MODULE_INCLUDES: [&str; 3] = [
"<stdbool.h>",
"<iostream>",
"<string>",
];
pub struct Codegen {
pub emitted: String,
}
@ -16,14 +22,12 @@ impl Codegen {
}
pub fn gen(&mut self, irs: Vec<IR>) {
self.emit("#include <stdbool.h>\n");
self.emit("#include <iostream>\n");
self.emit("#include <string>\n");
self.emit("int main() {\n");
for module in MODULE_INCLUDES {
self.emit(format!("#include {}\n", module));
}
for ir in irs {
self.emit(&self.gen_ir(&ir.kind));
}
self.emit("}");
}
fn gen_ir(&self, ir: &IRKind) -> String {
@ -38,6 +42,21 @@ impl Codegen {
_ => format!("{}({});\n", name, args.iter().map(|arg| self.gen_ir(arg)).collect::<Vec<_>>().join(", ")),
}
},
IRKind::Fun { name, return_type_hint, args, body } => {
let args = args.iter().map(|arg| format!("{} {}", arg.1, arg.0)).collect::<Vec<_>>().join(", ");
format!("{} {}({}) {{\n{}}}\n", return_type_hint, name, args, self.gen_ir(body))
},
IRKind::Return { value } => {
format!("return {};\n", self.gen_ir(value))
},
IRKind::Do { body } => {
let mut out = String::new();
for expr in body {
out.push_str(&self.gen_ir(&expr));
}
out
}
IRKind::Value { value } => {
match value {
Value::Int(value) => format!("{}", value),

View file

@ -9,10 +9,11 @@ pub enum IRKind {
Define { name: String, type_hint: String, value: Box<Self> },
Fun { name: String, return_type_hint: String, args: Vec<(String, String)>, body: Box<Self> },
Call { name: String, args: Vec<Self> },
Do { body: Box<Self> },
Do { body: Vec<Self> },
If { cond: Box<Self>, body: Box<Self>, else_body: Box<Self> },
Value { value: Value },
Binary { op: String, left: Box<Self>, right: Box<Self> },
Return { value: Box<Self> },
}
#[derive(Debug)]
@ -51,6 +52,19 @@ pub fn expr_to_ir(expr: &Expr) -> IRKind {
let args = args.0.iter().map(|arg| expr_to_ir(&arg.0)).collect::<Vec<_>>();
IRKind::Call { name, args }
},
Expr::Fun { name, type_hint, args, body } => {
let args = args.0.iter().map(|arg| (arg.0.0.clone(), gen_type_hint(&arg.1.0))).collect::<Vec<_>>();
let body = expr_to_ir(&body.0);
IRKind::Fun { name: name.to_string(), return_type_hint: gen_type_hint(type_hint), args, body: Box::new(body) }
},
Expr::Return { expr } => {
let expr = expr_to_ir(&expr.0);
IRKind::Return { value: Box::new(expr) }
},
Expr::Do { body } => {
let body = body.iter().map(|expr| expr_to_ir(&expr.0)).collect::<Vec<_>>();
IRKind::Do { body }
},
Expr::Int(value) => IRKind::Value { value: Value::Int(*value) },
Expr::Boolean(value) => IRKind::Value { value: Value::Boolean(*value) },

View file

@ -1,4 +1,4 @@
let foo: int = 1;
let baz: bool = true;
let qux: string = "Hello, World";
write(qux);
fun main: int = do
write("Hello, World!\n");
return 0;
end;