Don't have keywords in the lexer and parser.
Instead of recognizing "function" as a keyword, simply match it as a context-sensitive keyword in the parser outside functions.
This commit is contained in:
5
filetests/parser/keywords.cton
Normal file
5
filetests/parser/keywords.cton
Normal file
@@ -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()
|
||||||
@@ -26,7 +26,6 @@ pub enum Token<'a> {
|
|||||||
Colon, // ':'
|
Colon, // ':'
|
||||||
Equal, // '='
|
Equal, // '='
|
||||||
Arrow, // '->'
|
Arrow, // '->'
|
||||||
Function, // 'function'
|
|
||||||
Float(&'a str), // Floating point immediate
|
Float(&'a str), // Floating point immediate
|
||||||
Integer(&'a str), // Integer immediate
|
Integer(&'a str), // Integer immediate
|
||||||
Type(types::Type), // i32, f32, b32x4, ...
|
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
|
// 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.
|
// alphabetic char, followed by zero or more alphanumeric or '_' characters.
|
||||||
//
|
|
||||||
//
|
|
||||||
fn scan_word(&mut self) -> Result<LocatedToken<'a>, LocatedError> {
|
fn scan_word(&mut self) -> Result<LocatedToken<'a>, LocatedError> {
|
||||||
let begin = self.pos;
|
let begin = self.pos;
|
||||||
let loc = self.loc();
|
let loc = self.loc();
|
||||||
@@ -252,25 +249,13 @@ impl<'a> Lexer<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let text = &self.source[begin..self.pos];
|
let text = &self.source[begin..self.pos];
|
||||||
|
|
||||||
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);
|
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.
|
// Look for numbered well-known entities like ebb15, v45, ...
|
||||||
fn keyword(text: &str) -> Option<Token<'a>> {
|
token(Self::numbered_entity(prefix, suffix)
|
||||||
match text {
|
.or_else(|| Self::value_type(text, prefix, suffix))
|
||||||
"function" => Some(Token::Function),
|
.unwrap_or(Token::Identifier(text)),
|
||||||
_ => None,
|
loc)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If prefix is a well-known entity prefix and suffix is a valid entity number, return the
|
// 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));
|
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("vxvx4"), 1));
|
||||||
assert_eq!(lex.next(), token(Token::Identifier("function0"), 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::B1), 1));
|
||||||
assert_eq!(lex.next(), token(Token::Type(types::I32.by(4).unwrap()), 1));
|
assert_eq!(lex.next(), token(Token::Type(types::I32.by(4).unwrap()), 1));
|
||||||
assert_eq!(lex.next(), token(Token::Identifier("f32x5"), 1));
|
assert_eq!(lex.next(), token(Token::Identifier("f32x5"), 1));
|
||||||
|
|||||||
@@ -454,7 +454,7 @@ impl<'a> Parser<'a> {
|
|||||||
// function-spec ::= * "function" name signature
|
// function-spec ::= * "function" name signature
|
||||||
//
|
//
|
||||||
fn parse_function_spec(&mut self) -> Result<(Location, FunctionName, 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;
|
let location = self.loc;
|
||||||
|
|
||||||
// function-spec ::= "function" * name signature
|
// function-spec ::= "function" * name signature
|
||||||
|
|||||||
Reference in New Issue
Block a user