Skip to content

Commit

Permalink
Add more test cases fix discovered issues
Browse files Browse the repository at this point in the history
- Parse negative exponent reals
  - Produces errors on certain float literals, see rust-lang/rust#31407
- Switch order of checking for type references in init exprs
- Report an error when using type references as initializer values in
  var and const decls
- Don't use empty exprs when reporting the wrong number of init values
- Report when a forward type is not resolved
- Report errors on zero sized ranges in normal arrays
- Report errros on non-index type range specifiers in arrays
- Don't print out code unit
  • Loading branch information
DropDemBits committed Aug 17, 2020
1 parent ebe6e3c commit cd46ed7
Show file tree
Hide file tree
Showing 8 changed files with 324 additions and 35 deletions.
4 changes: 4 additions & 0 deletions src/compiler/frontend/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1507,6 +1507,10 @@ type enumeration : enum (a, b, c, d, e, f)
assert_eq!(parser.parse(), true);
let mut parser = make_test_parser("const a := 1 or 1");
assert_eq!(parser.parse(), true);
let mut parser = make_test_parser("const a := 1 & 1");
assert_eq!(parser.parse(), true);
let mut parser = make_test_parser("const a := 1 | 1");
assert_eq!(parser.parse(), true);
let mut parser = make_test_parser("const a := 1 xor 1");
assert_eq!(parser.parse(), true);
let mut parser = make_test_parser("const a := 1 in 1");
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/frontend/parser/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ impl<'s> Parser<'s> {
.types()
.type_from_ref(&ident.type_spec)
}) {
// Resolve forwards (otherwise `is_resolved` would be false)
// Resolve forwards (otherwise `is_resolved` would be true)

// We known that the old ident is valid (from above condtion)
let old_ident = old_ident.unwrap();
Expand Down
28 changes: 28 additions & 0 deletions src/compiler/frontend/scanner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,11 @@ impl<'s> Scanner<'s> {
// Nom the 'e'
self.next_char();

if self.peek == '-' {
// Consume negative exponent sign
self.next_char();
}

// Parse the exponent digits
while matches!(self.peek, '0'..='9') {
self.next_char();
Expand Down Expand Up @@ -1166,6 +1171,12 @@ mod test {
// Should still produce a token
assert_eq!(scanner.tokens[0].token_type, TokenType::NatLiteral(0));

// Out of range (= overflow)
let mut scanner = Scanner::new("18446744073709551616#0000");
assert!(!scanner.scan_tokens());
// Should still produce a token
assert_eq!(scanner.tokens[0].token_type, TokenType::NatLiteral(0));

// Invalid digit
let mut scanner = Scanner::new("10#999a999");
assert!(!scanner.scan_tokens());
Expand Down Expand Up @@ -1199,6 +1210,13 @@ mod test {
TokenType::RealLiteral(100.00e100)
);

let mut scanner = Scanner::new("100.00e-100");
assert!(scanner.scan_tokens());
assert_eq!(
scanner.tokens[0].token_type,
TokenType::RealLiteral(100.00e-100)
);

let mut scanner = Scanner::new("1e100");
assert!(scanner.scan_tokens());
assert_eq!(scanner.tokens[0].token_type, TokenType::RealLiteral(1e100));
Expand All @@ -1209,6 +1227,16 @@ mod test {
// Should still produce a value
assert_eq!(scanner.tokens[0].token_type, TokenType::RealLiteral(0f64));

let mut scanner = Scanner::new("1e-");
assert!(!scanner.scan_tokens());
// Should still produce a value
assert_eq!(scanner.tokens[0].token_type, TokenType::RealLiteral(0f64));

let mut scanner = Scanner::new("1e--2");
assert!(!scanner.scan_tokens());
// Should still produce a value
assert_eq!(scanner.tokens[0].token_type, TokenType::RealLiteral(0f64));

// Too big
let mut scanner = Scanner::new("1e600");
assert!(!scanner.scan_tokens());
Expand Down
22 changes: 11 additions & 11 deletions src/compiler/frontend/validator/expr_resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ impl Validator {
expr.set_span(span);
}

if !matches!(expr, Expr::Empty) && !expr.is_compile_eval() {
if super::is_type_reference(expr) {
self.reporter.report_error(
expr.get_span(),
format_args!("Expression is not a compile-time expression"),
format_args!("Reference does not refer to a variable or constant"),
);
} else if super::is_type_reference(expr) {
} else if !matches!(expr, Expr::Empty) && !expr.is_compile_eval() {
self.reporter.report_error(
expr.get_span(),
format_args!("Reference does not refer to a variable or constant"),
format_args!("Expression is not a compile-time expression"),
);
}
}
Expand Down Expand Up @@ -323,13 +323,13 @@ impl Validator {
*is_compile_eval = false;

match op {
TokenType::Not => self.reporter.report_error(loc, format_args!("Operand of 'not' must be an integer (int or nat) or a boolean")),
TokenType::Plus => self.reporter.report_error(loc, format_args!("Operand of prefix '+' must be a scalar (int, real, or nat)")),
TokenType::Minus => self.reporter.report_error(loc, format_args!("Operand of unary negation must be a scalar (int, real, or nat)")),
TokenType::Caret => self.reporter.report_error(loc, format_args!("Operand of pointer dereference must be a pointer")),
TokenType::Pound => self.reporter.report_error(loc, format_args!("Operand of nat cheat must be a literal, or a reference to a variable or constant")),
_ => unreachable!()
}
TokenType::Not => self.reporter.report_error(loc, format_args!("Operand of 'not' must be an integer (int or nat) or a boolean")),
TokenType::Plus => self.reporter.report_error(loc, format_args!("Operand of prefix '+' must be a scalar (int, real, or nat)")),
TokenType::Minus => self.reporter.report_error(loc, format_args!("Operand of unary negation must be a scalar (int, real, or nat)")),
TokenType::Caret => self.reporter.report_error(loc, format_args!("Operand of pointer dereference must be a pointer")),
TokenType::Pound => self.reporter.report_error(loc, format_args!("Operand of nat cheat must be a literal, or a reference to a variable or constant")),
_ => unreachable!()
}

// Produce no value
return None;
Expand Down
Loading

0 comments on commit cd46ed7

Please sign in to comment.