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