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

Compare commits

..

2 commits

7 changed files with 26 additions and 15 deletions

View file

@ -6,6 +6,12 @@ pub struct Codegen {
pub emitted: String, pub emitted: String,
} }
impl Default for Codegen {
fn default() -> Self {
Self::new()
}
}
impl Codegen { impl Codegen {
pub fn new() -> Self { pub fn new() -> Self {
Self { emitted: String::new() } Self { emitted: String::new() }
@ -63,11 +69,11 @@ impl Codegen {
"write_file" => { format!("writeFile({}, {}){}\n", self.gen_ir(&args[0], false), self.gen_ir(&args[1], false), semicolon!()) }, "write_file" => { format!("writeFile({}, {}){}\n", self.gen_ir(&args[0], false), self.gen_ir(&args[1], false), semicolon!()) },
"read" => { format!("read({}){}\n" , self.gen_ir(&args[0], false), semicolon!()) }, "read" => { format!("read({}){}\n" , self.gen_ir(&args[0], false), semicolon!()) },
"read_file" => { format!("readFile({}){}\n" , self.gen_ir(&args[0], false), semicolon!()) }, "read_file" => { format!("readFile({}){}\n" , self.gen_ir(&args[0], false), semicolon!()) },
"emit" => { format!("{}", self.gen_ir(&args[0], false).trim_start_matches('"').trim_end_matches('"')) }, "emit" => { self.gen_ir(&args[0], false).trim_start_matches('"').trim_end_matches('"').to_string() },
"get" => { format!("{}[{}]", self.gen_ir(&args[0], false), self.gen_ir(&args[1], false)) }, "get" => { format!("{}[{}]", self.gen_ir(&args[0], false), self.gen_ir(&args[1], false)) },
"len" => { format!("{}.length", self.gen_ir(&args[0], false)) }, "len" => { format!("{}.length", self.gen_ir(&args[0], false)) },
"throw" => { format!("throw new Error({}){}", self.gen_ir(&args[0], false), semicolon!()) }, "throw" => { format!("throw new Error({}){}", self.gen_ir(&args[0], false), semicolon!()) },
_ => unreachable!(format!("Unknown intrinsic: {}", name)) // Shoul be handled by lowering _ => unreachable!(format!("Unknown intrinsic: {}", name)) // Shoul be handled by lowering
} }
@ -99,7 +105,7 @@ impl Codegen {
IRKind::Do { body, .. } => { IRKind::Do { body, .. } => {
let mut out = "{\n".to_string(); let mut out = "{\n".to_string();
for expr in body { for expr in body {
out.push_str(&self.gen_ir(&expr, true)); out.push_str(&self.gen_ir(expr, true));
} }
out.push_str("}\n"); out.push_str("}\n");
out out

View file

@ -15,6 +15,12 @@ pub enum Kind {
TypecheckError(typecheck::TypecheckError), TypecheckError(typecheck::TypecheckError),
} }
impl Default for Diagnostics {
fn default() -> Self {
Self::new()
}
}
impl Diagnostics { impl Diagnostics {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
@ -126,7 +132,7 @@ impl Diagnostics {
_ => None, _ => None,
}); });
let typecheck_error = self.errors.iter().filter_map(|kind| match kind { let typecheck_error = self.errors.iter().filter_map(|kind| match kind {
Kind::TypecheckError(error) => Some(error.clone()), Kind::TypecheckError(error) => Some(<&typecheck::TypecheckError>::clone(&error)),
_ => None, _ => None,
}); });
// TODO: so many .iter(), maybe collapse them into one? // TODO: so many .iter(), maybe collapse them into one?
@ -138,12 +144,12 @@ impl Diagnostics {
let report = Report::build(ReportKind::Error, (), span.start) let report = Report::build(ReportKind::Error, (), span.start)
.with_message( .with_message(
format!("{}", message) message.to_string()
) )
.with_label( .with_label(
Label::new(span.clone()) Label::new(span.clone())
.with_message( .with_message(
format!("{}", message) message.to_string()
) )
.with_color(Color::Red) .with_color(Color::Red)
); );

View file

@ -94,7 +94,7 @@ pub struct IR {
pub span: Range<usize> pub span: Range<usize>
} }
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct LoweringError { pub struct LoweringError {
pub span: Range<usize>, pub span: Range<usize>,
pub message: String, pub message: String,

View file

@ -165,9 +165,10 @@ pub fn lexer() -> impl Parser<char, Vec<(Token, Span)>, Error = Simple<char>> {
.repeated() .repeated()
} }
#[allow(clippy::type_complexity)]
pub fn lex(src: String) -> (Option<Vec<(Token, std::ops::Range<usize>)>>, Vec<Simple<char>>) { pub fn lex(src: String) -> (Option<Vec<(Token, std::ops::Range<usize>)>>, Vec<Simple<char>>) {
let (tokens, lex_error) = lexer().parse_recovery(src.as_str()); let (tokens, lex_error) = lexer().parse_recovery(src.as_str());
return (tokens, lex_error); (tokens, lex_error)
} }
#[cfg(test)] #[cfg(test)]

View file

@ -286,7 +286,7 @@ fn expr_parser() -> impl Parser<Token, Vec<Spanned<Expr>>, Error = Simple<Token>
.map_with_span(|body, span| { .map_with_span(|body, span| {
( (
Expr::Do { Expr::Do {
body: (body.clone(), span.clone()), body: (body, span.clone()),
}, },
span, span,
) )
@ -366,13 +366,14 @@ fn expr_parser() -> impl Parser<Token, Vec<Spanned<Expr>>, Error = Simple<Token>
.then_ignore(end()) .then_ignore(end())
} }
#[allow(clippy::type_complexity)] // We are going to use this once anyway, why we need to make a type?
pub fn parse(tokens: Vec<(Token, std::ops::Range<usize>)>, len: usize) -> (Option<Vec<(Expr, std::ops::Range<usize>)>>, Vec<Simple<Token>>) { pub fn parse(tokens: Vec<(Token, std::ops::Range<usize>)>, len: usize) -> (Option<Vec<(Expr, std::ops::Range<usize>)>>, Vec<Simple<Token>>) {
let (ast, parse_error) = expr_parser().parse_recovery(Stream::from_iter( let (ast, parse_error) = expr_parser().parse_recovery(Stream::from_iter(
len..len + 1, len..len + 1,
tokens.into_iter(), tokens.into_iter(),
)); ));
return (ast, parse_error) (ast, parse_error)
} }
#[cfg(test)] #[cfg(test)]

View file

@ -29,7 +29,7 @@ pub struct TypecheckError {
pub span: std::ops::Range<usize>, pub span: std::ops::Range<usize>,
} }
pub fn check(irs: &Vec<IR>) -> Result<(), Vec<TypecheckError>> { pub fn check(irs: &[IR]) -> Result<(), Vec<TypecheckError>> {
let mut errors = Vec::new(); let mut errors = Vec::new();
for ir in irs { for ir in irs {
match &ir.kind { match &ir.kind {

View file

@ -1,3 +0,0 @@
fun main : int = do
"Hello, World" |> @write();
end;