Skip to content

Commit

Permalink
Merge pull request #15 from rozukke/fix/error-messages
Browse files Browse the repository at this point in the history
Fix various error message bugs
  • Loading branch information
rozukke authored Sep 15, 2024
2 parents 2eb28a2 + adfc4e4 commit 3f0b233
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 24 deletions.
32 changes: 24 additions & 8 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ use std::num::ParseIntError;

use miette::{miette, LabeledSpan, Report, Severity};

use crate::{lexer::Token, parser::Bits, symbol::Span};
use crate::{
lexer::{Token, TokenKind},
parser::Bits,
symbol::Span,
};

// Lexer errors

Expand Down Expand Up @@ -53,19 +57,21 @@ pub fn lex_unknown(span: Span, src: &'static str) -> Report {
// Preprocessor errors

pub fn preproc_bad_lit(span: Span, src: &'static str, is_present: bool) -> Report {
let (help, label) = if is_present {
let (help, label, severity) = if is_present {
(
"this directive expects a positive literal",
"you may have meant to use a positive literal",
"negative literal",
Severity::Warning,
)
} else {
(
"this directive requires an integer or hex literal to follow",
"not a numeric literal",
Severity::Error,
)
};
miette!(
severity = Severity::Error,
severity = severity,
code = "preproc::bad_lit",
help = help,
labels = vec![LabeledSpan::at(span, label)],
Expand All @@ -78,7 +84,7 @@ pub fn preproc_no_str(span: Span, src: &'static str) -> Report {
miette!(
severity = Severity::Error,
code = "preproc::stringz",
help = ".stringz requires a valid string literal like \"hello\n\"",
help = ".stringz requires a valid string literal like \"hello\\n\"",
labels = vec![LabeledSpan::at(span, "not a string literal")],
"Expected a valid string literal.",
)
Expand All @@ -99,11 +105,21 @@ pub fn parse_duplicate_label(span: Span, src: &'static str) -> Report {
}

pub fn parse_generic_unexpected(src: &'static str, expected: &str, found: Token) -> Report {
let mut help = "check the operands for this instruction".to_string();
if found.kind == TokenKind::Label {
let label = &src[found.span.offs()..found.span.offs() + found.span.len()];
if label.chars().all(|c| char::is_ascii_digit(&c)) {
help = format!("you may have meant to write a decimal literal: #{}", label)
}
}
miette!(
severity = Severity::Error,
code = "parse::unexpected_token",
help = "check the operands for this instruction",
labels = vec![LabeledSpan::at(found.span, "unexpected token")],
help = help,
labels = vec![LabeledSpan::at(
found.span,
format!("unexpected {}", found.kind)
)],
"Expected token of type {expected}, found {}",
found.kind
)
Expand All @@ -115,7 +131,7 @@ pub fn parse_eof(src: &'static str) -> Report {
severity = Severity::Error,
code = "parse::unexpected_eof",
help = "you may be missing operands in your last statement",
labels = vec![LabeledSpan::at_offset(src.len() - 1, "unexpected token")],
labels = vec![LabeledSpan::at_offset(src.len() - 1, "here")],
"Unexpected end of file",
)
.with_source_code(src)
Expand Down
22 changes: 13 additions & 9 deletions src/lexer/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::fmt::Display;
use std::str::FromStr;
use std::{i16, u16};

use miette::Result;

Expand Down Expand Up @@ -219,13 +220,16 @@ impl Cursor<'_> {
// i16 to handle negative values
let value = match i16::from_str_radix(&str_val, 10) {
Ok(value) => value,
Err(e) => {
return Err(error::lex_invalid_lit(
(start - prefix..self.abs_pos()).into(),
self.src(),
e,
))
}
Err(_) => match u16::from_str_radix(&str_val, 10) {
Ok(val) => val as i16,
Err(e) => {
return Err(error::lex_invalid_lit(
(start - prefix..self.abs_pos()).into(),
self.src(),
e,
))
}
},
};

Ok(TokenKind::Lit(LiteralKind::Dec(value)))
Expand Down Expand Up @@ -408,9 +412,9 @@ mod test {

#[test]
fn dec_too_large() {
let mut lex = Cursor::new("#32767 #32768");
let mut lex = Cursor::new("#65535 #65536");
let res = lex.advance_token().unwrap();
assert!(res.kind == TokenKind::Lit(LiteralKind::Dec(32767)));
assert!(res.kind == TokenKind::Lit(LiteralKind::Dec((65535 as u16) as i16)));
// Whitespace
assert!(lex.advance_real().is_err());
}
Expand Down
21 changes: 18 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,20 @@ fn main() -> miette::Result<()> {
// Available until end of program
let contents: &'static str =
Box::leak(Box::new(fs::read_to_string(&name).into_diagnostic()?));
println!(
"{:>12} {}",
"Assembling".green().bold(),
name.to_str().unwrap()
);
// Process asm
let parser = lace::AsmParser::new(&contents)?;
let mut air = parser.parse()?;
air.backpatch()?;
// Write to file
let mut file = File::create(dest.unwrap_or(
let out_file_name = dest.unwrap_or(
format!("{}.lc3", name.file_stem().unwrap().to_str().unwrap()).into(),
))
.unwrap();
);
let mut file = File::create(&out_file_name).unwrap();
// Deal with .orig
if let Some(orig) = air.orig() {
file.write(&orig.to_be_bytes());
Expand All @@ -87,6 +92,16 @@ fn main() -> miette::Result<()> {
for i in 0..air.len() {
file.write(&air.get(i).emit()?.to_be_bytes());
}
println!(
"{:>12} {}",
"Finished".green().bold(),
name.to_str().unwrap()
);
println!(
"{:>12} {}",
"Saved to".green().bold(),
out_file_name.to_str().unwrap()
);
Ok(())
}
Command::Clean { name } => todo!(),
Expand Down
9 changes: 5 additions & 4 deletions src/parser.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{borrow::Cow, fmt::Display, iter::Peekable, vec::IntoIter};
use std::{borrow::Cow, fmt::Display, iter::Peekable, u16, vec::IntoIter};

use miette::Result;

Expand Down Expand Up @@ -43,9 +43,9 @@ pub fn preprocess(src: &'static str) -> Result<Vec<Token>> {
}
TokenKind::Lit(LiteralKind::Dec(lit)) => {
if lit < 0 {
return Err(error::preproc_bad_lit(val.span, src, true));
println!("{:?}", error::preproc_bad_lit(val.span, src, true));
}
for _ in 0..lit {
for _ in 0..lit as u16 {
res.push(Token::nullbyte());
}
}
Expand Down Expand Up @@ -487,7 +487,8 @@ mod test {

#[test]
fn preproc_blkw_neg() {
assert!(preprocess("temp .blkw #-3").is_err())
// TODO: potentially test for warnings
assert!(preprocess("temp .blkw #-3").is_ok())
}

#[test]
Expand Down

0 comments on commit 3f0b233

Please sign in to comment.