|
|
@ -67,6 +67,32 @@ impl Parser { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn parse_function_parameters(&mut self) -> Result<Vec<String>, ParseError> { |
|
|
|
|
|
|
|
self.expect_punc(Punctuator::OpenParen, "function parameters ( expected")?; |
|
|
|
|
|
|
|
let mut args = Vec::new(); |
|
|
|
|
|
|
|
let mut tk = self.get_token(self.pos)?; |
|
|
|
|
|
|
|
while tk.data != TokenData::Punctuator(Punctuator::CloseParen) { |
|
|
|
|
|
|
|
match tk.data { |
|
|
|
|
|
|
|
TokenData::Identifier(ref id) => args.push(id.clone()), |
|
|
|
|
|
|
|
_ => { |
|
|
|
|
|
|
|
return Err(ParseError::Expected( |
|
|
|
|
|
|
|
vec![TokenData::Identifier("identifier".to_string())], |
|
|
|
|
|
|
|
tk.clone(), |
|
|
|
|
|
|
|
"function arguments", |
|
|
|
|
|
|
|
)) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
self.pos += 1; |
|
|
|
|
|
|
|
if self.get_token(self.pos)?.data == TokenData::Punctuator(Punctuator::Comma) { |
|
|
|
|
|
|
|
self.pos += 1; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
tk = self.get_token(self.pos)?; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.expect_punc(Punctuator::CloseParen, "function parameters ) expected")?; |
|
|
|
|
|
|
|
Ok(args) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
fn parse_struct(&mut self, keyword: Keyword) -> ParseResult { |
|
|
|
fn parse_struct(&mut self, keyword: Keyword) -> ParseResult { |
|
|
|
match keyword { |
|
|
|
match keyword { |
|
|
|
Keyword::Throw => { |
|
|
|
Keyword::Throw => { |
|
|
@ -306,27 +332,7 @@ impl Parser { |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
// Now we have the function identifier we should have an open paren for arguments ( )
|
|
|
|
// Now we have the function identifier we should have an open paren for arguments ( )
|
|
|
|
self.expect_punc(Punctuator::OpenParen, "function")?; |
|
|
|
let args = self.parse_function_parameters()?; |
|
|
|
let mut args: Vec<String> = Vec::new(); |
|
|
|
|
|
|
|
let mut tk = self.get_token(self.pos)?; |
|
|
|
|
|
|
|
while tk.data != TokenData::Punctuator(Punctuator::CloseParen) { |
|
|
|
|
|
|
|
match tk.data { |
|
|
|
|
|
|
|
TokenData::Identifier(ref id) => args.push(id.clone()), |
|
|
|
|
|
|
|
_ => { |
|
|
|
|
|
|
|
return Err(ParseError::Expected( |
|
|
|
|
|
|
|
vec![TokenData::Identifier("identifier".to_string())], |
|
|
|
|
|
|
|
tk.clone(), |
|
|
|
|
|
|
|
"function arguments", |
|
|
|
|
|
|
|
)) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
self.pos += 1; |
|
|
|
|
|
|
|
if self.get_token(self.pos)?.data == TokenData::Punctuator(Punctuator::Comma) { |
|
|
|
|
|
|
|
self.pos += 1; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
tk = self.get_token(self.pos)?; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
self.pos += 1; |
|
|
|
|
|
|
|
let block = self.parse()?; |
|
|
|
let block = self.parse()?; |
|
|
|
Ok(mk!( |
|
|
|
Ok(mk!( |
|
|
|
self, |
|
|
|
self, |
|
|
@ -536,17 +542,13 @@ impl Parser { |
|
|
|
self.parse()? |
|
|
|
self.parse()? |
|
|
|
} |
|
|
|
} |
|
|
|
TokenData::Punctuator(Punctuator::OpenParen) => { |
|
|
|
TokenData::Punctuator(Punctuator::OpenParen) => { |
|
|
|
self.pos += 1; |
|
|
|
let args = self.parse_function_parameters()?; |
|
|
|
self.expect( |
|
|
|
|
|
|
|
TokenData::Punctuator(Punctuator::CloseParen), |
|
|
|
|
|
|
|
"Method Block", |
|
|
|
|
|
|
|
)?; |
|
|
|
|
|
|
|
self.pos += 1; // {
|
|
|
|
self.pos += 1; // {
|
|
|
|
let expr = self.parse()?; |
|
|
|
let expr = self.parse()?; |
|
|
|
self.pos += 1; |
|
|
|
self.pos += 1; |
|
|
|
mk!( |
|
|
|
mk!( |
|
|
|
self, |
|
|
|
self, |
|
|
|
ExprDef::FunctionDecl(None, vec!(), Box::new(expr)), |
|
|
|
ExprDef::FunctionDecl(None, args, Box::new(expr)), |
|
|
|
token |
|
|
|
token |
|
|
|
) |
|
|
|
) |
|
|
|
} |
|
|
|
} |
|
|
@ -923,7 +925,7 @@ mod tests { |
|
|
|
); |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
#[test] |
|
|
|
#[test] |
|
|
|
fn check_object() { |
|
|
|
fn check_object_short_function() { |
|
|
|
// Testing short function syntax
|
|
|
|
// Testing short function syntax
|
|
|
|
let mut object_properties: BTreeMap<String, Expr> = BTreeMap::new(); |
|
|
|
let mut object_properties: BTreeMap<String, Expr> = BTreeMap::new(); |
|
|
|
object_properties.insert( |
|
|
|
object_properties.insert( |
|
|
@ -949,6 +951,32 @@ mod tests { |
|
|
|
); |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[test] |
|
|
|
|
|
|
|
fn check_object_short_function_arguments() { |
|
|
|
|
|
|
|
// Testing short function syntax
|
|
|
|
|
|
|
|
let mut object_properties: BTreeMap<String, Expr> = BTreeMap::new(); |
|
|
|
|
|
|
|
object_properties.insert( |
|
|
|
|
|
|
|
String::from("a"), |
|
|
|
|
|
|
|
Expr::new(ExprDef::Const(Const::Bool(true))), |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
object_properties.insert( |
|
|
|
|
|
|
|
String::from("b"), |
|
|
|
|
|
|
|
Expr::new(ExprDef::FunctionDecl( |
|
|
|
|
|
|
|
None, |
|
|
|
|
|
|
|
vec![String::from("test")], |
|
|
|
|
|
|
|
Box::new(Expr::new(ExprDef::Block(vec![]))), |
|
|
|
|
|
|
|
)), |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
check_parser( |
|
|
|
|
|
|
|
"{ |
|
|
|
|
|
|
|
a: true, |
|
|
|
|
|
|
|
b(test) {} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
", |
|
|
|
|
|
|
|
&[Expr::new(ExprDef::ObjectDecl(Box::new(object_properties)))], |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
} |
|
|
|
#[test] |
|
|
|
#[test] |
|
|
|
fn check_array() { |
|
|
|
fn check_array() { |
|
|
|
use crate::syntax::ast::constant::Const; |
|
|
|
use crate::syntax::ast::constant::Const; |
|
|
|