Add function test
This commit is contained in:
parent
b7153df9be
commit
6bcc5b1555
@ -125,6 +125,10 @@ impl<'src> Lexer<'src> {
|
||||
self.position += 2;
|
||||
|
||||
(Token::MinusEqual, Span(self.position - 2, self.position))
|
||||
} else if let Some('>') = second_char {
|
||||
self.position += 2;
|
||||
|
||||
(Token::ArrowThin, Span(self.position - 2, self.position))
|
||||
} else if let Some('0'..='9') = second_char {
|
||||
self.lex_numeric()?
|
||||
} else if "-Infinity" == self.peek_chars(9) {
|
||||
|
@ -1111,6 +1111,20 @@ impl<'src> Parser<'src> {
|
||||
}
|
||||
|
||||
function_parser.advance()?;
|
||||
|
||||
let return_type = if function_parser.allow(Token::ArrowThin)? {
|
||||
let r#type = function_parser.parse_type_from(
|
||||
function_parser.current_token,
|
||||
function_parser.current_position,
|
||||
)?;
|
||||
|
||||
function_parser.advance()?;
|
||||
|
||||
Some(Box::new(r#type))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
function_parser.expect(Token::LeftCurlyBrace)?;
|
||||
|
||||
while function_parser.current_token != Token::RightCurlyBrace {
|
||||
@ -1131,7 +1145,6 @@ impl<'src> Parser<'src> {
|
||||
self.current_token = function_parser.current_token;
|
||||
self.current_position = function_parser.current_position;
|
||||
|
||||
let return_type = take(&mut self.latest_value_type).map(Box::new);
|
||||
let function_type = FunctionType {
|
||||
type_parameters: None,
|
||||
value_parameters,
|
||||
@ -1300,6 +1313,11 @@ struct ParseRule<'a> {
|
||||
impl From<&Token<'_>> for ParseRule<'_> {
|
||||
fn from(token: &Token) -> Self {
|
||||
match token {
|
||||
Token::ArrowThin => ParseRule {
|
||||
prefix: Some(Parser::expect_expression),
|
||||
infix: None,
|
||||
precedence: Precedence::None,
|
||||
},
|
||||
Token::Async => todo!(),
|
||||
Token::Bang => ParseRule {
|
||||
prefix: Some(Parser::parse_unary),
|
||||
|
@ -38,6 +38,7 @@ pub enum Token<'src> {
|
||||
While,
|
||||
|
||||
// Symbols
|
||||
ArrowThin,
|
||||
BangEqual,
|
||||
Bang,
|
||||
Colon,
|
||||
@ -84,6 +85,7 @@ impl<'src> Token<'src> {
|
||||
Token::Integer(text) => text.len(),
|
||||
Token::String(text) => text.len() + 2,
|
||||
Token::Async => 5,
|
||||
Token::ArrowThin => 2,
|
||||
Token::Bool => 4,
|
||||
Token::Break => 5,
|
||||
Token::Else => 4,
|
||||
@ -144,6 +146,7 @@ impl<'src> Token<'src> {
|
||||
Token::Integer(text) => text,
|
||||
Token::String(text) => text,
|
||||
Token::Async => "async",
|
||||
Token::ArrowThin => "->",
|
||||
Token::Bool => "bool",
|
||||
Token::Break => "break",
|
||||
Token::Else => "else",
|
||||
@ -195,6 +198,7 @@ impl<'src> Token<'src> {
|
||||
|
||||
pub fn to_owned(&self) -> TokenOwned {
|
||||
match self {
|
||||
Token::ArrowThin => TokenOwned::ArrowThin,
|
||||
Token::Async => TokenOwned::Async,
|
||||
Token::BangEqual => TokenOwned::BangEqual,
|
||||
Token::Bang => TokenOwned::Bang,
|
||||
@ -255,6 +259,7 @@ impl<'src> Token<'src> {
|
||||
|
||||
pub fn kind(&self) -> TokenKind {
|
||||
match self {
|
||||
Token::ArrowThin => TokenKind::ArrowThin,
|
||||
Token::Async => TokenKind::Async,
|
||||
Token::BangEqual => TokenKind::BangEqual,
|
||||
Token::Bang => TokenKind::Bang,
|
||||
@ -359,6 +364,7 @@ impl<'src> Token<'src> {
|
||||
impl<'src> Display for Token<'src> {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Token::ArrowThin => write!(f, "->"),
|
||||
Token::Async => write!(f, "async"),
|
||||
Token::BangEqual => write!(f, "!="),
|
||||
Token::Bang => write!(f, "!"),
|
||||
@ -436,6 +442,7 @@ pub enum TokenOwned {
|
||||
String(String),
|
||||
|
||||
// Keywords
|
||||
Async,
|
||||
Bool,
|
||||
Break,
|
||||
Else,
|
||||
@ -452,7 +459,7 @@ pub enum TokenOwned {
|
||||
While,
|
||||
|
||||
// Symbols
|
||||
Async,
|
||||
ArrowThin,
|
||||
Bang,
|
||||
BangEqual,
|
||||
Colon,
|
||||
@ -490,6 +497,7 @@ pub enum TokenOwned {
|
||||
impl Display for TokenOwned {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
TokenOwned::ArrowThin => Token::ArrowThin.fmt(f),
|
||||
TokenOwned::Async => Token::Async.fmt(f),
|
||||
TokenOwned::Bang => Token::Bang.fmt(f),
|
||||
TokenOwned::BangEqual => Token::BangEqual.fmt(f),
|
||||
@ -581,6 +589,7 @@ pub enum TokenKind {
|
||||
While,
|
||||
|
||||
// Symbols
|
||||
ArrowThin,
|
||||
BangEqual,
|
||||
Bang,
|
||||
Colon,
|
||||
@ -619,6 +628,7 @@ pub enum TokenKind {
|
||||
impl Display for TokenKind {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
TokenKind::ArrowThin => Token::ArrowThin.fmt(f),
|
||||
TokenKind::Async => Token::Async.fmt(f),
|
||||
TokenKind::Bang => Token::Bang.fmt(f),
|
||||
TokenKind::BangEqual => Token::BangEqual.fmt(f),
|
||||
|
@ -316,6 +316,36 @@ fn equality_assignment_short() {
|
||||
assert_eq!(run(source), Ok(Some(Value::boolean(true))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn function() {
|
||||
let source = "fn(a: int, b: int) -> int { a + b }";
|
||||
|
||||
assert_eq!(
|
||||
run(source),
|
||||
Ok(Some(Value::function(
|
||||
Chunk::with_data(
|
||||
vec![
|
||||
(Instruction::add(2, 0, 1), Span(30, 31)),
|
||||
(Instruction::r#return(true), Span(34, 35)),
|
||||
],
|
||||
vec![],
|
||||
vec![
|
||||
Local::new(Identifier::new("a"), Some(Type::Integer), false, 0, 0),
|
||||
Local::new(Identifier::new("b"), Some(Type::Integer), false, 0, 1)
|
||||
]
|
||||
),
|
||||
FunctionType {
|
||||
type_parameters: None,
|
||||
value_parameters: Some(vec![
|
||||
(Identifier::new("a"), Type::Integer),
|
||||
(Identifier::new("b"), Type::Integer)
|
||||
]),
|
||||
return_type: Some(Box::new(Type::Integer)),
|
||||
}
|
||||
)))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn greater() {
|
||||
let source = "1 > 2";
|
||||
|
Loading…
Reference in New Issue
Block a user