diff --git a/filetests/parser/keywords.cton b/filetests/parser/keywords.cton new file mode 100644 index 0000000000..eb15f2624d --- /dev/null +++ b/filetests/parser/keywords.cton @@ -0,0 +1,5 @@ +test cat + +; 'function' is not a keyword, and can be used as the name of a function too. +function function() {} +; check: function function() diff --git a/src/libreader/lexer.rs b/src/libreader/lexer.rs index 7631e306ad..c57b8290cf 100644 --- a/src/libreader/lexer.rs +++ b/src/libreader/lexer.rs @@ -26,7 +26,6 @@ pub enum Token<'a> { Colon, // ':' Equal, // '=' Arrow, // '->' - Function, // 'function' Float(&'a str), // Floating point immediate Integer(&'a str), // Integer immediate Type(types::Type), // i32, f32, b32x4, ... @@ -235,8 +234,6 @@ impl<'a> Lexer<'a> { // Scan a 'word', which is an identifier-like sequence of characters beginning with '_' or an // alphabetic char, followed by zero or more alphanumeric or '_' characters. - // - // fn scan_word(&mut self) -> Result, LocatedError> { let begin = self.pos; let loc = self.loc(); @@ -252,25 +249,13 @@ impl<'a> Lexer<'a> { } } let text = &self.source[begin..self.pos]; + let (prefix, suffix) = text.split_at(text.len() - trailing_digits); - match if trailing_digits == 0 { - Self::keyword(text) - } else { - // Look for numbered well-known entities like ebb15, v45, ... - let (prefix, suffix) = text.split_at(text.len() - trailing_digits); - Self::numbered_entity(prefix, suffix).or_else(|| Self::value_type(text, prefix, suffix)) - } { - Some(t) => token(t, loc), - None => token(Token::Identifier(text), loc), - } - } - - // Recognize a keyword. - fn keyword(text: &str) -> Option> { - match text { - "function" => Some(Token::Function), - _ => None, - } + // Look for numbered well-known entities like ebb15, v45, ... + token(Self::numbered_entity(prefix, suffix) + .or_else(|| Self::value_type(text, prefix, suffix)) + .unwrap_or(Token::Identifier(text)), + loc) } // If prefix is a well-known entity prefix and suffix is a valid entity number, return the @@ -458,7 +443,7 @@ mod tests { token(Token::Value(Value::table_with_number(1).unwrap()), 1)); assert_eq!(lex.next(), token(Token::Identifier("vxvx4"), 1)); assert_eq!(lex.next(), token(Token::Identifier("function0"), 1)); - assert_eq!(lex.next(), token(Token::Function, 1)); + assert_eq!(lex.next(), token(Token::Identifier("function"), 1)); assert_eq!(lex.next(), token(Token::Type(types::B1), 1)); assert_eq!(lex.next(), token(Token::Type(types::I32.by(4).unwrap()), 1)); assert_eq!(lex.next(), token(Token::Identifier("f32x5"), 1)); diff --git a/src/libreader/parser.rs b/src/libreader/parser.rs index 45177aace7..6f65cbafa3 100644 --- a/src/libreader/parser.rs +++ b/src/libreader/parser.rs @@ -454,7 +454,7 @@ impl<'a> Parser<'a> { // function-spec ::= * "function" name signature // fn parse_function_spec(&mut self) -> Result<(Location, FunctionName, Signature)> { - try!(self.match_token(Token::Function, "expected 'function' keyword")); + try!(self.match_identifier("function", "expected 'function'")); let location = self.loc; // function-spec ::= "function" * name signature