1
1
Fork 0
mirror of https://github.com/azur1s/bobbylisp.git synced 2024-10-16 02:37:40 -05:00

Compare commits

..

No commits in common. "04e35046b2bd8f0c343469df34145d29f4cc555e" and "1079d53f052a97ea29f7aa6ce88ca2ad057b927e" have entirely different histories.

6 changed files with 9 additions and 65 deletions

View file

@ -1,13 +1,6 @@
# Hades # Hades
Programming language that compiles to C++! Programming language that compiles to C++!
```sml
fun main: int = do
@write("Hello, World!\n");
return 0;
end;
```
Note: Everything in this project can be changed at anytime! (I'm still finding out what work best for lots of thing) if you have an idea, feel free to create an issues about it, or even create a PR! (I'd be very happy) Note: Everything in this project can be changed at anytime! (I'm still finding out what work best for lots of thing) if you have an idea, feel free to create an issues about it, or even create a PR! (I'd be very happy)
# Prerequistie # Prerequistie

View file

@ -36,15 +36,12 @@ impl Codegen {
format!("{} {} = {};\n", type_hint, name, self.gen_ir(value)) format!("{} {} = {};\n", type_hint, name, self.gen_ir(value))
}, },
IRKind::Call { name, args } => { IRKind::Call { name, args } => {
format!("{}({});\n", name, args.iter().map(|arg| self.gen_ir(arg)).collect::<Vec<_>>().join(", "))
},
IRKind::Intrinsic { name, args } => {
match name.as_str() { match name.as_str() {
"write" => { format!("std::cout << {};\n", self.gen_ir(&args[0])) }, "write" => { format!("std::cout << {};\n", self.gen_ir(&args[0])) },
"read" => { format!("std::cin >> {};\n", self.gen_ir(&args[0])) }, "read" => { format!("std::cin >> {};\n", self.gen_ir(&args[0])) },
_ => unreachable!(format!("Unknown intrinsic: {}", name)) // Shoul be handled by lowering _ => format!("{}({});\n", name, args.iter().map(|arg| self.gen_ir(arg)).collect::<Vec<_>>().join(", ")),
}
} }
},
IRKind::Fun { name, return_type_hint, args, body } => { IRKind::Fun { name, return_type_hint, args, body } => {
let args = args.iter().map(|arg| format!("{} {}", arg.1, arg.0)).collect::<Vec<_>>().join(", "); 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)) format!("{} {}({}) {{\n{}}}\n", return_type_hint, name, args, self.gen_ir(body))

View file

@ -1,8 +1,6 @@
use std::ops::Range; use std::ops::Range;
use parser::Expr; use parser::Expr;
const INTRINSICS: [&str; 2] = ["write", "read"];
#[derive(Debug)] #[derive(Debug)]
pub enum Value { Int(i64), Boolean(bool), String(String), Ident(String) } pub enum Value { Int(i64), Boolean(bool), String(String), Ident(String) }
@ -11,7 +9,6 @@ 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> },
Intrinsic { name: String, args: Vec<Self> },
Do { body: Vec<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 },
@ -66,12 +63,7 @@ pub fn expr_to_ir(expr: &Expr) -> (Option<IRKind>, Option<LoweringError>) {
}, },
Expr::Call { name, args } => { Expr::Call { name, args } => {
let name = match &name.0 { let name = match &name.0 {
Expr::Identifier(s) => { Expr::Identifier(s) => s.clone(),
if INTRINSICS.contains(&s.as_str()) { s.clone() }
else {
return (None, Some(LoweringError { span: name.1.clone(), message: format!("Unknown intrinsic: {}", s) }));
}
}
// Should never happen because the parser should have caught this // Should never happen because the parser should have caught this
_ => return (None, Some(LoweringError { span: name.1.clone(), message: "Expected identifier".to_string() })) _ => return (None, Some(LoweringError { span: name.1.clone(), message: "Expected identifier".to_string() }))
}; };
@ -90,20 +82,6 @@ pub fn expr_to_ir(expr: &Expr) -> (Option<IRKind>, Option<LoweringError>) {
let ir_kind = IRKind::Call { name, args: largs }; let ir_kind = IRKind::Call { name, args: largs };
return (Some(ir_kind), None); return (Some(ir_kind), None);
}, },
Expr::Intrinsic { name, args } => {
let name = match &name.0 {
Expr::Identifier(s) => s.clone(),
_ => return (None, Some(LoweringError { span: name.1.clone(), message: "Expected identifier".to_string() }))
};
let mut largs = Vec::new();
for arg in &args.0 {
let arg = expr_to_ir(&arg.0);
if let Some(err) = arg.1 { return (None, Some(err)); }
else { largs.push(arg.0.unwrap()); }
}
let ir_kind = IRKind::Intrinsic { name, args: largs };
return (Some(ir_kind), None);
},
Expr::Fun { name, type_hint, args, body } => { Expr::Fun { name, type_hint, args, body } => {
// Iterate each argument and give it a type hint // Iterate each argument and give it a type hint
let args = args.0.iter().map(|arg| (arg.0.0.clone(), gen_type_hint(&arg.1.0))).collect::<Vec<_>>(); let args = args.0.iter().map(|arg| (arg.0.0.clone(), gen_type_hint(&arg.1.0))).collect::<Vec<_>>();

View file

@ -21,7 +21,6 @@ pub enum Token {
Dot, Comma, Dot, Comma,
Colon, SemiColon, Colon, SemiColon,
OpenParen, CloseParen, OpenParen, CloseParen,
At,
} }
impl std::fmt::Display for Token { impl std::fmt::Display for Token {
@ -58,7 +57,6 @@ impl std::fmt::Display for Token {
Token::SemiColon => write!(f, ";"), Token::SemiColon => write!(f, ";"),
Token::OpenParen => write!(f, "("), Token::OpenParen => write!(f, "("),
Token::CloseParen => write!(f, ")"), Token::CloseParen => write!(f, ")"),
Token::At => write!(f, "@"),
} }
} }
} }
@ -90,7 +88,6 @@ pub fn lexer() -> impl Parser<char, Vec<(Token, Span)>, Error = Simple<char>> {
just(';').to(Token::SemiColon), just(';').to(Token::SemiColon),
just('(').to(Token::OpenParen), just('(').to(Token::OpenParen),
just(')').to(Token::CloseParen), just(')').to(Token::CloseParen),
just('@').to(Token::At),
)); ));
let keyword = text::ident().map(|s: String| match s.as_str() { let keyword = text::ident().map(|s: String| match s.as_str() {

View file

@ -11,7 +11,6 @@ pub enum Expr {
Unary { op: String, rhs: Box<Spanned<Self>> }, Unary { op: String, rhs: Box<Spanned<Self>> },
Binary { lhs: Box<Spanned<Self>>, op: String, rhs: Box<Spanned<Self>> }, Binary { lhs: Box<Spanned<Self>>, op: String, rhs: Box<Spanned<Self>> },
Call { name: Box<Spanned<Self>>, args: Spanned<Vec<Spanned<Self>>> }, Call { name: Box<Spanned<Self>>, args: Spanned<Vec<Spanned<Self>>> },
Intrinsic { name: Box<Spanned<Self>>, args: Spanned<Vec<Spanned<Self>>> },
Let { Let {
name: String, name: String,
@ -61,7 +60,7 @@ fn expr_parser() -> impl Parser<Token, Vec<Spanned<Expr>>, Error = Simple<Token>
// .delimited_by(just(Token::OpenParen), just(Token::CloseParen))) // .delimited_by(just(Token::OpenParen), just(Token::CloseParen)))
.labelled("atom"); .labelled("atom");
let call = atom.clone() let call = atom
.then( .then(
args.clone() args.clone()
.delimited_by( .delimited_by(
@ -80,31 +79,11 @@ fn expr_parser() -> impl Parser<Token, Vec<Spanned<Expr>>, Error = Simple<Token>
) )
}); });
let intrinsic = just(Token::At)
.ignore_then(atom)
.then(
args.clone()
.delimited_by(
just(Token::OpenParen),
just(Token::CloseParen),
)
.repeated()
)
.foldl(|name, args| {
(
Expr::Intrinsic {
name: Box::new(name.clone()),
args: (args, name.1.clone()),
},
name.1,
)
});
let unary = choice(( let unary = choice((
just(Token::Plus), just(Token::Plus),
just(Token::Minus))) just(Token::Minus)))
.repeated() .repeated()
.then(call.or(intrinsic)) .then(call)
.foldr(|op, rhs| { .foldr(|op, rhs| {
( (
Expr::Unary { Expr::Unary {

View file

@ -1,4 +1,4 @@
fun main: int = do fun main: int = do
@write("Hello, World!\n"); write("Hello, World!\n");
return 0; return 0;
end; end;