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
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)
# Prerequistie

View file

@ -29,22 +29,19 @@ impl Codegen {
self.emit(&self.gen_ir(&ir.kind));
}
}
fn gen_ir(&self, ir: &IRKind) -> String {
match ir {
IRKind::Define { name, type_hint, value } => {
format!("{} {} = {};\n", type_hint, name, self.gen_ir(value))
},
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() {
"write" => { format!("std::cout << {};\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 } => {
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))

View file

@ -1,8 +1,6 @@
use std::ops::Range;
use parser::Expr;
const INTRINSICS: [&str; 2] = ["write", "read"];
#[derive(Debug)]
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> },
Fun { name: String, return_type_hint: String, args: Vec<(String, String)>, body: Box<Self> },
Call { name: String, args: Vec<Self> },
Intrinsic { name: String, args: Vec<Self> },
Do { body: Vec<Self> },
If { cond: Box<Self>, body: Box<Self>, else_body: Box<Self> },
Value { value: Value },
@ -66,12 +63,7 @@ pub fn expr_to_ir(expr: &Expr) -> (Option<IRKind>, Option<LoweringError>) {
},
Expr::Call { name, args } => {
let name = match &name.0 {
Expr::Identifier(s) => {
if INTRINSICS.contains(&s.as_str()) { s.clone() }
else {
return (None, Some(LoweringError { span: name.1.clone(), message: format!("Unknown intrinsic: {}", s) }));
}
}
Expr::Identifier(s) => s.clone(),
// Should never happen because the parser should have caught this
_ => 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 };
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 } => {
// 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<_>>();

View file

@ -15,13 +15,12 @@ pub enum Token {
// Operators
Plus, Minus, Multiply, Divide,
Not, Equal, NotEqual, Less, Greater,
// Symbols & Delimiters
Assign,
Dot, Comma,
Colon, SemiColon,
OpenParen, CloseParen,
At,
}
impl std::fmt::Display for Token {
@ -50,7 +49,7 @@ impl std::fmt::Display for Token {
Token::NotEqual => write!(f, "!="),
Token::Less => write!(f, "<"),
Token::Greater => write!(f, ">"),
Token::Assign => write!(f, "="),
Token::Dot => write!(f, "."),
Token::Comma => write!(f, ","),
@ -58,7 +57,6 @@ impl std::fmt::Display for Token {
Token::SemiColon => write!(f, ";"),
Token::OpenParen => 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::OpenParen),
just(')').to(Token::CloseParen),
just('@').to(Token::At),
));
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>> },
Binary { lhs: Box<Spanned<Self>>, op: String, rhs: Box<Spanned<Self>> },
Call { name: Box<Spanned<Self>>, args: Spanned<Vec<Spanned<Self>>> },
Intrinsic { name: Box<Spanned<Self>>, args: Spanned<Vec<Spanned<Self>>> },
Let {
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)))
.labelled("atom");
let call = atom.clone()
let call = atom
.then(
args.clone()
.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((
just(Token::Plus),
just(Token::Minus)))
.repeated()
.then(call.or(intrinsic))
.then(call)
.foldr(|op, rhs| {
(
Expr::Unary {

View file

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