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}; use hir::{IR, IRKind, Value};
const MODULE_INCLUDES: [&str; 3] = [
"<stdbool.h>",
"<iostream>",
"<string>",
];
pub struct Codegen { pub struct Codegen {
pub emitted: String, pub emitted: String,
} }
@ -16,14 +22,12 @@ impl Codegen {
} }
pub fn gen(&mut self, irs: Vec<IR>) { pub fn gen(&mut self, irs: Vec<IR>) {
self.emit("#include <stdbool.h>\n"); for module in MODULE_INCLUDES {
self.emit("#include <iostream>\n"); self.emit(format!("#include {}\n", module));
self.emit("#include <string>\n"); }
self.emit("int main() {\n");
for ir in irs { for ir in irs {
self.emit(&self.gen_ir(&ir.kind)); self.emit(&self.gen_ir(&ir.kind));
} }
self.emit("}");
} }
fn gen_ir(&self, ir: &IRKind) -> String { 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(", ")), _ => 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 } => { IRKind::Value { value } => {
match value { match value {
Value::Int(value) => format!("{}", value), Value::Int(value) => format!("{}", value),

View file

@ -9,10 +9,11 @@ pub enum IRKind {
Define { name: String, type_hint: String, value: Box<Self> }, Define { name: String, type_hint: String, value: Box<Self> },
Fun { name: String, return_type_hint: String, args: Vec<(String, String)>, body: Box<Self> }, Fun { name: String, return_type_hint: String, args: Vec<(String, String)>, body: Box<Self> },
Call { name: String, args: Vec<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> }, If { cond: Box<Self>, body: Box<Self>, else_body: Box<Self> },
Value { value: Value }, Value { value: Value },
Binary { op: String, left: Box<Self>, right: Box<Self> }, Binary { op: String, left: Box<Self>, right: Box<Self> },
Return { value: Box<Self> },
} }
#[derive(Debug)] #[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<_>>(); let args = args.0.iter().map(|arg| expr_to_ir(&arg.0)).collect::<Vec<_>>();
IRKind::Call { name, args } 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::Int(value) => IRKind::Value { value: Value::Int(*value) },
Expr::Boolean(value) => IRKind::Value { value: Value::Boolean(*value) }, Expr::Boolean(value) => IRKind::Value { value: Value::Boolean(*value) },

View file

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