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:
parent
dccbe7c17c
commit
9f4cf84f34
|
@ -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),
|
||||
|
|
|
@ -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) },
|
||||
|
|
|
@ -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;
|
Loading…
Reference in a new issue