mirror of
https://github.com/azur1s/bobbylisp.git
synced 2024-10-16 02:37:40 -05:00
Implement more IRs
This commit is contained in:
parent
03e84d1c80
commit
21ad37e033
63
Cargo.lock
generated
63
Cargo.lock
generated
|
@ -419,6 +419,9 @@ name = "ir"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chumsky",
|
"chumsky",
|
||||||
|
"serde",
|
||||||
|
"serde-lexpr",
|
||||||
|
"serde_derive",
|
||||||
"syntax",
|
"syntax",
|
||||||
"typing",
|
"typing",
|
||||||
]
|
]
|
||||||
|
@ -435,6 +438,33 @@ dependencies = [
|
||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lexpr"
|
||||||
|
version = "0.2.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6a84de6a9df442363b08f5dbf0cd5b92edc70097b89c4ce4bfea4679fe48bc67"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"lexpr-macros",
|
||||||
|
"ryu",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lexpr-macros"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "36b5cb8bb985c81a8ac1a0f8b5c4865214f574ddd64397ef7a99c236e21f35bb"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.142"
|
version = "0.2.142"
|
||||||
|
@ -540,6 +570,39 @@ dependencies = [
|
||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.164"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde-lexpr"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bb4cda13396159f59e7946118cdac0beadeecfb7cf76b197f4147e546f4ead6f"
|
||||||
|
dependencies = [
|
||||||
|
"lexpr",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.164"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slice-group-by"
|
name = "slice-group-by"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use ariadne::{sources, Color, Label, Report, ReportKind};
|
use ariadne::{sources, Color, Label, Report, ReportKind};
|
||||||
use chumsky::{Parser, prelude::Input};
|
use chumsky::{Parser, prelude::Input};
|
||||||
|
|
||||||
|
use ir::lower_expr;
|
||||||
use syntax::parser::{lexer, exprs_parser};
|
use syntax::parser::{lexer, exprs_parser};
|
||||||
use typing::infer::{infer_exprs, InferErrorKind};
|
use typing::infer::{infer_exprs, InferErrorKind};
|
||||||
use ir::Lowerer;
|
|
||||||
|
|
||||||
pub mod args;
|
pub mod args;
|
||||||
|
|
||||||
|
@ -59,9 +59,8 @@ fn main() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// ast.iter().for_each(|node| println!("{:?}", node.0));
|
// ast.iter().for_each(|node| println!("{:?}", node.0));
|
||||||
let mut l = Lowerer::new();
|
let irs = ast.into_iter().map(|node| lower_expr(node.0)).collect::<Vec<_>>();
|
||||||
let irs = l.lower_texprs(ast);
|
irs.iter().for_each(|ir| println!("{}", ir));
|
||||||
irs.iter().for_each(|ir| println!("{:?}", ir));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,5 +5,8 @@ edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
chumsky = "1.0.0-alpha.3"
|
chumsky = "1.0.0-alpha.3"
|
||||||
|
serde = "1.0.164"
|
||||||
|
serde-lexpr = "0.1.3"
|
||||||
|
serde_derive = "1.0.164"
|
||||||
syntax = { path = "../syntax" }
|
syntax = { path = "../syntax" }
|
||||||
typing = { path = "../typing" }
|
typing = { path = "../typing" }
|
228
ir/src/lib.rs
228
ir/src/lib.rs
|
@ -1,115 +1,149 @@
|
||||||
use chumsky::span::SimpleSpan;
|
|
||||||
use syntax::expr::{Lit, UnaryOp, BinaryOp};
|
|
||||||
use typing::typed::TExpr;
|
use typing::typed::TExpr;
|
||||||
|
use syntax::expr::{Lit as ExprLit, UnaryOp, BinaryOp};
|
||||||
|
|
||||||
|
use std::fmt::{self, Display, Formatter, Result as FmtResult};
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum IExpr<'src> {
|
pub enum Lit<'src> {
|
||||||
BoolAnd,
|
Unit,
|
||||||
IntPush(i64),
|
Bool(bool),
|
||||||
IntAdd,
|
Int(i64),
|
||||||
IntSub,
|
Str(&'src str),
|
||||||
IntRem,
|
|
||||||
IntEq,
|
|
||||||
StrPush(&'src str),
|
|
||||||
Branch(Vec<Self>, Vec<Self>),
|
|
||||||
VarLoad(&'src str),
|
|
||||||
VarStore(&'src str),
|
|
||||||
FnPush(Vec<Self>),
|
|
||||||
Call,
|
|
||||||
Ret,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
impl Display for Lit<'_> {
|
||||||
pub struct Lowerer {
|
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
|
||||||
}
|
match self {
|
||||||
|
Lit::Unit => write!(f, "()"),
|
||||||
impl Lowerer {
|
Lit::Bool(b) => write!(f, "{}", b),
|
||||||
pub fn new() -> Self {
|
Lit::Int(i) => write!(f, "{}", i),
|
||||||
Self {}
|
Lit::Str(s) => write!(f, "\"{}\"", s),
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn lower_texpr<'a>(self: &mut Self, e: TExpr<'a>) -> Vec<IExpr<'a>> {
|
#[derive(Clone, Debug)]
|
||||||
use IExpr::*;
|
pub enum Expr<'src> {
|
||||||
|
Lit(Lit<'src>),
|
||||||
|
// v0
|
||||||
|
Var(&'src str),
|
||||||
|
// f(v0, v1, ...)
|
||||||
|
Call(Vec<Self>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for Expr<'_> {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
|
||||||
|
match self {
|
||||||
|
Expr::Lit(l) => write!(f, "{}", l),
|
||||||
|
Expr::Var(s) => write!(f, "{}", s),
|
||||||
|
Expr::Call(v) => {
|
||||||
|
write!(f, "(")?;
|
||||||
|
for (i, e) in v.iter().enumerate() {
|
||||||
|
if i != 0 {
|
||||||
|
write!(f, " ")?;
|
||||||
|
}
|
||||||
|
write!(f, "{}", e)?;
|
||||||
|
}
|
||||||
|
write!(f, ")")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! unbox {
|
||||||
|
($e:expr) => {
|
||||||
|
*(($e).0)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! str {
|
||||||
|
($e:expr) => {
|
||||||
|
Expr::Lit(Lit::Str($e))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! var {
|
||||||
|
($e:expr) => {
|
||||||
|
Expr::Var($e)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! call {
|
||||||
|
($e:expr) => {
|
||||||
|
Expr::Call($e)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn lower_lit(lit: ExprLit) -> Lit {
|
||||||
|
match lit {
|
||||||
|
ExprLit::Unit => Lit::Unit,
|
||||||
|
ExprLit::Bool(b) => Lit::Bool(b),
|
||||||
|
ExprLit::Int(i) => Lit::Int(i),
|
||||||
|
ExprLit::Str(s) => Lit::Str(s),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn lower_expr(e: TExpr) -> Expr {
|
||||||
match e {
|
match e {
|
||||||
TExpr::Lit(l) => match l {
|
TExpr::Lit(l) => Expr::Lit(lower_lit(l)),
|
||||||
Lit::Unit => vec![],
|
TExpr::Ident(s) => var!(s),
|
||||||
Lit::Bool(_) => todo!(),
|
|
||||||
Lit::Int(n) => vec![IntPush(n)],
|
|
||||||
Lit::Str(s) => vec![StrPush(s)],
|
|
||||||
}
|
|
||||||
TExpr::Ident(s) => vec![VarLoad(s)],
|
|
||||||
TExpr::Unary { op, expr, .. } => {
|
TExpr::Unary { op, expr, .. } => {
|
||||||
let mut expr = self.lower_texpr(*expr.0);
|
let expr = lower_expr(unbox!(expr));
|
||||||
expr.push(match op {
|
match op {
|
||||||
UnaryOp::Neg => IntSub,
|
UnaryOp::Neg => call!(vec![var!("neg"), expr]),
|
||||||
UnaryOp::Not => todo!(),
|
UnaryOp::Not => call!(vec![var!("not"), expr]),
|
||||||
});
|
|
||||||
expr
|
|
||||||
}
|
}
|
||||||
TExpr::Binary { op, lhs, rhs, .. } if op == BinaryOp::Pipe => {
|
}
|
||||||
println!("{lhs:?}");
|
TExpr::Binary { op: BinaryOp::Pipe, lhs, rhs, .. } => {
|
||||||
println!("{rhs:?}");
|
let lhs = lower_expr(unbox!(lhs)); // arguments
|
||||||
todo!()
|
let rhs = lower_expr(unbox!(rhs)); // function
|
||||||
|
call!(vec![rhs, lhs])
|
||||||
}
|
}
|
||||||
TExpr::Binary { op, lhs, rhs, .. } => {
|
TExpr::Binary { op, lhs, rhs, .. } => {
|
||||||
let mut lhs = self.lower_texpr(*lhs.0);
|
let lhs = lower_expr(unbox!(lhs));
|
||||||
let mut rhs = self.lower_texpr(*rhs.0);
|
let rhs = lower_expr(unbox!(rhs));
|
||||||
lhs.append(&mut rhs);
|
match op {
|
||||||
lhs.push(match op {
|
BinaryOp::Add => call!(vec![var!("+"), lhs, rhs]),
|
||||||
BinaryOp::Add => IExpr::IntAdd,
|
BinaryOp::Sub => call!(vec![var!("-"), lhs, rhs]),
|
||||||
BinaryOp::Sub => IExpr::IntSub,
|
BinaryOp::Mul => call!(vec![var!("*"), lhs, rhs]),
|
||||||
BinaryOp::Mul => todo!(),
|
BinaryOp::Div => call!(vec![var!("/"), lhs, rhs]),
|
||||||
BinaryOp::Div => todo!(),
|
BinaryOp::Rem => call!(vec![var!("%"), lhs, rhs]),
|
||||||
BinaryOp::Rem => IExpr::IntRem,
|
BinaryOp::Eq => call!(vec![var!("=="), lhs, rhs]),
|
||||||
BinaryOp::Eq => IExpr::IntEq,
|
BinaryOp::Ne => call!(vec![var!("!="), lhs, rhs]),
|
||||||
BinaryOp::Ne => todo!(),
|
BinaryOp::Lt => call!(vec![var!("<"), lhs, rhs]),
|
||||||
BinaryOp::Lt => todo!(),
|
BinaryOp::Le => call!(vec![var!("<="), lhs, rhs]),
|
||||||
BinaryOp::Gt => todo!(),
|
BinaryOp::Gt => call!(vec![var!(">"), lhs, rhs]),
|
||||||
BinaryOp::Le => todo!(),
|
BinaryOp::Ge => call!(vec![var!(">="), lhs, rhs]),
|
||||||
BinaryOp::Ge => todo!(),
|
BinaryOp::And => call!(vec![var!("&&"), lhs, rhs]),
|
||||||
BinaryOp::And => IExpr::BoolAnd,
|
BinaryOp::Or => call!(vec![var!("||"), lhs, rhs]),
|
||||||
BinaryOp::Or => todo!(),
|
BinaryOp::Pipe => unreachable!("pipe operator is handled separately"),
|
||||||
BinaryOp::Pipe => unreachable!(),
|
}
|
||||||
});
|
}
|
||||||
lhs
|
TExpr::Lambda { params, body, .. } => {
|
||||||
|
let body = lower_expr(unbox!(body));
|
||||||
|
call!(vec![
|
||||||
|
var!("lambda"),
|
||||||
|
call!(params.into_iter().map(|(p, _)| var!(p)).collect()),
|
||||||
|
body,
|
||||||
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
TExpr::Lambda { body, .. } => {
|
|
||||||
let mut es = self.lower_texpr(*body.0);
|
|
||||||
es.push(IExpr::Ret);
|
|
||||||
vec![IExpr::FnPush(es)]
|
|
||||||
},
|
|
||||||
TExpr::Call { func, args } => {
|
TExpr::Call { func, args } => {
|
||||||
let mut es: Vec<IExpr> = args.into_iter()
|
let func = lower_expr(unbox!(func));
|
||||||
.flat_map(|(e, _)| self.lower_texpr(e))
|
let args = args.into_iter()
|
||||||
.collect();
|
.map(|(a, _)| lower_expr(a))
|
||||||
es.append(&mut self.lower_texpr(*func.0));
|
.collect::<Vec<_>>();
|
||||||
es.push(IExpr::Call);
|
call!(vec![func].into_iter().chain(args).collect())
|
||||||
es
|
}
|
||||||
},
|
TExpr::If { cond, t, f, br_ty } => todo!(),
|
||||||
|
TExpr::Let { name, value, body, .. } => {
|
||||||
TExpr::If { cond, t, f, .. } => {
|
let value = lower_expr(unbox!(value));
|
||||||
let mut es = self.lower_texpr(*cond.0);
|
let body = lower_expr(unbox!(body));
|
||||||
es.push(IExpr::Branch(
|
call!(vec![var!("let"), str!(name), value, body])
|
||||||
self.lower_texpr(*t.0),
|
}
|
||||||
self.lower_texpr(*f.0),
|
|
||||||
));
|
|
||||||
es
|
|
||||||
},
|
|
||||||
TExpr::Define { name, value, .. } => {
|
TExpr::Define { name, value, .. } => {
|
||||||
let mut es = self.lower_texpr(*value.0);
|
let value = lower_expr(unbox!(value));
|
||||||
es.push(IExpr::VarStore(name));
|
call!(vec![var!("define"), str!(name), value])
|
||||||
es
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
e => unimplemented!("{:?}", e)
|
|
||||||
}
|
}
|
||||||
}
|
TExpr::Block { exprs, void, ret_ty } => todo!(),
|
||||||
|
|
||||||
pub fn lower_texprs<'a>(self: &mut Self, e: Vec<(TExpr<'a>, SimpleSpan)>) -> Vec<IExpr<'a>> {
|
|
||||||
e.into_iter()
|
|
||||||
.flat_map(|(e, _)| self.lower_texpr(e))
|
|
||||||
.collect()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,2 +1,5 @@
|
||||||
let f = fun (x Int, y) Int -> x + y;
|
let add = fun (x Int, y Int) Int -> x + y;
|
||||||
f(34, 35);
|
let succ = fun (x) -> x + 1;
|
||||||
|
|
||||||
|
add(33, 34)
|
||||||
|
|> fun (x) -> succ(x)
|
Loading…
Reference in a new issue