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};
|
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),
|
||||||
|
|
|
@ -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) },
|
||||||
|
|
|
@ -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;
|
Loading…
Reference in a new issue