mirror of
https://github.com/azur1s/bobbylisp.git
synced 2024-10-16 02:37:40 -05:00
Compare commits
No commits in common. "8c63304acf5cba6bf3e284daaa52c6ed6a64543c" and "2d45cf240b451f6239925b55a25e341aa15202e6" have entirely different histories.
8c63304acf
...
2d45cf240b
|
@ -31,10 +31,9 @@ impl Codegen {
|
||||||
macro_rules! semicolon { () => { if should_gen_semicolon { ";" } else { "" } }; }
|
macro_rules! semicolon { () => { if should_gen_semicolon { ";" } else { "" } }; }
|
||||||
|
|
||||||
match ir {
|
match ir {
|
||||||
IRKind::Define { name, type_hint, value, mutable } => {
|
IRKind::Define { name, type_hint, value } => {
|
||||||
format!(
|
format!(
|
||||||
"{} {}: {} = {}{}\n",
|
"const {}: {} = {}{}\n",
|
||||||
if *mutable { "let" } else { "const" },
|
|
||||||
name,
|
name,
|
||||||
type_hint,
|
type_hint,
|
||||||
self.gen_ir(value, false),
|
self.gen_ir(value, false),
|
||||||
|
|
|
@ -13,7 +13,7 @@ pub enum Value { Int(i64), Boolean(bool), String(String), Ident(String) }
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum IRKind {
|
pub enum IRKind {
|
||||||
Define { name: String, type_hint: String, value: Box<Self>, mutable: bool },
|
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> },
|
||||||
Intrinsic { name: String, args: Vec<Self> },
|
Intrinsic { name: String, args: Vec<Self> },
|
||||||
|
@ -115,16 +115,14 @@ pub fn expr_to_ir(expr: &Expr) -> (Option<IRKind>, Option<LoweringError>) {
|
||||||
_ => return (None, Some(LoweringError { span: name.1.clone(), message: "Expected identifier".to_string(), note: None }))
|
_ => return (None, Some(LoweringError { span: name.1.clone(), message: "Expected identifier".to_string(), note: None }))
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get all the `Hole` indexes
|
// Get the index where the `Hole` is at
|
||||||
let mut indexes = Vec::new();
|
let index = args.0.iter().position(|arg| match arg.0 {
|
||||||
for (i, arg) in args.0.iter().enumerate() {
|
Expr::Hole(..) => true,
|
||||||
if let Expr::Hole(..) = &arg.0 {
|
_ => false
|
||||||
indexes.push(i);
|
});
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there is no `Hole` in the args then return early
|
// If there is no `Hole` in the args then return early
|
||||||
if indexes.is_empty() {
|
if let None = index {
|
||||||
return (None, Some(LoweringError {
|
return (None, Some(LoweringError {
|
||||||
span: rhs.1.clone(),
|
span: rhs.1.clone(),
|
||||||
message: "Expected hole in piping".to_string(),
|
message: "Expected hole in piping".to_string(),
|
||||||
|
@ -134,9 +132,7 @@ pub fn expr_to_ir(expr: &Expr) -> (Option<IRKind>, Option<LoweringError>) {
|
||||||
|
|
||||||
// Remove the `Hole` from the args
|
// Remove the `Hole` from the args
|
||||||
let mut new_args = args.0.clone();
|
let mut new_args = args.0.clone();
|
||||||
for index in indexes.iter().rev() {
|
new_args.remove(index.unwrap());
|
||||||
new_args.remove(*index);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make a new call expression with the new args
|
// Make a new call expression with the new args
|
||||||
let new_call = match call {
|
let new_call = match call {
|
||||||
|
@ -186,18 +182,12 @@ pub fn expr_to_ir(expr: &Expr) -> (Option<IRKind>, Option<LoweringError>) {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
Expr::Let { name, type_hint, value, mutable } => {
|
Expr::Let { name, type_hint, value } => {
|
||||||
let value = expr_to_ir(&value.0);
|
let value = expr_to_ir(&value.0);
|
||||||
if_err_return!(value.1);
|
if_err_return!(value.1);
|
||||||
|
|
||||||
let value = value.0.unwrap();
|
let value = value.0.unwrap();
|
||||||
let ir_kind = IRKind::Define {
|
let ir_kind = IRKind::Define { name: name.clone(), type_hint: gen_type_hint(type_hint), value: Box::new(value) };
|
||||||
name: name.clone(),
|
|
||||||
type_hint: gen_type_hint(type_hint),
|
|
||||||
value: Box::new(value),
|
|
||||||
mutable: *mutable
|
|
||||||
};
|
|
||||||
|
|
||||||
return (Some(ir_kind), None);
|
return (Some(ir_kind), None);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ use chumsky::prelude::*;
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub enum Token {
|
pub enum Token {
|
||||||
// Keywords
|
// Keywords
|
||||||
KwLet, KwMut, KwFun,
|
KwLet, KwFun,
|
||||||
KwDo, KwEnd,
|
KwDo, KwEnd,
|
||||||
KwIf, KwThen, KwElse,
|
KwIf, KwThen, KwElse,
|
||||||
KwReturn,
|
KwReturn,
|
||||||
|
@ -30,7 +30,6 @@ impl std::fmt::Display for Token {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Token::KwLet => write!(f, "let"),
|
Token::KwLet => write!(f, "let"),
|
||||||
Token::KwMut => write!(f, "mut"),
|
|
||||||
Token::KwFun => write!(f, "fun"),
|
Token::KwFun => write!(f, "fun"),
|
||||||
Token::KwDo => write!(f, "do"),
|
Token::KwDo => write!(f, "do"),
|
||||||
Token::KwEnd => write!(f, "end"),
|
Token::KwEnd => write!(f, "end"),
|
||||||
|
|
|
@ -18,7 +18,6 @@ pub enum Expr {
|
||||||
name: String,
|
name: String,
|
||||||
type_hint: String,
|
type_hint: String,
|
||||||
value: Box<Spanned<Self>>,
|
value: Box<Spanned<Self>>,
|
||||||
mutable: bool,
|
|
||||||
},
|
},
|
||||||
Fun {
|
Fun {
|
||||||
name: String,
|
name: String,
|
||||||
|
@ -194,19 +193,17 @@ fn expr_parser() -> impl Parser<Token, Vec<Spanned<Expr>>, Error = Simple<Token>
|
||||||
});
|
});
|
||||||
|
|
||||||
let let_ = just(Token::KwLet)
|
let let_ = just(Token::KwLet)
|
||||||
.ignore_then(just(Token::KwMut)).or_not()
|
.ignore_then(identifier)
|
||||||
.then(identifier)
|
|
||||||
.then_ignore(just(Token::Colon))
|
.then_ignore(just(Token::Colon))
|
||||||
.then(identifier)
|
.then(identifier)
|
||||||
.then_ignore(just(Token::Assign))
|
.then_ignore(just(Token::Assign))
|
||||||
.then(expr.clone())
|
.then(expr.clone())
|
||||||
.map(|(((mutable, name), type_hint), value)| {
|
.map(|((name, type_hint), value)| {
|
||||||
(
|
(
|
||||||
Expr::Let {
|
Expr::Let {
|
||||||
name: name.0.clone(),
|
name: name.0.clone(),
|
||||||
type_hint: type_hint.0,
|
type_hint: type_hint.0,
|
||||||
value: Box::new(value.clone()),
|
value: Box::new(value.clone()),
|
||||||
mutable: mutable.is_some(),
|
|
||||||
},
|
},
|
||||||
name.1.start..value.1.end,
|
name.1.start..value.1.end,
|
||||||
)
|
)
|
||||||
|
@ -251,13 +248,13 @@ fn expr_parser() -> impl Parser<Token, Vec<Spanned<Expr>>, Error = Simple<Token>
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
let do_block = expr.clone()
|
let do_block = just(Token::KwDo)
|
||||||
|
.ignore_then(
|
||||||
|
expr.clone()
|
||||||
.then_ignore(just(Token::SemiColon))
|
.then_ignore(just(Token::SemiColon))
|
||||||
.repeated()
|
.repeated()
|
||||||
.delimited_by(
|
|
||||||
just(Token::KwDo),
|
|
||||||
just(Token::KwEnd),
|
|
||||||
)
|
)
|
||||||
|
.then_ignore(just(Token::KwEnd))
|
||||||
.map_with_span(|body, span| {
|
.map_with_span(|body, span| {
|
||||||
(
|
(
|
||||||
Expr::Do {
|
Expr::Do {
|
||||||
|
|
|
@ -12,8 +12,4 @@ fun main: void = do
|
||||||
|> qux(_)
|
|> qux(_)
|
||||||
|> quux(1, _)
|
|> quux(1, _)
|
||||||
|> @write(_);
|
|> @write(_);
|
||||||
|
|
||||||
210
|
|
||||||
|> bar(_, _)
|
|
||||||
|> @write(_);
|
|
||||||
end;
|
end;
|
Loading…
Reference in a new issue