mirror of
https://github.com/azur1s/bobbylisp.git
synced 2024-10-16 02:37:40 -05:00
Compare commits
2 commits
d696c17b05
...
9c1e0927da
Author | SHA1 | Date | |
---|---|---|---|
Natapat Samutpong | 9c1e0927da | ||
Natapat Samutpong | 834e203c53 |
|
@ -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,7 +69,7 @@ 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)) },
|
||||||
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
);
|
);
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue