Skip to content

Commit

Permalink
feat: Minimal scan errors
Browse files Browse the repository at this point in the history
  • Loading branch information
can-keklik committed Nov 22, 2023
1 parent d7ba04c commit 5bb44fa
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 45 deletions.
7 changes: 7 additions & 0 deletions examples/scan_err.ly
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Define recursive Fibonacci function
fun fib($n) {
if ($n < 2) return $n;
return fib($n - 2) + fib($n - 1);
}

"some unterminated string
1 change: 0 additions & 1 deletion src/lang/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ pub enum Expr {
Call(ExprId, Token, Vec<ExprId>),
}


pub type ExprId = usize;
pub type StmtId = usize;

Expand Down
8 changes: 2 additions & 6 deletions src/lang/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,9 +278,7 @@ impl<'a> Parser<'a> {
let value = self.assignment()?;
match self.arena.get_expression(expr) {
Variable(tok) => {
return Ok(self
.arena
.expression(Expr::Assignment(tok.clone(), value)));
return Ok(self.arena.expression(Expr::Assignment(tok.clone(), value)));
}
_ => {
return Err(ParseError::InvalidAssignmentTarget {
Expand Down Expand Up @@ -463,9 +461,7 @@ impl<'a> Parser<'a> {
}
let paren = self.expected(sym!(RightParen))?.clone();

Ok(self
.arena
.expression(Expr::Call(callee, paren, arguments)))
Ok(self.arena.expression(Expr::Call(callee, paren, arguments)))
}

fn call(&mut self) -> ParseResult<ExprId> {
Expand Down
2 changes: 1 addition & 1 deletion src/lang/scanner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ impl Scanner {
}

if self.is_at_end() {
let err_span: String = self.chars[self.start + 1..self.current - 1]
let err_span: String = self.chars[self.start + 1..self.current]
.iter()
.collect();
return Err(ScanError::UnterminatedString {
Expand Down
58 changes: 23 additions & 35 deletions src/runtime/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,43 +7,31 @@ pub enum ExecutionError {
Parse(ParseError),
Resolve(ResolveError),
}
/*
fn report() {
use ariadne::{Color, ColorGenerator, Fmt, Label, Report, ReportKind, Source};

let mut colors = ColorGenerator::new();
pub fn report_error(filename: &str, source: &str, error: ScanError) {
use ariadne::{Color, Fmt, Label, Report, ReportKind, Source};

// Generate & choose some colours for each of our elements
let a = colors.next();
let b = colors.next();
let out = Color::Fixed(81);

Report::build(ReportKind::Error, filename, 12)
.with_code(3)
.with_message(format!("Incompatible types"))
.with_label(
Label::new((filename, 12..13))
.with_message(format!("This is of type {}", "Nat".fg(a)))
.with_color(a),
)
.with_label(
Label::new((filename, 2..5))
.with_message(format!("This is of type {}", "Str".fg(b)))
.with_color(b),
)
.with_label(
Label::new((filename, 1..4))
.with_message(format!(
"The values are outputs of this {} expression",
"match".fg(out),
))
.with_color(out),
)
.with_note(format!(
"Outputs of {} expressions must coerce to the same type",
"match".fg(out)
))
.finish()
.print((filename, Source::from(filename)))
.unwrap();
} */
match error {
ScanError::UnexpectedCharacter { span, message }|
ScanError::UnterminatedString { span, message } |
ScanError::MalformedNumberLiteral { span, message } => {
Report::build(ReportKind::Error, filename, 12)
.with_code(3)
.with_message(message)
.with_label(
Label::new((filename, span.start..span.start + span.lexeme.len()))
.with_message(format!(
"The values are outputs of this {} expression",
"match".fg(out),
))
.with_color(out),
)
.finish()
.print((filename, Source::from(&source)))
.unwrap();
}
}
}
9 changes: 7 additions & 2 deletions src/runtime/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use self::error::report_error;
use self::resolver::Resolver;
use crate::lang::ast::Visitor;
use crate::lang::parser::Parser;
Expand Down Expand Up @@ -84,8 +85,12 @@ impl Runtime {
}

pub fn interpret(&mut self, source: &str) {
let tokens = Scanner::scan(source).unwrap();
let parsed = Parser::parse(&tokens);
let tokens = Scanner::scan(source);
if tokens.is_err() {
report_error("filename", source, tokens.err().unwrap());
return;
}
let parsed = Parser::parse(&tokens.unwrap());
let arena = Rc::clone(&parsed.arena);
//
let mut resolver = Resolver::new(arena.clone());
Expand Down

0 comments on commit 5bb44fa

Please sign in to comment.