@@ -405,6 +405,28 @@ std::unique_ptr<Expr> Parser::parseArrayExpr() {
405405 return std::make_unique<ArrayLiteral>(std::move (elements));
406406}
407407
408+ std::unique_ptr<Expr> Parser::parseCallbackFunctionExpr () {
409+ std::vector<Token> params;
410+ while (!(peek ().tag == Token::TypeTag::SYNTAX && peek ().type .syntaxToken == SyntaxToken::CLOSE_PARENTHESIS)) {
411+ if (params.size () > 0 ) {
412+ assertToken (" SyntaxToken::COMMA" , " Expected comma between callback function parameters." );
413+ }
414+ params.push_back (assertToken (" DataToken::IDENTIFIER" , " Expected identifier in callback function parameters." ));
415+ }
416+ assertToken (" SyntaxToken::CLOSE_PARENTHESIS" , " Expected closing parenthesis after callback function parameters." );
417+ assertToken (" SyntaxToken::CALLBACK" , " Expected '=>' to start callback function body." );
418+ std::vector<std::unique_ptr<Stmt>> body = {};
419+ if (peek ().tag == Token::TypeTag::SYNTAX && peek ().type .syntaxToken == SyntaxToken::OPEN_BRACE) {
420+ assertToken (" SyntaxToken::OPEN_BRACE" , " Expected '{' to start callback function body." );
421+ body = parseStatementBlock ();
422+ } else {
423+ body.push_back (parseStatement ());
424+ skipSemicolon ();
425+ }
426+ skipSemicolon ();
427+ return std::make_unique<CallbackFunctionExpr>(std::move (params), std::move (body));
428+ }
429+
408430std::unique_ptr<Expr> Parser::parseShortData () {
409431 assertToken (" SyntaxToken::AT" , " Expected '@' to start short data notation." );
410432 // Short Notation -> Object @ key:value, key:value
@@ -598,12 +620,31 @@ std::unique_ptr<Expr> Parser::parsePrimaryExpr() {
598620 } else if (token.tag == Token::TypeTag::SYNTAX) {
599621 std::unique_ptr<Expr> expression;
600622 std::string value;
623+ int i, scope = 0 ;
601624 switch (token.type .syntaxToken ) {
602625 case SyntaxToken::OPEN_PARENTHESIS:
603626 assertToken (" SyntaxToken::OPEN_PARENTHESIS" , " Expected '(' to start parenthesised expression." );
604- expression = parseExpression ();
605- assertToken (" SyntaxToken::CLOSE_PARENTHESIS" ,
606- " Unexpected token found inside parenthesised expression. Expected closing parenthesis." );
627+ while (true ) {
628+ i++;
629+ if (lookAhead (i).tag == Token::TypeTag::SYNTAX &&
630+ lookAhead (i).type .syntaxToken == SyntaxToken::OPEN_PARENTHESIS) {
631+ scope++;
632+ } else if (lookAhead (i).tag == Token::TypeTag::SYNTAX &&
633+ lookAhead (i).type .syntaxToken == SyntaxToken::CLOSE_PARENTHESIS) {
634+ if (scope == 0 ) {
635+ break ;
636+ }
637+ scope--;
638+ }
639+ }
640+ if (lookAhead (i + 1 ).tag == Token::TypeTag::SYNTAX &&
641+ lookAhead (i + 1 ).type .syntaxToken == SyntaxToken::CALLBACK) {
642+ expression = parseCallbackFunctionExpr ();
643+ } else {
644+ expression = parseExpression ();
645+ assertToken (" SyntaxToken::CLOSE_PARENTHESIS" ,
646+ " Unexpected token found inside parenthesised expression. Expected closing parenthesis." );
647+ }
607648 return expression;
608649 case SyntaxToken::DOUBLE_QUOTE:
609650 assertToken (" SyntaxToken::DOUBLE_QUOTE" , " Expected opening double quote" );
@@ -731,6 +772,14 @@ Token Parser::peek(int steps) {
731772 }
732773}
733774
775+ Token Parser::lookAhead (int steps) {
776+ if (tokens.size () < steps) {
777+ throw std::runtime_error (" Unexpected end of file" );
778+ } else {
779+ return tokens[steps - 1 ];
780+ }
781+ }
782+
734783Token Parser::advance () {
735784 Token token = tokens.front ();
736785 tokens.erase (tokens.begin ());
0 commit comments