After analyzing the failing tests and parser errors, I've identified several issues with interface method declarations and type handling. This document outlines a detailed plan to fix the parser to properly support interfaces.
-
Method Declaration Syntax: Parser fails to handle both dot notation (
Person.greet()
) and colon notation (Person:greet()
). -
Interface Method Signatures: Fails to parse method signatures like
greet() tea;
in interface definitions. -
Type Annotations: Cannot parse type annotations in variable declarations like
sus g Greeter = p;
.
The following tests are currently failing:
failures:
test_interface_generic
test_interface_multiple
test_interface_simple
All these failures stem from parser limitations in handling interface syntax.
// in parse_method_declaration function
pub fn parse_method_declaration(&mut self) -> Result<Box<dyn Statement>, Error> {
// Store the 'slay' token
let token = self.current_token.token_literal();
// Parse receiver type (struct name)
if !self.expect_peek_identifier() {
return Err(Error::from_str(&format!("Expected identifier after 'slay', got {:?}", self.peek_token)));
}
let receiver_type = ast::Identifier {
token: self.current_token.token_literal(),
value: self.current_token.token_literal(),
};
// Support both colon and dot notation
if !(self.expect_peek(&Token::Colon) || self.expect_peek(&Token::Dot)) {
return Err(Error::from_str(&format!("Expected ':' or '.' after receiver type, got {:?}", self.peek_token)));
}
// Rest of method parsing...
// in parse_collab_statement function
fn parse_collab_statement(&mut self, token: String, name: ast::Identifier, type_parameters: Vec<ast::Identifier>) -> Result<Box<dyn Statement>, Error> {
// ... existing code ...
// Parse method signature
if let Token::Identifier(method_name) = &self.current_token {
let method_id = ast::Identifier {
token: self.current_token.token_literal(),
value: method_name.clone(),
};
// Handle parameter list - make LParen optional for parameterless methods
let params = if self.peek_token == Token::LParen {
self.next_token()?; // consume LParen
self.parse_parameters()?
} else {
Vec::new() // No parameters
};
// Handle return type
let return_type = if let Token::Identifier(_) = &self.current_token {
Some(/* parse return type */)
} else {
None
};
// ... rest of method signature parsing
}
// in parse_let_statement
fn parse_let_statement(&mut self) -> Result<Box<dyn Statement>, Error> {
// ... existing code ...
// After parsing variable name, check for type annotation
if let Token::Identifier(_) = &self.peek_token {
self.next_token()?; // consume type name
// Now expect '=' for the value
if !self.expect_peek(&Token::Assign) {
return Err(Error::from_str(&format!("Expected '=' after type annotation, got {:?}", self.peek_token)));
}
}
// ... rest of variable parsing
}
- Create isolated test cases for each feature to test incrementally
- Implement fixes one at a time, starting with method declarations
- Add extensive error reporting to help diagnose future issues
- Add parser unit tests for each fix to ensure correctness
- Update grammar documentation to clearly specify both supported syntaxes
-
Create minimal test cases for each syntax feature:
- Method declaration (both dot and colon notation)
- Interface method signatures
- Type annotations in variable declarations
-
Expand to integration tests with full interfaces once individual features work
-
Ensure backward compatibility with existing code
Once these parser changes are implemented, the interface tests should pass without requiring test modifications.
After implementation, the following documentation should be updated:
specs/grammar.md
- Document supported interface syntaxspecs/types.md
- Clarify interface method signatures- Add examples showing correct interface usage